Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Thu, 15 Mar 2012 17:21:05 -0700
changeset 112857 7d23c3ea2afe4f01716d32f376176036151c6419
parent 112856 49a7d5a3b400157aad17a8cd04dc057734eac4ed (current diff)
parent 93175 2b1950d50397373728c160faba95d980528ae404 (diff)
child 112858 da20de5ab4b87f7042aedf4c8b026368cb98c41e
push id239
push userakeybl@mozilla.com
push dateThu, 03 Jan 2013 21:54:43 +0000
treeherdermozilla-release@3a7b66445659 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/src/base/AccIterator.cpp
accessible/src/base/AccIterator.h
accessible/src/base/NotificationController.cpp
accessible/src/base/nsARIAMap.cpp
accessible/src/base/nsARIAMap.h
accessible/src/base/nsAccessible.cpp
accessible/src/html/nsHyperTextAccessible.cpp
accessible/tests/mochitest/states.js
accessible/tests/mochitest/states/Makefile.in
accessible/tests/mochitest/states/test_inputs.xul
b2g/chrome/jar.mn
b2g/confvars.sh
b2g/installer/package-manifest.in
browser/app/profile/firefox.js
browser/base/content/browser.js
browser/base/content/browser.xul
browser/components/migration/src/nsBrowserProfileMigratorUtils.cpp
browser/components/migration/src/nsBrowserProfileMigratorUtils.h
browser/components/migration/src/nsIEProfileMigrator.cpp
browser/components/migration/src/nsSafariProfileMigrator.cpp
browser/components/migration/tests/unit/bookmarks.html
browser/components/nsBrowserGlue.js
browser/devtools/styleinspector/CssLogic.jsm
browser/devtools/styleinspector/StyleInspector.jsm
browser/locales/en-US/chrome/browser/browser.properties
browser/locales/en-US/chrome/browser/devtools/styleinspector.properties
config/system-headers
configure.in
content/base/public/nsContentUtils.h
content/base/public/nsDOMFile.h
content/base/public/nsIContent.h
content/base/public/nsIDocument.h
content/base/public/nsINode.h
content/base/src/Makefile.in
content/base/src/nsAttrAndChildArray.cpp
content/base/src/nsAttrAndChildArray.h
content/base/src/nsAttrValue.cpp
content/base/src/nsAttrValue.h
content/base/src/nsCommentNode.cpp
content/base/src/nsContentList.cpp
content/base/src/nsContentList.h
content/base/src/nsContentUtils.cpp
content/base/src/nsDOMFile.cpp
content/base/src/nsDOMTokenList.cpp
content/base/src/nsDOMTokenList.h
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/base/src/nsFrameLoader.cpp
content/base/src/nsFrameLoader.h
content/base/src/nsGenericDOMDataNode.cpp
content/base/src/nsGenericDOMDataNode.h
content/base/src/nsGenericElement.cpp
content/base/src/nsGenericElement.h
content/base/src/nsLineBreaker.cpp
content/base/src/nsMappedAttributeElement.h
content/base/src/nsMappedAttributes.cpp
content/base/src/nsMappedAttributes.h
content/base/src/nsStyledElement.h
content/base/src/nsTextFragment.cpp
content/base/src/nsTextFragment.h
content/base/src/nsTextNode.cpp
content/base/src/nsTextNode.h
content/events/src/nsDOMTouchEvent.h
content/events/src/nsEventListenerManager.cpp
content/events/src/nsEventListenerManager.h
content/html/content/src/nsFormSubmission.cpp
content/html/content/src/nsGenericHTMLElement.h
content/html/content/src/nsHTMLAnchorElement.cpp
content/html/content/src/nsHTMLAreaElement.cpp
content/html/content/src/nsHTMLDivElement.cpp
content/html/content/src/nsHTMLFormElement.cpp
content/html/content/src/nsHTMLLinkElement.cpp
content/html/content/src/nsHTMLSelectElement.cpp
content/html/content/src/nsHTMLSelectElement.h
content/html/content/src/nsHTMLTableElement.cpp
content/html/document/src/nsHTMLDocument.cpp
content/html/document/src/nsHTMLDocument.h
content/svg/content/src/DOMSVGLengthList.h
content/svg/content/src/DOMSVGNumberList.h
content/svg/content/src/DOMSVGPathSegList.cpp
content/svg/content/src/DOMSVGPathSegList.h
content/svg/content/src/DOMSVGPointList.cpp
content/svg/content/src/DOMSVGPointList.h
content/svg/content/src/DOMSVGTransformList.h
content/xbl/src/nsBindingManager.cpp
content/xml/content/src/nsXMLCDATASection.cpp
content/xml/content/src/nsXMLProcessingInstruction.h
content/xml/document/src/nsXMLDocument.cpp
content/xml/document/src/nsXMLDocument.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/base/nsDOMWindowUtils.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsJSEnvironment.cpp
dom/base/nsWrapperCache.h
dom/dom-config.mk
dom/indexedDB/IDBCursor.cpp
dom/indexedDB/IDBTransaction.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
dom/interfaces/geolocation/nsIDOMGeoPositionAddress.idl
dom/interfaces/html/nsIDOMHTMLDocument.idl
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/PContent.ipdl
dom/plugins/base/nsJSNPRuntime.cpp
dom/plugins/base/nsNPAPIPlugin.cpp
dom/plugins/base/nsNPAPIPlugin.h
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginInstance.h
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/base/nsPluginInstanceOwner.h
dom/plugins/base/nsPluginNativeWindowGtk2.cpp
dom/plugins/ipc/PPluginModule.ipdl
dom/plugins/ipc/PluginInstanceChild.cpp
dom/plugins/ipc/PluginInstanceChild.h
dom/plugins/ipc/PluginInstanceParent.cpp
dom/plugins/ipc/PluginInstanceParent.h
dom/plugins/ipc/PluginMessageUtils.h
dom/plugins/ipc/PluginModuleChild.cpp
dom/plugins/ipc/PluginModuleChild.h
dom/plugins/ipc/PluginModuleParent.cpp
dom/plugins/test/reftest/reftest.list
dom/system/b2g/AudioManager.cpp
dom/system/b2g/AudioManager.h
dom/system/b2g/GonkGPSGeolocationProvider.cpp
dom/system/b2g/GonkGPSGeolocationProvider.h
dom/system/b2g/Makefile.in
dom/system/b2g/RadioInterfaceLayer.js
dom/system/b2g/RadioInterfaceLayer.manifest
dom/system/b2g/SystemWorkerManager.cpp
dom/system/b2g/SystemWorkerManager.h
dom/system/b2g/net_worker.js
dom/system/b2g/nsIAudioManager.idl
dom/system/b2g/nsIRadioInterfaceLayer.idl
dom/system/b2g/nsIWorkerHolder.idl
dom/system/b2g/nsRadioInterfaceLayer.h
dom/system/b2g/ril_consts.js
dom/system/b2g/ril_worker.js
dom/system/b2g/systemlibs.js
dom/system/b2g/tests/header_helpers.js
dom/system/b2g/tests/test_ril_worker_buf.js
dom/system/b2g/tests/test_ril_worker_sms.js
dom/system/b2g/tests/xpcshell.ini
dom/system/nsDeviceMotion.cpp
dom/system/nsDeviceMotion.h
dom/system/windows/nsDeviceMotionSystem.cpp
editor/composer/src/nsEditorParserObserver.cpp
editor/composer/src/nsEditorParserObserver.h
embedding/android/GeckoAppShell.java
embedding/android/GeckoSurfaceView.java
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProviderCGL.mm
gfx/gl/GLContextProviderEGL.cpp
gfx/layers/ImageLayers.h
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/basic/BasicLayers.cpp
gfx/layers/basic/BasicLayers.h
gfx/layers/d3d10/ImageLayerD3D10.cpp
gfx/layers/d3d10/ImageLayerD3D10.h
gfx/layers/d3d9/ImageLayerD3D9.cpp
gfx/layers/d3d9/ImageLayerD3D9.h
gfx/layers/ipc/PLayers.ipdl
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
gfx/layers/ipc/ShadowLayersParent.cpp
gfx/layers/ipc/ShadowLayersParent.h
gfx/layers/opengl/CanvasLayerOGL.cpp
gfx/layers/opengl/ContainerLayerOGL.cpp
gfx/layers/opengl/ImageLayerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.h
gfx/layers/opengl/ThebesLayerOGL.cpp
gfx/thebes/gfx3DMatrix.h
gfx/thebes/gfxASurface.cpp
gfx/thebes/gfxASurface.h
gfx/thebes/gfxAndroidPlatform.cpp
gfx/thebes/gfxAndroidPlatform.h
gfx/thebes/gfxSharedImageSurface.cpp
gfx/thebes/gfxSharedImageSurface.h
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxUtils.h
image/src/imgLoader.cpp
intl/unicharutil/public/nsUnicodeProperties.h
intl/unicharutil/public/nsUnicodeScriptCodes.h
intl/unicharutil/src/casetable.h
intl/unicharutil/src/nsUnicodeProperties.cpp
intl/unicharutil/src/nsUnicodePropertyData.cpp
intl/unicharutil/tools/gencasetable.pl
intl/unicharutil/util/nsUnicharUtils.cpp
intl/unicharutil/util/nsUnicharUtils.h
ipc/testshell/XPCShellEnvironment.cpp
js/jsd/jsd_xpc.cpp
js/src/config/system-headers
js/src/configure.in
js/src/gc/Statistics.h
js/src/jsanalyze.cpp
js/src/jsanalyze.h
js/src/jsapi-tests/Makefile.in
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jscntxt.h
js/src/jscompartment.cpp
js/src/jscompartment.h
js/src/jsexn.cpp
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsiter.cpp
js/src/jsiter.h
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsopcode.cpp
js/src/jsproxy.cpp
js/src/jspubtd.h
js/src/jsreflect.cpp
js/src/jsstr.cpp
js/src/jsutil.h
js/src/methodjit/Compiler.cpp
js/src/methodjit/PolyIC.cpp
js/src/shell/js.cpp
js/src/tests/js1_8_5/extensions/jstests.list
js/src/vm/Debugger.cpp
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/xpconnect/shell/xpcshell.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
layout/base/FrameLayerBuilder.cpp
layout/base/FrameLayerBuilder.h
layout/base/crashtests/crashtests.list
layout/base/nsBidiPresUtils.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsDocumentViewer.cpp
layout/base/nsIPresShell.h
layout/base/nsLayoutDebugger.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsPresContext.cpp
layout/base/nsPresShell.cpp
layout/build/Makefile.in
layout/build/nsLayoutModule.cpp
layout/build/nsLayoutStatics.cpp
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsFileControlFrame.cpp
layout/forms/nsGfxCheckboxControlFrame.cpp
layout/forms/nsListControlFrame.cpp
layout/forms/nsTextControlFrame.cpp
layout/generic/TextOverflow.cpp
layout/generic/nsAbsoluteContainingBlock.cpp
layout/generic/nsContainerFrame.cpp
layout/generic/nsFrame.h
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsImageFrame.cpp
layout/generic/nsImageMap.cpp
layout/generic/nsObjectFrame.cpp
layout/generic/nsSelection.cpp
layout/generic/nsSimplePageSequence.cpp
layout/generic/nsSubDocumentFrame.h
layout/generic/nsTextFrameThebes.cpp
layout/generic/nsTextRunTransformations.cpp
layout/generic/nsVideoFrame.cpp
layout/ipc/RenderFrameParent.cpp
layout/ipc/RenderFrameParent.h
layout/printing/nsPrintEngine.cpp
layout/reftests/bugs/reftest.list
layout/style/nsCSSRuleProcessor.cpp
layout/style/nsHTMLStyleSheet.cpp
layout/style/nsHTMLStyleSheet.h
layout/style/nsRuleNode.cpp
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableFrame.cpp
layout/xul/base/src/nsBoxFrame.cpp
layout/xul/base/src/nsBoxObject.cpp
layout/xul/base/src/nsImageBoxFrame.cpp
layout/xul/base/src/nsMenuPopupFrame.cpp
layout/xul/base/src/nsSprocketLayout.cpp
layout/xul/base/src/nsXULPopupManager.cpp
layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
mobile/android/base/AndroidManifest.xml.in
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/Makefile.in
mobile/android/base/gfx/GeckoSoftwareLayerClient.java
mobile/android/base/gfx/LayerClient.java
mobile/android/base/gfx/MultiTileLayer.java
mobile/android/base/gfx/WidgetTileLayer.java
mobile/android/chrome/tests/Makefile.in
mobile/android/chrome/tests/addons/browser_install1_1/bootstrap.js
mobile/android/chrome/tests/addons/browser_install1_1/install.rdf
mobile/android/chrome/tests/addons/browser_install1_2/install.rdf
mobile/android/chrome/tests/addons/browser_install1_3/install.rdf
mobile/android/chrome/tests/addons/browser_locale1/boostrap.js
mobile/android/chrome/tests/addons/browser_locale1/chrome.manifest
mobile/android/chrome/tests/addons/browser_locale1/install.rdf
mobile/android/chrome/tests/browser_addons.js
mobile/android/chrome/tests/browser_addons_locales.js
mobile/android/chrome/tests/browser_appmenu.js
mobile/android/chrome/tests/browser_autocomplete.html
mobile/android/chrome/tests/browser_autocomplete.js
mobile/android/chrome/tests/browser_autocompletesearch.js
mobile/android/chrome/tests/browser_awesomescreen.js
mobile/android/chrome/tests/browser_blank_01.html
mobile/android/chrome/tests/browser_blank_02.html
mobile/android/chrome/tests/browser_blank_03.html
mobile/android/chrome/tests/browser_bookmarks.js
mobile/android/chrome/tests/browser_bookmarks_star.js
mobile/android/chrome/tests/browser_bookmarks_tags.js
mobile/android/chrome/tests/browser_click_content.html
mobile/android/chrome/tests/browser_click_content.js
mobile/android/chrome/tests/browser_contacts.js
mobile/android/chrome/tests/browser_contentpopup.html
mobile/android/chrome/tests/browser_contentpopup.js
mobile/android/chrome/tests/browser_dragger.js
mobile/android/chrome/tests/browser_escape.js
mobile/android/chrome/tests/browser_find.js
mobile/android/chrome/tests/browser_focus.html
mobile/android/chrome/tests/browser_focus.js
mobile/android/chrome/tests/browser_forms.html
mobile/android/chrome/tests/browser_forms.js
mobile/android/chrome/tests/browser_formsZoom.html
mobile/android/chrome/tests/browser_formsZoom.js
mobile/android/chrome/tests/browser_history.js
mobile/android/chrome/tests/browser_install.xml
mobile/android/chrome/tests/browser_localepicker.js
mobile/android/chrome/tests/browser_localepicker_escape.js
mobile/android/chrome/tests/browser_localerepository.js
mobile/android/chrome/tests/browser_localerepository_buildid.js
mobile/android/chrome/tests/browser_localerepository_pref.js
mobile/android/chrome/tests/browser_mainui.js
mobile/android/chrome/tests/browser_navigation.js
mobile/android/chrome/tests/browser_preferences_fulltoggle.js
mobile/android/chrome/tests/browser_preferences_text.js
mobile/android/chrome/tests/browser_rect.js
mobile/android/chrome/tests/browser_rememberPassword.js
mobile/android/chrome/tests/browser_scroll.html
mobile/android/chrome/tests/browser_scroll.js
mobile/android/chrome/tests/browser_scrollbar.js
mobile/android/chrome/tests/browser_scrollbar.sjs
mobile/android/chrome/tests/browser_select.html
mobile/android/chrome/tests/browser_select.js
mobile/android/chrome/tests/browser_sessionstore.js
mobile/android/chrome/tests/browser_sidebars.js
mobile/android/chrome/tests/browser_tabs.js
mobile/android/chrome/tests/browser_tap_content.html
mobile/android/chrome/tests/browser_tap_contentedit.html
mobile/android/chrome/tests/browser_tapping.js
mobile/android/chrome/tests/browser_tapping_edit.js
mobile/android/chrome/tests/browser_test.js
mobile/android/chrome/tests/browser_thumbnails.js
mobile/android/chrome/tests/browser_title.sjs
mobile/android/chrome/tests/browser_upgrade.rdf
mobile/android/chrome/tests/browser_viewport.js
mobile/android/chrome/tests/browser_viewport.sjs
mobile/android/chrome/tests/browser_vkb.js
mobile/android/chrome/tests/head.js
mobile/android/chrome/tests/locales_list.sjs
mobile/android/chrome/tests/mock_autocomplete.json
mobile/android/chrome/tests/remote_autocomplete.js
mobile/android/chrome/tests/remote_contentpopup.js
mobile/android/chrome/tests/remote_focus.js
mobile/android/chrome/tests/remote_forms.js
mobile/android/chrome/tests/remote_formsZoom.js
mobile/android/chrome/tests/remote_head.js
mobile/android/chrome/tests/remote_vkb.js
mobile/xul/installer/package-manifest.in
modules/libpref/src/init/all.js
mozglue/android/APKOpen.cpp
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/HttpChannelParent.cpp
parser/html/nsHtml5StreamParser.cpp
security/manager/ssl/src/nsNSSIOLayer.h
storage/src/mozStorageConnection.cpp
testing/xpcshell/xpcshell.ini
toolkit/components/autocomplete/nsAutoCompleteController.cpp
toolkit/components/autocomplete/nsAutoCompleteController.h
toolkit/components/telemetry/Telemetry.cpp
toolkit/components/telemetry/TelemetryPing.js
toolkit/content/license.html
toolkit/content/widgets/videocontrols.xml
toolkit/mozapps/installer/packager.mk
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/AndroidJNI.cpp
widget/android/nsAppShell.cpp
widget/android/nsAppShell.h
widget/android/nsWindow.cpp
widget/android/nsWindow.h
widget/cocoa/nsChildView.h
widget/cocoa/nsChildView.mm
widget/nsIWidget.h
widget/windows/GfxInfo.cpp
widget/xpwidgets/nsBaseWidget.cpp
widget/xpwidgets/nsBaseWidget.h
xpcom/glue/nsStringAPI.h
xpcom/glue/nsTObserverArray.h
--- a/accessible/src/base/AccIterator.cpp
+++ b/accessible/src/base/AccIterator.cpp
@@ -36,16 +36,19 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "AccIterator.h"
 
 #include "nsAccessibilityService.h"
 #include "nsAccessible.h"
 
 #include "mozilla/dom/Element.h"
+#include "nsBindingManager.h"
+
+using namespace mozilla;
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccIterator
 ////////////////////////////////////////////////////////////////////////////////
 
 AccIterator::AccIterator(nsAccessible *aAccessible,
                          filters::FilterFuncPtr aFilterFunc,
                          IterationType aIterationType) :
@@ -124,27 +127,31 @@ RelatedAccIterator::Next()
   if (!mProviders)
     return nsnull;
 
   while (mIndex < mProviders->Length()) {
     nsDocAccessible::AttrRelProvider* provider = (*mProviders)[mIndex++];
 
     // Return related accessible for the given attribute and if the provider
     // content is in the same binding in the case of XBL usage.
-    if (provider->mRelAttr == mRelAttr &&
-        (!mBindingParent ||
-         mBindingParent == provider->mContent->GetBindingParent())) {
-      nsAccessible* related = mDocument->GetAccessible(provider->mContent);
-      if (related)
-        return related;
+    if (provider->mRelAttr == mRelAttr) {
+      nsIContent* bindingParent = provider->mContent->GetBindingParent();
+      bool inScope = mBindingParent == bindingParent ||
+        mBindingParent == provider->mContent;
 
-      // If the document content is pointed by relation then return the document
-      // itself.
-      if (provider->mContent == mDocument->GetContent())
-        return mDocument;
+      if (inScope) {
+        nsAccessible* related = mDocument->GetAccessible(provider->mContent);
+        if (related)
+          return related;
+
+        // If the document content is pointed by relation then return the document
+        // itself.
+        if (provider->mContent == mDocument->GetContent())
+          return mDocument;
+      }
     }
   }
 
   return nsnull;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -266,28 +273,20 @@ XULDescriptionIterator::Next()
   return nsnull;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // IDRefsIterator
 ////////////////////////////////////////////////////////////////////////////////
 
 IDRefsIterator::IDRefsIterator(nsIContent* aContent, nsIAtom* aIDRefsAttr) :
-  mCurrIdx(0)
+  mCurrIdx(0), mContent(aContent)
 {
-  if (!aContent->IsInDoc() ||
-      !aContent->GetAttr(kNameSpaceID_None, aIDRefsAttr, mIDs))
-    return;
-
-  if (aContent->IsInAnonymousSubtree()) {
-    mXBLDocument = do_QueryInterface(aContent->OwnerDoc());
-    mBindingParent = do_QueryInterface(aContent->GetBindingParent());
-  } else {
-    mDocument = aContent->OwnerDoc();
-  }
+  if (mContent->IsInDoc())
+    mContent->GetAttr(kNameSpaceID_None, aIDRefsAttr, mIDs);
 }
 
 const nsDependentSubstring
 IDRefsIterator::NextID()
 {
   for (; mCurrIdx < mIDs.Length(); mCurrIdx++) {
     if (!NS_IsAsciiWhitespace(mIDs[mCurrIdx]))
       break;
@@ -319,30 +318,55 @@ IDRefsIterator::NextElem()
   }
 
   return nsnull;
 }
 
 nsIContent*
 IDRefsIterator::GetElem(const nsDependentSubstring& aID)
 {
-  if (mXBLDocument) {
-    // If content is anonymous subtree then use "anonid" attribute to get
-    // elements, otherwise search elements in DOM by ID attribute.
-
-    nsCOMPtr<nsIDOMElement> refElm;
-    mXBLDocument->GetAnonymousElementByAttribute(mBindingParent,
-                                                 NS_LITERAL_STRING("anonid"),
-                                                 aID,
-                                                 getter_AddRefs(refElm));
-    nsCOMPtr<nsIContent> refContent = do_QueryInterface(refElm);
-    return refContent;
+  // Get elements in DOM tree by ID attribute if this is an explicit content.
+  // In case of bound element check its anonymous subtree.
+  if (!mContent->IsInAnonymousSubtree()) {
+    dom::Element* refElm = mContent->OwnerDoc()->GetElementById(aID);
+    if (refElm || !mContent->OwnerDoc()->BindingManager()->GetBinding(mContent))
+      return refElm;
   }
 
-  return mDocument->GetElementById(aID);
+  // If content is in anonymous subtree or an element having anonymous subtree
+  // then use "anonid" attribute to get elements in anonymous subtree.
+  nsCOMPtr<nsIDOMElement> refDOMElm;
+  nsCOMPtr<nsIDOMDocumentXBL> xblDocument =
+    do_QueryInterface(mContent->OwnerDoc());
+
+  // Check inside the binding the element is contained in.
+  nsIContent* bindingParent = mContent->GetBindingParent();
+  if (bindingParent) {
+    nsCOMPtr<nsIDOMElement> bindingParentElm = do_QueryInterface(bindingParent);
+    xblDocument->GetAnonymousElementByAttribute(bindingParentElm,
+                                                NS_LITERAL_STRING("anonid"),
+                                                aID,
+                                                getter_AddRefs(refDOMElm));
+    nsCOMPtr<dom::Element> refElm = do_QueryInterface(refDOMElm);
+    if (refElm)
+      return refElm;
+  }
+
+  // Check inside the binding of the element.
+  if (mContent->OwnerDoc()->BindingManager()->GetBinding(mContent)) {
+    nsCOMPtr<nsIDOMElement> elm = do_QueryInterface(mContent);
+    xblDocument->GetAnonymousElementByAttribute(elm,
+                                                NS_LITERAL_STRING("anonid"),
+                                                aID,
+                                                getter_AddRefs(refDOMElm));
+    nsCOMPtr<dom::Element> refElm = do_QueryInterface(refDOMElm);
+    return refElm;
+  }
+
+  return nsnull;
 }
 
 nsAccessible*
 IDRefsIterator::Next()
 {
   nsIContent* nextElm = NextElem();
   return nextElm ? GetAccService()->GetAccessible(nextElm, nsnull) : nsnull;
 }
--- a/accessible/src/base/AccIterator.h
+++ b/accessible/src/base/AccIterator.h
@@ -286,21 +286,18 @@ public:
   virtual nsAccessible* Next();
 
 private:
   IDRefsIterator();
   IDRefsIterator(const IDRefsIterator&);
   IDRefsIterator operator = (const IDRefsIterator&);
 
   nsString mIDs;
+  nsIContent* mContent;
   nsAString::index_type mCurrIdx;
-
-  nsIDocument* mDocument;
-  nsCOMPtr<nsIDOMDocumentXBL> mXBLDocument;
-  nsCOMPtr<nsIDOMElement> mBindingParent;
 };
 
 /**
  * Iterator that points to a single accessible returning it on the first call
  * to Next().
  */
 class SingleAccIterator : public AccIterable
 {
--- a/accessible/src/base/NotificationController.cpp
+++ b/accessible/src/base/NotificationController.cpp
@@ -112,18 +112,20 @@ NotificationController::Shutdown()
 {
   if (mObservingState != eNotObservingRefresh &&
       mPresShell->RemoveRefreshObserver(this, Flush_Display)) {
     mObservingState = eNotObservingRefresh;
   }
 
   // Shutdown handling child documents.
   PRInt32 childDocCount = mHangingChildDocuments.Length();
-  for (PRInt32 idx = childDocCount - 1; idx >= 0; idx--)
-    mHangingChildDocuments[idx]->Shutdown();
+  for (PRInt32 idx = childDocCount - 1; idx >= 0; idx--) {
+    if (!mHangingChildDocuments[idx]->IsDefunct())
+      mHangingChildDocuments[idx]->Shutdown();
+  }
 
   mHangingChildDocuments.Clear();
 
   mDocument = nsnull;
   mPresShell = nsnull;
 
   mTextHash.Clear();
   mContentInsertions.Clear();
@@ -254,16 +256,18 @@ NotificationController::WillRefresh(mozi
   // Process rendered text change notifications.
   mTextHash.EnumerateEntries(TextEnumerator, mDocument);
   mTextHash.Clear();
 
   // Bind hanging child documents.
   PRUint32 hangingDocCnt = mHangingChildDocuments.Length();
   for (PRUint32 idx = 0; idx < hangingDocCnt; idx++) {
     nsDocAccessible* childDoc = mHangingChildDocuments[idx];
+    if (childDoc->IsDefunct())
+      continue;
 
     nsIContent* ownerContent = mDocument->GetDocumentNode()->
       FindContentForSubDocument(childDoc->GetDocumentNode());
     if (ownerContent) {
       nsAccessible* outerDocAcc = mDocument->GetAccessible(ownerContent);
       if (outerDocAcc && outerDocAcc->AppendChild(childDoc)) {
         if (mDocument->AppendChildDocument(childDoc))
           continue;
--- a/accessible/src/base/nsARIAMap.cpp
+++ b/accessible/src/base/nsARIAMap.cpp
@@ -93,17 +93,18 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] 
   },
   {
     "article",
     roles::DOCUMENT,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
-    states::READONLY
+    kNoReqStates,
+    eReadonlyUntilEditable
   },
   {
     "button",
     roles::PUSHBUTTON,
     kUseMapRole,
     eNoValue,
     ePressAction,
     eNoLiveAttr,
@@ -163,17 +164,18 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] 
   },
   {
     "document",
     roles::DOCUMENT,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
-    states::READONLY
+    kNoReqStates,
+    eReadonlyUntilEditable
   },
   {
     "grid",
     roles::TABLE,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
@@ -656,17 +658,20 @@ nsStateMapEntry nsARIAMap::gWAIStateMap[
                   0, states::READONLY, states::EDITABLE, true),
 
   // eARIARequired
   nsStateMapEntry(&nsGkAtoms::aria_required, kBoolType,
                   0, states::REQUIRED),
 
   // eARIASelectable
   nsStateMapEntry(&nsGkAtoms::aria_selected, kBoolType,
-                  states::SELECTABLE, states::SELECTED, 0, true)
+                  states::SELECTABLE, states::SELECTED, 0, true),
+
+  // eReadonlyUntilEditable
+  nsStateMapEntry(states::READONLY, states::EDITABLE)
 };
 
 /**
  * Universal (Global) states:
  * The following state rules are applied to any accessible element,
  * whether there is an ARIA role or not:
  */
 eStateMapEntryID nsARIAMap::gWAIUnivStateMap[] = {
@@ -737,76 +742,103 @@ nsStateMapEntry::nsStateMapEntry() :
   mValue2(nsnull),
   mState2(0),
   mValue3(nsnull),
   mState3(0),
   mDefaultState(0),
   mDefinedIfAbsent(false)
 {}
 
+nsStateMapEntry::nsStateMapEntry(PRUint64 aDefaultState,
+                                 PRUint64 aExclusingState) :
+  mAttributeName(nsnull),
+  mIsToken(false),
+  mPermanentState(0),
+  mValue1(nsnull),
+  mState1(0),
+  mValue2(nsnull),
+  mState2(0),
+  mValue3(nsnull),
+  mState3(0),
+  mDefaultState(aDefaultState),
+  mDefinedIfAbsent(false),
+  mExcludingState(aExclusingState)
+{
+}
+
 nsStateMapEntry::nsStateMapEntry(nsIAtom** aAttrName, eStateValueType aType,
                                  PRUint64 aPermanentState,
                                  PRUint64 aTrueState,
                                  PRUint64 aFalseState,
                                  bool aDefinedIfAbsent) :
   mAttributeName(aAttrName),
   mIsToken(true),
   mPermanentState(aPermanentState),
   mValue1("false"),
   mState1(aFalseState),
   mValue2(nsnull),
   mState2(0),
   mValue3(nsnull),
   mState3(0),
   mDefaultState(aTrueState),
-  mDefinedIfAbsent(aDefinedIfAbsent)
+  mDefinedIfAbsent(aDefinedIfAbsent),
+  mExcludingState(0)
 {
   if (aType == kMixedType) {
     mValue2 = "mixed";
     mState2 = states::MIXED;
   }
 }
 
 nsStateMapEntry::nsStateMapEntry(nsIAtom** aAttrName,
                                  const char* aValue1, PRUint64 aState1,
                                  const char* aValue2, PRUint64 aState2,
                                  const char* aValue3, PRUint64 aState3) :
   mAttributeName(aAttrName), mIsToken(false), mPermanentState(0),
   mValue1(aValue1), mState1(aState1),
   mValue2(aValue2), mState2(aState2),
   mValue3(aValue3), mState3(aState3),
-  mDefaultState(0), mDefinedIfAbsent(false)
+  mDefaultState(0), mDefinedIfAbsent(false), mExcludingState(0)
 {
 }
 
 nsStateMapEntry::nsStateMapEntry(nsIAtom** aAttrName,
                                  EDefaultStateRule aDefaultStateRule,
                                  const char* aValue1, PRUint64 aState1,
                                  const char* aValue2, PRUint64 aState2,
                                  const char* aValue3, PRUint64 aState3) :
   mAttributeName(aAttrName), mIsToken(true), mPermanentState(0),
   mValue1(aValue1), mState1(aState1),
   mValue2(aValue2), mState2(aState2),
   mValue3(aValue3), mState3(aState3),
-  mDefaultState(0), mDefinedIfAbsent(true)
+  mDefaultState(0), mDefinedIfAbsent(true), mExcludingState(0)
 {
   if (aDefaultStateRule == eUseFirstState)
     mDefaultState = aState1;
 }
 
 bool
 nsStateMapEntry::MapToStates(nsIContent* aContent, PRUint64* aState,
                              eStateMapEntryID aStateMapEntryID)
 {
   // Return true if we should continue.
   if (aStateMapEntryID == eARIANone)
     return false;
 
   const nsStateMapEntry& entry = nsARIAMap::gWAIStateMap[aStateMapEntryID];
 
+  // Non ARIA attribute case. Expose default state until excluding state is
+  // presented.
+  if (!entry.mAttributeName) {
+    if (!(*aState & entry.mExcludingState))
+      *aState |= entry.mDefaultState;
+
+    return true;
+  }
+
   if (entry.mIsToken) {
     // If attribute is considered as defined when it's absent then let's act
     // attribute value is "false" supposedly.
     bool hasAttr = aContent->HasAttr(kNameSpaceID_None, *entry.mAttributeName);
     if (entry.mDefinedIfAbsent && !hasAttr) {
       if (entry.mPermanentState)
         *aState |= entry.mPermanentState;
       if (entry.mState1)
--- a/accessible/src/base/nsARIAMap.h
+++ b/accessible/src/base/nsARIAMap.h
@@ -182,28 +182,35 @@ enum eStateMapEntryID
   eARIAInvalid,
   eARIAMultiline,
   eARIAMultiSelectable,
   eARIAOrientation,
   eARIAPressed,
   eARIAReadonly,
   eARIAReadonlyOrEditable,
   eARIARequired,
-  eARIASelectable
+  eARIASelectable,
+  eReadonlyUntilEditable
 };
 
 class nsStateMapEntry
 {
 public:
   /**
    * Used to create stub.
    */
   nsStateMapEntry();
 
   /**
+   * Used to expose permanent states presented until accessible has an excluding
+   * state.
+   */
+  nsStateMapEntry(PRUint64 aDefaultState, PRUint64 aExclusingState);
+
+  /**
    * Used for ARIA attributes having boolean or mixed values.
    */
   nsStateMapEntry(nsIAtom** aAttrName, eStateValueType aType,
                   PRUint64 aPermanentState,
                   PRUint64 aTrueState,
                   PRUint64 aFalseState = 0,
                   bool aDefinedIfAbsent = false);
 
@@ -255,16 +262,19 @@ private:
   const char* mValue3;
   PRUint64 mState3;
 
   // States applied if no stored values above are matched
   PRUint64 mDefaultState;
 
   // Permanent and false states are applied if attribute is absent
   bool mDefinedIfAbsent;
+
+  // If this state is presented in state bits then default state is not exposed.
+  PRUint64 mExcludingState;
 };
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Role map entry
 
 /**
  * For each ARIA role, this maps the nsIAccessible information.
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -1612,21 +1612,17 @@ nsAccessible::State()
     // In XUL all boxes are either vertical or horizontal
     if (xulStyle->mBoxOrient == NS_STYLE_BOX_ORIENT_VERTICAL) {
       state |= states::VERTICAL;
     }
     else {
       state |= states::HORIZONTAL;
     }
   }
-  
-  // If we are editable, force readonly bit off
-  if (state & states::EDITABLE)
-    state &= ~states::READONLY;
- 
+
   return state;
 }
 
 void
 nsAccessible::ApplyARIAState(PRUint64* aState)
 {
   // Test for universal states first
   *aState |= nsARIAMap::UniversalStatesFor(mContent);
@@ -1663,26 +1659,24 @@ nsAccessible::ApplyARIAState(PRUint64* a
         break;
       }
     }    
   }
 
   if (!mRoleMapEntry)
     return;
 
-  // Note: the readonly bitflag will be overridden later if content is editable
   *aState |= mRoleMapEntry->state;
   if (nsStateMapEntry::MapToStates(mContent, aState,
                                    mRoleMapEntry->attributeMap1) &&
       nsStateMapEntry::MapToStates(mContent, aState,
                                    mRoleMapEntry->attributeMap2)) {
     nsStateMapEntry::MapToStates(mContent, aState,
                                  mRoleMapEntry->attributeMap3);
   }
-
 }
 
 // Not implemented by this class
 
 /* DOMString getValue (); */
 NS_IMETHODIMP
 nsAccessible::GetValue(nsAString& aValue)
 {
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -163,21 +163,18 @@ nsHyperTextAccessible::NativeRole()
 
 PRUint64
 nsHyperTextAccessible::NativeState()
 {
   PRUint64 states = nsAccessibleWrap::NativeState();
 
   nsCOMPtr<nsIEditor> editor = GetEditor();
   if (editor) {
-    PRUint32 flags;
-    editor->GetFlags(&flags);
-    if (0 == (flags & nsIPlaintextEditor::eEditorReadonlyMask)) {
-      states |= states::EDITABLE;
-    }
+    states |= states::EDITABLE;
+
   } else if (mContent->Tag() == nsGkAtoms::article) {
     // We want <article> to behave like a document in terms of readonly state.
     states |= states::READONLY;
   }
 
   if (GetChildCount() > 0)
     states |= states::SELECTABLE_TEXT;
 
--- a/accessible/src/msaa/CAccessibleComponent.cpp
+++ b/accessible/src/msaa/CAccessibleComponent.cpp
@@ -49,23 +49,16 @@
 
 #include "nsString.h"
 
 #include "nsIDOMCSSPrimitiveValue.h"
 #include "nsIDOMNSRGBAColor.h"
 
 using namespace mozilla::a11y;
 
-enum {
-  IA2AlphaShift = 24,
-  IA2RedShift = 16,
-  IA2GreenShift = 8,
-  IA2BlueShift = 0
-};
-
 // IUnknown
 
 STDMETHODIMP
 CAccessibleComponent::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = NULL;
 
   if (IID_IAccessibleComponent == iid) {
@@ -125,115 +118,45 @@ CAccessibleComponent::get_locationInPare
   *aY = y - parenty;
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleComponent::get_foreground(IA2Color *aForeground)
+CAccessibleComponent::get_foreground(IA2Color* aForeground)
 {
 __try {
-  return GetARGBValueFromCSSProperty(NS_LITERAL_STRING("color"), aForeground);
+  nsRefPtr<nsAccessible> acc(do_QueryObject(this));
+  if (acc->IsDefunct())
+    return E_FAIL;
+
+  nsIFrame* frame = acc->GetFrame();
+  if (frame)
+    *aForeground = frame->GetStyleColor()->mColor;
+
+  return S_OK;
+
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleComponent::get_background(IA2Color *aBackground)
+CAccessibleComponent::get_background(IA2Color* aBackground)
 {
 __try {
-  return GetARGBValueFromCSSProperty(NS_LITERAL_STRING("background-color"),
-                                     aBackground);
+  nsRefPtr<nsAccessible> acc(do_QueryObject(this));
+  if (acc->IsDefunct())
+    return E_FAIL;
+
+  nsIFrame* frame = acc->GetFrame();
+  if (frame)
+    *aBackground = frame->GetStyleBackground()->mBackgroundColor;
+
+  return S_OK;
+
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return E_FAIL;
 }
 
-HRESULT
-CAccessibleComponent::GetARGBValueFromCSSProperty(const nsAString& aPropName,
-                                                  IA2Color *aColorValue)
-{
-__try {
-  *aColorValue = 0;
-
-  nsRefPtr<nsAccessible> acc(do_QueryObject(this));
-  if (acc->IsDefunct())
-    return E_FAIL;
-
-  nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl =
-    nsWinUtils::GetComputedStyleDeclaration(acc->GetContent());
-  NS_ENSURE_STATE(styleDecl);
-
-  nsCOMPtr<nsIDOMCSSValue> cssGenericValue;
-  styleDecl->GetPropertyCSSValue(aPropName, getter_AddRefs(cssGenericValue));
-
-  nsCOMPtr<nsIDOMCSSPrimitiveValue> cssValue =
-    do_QueryInterface(cssGenericValue);
-  if (!cssValue)
-    return E_FAIL;
-
-  nsCOMPtr<nsIDOMRGBColor> rgbColor;
-  nsresult rv = cssValue->GetRGBColorValue(getter_AddRefs(rgbColor));
-  if (NS_FAILED(rv) || !rgbColor)
-    return GetHRESULT(rv);
-
-  nsCOMPtr<nsIDOMNSRGBAColor> rgbaColor(do_QueryInterface(rgbColor));
-  if (!rgbaColor)
-    return GetHRESULT(rv);
-
-  // get alpha
-  nsCOMPtr<nsIDOMCSSPrimitiveValue> alphaValue;
-  rv = rgbaColor->GetAlpha(getter_AddRefs(alphaValue));
-  if (NS_FAILED(rv) || !alphaValue)
-    return GetHRESULT(rv);
-
-  float alpha = 0.0;
-  rv = alphaValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &alpha);
-  if (NS_FAILED(rv))
-    return GetHRESULT(rv);
-
-  // get red
-  nsCOMPtr<nsIDOMCSSPrimitiveValue> redValue;
-  rv = rgbaColor->GetRed(getter_AddRefs(redValue));
-  if (NS_FAILED(rv) || !redValue)
-    return GetHRESULT(rv);
-
-  float red = 0.0;
-  rv = redValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &red);
-  if (NS_FAILED(rv))
-    return GetHRESULT(rv);
-
-  // get green
-  nsCOMPtr<nsIDOMCSSPrimitiveValue> greenValue;
-  rv = rgbaColor->GetGreen(getter_AddRefs(greenValue));
-  if (NS_FAILED(rv) || !greenValue)
-    return GetHRESULT(rv);
-
-  float green = 0.0;
-  rv = greenValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &green);
-  if (NS_FAILED(rv))
-    return GetHRESULT(rv);
-
-  // get blue
-  nsCOMPtr<nsIDOMCSSPrimitiveValue> blueValue;
-  rv = rgbaColor->GetBlue(getter_AddRefs(blueValue));
-  if (NS_FAILED(rv) || !blueValue)
-    return GetHRESULT(rv);
-
-  float blue = 0.0;
-  rv = blueValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &blue);
-  if (NS_FAILED(rv))
-    return GetHRESULT(rv);
-
-  // compose ARGB value
-  *aColorValue = (((IA2Color) blue) << IA2BlueShift) |
-                 (((IA2Color) green) << IA2GreenShift) |
-                 (((IA2Color) red) << IA2RedShift) |
-                 (((IA2Color) (alpha * 0xff)) << IA2AlphaShift);
-  return S_OK;
-
-} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
-  return E_FAIL;
-}
-
--- a/accessible/src/msaa/CAccessibleComponent.h
+++ b/accessible/src/msaa/CAccessibleComponent.h
@@ -60,20 +60,12 @@ public:
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_foreground(
       /* [retval][out] */ IA2Color *foreground);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_background(
       /* [retval][out] */ IA2Color *background);
 
   // nsISupports
   NS_IMETHOD QueryInterface(const nsIID& uuid, void** result) = 0;
-
-protected:
-
-  /**
-   * Return ARGB value for CSS property like 'color' or 'background-color'.
-   */
-  HRESULT GetARGBValueFromCSSProperty(const nsAString& aPropName,
-                                      IA2Color *aColorValue);
 };
 
 #endif
 
--- a/accessible/tests/mochitest/relations.js
+++ b/accessible/tests/mochitest/relations.js
@@ -73,17 +73,17 @@ function testRelation(aIdentifier, aRelT
     while (enumerate.hasMoreElements()) {
       var relatedAcc = enumerate.getNext().QueryInterface(nsIAccessible);
       if (targets[idx] == relatedAcc) {
         isFound = true;
         break;
       }
     }
 
-    ok(isFound, relatedIds[idx] + " is not a target of" + relDescr);
+    ok(isFound, prettyName(relatedIds[idx]) + " is not a target of" + relDescr);
   }
 
   // Check if all obtained targets are given related accessibles.
   var enumerate = actualTargets.enumerate();
   while (enumerate.hasMoreElements()) {
     var relatedAcc = enumerate.getNext().QueryInterface(nsIAccessible);
     for (var idx = 0; idx < targets.length && relatedAcc != targets[idx]; idx++);
 
--- a/accessible/tests/mochitest/relations/Makefile.in
+++ b/accessible/tests/mochitest/relations/Makefile.in
@@ -41,18 +41,20 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible/relations
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =\
+		test_bindings.xhtml \
 		test_embeds.xul \
 		test_general.html \
 		test_general.xul \
 		test_tabbrowser.xul \
 		test_tree.xul \
+		test_ui_modalprompt.html \
 		test_update.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/relations/test_bindings.xhtml
@@ -0,0 +1,103 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+  <title>Accessible relations for bindings</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <style>
+    .button {
+      -moz-binding: url('#custombutton');
+    }
+
+    .button2 {
+      -moz-binding: url('#custombutton2');
+    }
+  </style>
+
+  <bindings xmlns="http://www.mozilla.org/xbl">
+    <binding id="custombutton">
+      <content aria-labelledby="button.label label">
+        <label xmlns="http://www.w3.org/1999/xhtml" anonid="button.label">
+          anon label
+        </label>
+        <button xmlns="http://www.w3.org/1999/xhtml" anonid="button.button"
+                aria-labelledby="button.label label">
+          a button
+        </button>
+        <div xmlns="http://www.w3.org/1999/xhtml"
+             anonid="button.button2" class="button2"
+             aria-labelledby="button.label"></div>
+        <div xmlns="http://www.w3.org/1999/xhtml"
+             anonid="button.button3" class="button2"></div>
+      </content>
+    </binding>
+    <binding id="custombutton2">
+      <content aria-labelledby="button2.label">
+        <label xmlns="http://www.w3.org/1999/xhtml" anonid="button2.label">
+          nested anon label
+        </label>
+      </content>
+    </binding>
+  </bindings>
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../relations.js"></script>
+
+  <script type="application/javascript">
+    function doTests()
+    {
+      var button = document.getElementById("button");
+      var anonLabel = document.
+        getAnonymousElementByAttribute(button, "anonid", "button.label");
+      var anonButton = document.
+        getAnonymousElementByAttribute(button, "anonid", "button.button");
+      var anonButton2 = document.
+        getAnonymousElementByAttribute(button, "anonid", "button.button2");
+      var anonButton3 = document.
+        getAnonymousElementByAttribute(button, "anonid", "button.button3");
+      var anonAnonLabel = document.
+        getAnonymousElementByAttribute(anonButton3, "anonid", "button2.label");
+
+      testRelation("label", RELATION_LABEL_FOR, button);
+      testRelation(anonLabel, RELATION_LABEL_FOR, [button, anonButton, anonButton2]);
+      testRelation(button, RELATION_LABELLED_BY, [anonLabel, "label"]);
+      testRelation(anonButton, RELATION_LABELLED_BY, anonLabel);
+      testRelation(anonButton2, RELATION_LABELLED_BY, anonLabel);
+      testRelation(anonButton3, RELATION_LABELLED_BY, anonAnonLabel);
+      testRelation(anonAnonLabel, RELATION_LABEL_FOR, anonButton3);
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTests);
+  </script>
+</head>
+
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=421242"
+     title="Allow relations in anonymous content for binding parent">
+    Mozilla Bug 421242
+  </a>
+
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+  <div id="eventdump"></div>
+
+  <label id="label">explicit label</label>
+  <div id="button" class="button"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/relations/test_ui_modalprompt.html
@@ -0,0 +1,95 @@
+<html>
+
+<head>
+  <title>Modal prompts</title>
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../relations.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+  <script type="application/javascript"
+          src="../events.js"></script>
+  <script type="application/javascript"
+          src="../browser.js"></script>
+
+  <script type="application/javascript">
+    function showAlert()
+    {
+      this.eventSeq = [
+        {
+          type: EVENT_SHOW,
+          match: function(aEvent)
+          {
+            return aEvent.accessible.role == ROLE_DIALOG;
+          }
+        }
+      ];
+
+      this.invoke = function showAlert_invoke()
+      {
+        window.setTimeout(
+          function()
+          {
+            currentTabDocument().defaultView.alert("hello");
+          }, 0);
+      }
+
+      this.check = function showAlert_finalCheck(aEvent)
+      {
+        var dialog = aEvent.accessible.DOMNode;
+        var info = dialog.ui.infoBody;
+        testRelation(info, RELATION_DESCRIPTION_FOR, dialog);
+        testRelation(dialog, RELATION_DESCRIBED_BY, info);
+      }
+
+      this.getID = function showAlert_getID()
+      {
+        return "show alert";
+      }
+    }
+
+    //gA11yEventDumpToConsole = true; // debug
+
+    var gQueue = null;
+    function doTests()
+    {
+      gQueue = new eventQueue();
+      gQueue.push(new showAlert());
+      gQueue.onFinish = function()
+      {
+        synthesizeKey("VK_RETURN", {}, browserWindow());
+        closeBrowserWindow();
+      }
+      gQueue.invoke(); // will call SimpleTest.finish()
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    openBrowserWindow(doTests);
+  </script>
+
+</head>
+
+<body id="body">
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=661293"
+     title="The tabmodalprompt dialog's prompt label doesn't get the text properly associated for accessibility">
+    Mozilla Bug 661293
+  </a>
+  <br>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+</body>
+</html>
--- a/accessible/tests/mochitest/states.js
+++ b/accessible/tests/mochitest/states.js
@@ -97,25 +97,16 @@ function testStates(aAccOrElmOrID, aStat
     isState(state & STATE_FOCUSABLE, STATE_FOCUSABLE, false,
             "Focussed " + id + " must be focusable!");
 
   if (aAbsentState && (aAbsentState & STATE_FOCUSABLE)) {
     isState(state & STATE_FOCUSED, 0, false,
               "Not focusable " + id + " must be not focused!");
   }
 
-  // readonly/editable
-  if (state & STATE_READONLY)
-    isState(extraState & EXT_STATE_EDITABLE, 0, true,
-            "Read-only " + id + " cannot be editable!");
-
-  if (extraState & EXT_STATE_EDITABLE)
-    isState(state & STATE_READONLY, 0, true,
-            "Editable " + id + " cannot be readonly!");
-
   // multiline/singleline
   if (extraState & EXT_STATE_MULTI_LINE)
     isState(extraState & EXT_STATE_SINGLE_LINE, 0, true,
             "Multiline " + id + " cannot be singleline!");
 
   if (extraState & EXT_STATE_SINGLE_LINE)
     isState(extraState & EXT_STATE_MULTI_LINE, 0, true,
             "Singleline " + id + " cannot be multiline!");
--- a/accessible/tests/mochitest/states/Makefile.in
+++ b/accessible/tests/mochitest/states/Makefile.in
@@ -45,23 +45,23 @@ relativesrcdir  = accessible/states
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =\
 		test_aria.html \
 		test_aria_imgmap.html \
 		test_aria_widgetitems.html \
 		test_buttons.html \
+		test_controls.xul \
 		test_doc.html \
 		test_docarticle.html \
 		test_editablebody.html \
 		test_expandable.xul \
 		test_frames.html \
 		test_inputs.html \
-		test_inputs.xul \
 		test_link.html \
 		test_popup.xul \
 		test_selects.html \
 		test_stale.html \
 		test_textbox.xul \
 		test_tree.xul \
 		test_visibility.html \
 		z_frames.html \
rename from accessible/tests/mochitest/states/test_inputs.xul
rename to accessible/tests/mochitest/states/test_controls.xul
--- a/accessible/tests/mochitest/states/test_inputs.xul
+++ b/accessible/tests/mochitest/states/test_controls.xul
@@ -14,20 +14,16 @@
   <script type="application/javascript"
           src="../states.js" />
 
   <script type="application/javascript">
   <![CDATA[
 
     function doTest()
     {
-      testStates("some-text", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE);
-      testStates("some-text2", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE);
-      testStates("some-password", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE);
-      testStates("some-password2", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE);
       testStates("checkbox", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE);
       testStates("checkbox2", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE);
       testStates("radio-group", 0, 0, STATE_UNAVAILABLE);
       testStates("orange", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE);
       testStates("violet", 0, 0, STATE_UNAVAILABLE);
       testStates("radio-group2", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE);
       testStates("orange2", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE);
 
@@ -50,21 +46,16 @@
       <div id="content" style="display: none">
       </div>
       <pre id="test">
       </pre>
     </body>
 
     <vbox flex="1">
 
-    <textbox id="some-text"/>
-    <textbox id="some-text2" disabled="true"/>
-    <textbox id="some-password" type="password" maxlength="8"/>
-    <textbox id="some-password2" type="password" maxlength="8" disabled="true"/>
-
     <checkbox id="checkbox" checked="true" label="Steak"/>
     <checkbox id="checkbox2" checked="true" label="Salad" disabled="true"/>
 
     <radiogroup id="radio-group">
       <radio id="orange" label="Orange" disabled="true"/>
       <radio id="violet" selected="true" label="Violet"/>
       <radio id="yellow" label="Yellow"/>
     </radiogroup>
--- a/accessible/tests/mochitest/states/test_doc.html
+++ b/accessible/tests/mochitest/states/test_doc.html
@@ -15,42 +15,42 @@
 
   <script type="application/javascript">
     function doTest()
     {
       // Bug 566542: root accesible should expose active state when focused.
       testStates(getRootAccessible(), 0, EXT_STATE_ACTIVE);
 
       // Bug 509696, 607219.
-      testStates(document, STATE_READONLY); // role=""
+      testStates(document, STATE_READONLY, 0); // role=""
 
       document.body.setAttribute("role","banner"); // no platform mapping
       testStates(document, STATE_READONLY);
       document.body.setAttribute("role","foo"); // bogus role
       testStates(document, STATE_READONLY);
       document.body.removeAttribute("role");
       testStates(document, STATE_READONLY);
 
       // Bugs 454997 and 467387
       testStates(document, STATE_READONLY);
       testStates("document", STATE_READONLY);
-      testStates("editable_document", 0, EXT_STATE_EDITABLE);
+      testStates("editable_document", 0, EXT_STATE_EDITABLE, STATE_READONLY);
 
       document.designMode = "on";
 
-      testStates(document, 0, EXT_STATE_EDITABLE);
-      testStates("p", 0, EXT_STATE_EDITABLE);
-      testStates("document", 0, EXT_STATE_EDITABLE);
-      testStates("editable_document", 0, EXT_STATE_EDITABLE);
+      testStates(document, 0, EXT_STATE_EDITABLE, STATE_READONLY);
+      testStates("p", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+      testStates("document", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+      testStates("editable_document", 0, EXT_STATE_EDITABLE, STATE_READONLY);
 
       document.designMode = "off";
 
       testStates(document, STATE_READONLY);
       testStates("document", STATE_READONLY);
-      testStates("editable_document", 0, EXT_STATE_EDITABLE);
+      testStates("editable_document", 0, EXT_STATE_EDITABLE, STATE_READONLY);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
--- a/accessible/tests/mochitest/states/test_docarticle.html
+++ b/accessible/tests/mochitest/states/test_docarticle.html
@@ -15,35 +15,36 @@
 
   <script type="application/javascript">
     function doTest()
     {
       var docAcc = getAccessible(document, [nsIAccessibleDocument]);
       if (docAcc) {
         testStates(docAcc, STATE_READONLY);
         testStates("aria_article", STATE_READONLY);
-        testStates("editable_aria_article", 0, EXT_STATE_EDITABLE);
+        testStates("editable_aria_article", 0, EXT_STATE_EDITABLE,
+                   STATE_READONLY);
         testStates("article", STATE_READONLY);
-        testStates("editable_article", 0, EXT_STATE_EDITABLE);
+        testStates("editable_article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
 
         document.designMode = "on";
 
-        testStates(docAcc, 0, EXT_STATE_EDITABLE);
-        testStates("aria_article", 0, EXT_STATE_EDITABLE);
-        testStates("editable_aria_article", 0, EXT_STATE_EDITABLE);
-        testStates("article", 0, EXT_STATE_EDITABLE);
-        testStates("editable_article", 0, EXT_STATE_EDITABLE);
+        testStates(docAcc, 0, EXT_STATE_EDITABLE, STATE_READONLY);
+        testStates("aria_article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+        testStates("editable_aria_article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+        testStates("article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+        testStates("editable_article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
   
         document.designMode = "off";
 
         testStates(docAcc, STATE_READONLY);
         testStates("aria_article", STATE_READONLY);
-        testStates("editable_aria_article", 0, EXT_STATE_EDITABLE);
+        testStates("editable_aria_article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
         testStates("article", STATE_READONLY);
-        testStates("editable_article", 0, EXT_STATE_EDITABLE);
+        testStates("editable_article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
       }
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
--- a/accessible/tests/mochitest/states/test_frames.html
+++ b/accessible/tests/mochitest/states/test_frames.html
@@ -17,32 +17,42 @@
   <script type="application/javascript">
     function doTest()
     {
       frameDoc = document.getElementById("frame_doc").contentDocument;
       frameDocArticle = document.getElementById("frame_doc_article").contentDocument;
       frameDocCheckbox = document.getElementById("frame_doc_checkbox").contentDocument;
       frameDocTextbox = document.getElementById("frame_doc_textbox").contentDocument;
 
-      testStates(frameDoc, STATE_READONLY, 0, 0, 0, "test1: frameDoc");
-      testStates(frameDocArticle, STATE_READONLY, 0, 0, 0, "test1: frameDocArticle");
-      testStates(frameDocCheckbox, 0, 0, STATE_READONLY, 0, "test1: frameDocCheckbox");
-      testStates(frameDocTextbox, 0, EXT_STATE_EDITABLE, 0, 0, "test1: frameDocTextbox");
+      testStates(frameDoc, STATE_READONLY, 0, 0, 0,
+                 "test1: frameDoc");
+      testStates(frameDocArticle, STATE_READONLY, 0, 0, 0,
+                 "test1: frameDocArticle");
+      testStates(frameDocCheckbox, 0, 0, STATE_READONLY, 0,
+                 "test1: frameDocCheckbox");
+      testStates(frameDocTextbox, 0, EXT_STATE_EDITABLE, STATE_READONLY, 0,
+                 "test1: frameDocTextbox");
 
       frameDoc.designMode = "on";
-      testStates(frameDoc,  0, EXT_STATE_EDITABLE, 0, 0, "test2: frameDoc");
-      testStates(frameDocArticle, STATE_READONLY, 0, 0, 0, "test2: frameDocArticle");
-      testStates(frameDocCheckbox, 0, 0, STATE_READONLY, 0, "test2: frameDocCheckbox");
-      testStates(frameDocTextbox, 0, EXT_STATE_EDITABLE, 0, 0, "test2: frameDocTextbox");
+      testStates(frameDoc,  0, EXT_STATE_EDITABLE, STATE_READONLY, 0,
+                 "test2: frameDoc");
+      testStates(frameDocArticle, STATE_READONLY, 0, 0, 0,
+                 "test2: frameDocArticle");
+      testStates(frameDocCheckbox, 0, 0, STATE_READONLY, 0,
+                 "test2: frameDocCheckbox");
+      testStates(frameDocTextbox, 0, EXT_STATE_EDITABLE, STATE_READONLY, 0,
+                 "test2: frameDocTextbox");
 
       frameDocArticle.designMode = "on";
-      testStates(frameDocArticle, 0, EXT_STATE_EDITABLE, 0, 0, "test3: frameDocArticle");
+      testStates(frameDocArticle, 0, EXT_STATE_EDITABLE, STATE_READONLY, 0,
+                 "test3: frameDocArticle");
 
       frameDocCheckbox.designMode = "on";
-      testStates(frameDocCheckbox, 0, 0, STATE_READONLY, 0, "test4: frameDocCheckbox");
+      testStates(frameDocCheckbox, 0, 0, STATE_READONLY, 0,
+                 "test4: frameDocCheckbox");
 
       // Replace iframe document body before the document accessible tree is
       // created. Check the states are updated for new body.
       var frameUpdateDoc =
         document.getElementById("frame_updatedoc").contentDocument;
       testStates(frameUpdateDoc, 0, EXT_STATE_EDITABLE,
                  STATE_READONLY, EXT_STATE_STALE, "test5: frameUpdateDoc");
 
--- a/accessible/tests/mochitest/states/test_inputs.html
+++ b/accessible/tests/mochitest/states/test_inputs.html
@@ -11,47 +11,76 @@
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../states.js"></script>
 
   <script type="application/javascript">
   function doTest()
   {
-    // 'required' state. Also piggyback 'unavailable' testing here.
+    ////////////////////////////////////////////////////////////////////////////
+    // 'editable' and 'multiline' states.
+    testStates("input", 0, EXT_STATE_EDITABLE, 0, EXT_STATE_MULTI_LINE);
+    testStates("textarea", 0, EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE);
+
+    testStates("input_readonly", 0, EXT_STATE_EDITABLE);
+    testStates("input_disabled", 0, EXT_STATE_EDITABLE);
+    testStates("textarea_readonly", 0, EXT_STATE_EDITABLE);
+    testStates("textarea_disabled", 0, EXT_STATE_EDITABLE);
+
+    ////////////////////////////////////////////////////////////////////////////
+    // 'required', 'readonly' and 'unavailable' states.
     var maybe_required = ["input","search","radio","checkbox","textarea"];
     var never_required = ["submit","button","reset","image"];
 
     var i;
     for (i in maybe_required) {
-      testStates(maybe_required[i], STATE_REQUIRED, 0, STATE_UNAVAILABLE);
-      testStates(maybe_required[i] + "2", 0, 0, STATE_REQUIRED);
-      testStates(maybe_required[i] + "3", STATE_UNAVAILABLE);
+      testStates(maybe_required[i],
+                 STATE_FOCUSABLE, 0,
+                 STATE_REQUIRED | STATE_READONLY | STATE_UNAVAILABLE);
+
+      testStates(maybe_required[i] + "_required",
+                 STATE_FOCUSABLE | STATE_REQUIRED, 0,
+                 STATE_UNAVAILABLE | STATE_READONLY);
+
+      var readonlyID = maybe_required[i] + "_readonly";
+      if (document.getElementById(readonlyID)) {
+        testStates(readonlyID,
+                   STATE_FOCUSABLE | STATE_READONLY, 0,
+                   STATE_UNAVAILABLE | STATE_REQUIRED);
+      }
+
+      testStates(maybe_required[i] + "_disabled",
+                 STATE_UNAVAILABLE, 0,
+                 STATE_FOCUSABLE | STATE_READONLY | STATE_REQUIRED);
     }
 
     for (i in never_required) {
       testStates(never_required[i], 0, 0, STATE_REQUIRED);
     }
 
+    ////////////////////////////////////////////////////////////////////////////
     // inherited 'unavailable' state
     testStates("f", STATE_UNAVAILABLE);
     testStates("f_input", STATE_UNAVAILABLE);
     testStates("f_input_disabled", STATE_UNAVAILABLE);
 
+    ////////////////////////////////////////////////////////////////////////////
     // inherited from file control
     var fileTextField = getAccessible("file").firstChild;
     testStates(fileTextField, STATE_UNAVAILABLE | STATE_REQUIRED);
     var fileBrowseButton = getAccessible("file").lastChild;
     testStates(fileBrowseButton, STATE_UNAVAILABLE | STATE_REQUIRED);
 
-    /**
-     * maxlength doesn't make the element invalid until bug 613016 and bug 613019
-     * are fixed. Commenting out related lines and adding a todo to make sure
-     * it will be uncommented as soon as possible.
-     */
+    ////////////////////////////////////////////////////////////////////////////
+    // 'invalid' state
+
+    // XXX: maxlength doesn't make the element invalid until bug 613016 and
+    // bug 613019 are fixed. Commenting out related lines and adding a todo to
+    // make sure it will be uncommented as soon as possible.
     var todoInput = document.createElement("input");
     todoInput.maxLength = '2';
     todoInput.value = 'foo';
     todo(!todoInput.validity.valid,
          "input should be invalid because of maxlength");
 
     // invalid/valid state
     //var invalid = ["maxlength","pattern","email","url"];
@@ -66,16 +95,17 @@
     //var invalid = ["maxlength","pattern","email","url"];
     //document.getElementById("maxlength").value = "i am too long";
     var invalid = ["pattern","email","url"];
     for (i in invalid) {
       testStates(invalid[i], STATE_INVALID);
       testStates(invalid[i] + "2", 0, 0, STATE_INVALID);
     }
 
+    ////////////////////////////////////////////////////////////////////////////
     // autocomplete states
     testStates("autocomplete-default", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
     testStates("autocomplete-off", 0, 0, 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
     testStates("autocomplete-formoff", 0, 0, 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
     testStates("autocomplete-list", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
     testStates("autocomplete-list2", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
     SimpleTest.finish();
   }
@@ -116,38 +146,46 @@
      title="Add accessibility support for @list on HTML input and for HTML datalist">
     Mozilla Bug 559766
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=699017"
      title="File input control should be propogate states to descendants">
     Mozilla Bug 699017
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=733382"
+     title="Editable state bit should be present on readonly inputs">
+    Mozilla Bug 733382
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
 
   <form>
-    <input id="input" type="input" required>
-    <input id="input2" type="input">
-    <input id="input3" type="input" disabled>
-    <input id="search" type="search" required>
-    <input id="search2" type="search">
-    <input id="search3" type="search" disabled>
-    <input id="radio" type="radio" required>
-    <input id="radio2" type="radio">
-    <input id="radio3" type="radio" disabled>
-    <input id="checkbox" type="checkbox" required>
-    <input id="checkbox2" type="checkbox">
-    <input id="checkbox3" type="checkbox" disabled>
-    <textarea id="textarea" required></textarea>
-    <textarea id="textarea2"></textarea>
-    <textarea id="textarea3" disabled></textarea>
+    <input id="input" type="input">
+    <input id="input_required" type="input" required>
+    <input id="input_readonly" type="input" readonly>
+    <input id="input_disabled" type="input" disabled>
+    <input id="search" type="search">
+    <input id="search_required" type="search" required>
+    <input id="search_readonly" type="search" readonly>
+    <input id="search_disabled" type="search" disabled>
+    <input id="radio" type="radio">
+    <input id="radio_required" type="radio" required>
+    <input id="radio_disabled" type="radio" disabled>
+    <input id="checkbox" type="checkbox">
+    <input id="checkbox_required" type="checkbox" required>
+    <input id="checkbox_disabled" type="checkbox" disabled>
+    <textarea id="textarea"></textarea>
+    <textarea id="textarea_required" required></textarea>
+    <textarea id="textarea_readonly" readonly></textarea>
+    <textarea id="textarea_disabled" disabled></textarea>
   </form>
 
   <!-- bogus required usage -->
   <input id="submit" type="submit" required>
   <input id="button" type="button" required>
   <input id="reset" type="reset" required>
   <input id="image" type="image" required>
 
--- a/accessible/tests/mochitest/states/test_textbox.xul
+++ b/accessible/tests/mochitest/states/test_textbox.xul
@@ -18,75 +18,93 @@
 
   <script type="application/javascript">
   <![CDATA[
     function doTest()
     {
       //////////////////////////////////////////////////////////////////////////
       // Ordinary textbox
       testStates("textbox",
-                 STATE_FOCUSABLE, EXT_STATE_EDITABLE,
-                 STATE_PROTECTED | STATE_UNAVAILABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 STATE_FOCUSABLE,
+                 EXT_STATE_EDITABLE,
+                 STATE_PROTECTED | STATE_UNAVAILABLE,
+                 EXT_STATE_SUPPORTS_AUTOCOMPLETION,
                  "ordinary textbox");
 
       //////////////////////////////////////////////////////////////////////////
       // Password textbox
       testStates("password",
-                 STATE_FOCUSABLE | STATE_PROTECTED, EXT_STATE_EDITABLE,
-                 STATE_UNAVAILABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 STATE_FOCUSABLE | STATE_PROTECTED,
+                 EXT_STATE_EDITABLE,
+                 STATE_UNAVAILABLE,
+                 EXT_STATE_SUPPORTS_AUTOCOMPLETION,
                  "password textbox");
 
       //////////////////////////////////////////////////////////////////////////
       // Textarea
       testStates("textarea",
-                 STATE_FOCUSABLE, EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE,
-                 STATE_PROTECTED | STATE_UNAVAILABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 STATE_FOCUSABLE,
+                 EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE,
+                 STATE_PROTECTED | STATE_UNAVAILABLE,
+                 EXT_STATE_SUPPORTS_AUTOCOMPLETION,
                  "multiline textbox");
 
       //////////////////////////////////////////////////////////////////////////
       // Readonly textbox
       testStates("readonly_textbox",
-                 STATE_FOCUSABLE | STATE_READONLY, 0,
-                 STATE_PROTECTED | STATE_UNAVAILABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 STATE_FOCUSABLE | STATE_READONLY,
+                 EXT_STATE_EDITABLE,
+                 STATE_PROTECTED | STATE_UNAVAILABLE,
+                 EXT_STATE_SUPPORTS_AUTOCOMPLETION,
                  "readonly textbox");
 
       //////////////////////////////////////////////////////////////////////////
       // Disabled textbox
       testStates("disabled_textbox",
-                 STATE_UNAVAILABLE, 0,
-                 STATE_FOCUSABLE | STATE_PROTECTED, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 STATE_UNAVAILABLE,
+                 EXT_STATE_EDITABLE,
+                 STATE_FOCUSABLE | STATE_PROTECTED,
+                 EXT_STATE_SUPPORTS_AUTOCOMPLETION,
                  "readonly textbox");
 
       //////////////////////////////////////////////////////////////////////////
       // Readonly textarea
       testStates("readonly_textarea",
-                 STATE_FOCUSABLE | STATE_READONLY, EXT_STATE_MULTI_LINE,
-                 STATE_PROTECTED | STATE_UNAVAILABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 STATE_FOCUSABLE | STATE_READONLY,
+                 EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE,
+                 STATE_PROTECTED | STATE_UNAVAILABLE,
+                 EXT_STATE_SUPPORTS_AUTOCOMPLETION,
                  "readonly multiline textbox");
 
       //////////////////////////////////////////////////////////////////////////
       // Disabled textarea
       testStates("disabled_textarea",
-                 STATE_UNAVAILABLE, EXT_STATE_MULTI_LINE,
-                 STATE_PROTECTED | STATE_FOCUSABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 STATE_UNAVAILABLE,
+                 EXT_STATE_EDITABLE| EXT_STATE_MULTI_LINE,
+                 STATE_PROTECTED | STATE_FOCUSABLE,
+                 EXT_STATE_SUPPORTS_AUTOCOMPLETION,
                  "readonly multiline textbox");
 
       //////////////////////////////////////////////////////////////////////////
       // Search textbox without search button, searches as you type and filters
       // a separate control.
       testStates("searchbox",
-                 STATE_FOCUSABLE, EXT_STATE_EDITABLE | EXT_STATE_SUPPORTS_AUTOCOMPLETION,
-                 STATE_PROTECTED | STATE_UNAVAILABLE, 0,
+                 STATE_FOCUSABLE,
+                 EXT_STATE_EDITABLE | EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 STATE_PROTECTED | STATE_UNAVAILABLE,
+                 0,
                  "searchbox");
 
       //////////////////////////////////////////////////////////////////////////
       // Search textbox with search button, does not support autoCompletion.
       testStates("searchfield",
-                 STATE_FOCUSABLE, EXT_STATE_EDITABLE,
-                 STATE_PROTECTED | STATE_UNAVAILABLE, EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+                 STATE_FOCUSABLE,
+                 EXT_STATE_EDITABLE,
+                 STATE_PROTECTED | STATE_UNAVAILABLE,
+                 EXT_STATE_SUPPORTS_AUTOCOMPLETION,
                  "searchfield");
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   ]]>
--- a/accessible/tests/mochitest/testTextboxes.js
+++ b/accessible/tests/mochitest/testTextboxes.js
@@ -22,25 +22,22 @@ function testAction(aID, aAcc, aNumActio
     // Test first action. Normally only 1 should be present.
     is(aAcc.getActionName(0), aActionName,
        "Wrong name of action for " + aID + "!");
     is(aAcc.getActionDescription(0), aActionDescription,
        "Wrong description of action for " + aID + "!");
   }
 }
 
-function testThis(aID, aName, aValue, aDescription, aRole, aState,
-                  aExtraState, aAbsentState, aNumActions, aActionName,
-                  aActionDescription)
+function testThis(aID, aName, aValue, aDescription, aRole,
+                  aNumActions, aActionName, aActionDescription)
 {
   var acc = getAccessible(aID);
   if (!acc)
     return;
 
   is(acc.name, aName, "Wrong name for " + aID + "!");
   testValue(aID, acc, aValue, aRole);
   is(acc.description, aDescription, "Wrong description for " + aID + "!");
   testRole(aID, aRole);
 
-  testStates(acc, aState, aExtraState, aAbsentState);
-
   testAction(aID, acc, aNumActions, aActionName, aActionDescription);
 }
--- a/accessible/tests/mochitest/test_textboxes.html
+++ b/accessible/tests/mochitest/test_textboxes.html
@@ -25,131 +25,104 @@ https://bugzilla.mozilla.org/show_bug.cg
     {
       //////////////////////////////////////////////////////////////////////////
       // normal textbox without content and with no proper label
       testThis("unlabelled_Textbox", // ID
                null, // name
                "", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // normal textbox without content and with a proper label
       testThis("labelled_textbox", // ID
                "Second textbox:", // name
                "", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // normal textbox with content and with a proper label
       testThis("prefilled_textbox", // ID
                "Textbox with predefined value:", // name
                "I have some text", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // password textbox with a proper label
       testThis("password_textbox", // ID
                "Enter some password here:", // name
                "", // value
                "", // description
                ROLE_PASSWORD_TEXT, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // textarea without content and label
       testThis("unlabelled_Textarea", // ID
                null, // name
                "", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // textarea without content and with proper label
       testThis("labelled_textarea", // ID
                "Labelled textarea:", // name
                "", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // textarea with content and with proper label
       testThis("prefilled_textarea", // ID
                "Pre-filled textarea:", // name
                "    I also have some text.\n    ", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // readonly textbox with content and with proper label
       testThis("readonly_textbox", // ID
                "The following is a read-only textbox:", // name
                "You cannot change me.", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE | STATE_READONLY), // state
-               (0), // extState
-               (0), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // readonly textarea with content and with proper label
       testThis("readonly_textarea", // ID
                "This textarea is readonly, too:", // name
                "    You cannot change me, either.\n    ", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE | STATE_READONLY), // state
-               (EXT_STATE_MULTI_LINE), // extState
-               (0), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
--- a/accessible/tests/mochitest/test_textboxes.xul
+++ b/accessible/tests/mochitest/test_textboxes.xul
@@ -25,160 +25,127 @@
     {
       //////////////////////////////////////////////////////////////////////////
       // normal textbox without content and with no proper label
       testThis("unlabelled_Textbox", // ID
                null, // name
                "", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // normal textbox without content and with a proper label
       testThis("labelled_textbox", // ID
                "Second textbox:", // name
                "", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // normal textbox with content and with a proper label
       testThis("prefilled_textbox", // ID
                "Textbox with predefined value:", // name
                "I have some text", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // password textbox with a proper label
       testThis("password_textbox", // ID
                "Enter some password here:", // name
                "", // value
                "", // description
                ROLE_PASSWORD_TEXT, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // textarea without content and label
       testThis("unlabelled_Textarea", // ID
                null, // name
                "", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // textarea without content and with proper label
       testThis("labelled_textarea", // ID
                "Labelled textarea:", // name
                "", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // textarea with content and with proper label
       testThis("prefilled_textarea", // ID
                "Pre-filled textarea:", // name
                "I also have some text.", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE), // extState
-               (STATE_READONLY), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // readonly textbox with content and with proper label
       testThis("readonly_textbox", // ID
                "The following is a read-only textbox:", // name
                "You cannot change me.", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE | STATE_READONLY), // state
-               (0), // extState
-               (0), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // readonly textarea with content and with proper label
       testThis("readonly_textarea", // ID
                "This textarea is readonly, too:", // name
                "You cannot change me, either.", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE | STATE_READONLY), // state
-               (EXT_STATE_MULTI_LINE), // extState
-               (0), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // Search textbox without search button, searches as you type and filters
       // a separate control.
       testThis("search-box", // ID
                "Search History:", // name
                "", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (EXT_STATE_SUPPORTS_AUTOCOMPLETION), // extState
-               (0), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
 
       //////////////////////////////////////////////////////////////////////////
       // Search textbox with search button, does not support autoCompletion.
       testThis("searchfield", // ID
                "Search all add-ons", // name
                "", // value
                "", // description
                ROLE_ENTRY, // role
-               (STATE_FOCUSABLE), // state
-               (0), // extState
-               (0), // absentState
                1, // numActions
                "activate",  // ActionName
                "Activate"); // ActionDescription
       testStates("searchfield", 0, 0, 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
 
       SimpleTest.finish();
     }
 
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -60,17 +60,18 @@ 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', 'webcontacts-manage'
+    'indexedDB', 'indexedDB-unlimited', 'webapps-manage', 'offline-app',
+    'content-camera', 'webcontacts-manage', 'wifi-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);
     });
new file mode 100644
--- /dev/null
+++ b/b2g/config/mozconfigs/linux32/debug
@@ -0,0 +1,21 @@
+#GONK_TOOLCHAIN_VERSION=0
+#export GONK_PRODUCT=generic
+#gonk="/home/cjones/mozilla/gonk-toolchain-$GONK_TOOLCHAIN_VERSION"
+
+mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-prof-gonk
+
+mk_add_options MOZ_MAKE_FLAGS="-s -j16"
+
+ac_add_options --enable-application=b2g
+
+ac_add_options --target=arm-android-eabi
+ac_add_options --with-gonk="$gonk"
+ac_add_options --with-endian=little
+ac_add_options --disable-elf-hack
+ac_add_options --enable-debug-symbols
+ac_add_options --enable-profiling
+ac_add_options --with-ccache
+ac_add_options --enable-marionette
+
+# Enable dump() from JS.
+export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
new file mode 100644
--- /dev/null
+++ b/b2g/config/tooltool-manifests/releng.manifest
@@ -0,0 +1,14 @@
+[
+{
+    "size": 195, 
+    "digest": "85369693c2362131515014cd4547cd0824225b03e1e52a352a84012e6e8586fa46ad619181167d220c463761865719a1747a83aeee76a5fcc5ab7859c14ef24a", 
+    "algorithm": "sha512", 
+    "filename": "setup.sh"
+}, 
+{
+    "size": 121344236, 
+    "digest": "0bf5cceced8add6142c1c7522890c39554b94848e3f5eb9b92de2a8c6f6af3c0e8ab69ddf7bae39eaab2bcb637233ff02de07b47a1850767d2810a46fb31bf65", 
+    "algorithm": "sha512", 
+    "filename": "gonk-toolchain-0.tar.bz2"
+}
+]
--- a/b2g/confvars.sh
+++ b/b2g/confvars.sh
@@ -33,17 +33,17 @@
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 MOZ_APP_BASENAME=B2G
 MOZ_APP_VENDOR=Mozilla
 
-MOZ_APP_VERSION=13.0a1
+MOZ_APP_VERSION=14.0a1
 MOZ_APP_UA_NAME=Firefox
 
 MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial
 MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official
 # MOZ_APP_DISPLAYNAME is set by branding/configure.sh
 
 MOZ_SAFE_BROWSING=
 MOZ_SERVICES_SYNC=
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -143,17 +143,17 @@
 @BINPATH@/components/cookie.xpt
 @BINPATH@/components/directory.xpt
 @BINPATH@/components/docshell.xpt
 @BINPATH@/components/dom.xpt
 @BINPATH@/components/dom_base.xpt
 #ifdef MOZ_B2G_RIL
 @BINPATH@/components/dom_telephony.xpt
 @BINPATH@/components/dom_wifi.xpt
-@BINPATH@/components/dom_system_b2g.xpt
+@BINPATH@/components/dom_system_gonk.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
@@ -404,16 +404,18 @@
 @BINPATH@/components/nsFilePicker.manifest
 #ifdef MOZ_B2G_RIL
 @BINPATH@/components/RadioInterfaceLayer.manifest
 @BINPATH@/components/RadioInterfaceLayer.js
 @BINPATH@/components/SmsDatabaseService.manifest
 @BINPATH@/components/SmsDatabaseService.js
 @BINPATH@/components/nsWifiWorker.js
 @BINPATH@/components/nsWifiWorker.manifest
+@BINPATH@/components/nsDOMWifiManager.js
+@BINPATH@/components/nsDOMWifiManager.manifest
 #endif
 #ifdef XP_MACOSX
 @BINPATH@/components/libalerts.dylib
 #endif
 #ifdef MOZ_ENABLE_DBUS
 @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
 #endif
 @BINPATH@/components/nsINIProcessor.manifest
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -34,18 +34,23 @@
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 // XXX Toolkit-specific preferences should be moved into toolkit.js
 
 #filter substitution
 
-# SYNTAX HINTS:  dashes are delimiters.  Use underscores instead.
-#  The first character after a period must be alphabetic.
+#
+# SYNTAX HINTS:
+#
+#  - Dashes are delimiters; use underscores instead.
+#  - The first character after a period must be alphabetic.
+#  - Computed values (e.g. 50 * 1024) don't work.
+#
 
 #ifdef XP_UNIX
 #ifndef XP_MACOSX
 #define UNIX_BUT_NOT_MAC
 #endif
 #endif
 
 pref("browser.chromeURL","chrome://browser/content/");
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -319,16 +319,17 @@
     <key id="goForwardKb2" key="&goForwardCmd.commandKey;" command="Browser:Forward" modifiers="accel"/>
 #endif
     <key id="goHome" keycode="VK_HOME" command="Browser:Home" modifiers="alt"/>
     <key keycode="VK_F5" command="Browser:Reload"/>
 #ifndef XP_MACOSX
     <key id="showAllHistoryKb" key="&showAllHistoryCmd.commandkey;" command="Browser:ShowAllHistory" modifiers="accel,shift"/>
     <key keycode="VK_F5" command="Browser:ReloadSkipCache" modifiers="accel"/>
     <key keycode="VK_F6" command="Browser:FocusNextFrame"/>
+    <key keycode="VK_F6" command="Browser:FocusNextFrame" modifiers="shift"/>
     <key id="key_fullScreen" keycode="VK_F11" command="View:FullScreen"/>
 #else
     <key id="key_fullScreen" key="&fullScreenCmd.macCommandKey;" command="View:FullScreen" modifiers="accel,shift"/>
     <key keycode="VK_F11" command="View:FullScreen"/>
 #endif
     <key key="&reloadCmd.commandkey;" command="Browser:Reload" modifiers="accel" id="key_reload"/>
     <key key="&reloadCmd.commandkey;" command="Browser:ReloadSkipCache" modifiers="accel,shift"/>
     <key id="key_viewSource" key="&pageSourceCmd.commandkey;" command="View:PageSource" modifiers="accel"/>
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -4492,18 +4492,23 @@ var XULBrowserWindow = {
   setDefaultStatus: function (status) {
     this.defaultStatus = status;
     this.updateStatusField();
   },
 
   setOverLink: function (url, anchorElt) {
     // Encode bidirectional formatting characters.
     // (RFC 3987 sections 3.2 and 4.1 paragraph 6)
-    this.overLink = url.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
-                                encodeURIComponent);
+    url = url.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
+                      encodeURIComponent);
+
+    if (gURLBar && gURLBar._mayTrimURLs /* corresponds to browser.urlbar.trimURLs */)
+      url = trimURL(url);
+
+    this.overLink = url;
     LinkTargetDisplay.update();
   },
 
   updateStatusField: function () {
     var text, type, types = ["overLink"];
     if (this._busyUI)
       types.push("status");
     types.push("jsStatus", "jsDefaultStatus", "defaultStatus");
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -522,17 +522,17 @@
                  onfocus="document.getElementById('identity-box').style.MozUserFocus= 'normal'"
                  onblur="setTimeout(function() document.getElementById('identity-box').style.MozUserFocus = '', 0);">
           <box id="notification-popup-box" hidden="true" align="center">
             <image id="default-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="geo-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="addons-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="indexedDB-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="password-notification-icon" class="notification-anchor-icon" role="button"/>
-            <image id="webapps-notification-icon" class="webapps-anchor-icon" role="button"/>
+            <image id="webapps-notification-icon" class="notification-anchor-icon" role="button"/>
           </box>
           <!-- Use onclick instead of normal popup= syntax since the popup
                code fires onmousedown, and hence eats our favicon drag events.
                We only add the identity-box button to the tab order when the location bar
                has focus, otherwise pressing F6 focuses it instead of the location bar -->
           <box id="identity-box" role="button"
                onclick="gIdentityHandler.handleIdentityButtonEvent(event);"
                onkeypress="gIdentityHandler.handleIdentityButtonEvent(event);"
--- a/browser/components/migration/src/nsBrowserProfileMigratorUtils.cpp
+++ b/browser/components/migration/src/nsBrowserProfileMigratorUtils.cpp
@@ -51,17 +51,17 @@
 
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsIRDFService.h"
 #include "nsIStringBundle.h"
 #include "nsXPCOMCID.h"
 
 #define MIGRATION_BUNDLE "chrome://browser/locale/migration/migration.properties"
 
-#define BOOKMARKS_FILE_NAME NS_LITERAL_STRING("bookmarks.html")
+#define DEFAULT_BOOKMARKS NS_LITERAL_CSTRING("resource:///defaults/profile/bookmarks.html")
 
 void SetUnicharPref(const char* aPref, const nsAString& aValue,
                     nsIPrefBranch* aPrefs)
 {
   nsCOMPtr<nsISupportsString> supportsString =
     do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);    
   if (supportsString) {
      supportsString->SetData(aValue); 
@@ -159,77 +159,24 @@ GetProfilePath(nsIProfileStartup* aStart
     if (dirSvc) {
       dirSvc->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
                   (void**) getter_AddRefs(aProfileDir));
     }
   }
 }
 
 nsresult
-ImportBookmarksHTML(nsIFile* aBookmarksFile, 
-                    bool aImportIntoRoot,
-                    bool aOverwriteDefaults,
-                    const PRUnichar* aImportSourceNameKey)
+ImportDefaultBookmarks()
 {
-  nsresult rv;
-
-  nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(aBookmarksFile));
-  NS_ENSURE_TRUE(localFile, NS_ERROR_FAILURE);
-  nsCOMPtr<nsIPlacesImportExportService> importer = do_GetService(NS_PLACESIMPORTEXPORTSERVICE_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Import file directly into the bookmarks root folder.
-  if (aImportIntoRoot) {
-    rv = importer->ImportHTMLFromFile(localFile, aOverwriteDefaults);
-    NS_ENSURE_SUCCESS(rv, rv);
-    return NS_OK;
-  }
-
-  // Get the source application name.
-  nsCOMPtr<nsIStringBundleService> bundleService =
-    do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr<nsIStringBundle> bundle;
-  rv = bundleService->CreateBundle(MIGRATION_BUNDLE, getter_AddRefs(bundle));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsString sourceName;
-  rv = bundle->GetStringFromName(aImportSourceNameKey,
-                                 getter_Copies(sourceName));
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIPlacesImportExportService> importer =
+    do_GetService(NS_PLACESIMPORTEXPORTSERVICE_CONTRACTID);
+  NS_ENSURE_STATE(importer);
 
-  const PRUnichar* sourceNameStrings[] = { sourceName.get() };
-  nsString importedBookmarksTitle;
-  rv = bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
-                                    sourceNameStrings, 1, 
-                                    getter_Copies(importedBookmarksTitle));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Get the bookmarks service.
-  nsCOMPtr<nsINavBookmarksService> bms =
-    do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Create an imported bookmarks folder under the bookmarks menu.
-  PRInt64 root;
-  rv = bms->GetBookmarksMenuFolder(&root);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIIOService> ioService = mozilla::services::GetIOService();
+  NS_ENSURE_STATE(ioService);
+  nsCOMPtr<nsIURI> bookmarksURI;
+  nsresult rv = ioService->NewURI(DEFAULT_BOOKMARKS, nsnull, nsnull,
+                                  getter_AddRefs(bookmarksURI));
+  if (NS_FAILED(rv))
+    return rv;
 
-  PRInt64 folder;
-  rv = bms->CreateFolder(root, NS_ConvertUTF16toUTF8(importedBookmarksTitle),
-                         nsINavBookmarksService::DEFAULT_INDEX, &folder);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Import the bookmarks into the folder.
-  return importer->ImportHTMLFromFileToFolder(localFile, folder, false);
+  return importer->ImportHTMLFromURI(bookmarksURI, true);
 }
-
-nsresult
-InitializeBookmarks(nsIFile* aTargetProfile)
-{
-  nsCOMPtr<nsIFile> bookmarksFile;
-  aTargetProfile->Clone(getter_AddRefs(bookmarksFile));
-  bookmarksFile->Append(BOOKMARKS_FILE_NAME);
-  
-  nsresult rv = ImportBookmarksHTML(bookmarksFile, true, true, EmptyString().get());
-  NS_ENSURE_SUCCESS(rv, rv);
-  return NS_OK;
-}
--- a/browser/components/migration/src/nsBrowserProfileMigratorUtils.h
+++ b/browser/components/migration/src/nsBrowserProfileMigratorUtils.h
@@ -94,23 +94,15 @@ void GetMigrateDataFromArray(MigrationDa
                              nsIFile* aSourceProfile, 
                              PRUint16* aResult);
 
 
 // get the base directory of the *target* profile
 // this is already cloned, modify it to your heart's content
 void GetProfilePath(nsIProfileStartup* aStartup, nsCOMPtr<nsIFile>& aProfileDir);
 
-// In-place import from aBookmarksFile into a folder in the user's bookmarks.
-// If the importIntoRoot parameter has a value of true, the bookmarks will be
-// imported into the bookmarks root folder. Otherwise, they'll be imported into
-// a new folder with the name "From (STR:aImportSourceNameKey)".
-// aImportSourceNameKey is a key into migration.properties with the pretty name
-// of the application.
-nsresult ImportBookmarksHTML(nsIFile* aBookmarksFile, 
-                             bool aImportIntoRoot,
-                             bool aOverwriteDefaults,
-                             const PRUnichar* aImportSourceNameKey);
-
-nsresult InitializeBookmarks(nsIFile* aTargetProfile);
+/**
+ * Imports default bookmarks to the profile.
+ */
+nsresult ImportDefaultBookmarks();
 
 #endif
 
--- a/browser/components/migration/src/nsIEProfileMigrator.cpp
+++ b/browser/components/migration/src/nsIEProfileMigrator.cpp
@@ -1399,21 +1399,20 @@ nsIEProfileMigrator::CopyFavoritesBatche
 
     rv = bms->CreateFolder(bookmarksMenuFolderId,
                            NS_ConvertUTF16toUTF8(importedIEFavsTitle),
                            nsINavBookmarksService::DEFAULT_INDEX,
                            &folder);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   else {
-    // Initialize the default bookmarks
-    nsCOMPtr<nsIFile> profile;
-    GetProfilePath(nsnull, profile);
-    rv = InitializeBookmarks(profile);
-    NS_ENSURE_SUCCESS(rv, rv);
+    // If importing defaults fails for whatever reason, let the import process
+    // continue.
+    DebugOnly<nsresult> rv = ImportDefaultBookmarks();
+    MOZ_ASSERT(NS_SUCCEEDED(rv), "Should be able to import default bookmarks");
 
     // Locate the Links toolbar folder, we want to replace the Personal Toolbar
     // content with Favorites in this folder.
     // On versions minor or equal to IE6 the folder name is stored in the
     // LinksFolderName registry key, but in newer versions it may be just a
     // Links subfolder inside the default Favorites folder.
     nsCOMPtr<nsIWindowsRegKey> regKey =
       do_CreateInstance("@mozilla.org/windows-registry-key;1");
--- a/browser/components/migration/src/nsSafariProfileMigrator.cpp
+++ b/browser/components/migration/src/nsSafariProfileMigrator.cpp
@@ -60,27 +60,31 @@
 #include "nsIServiceManager.h"
 #include "nsIStringBundle.h"
 #include "nsISupportsPrimitives.h"
 #include "nsSafariProfileMigrator.h"
 #include "nsToolkitCompsCID.h"
 #include "nsNetUtil.h"
 #include "nsTArray.h"
 
+#include "mozilla/Util.h"
+
 #include <Carbon/Carbon.h>
 
 #define SAFARI_PREFERENCES_FILE_NAME      NS_LITERAL_STRING("com.apple.Safari.plist")
 #define SAFARI_BOOKMARKS_FILE_NAME        NS_LITERAL_STRING("Bookmarks.plist")
 #define SAFARI_HISTORY_FILE_NAME          NS_LITERAL_STRING("History.plist")
 #define SAFARI_COOKIES_FILE_NAME          NS_LITERAL_STRING("Cookies.plist")
 #define SAFARI_COOKIE_BEHAVIOR_FILE_NAME  NS_LITERAL_STRING("com.apple.WebFoundation.plist")
 #define SAFARI_DATE_OFFSET                978307200
 #define SAFARI_HOME_PAGE_PREF             "HomePage"
 #define MIGRATION_BUNDLE                  "chrome://browser/locale/migration/migration.properties"
 
+using namespace mozilla;
+
 ///////////////////////////////////////////////////////////////////////////////
 // nsSafariProfileMigrator
 
 NS_IMPL_ISUPPORTS1(nsSafariProfileMigrator, nsIBrowserProfileMigrator)
 
 nsSafariProfileMigrator::nsSafariProfileMigrator()
 {
   mObserverService = do_GetService("@mozilla.org/observer-service;1");
@@ -972,20 +976,21 @@ nsSafariProfileMigrator::CopyBookmarksBa
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = bms->CreateFolder(bookmarksMenuFolderId,
                            NS_ConvertUTF16toUTF8(importedSafariBookmarksTitle),
                            nsINavBookmarksService::DEFAULT_INDEX, &folder);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   else {
-    nsCOMPtr<nsIFile> profile;
-    GetProfilePath(nsnull, profile);
-    rv = InitializeBookmarks(profile);
-    NS_ENSURE_SUCCESS(rv, rv);
+    // If importing defaults fails for whatever reason, let the import process
+    // continue.
+    DebugOnly<nsresult> rv = ImportDefaultBookmarks();
+    MOZ_ASSERT(NS_SUCCEEDED(rv), "Should be able to import default bookmarks");
+
     // In replace mode we are merging at the top level.
     folder = bookmarksMenuFolderId;
   }
 
   nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
   nsCOMPtr<nsILocalFile> safariBookmarksFile;
   fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile),
                    getter_AddRefs(safariBookmarksFile));
deleted file mode 100644
--- a/browser/components/migration/tests/unit/bookmarks.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE NETSCAPE-Bookmark-file-1>
-<!-- This is an automatically generated file.
-     It will be read and overwritten.
-     DO NOT EDIT! -->
-<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
-<TITLE>Bookmarks</TITLE>
-<H1>Bookmarks Menu</H1>
-
-<DL><p>
-    <DT><A HREF="http://example.com/" ADD_DATE="1233157972" LAST_MODIFIED="1233157984">example</A>
-    <DT><H3 ADD_DATE="1233157910" LAST_MODIFIED="1233157972" PERSONAL_TOOLBAR_FOLDER="true">Bookmarks Toolbar</H3>
-<DD>Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar
-    <DL><p>
-        <DT><A HREF="http://example.com/" ADD_DATE="1233157972" LAST_MODIFIED="1233157984">example</A>
-    </DL><p>
-</DL><p>
--- a/browser/components/migration/tests/unit/head_migration.js
+++ b/browser/components/migration/tests/unit/head_migration.js
@@ -17,12 +17,8 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 
 // Initialize profile.
 let gProfD = do_get_profile();
 
 function newMigratorFor(aKey) {
   let cid = "@mozilla.org/profile/migrator;1?app=browser&type=" + aKey;
   return Cc[cid].createInstance(Ci.nsIBrowserProfileMigrator);
 }
-
-let (bookmarkshtml = do_get_file("bookmarks.html")) {
-  bookmarkshtml.copyTo(gProfD, "bookmarks.html");
-}
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -910,17 +910,17 @@ BrowserGlue.prototype = {
     // 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);
     
-    var telemetryPrompt = browserBundle.formatStringFromName("telemetryPrompt", [productName, serverOwner], 2);
+    var telemetryPrompt = browserBundle.formatStringFromName("telemetryOptInPrompt", [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);
--- a/browser/devtools/shared/Promise.jsm
+++ b/browser/devtools/shared/Promise.jsm
@@ -4,43 +4,71 @@
  * http://opensource.org/licenses/BSD-3-Clause
  */
 
 
 var EXPORTED_SYMBOLS = [ "Promise" ];
 
 /**
  * Create an unfulfilled promise
+ *
+ * @param {*=} aTrace A debugging value
+ *
  * @constructor
  */
-function Promise() {
+function Promise(aTrace) {
   this._status = Promise.PENDING;
   this._value = undefined;
   this._onSuccessHandlers = [];
   this._onErrorHandlers = [];
+  this._trace = aTrace;
 
   // Debugging help
-  this._id = Promise._nextId++;
-  Promise._outstanding[this._id] = this;
+  if (Promise.Debug._debug) {
+    this._id = Promise.Debug._nextId++;
+    Promise.Debug._outstanding[this._id] = this;
+  }
 }
 
 /**
- * We give promises and ID so we can track which are outstanding
- */
-Promise._nextId = 0;
-
-/**
- * Outstanding promises. Handy list for debugging only
+ * Debugging options and tools.
  */
-Promise._outstanding = [];
+Promise.Debug = {
+  /**
+   * Set current debugging mode.
+   *
+   * @param {boolean} value If |true|, maintain _nextId, _outstanding, _recent.
+   * Otherwise, cleanup debugging data.
+   */
+  setDebug: function(value) {
+    Promise.Debug._debug = value;
+    if (!value) {
+      Promise.Debug._outstanding = [];
+      Promise.Debug._recent = [];
+    }
+  },
+
+  _debug: false,
 
-/**
- * Recently resolved promises. Also for debugging only
- */
-Promise._recent = [];
+  /**
+   * We give promises and ID so we can track which are outstanding.
+   */
+  _nextId: 0,
+
+  /**
+   * Outstanding promises. Handy for debugging (only).
+   */
+  _outstanding: [],
+
+  /**
+   * Recently resolved promises. Also for debugging only.
+   */
+  _recent: []
+};
+
 
 /**
  * A promise can be in one of 2 states.
  * The ERROR and SUCCESS states are terminal, the PENDING state is the only
  * start state.
  */
 Promise.ERROR = -1;
 Promise.PENDING = 0;
@@ -135,49 +163,113 @@ Promise.prototype.reject = function(data
 
 /**
  * Internal method to be called on resolve() or reject()
  * @private
  */
 Promise.prototype._complete = function(list, status, data, name) {
   // Complain if we've already been completed
   if (this._status != Promise.PENDING) {
-    if (typeof 'console' === 'object') {
-      console.error('Promise complete. Attempted ' + name + '() with ', data);
-      console.error('Prev status = ', this._status, ', value = ', this._value);
-    }
+    Promise._error("Promise complete.", "Attempted ", name, "() with ", data);
+    Promise._error("Previous status: ", this._status, ", value =", this._value);
     throw new Error('Promise already complete');
   }
 
+  if (list.length == 0 && status == Promise.ERROR) {
+    var frame;
+    var text;
+
+    //Complain if a rejection is ignored
+    //(this is the equivalent of an empty catch-all clause)
+    Promise._error("Promise rejection ignored and silently dropped", data);
+    if (data.stack) {// This looks like an exception. Try harder to display it
+      if (data.fileName && data.lineNumber) {
+        Promise._error("Error originating at", data.fileName,
+                       ", line", data.lineNumber );
+      }
+      try {
+        for (frame = data.stack; frame; frame = frame.caller) {
+          text += frame + "\n";
+        }
+        Promise._error("Attempting to extract exception stack", text);
+      } catch (x) {
+        Promise._error("Could not extract exception stack.");
+      }
+    } else {
+      Promise._error("Exception stack not available.");
+    }
+    if (Components && Components.stack) {
+      try {
+        text = "";
+        for (frame = Components.stack; frame; frame = frame.caller) {
+          text += frame + "\n";
+        }
+        Promise._error("Attempting to extract current stack", text);
+      } catch (x) {
+        Promise._error("Could not extract current stack.");
+      }
+    } else {
+      Promise._error("Current stack not available.");
+    }
+  }
+
+
   this._status = status;
   this._value = data;
 
   // Call all the handlers, and then delete them
   list.forEach(function(handler) {
     handler.call(null, this._value);
   }, this);
   delete this._onSuccessHandlers;
   delete this._onErrorHandlers;
 
   // Remove the given {promise} from the _outstanding list, and add it to the
   // _recent list, pruning more than 20 recent promises from that list
-  delete Promise._outstanding[this._id];
+  delete Promise.Debug._outstanding[this._id];
   // The original code includes this very useful debugging aid, however there
   // is concern that it will create a memory leak, so we leave it out here.
   /*
   Promise._recent.push(this);
   while (Promise._recent.length > 20) {
     Promise._recent.shift();
   }
   */
 
   return this;
 };
 
 /**
+ * Log an error on the most appropriate channel.
+ *
+ * If the console is available, this method uses |console.warn|. Otherwise,
+ * this method falls back to |dump|.
+ *
+ * @param {...*} items Items to log.
+ */
+Promise._error = null;
+if (typeof console != "undefined" && console.warn) {
+  Promise._error = function() {
+    var args = Array.prototype.slice.call(arguments);
+    args.unshift("Promise");
+    console.warn.call(console, args);
+  };
+} else {
+  Promise._error = function() {
+    var i;
+    var len = arguments.length;
+    dump("Promise: ");
+    for (i = 0; i < len; ++i) {
+      dump(arguments[i]+" ");
+    }
+    dump("\n");
+  };
+}
+
+/**
  * Takes an array of promises and returns a promise that that is fulfilled once
  * all the promises in the array are fulfilled
  * @param promiseList The array of promises
  * @return the promise that is fulfilled when all the array is fulfilled
  */
 Promise.group = function(promiseList) {
   if (!Array.isArray(promiseList)) {
     promiseList = Array.prototype.slice.call(arguments);
@@ -208,8 +300,110 @@ Promise.group = function(promiseList) {
   promiseList.forEach(function(promise, index) {
     var onSuccess = onSuccessFactory(index);
     var onError = groupPromise.reject.bind(groupPromise);
     promise.then(onSuccess, onError);
   });
 
   return groupPromise;
 };
+
+/**
+ * Trap errors.
+ *
+ * This function serves as an asynchronous counterpart to |catch|.
+ *
+ * Example:
+ *  myPromise.chainPromise(a) //May reject
+ *           .chainPromise(b) //May reject
+ *           .chainPromise(c) //May reject
+ *           .trap(d)       //Catch any rejection from a, b or c
+ *           .chainPromise(e) //If either a, b and c or
+ *                            //d has resolved, execute
+ *
+ * Scenario 1:
+ *   If a, b, c resolve, e is executed as if d had not been added.
+ *
+ * Scenario 2:
+ *   If a, b or c rejects, d is executed. If d resolves, we proceed
+ *   with e as if nothing had happened. Otherwise, we proceed with
+ *   the rejection of d.
+ *
+ * @param {Function} aTrap Called if |this| promise is rejected,
+ *   with one argument: the rejection.
+ * @return {Promise} A new promise. This promise resolves if all
+ *   previous promises have resolved or if |aTrap| succeeds.
+ */
+Promise.prototype.trap = function(aTrap) {
+  var promise = new Promise();
+  var resolve = Promise.prototype.resolve.bind(promise);
+  var reject = function(aRejection) {
+    try {
+      //Attempt to handle issue
+      var result = aTrap.call(aTrap, aRejection);
+      promise.resolve(result);
+    } catch (x) {
+      promise.reject(x);
+    }
+  };
+  this.then(resolve, reject);
+  return promise;
+};
+
+/**
+ * Execute regardless of errors.
+ *
+ * This function serves as an asynchronous counterpart to |finally|.
+ *
+ * Example:
+ *  myPromise.chainPromise(a) //May reject
+ *           .chainPromise(b) //May reject
+ *           .chainPromise(c) //May reject
+ *           .always(d)       //Executed regardless
+ *           .chainPromise(e)
+ *
+ * Whether |a|, |b| or |c| resolve or reject, |d| is executed.
+ *
+ * @param {Function} aTrap Called regardless of whether |this|
+ *   succeeds or fails.
+ * @return {Promise} A new promise. This promise holds the same
+ *   resolution/rejection as |this|.
+ */
+Promise.prototype.always = function(aTrap) {
+  var promise = new Promise();
+  var resolve = function(result) {
+    try {
+      aTrap.call(aTrap);
+      promise.resolve(result);
+    } catch (x) {
+      promise.reject(x);
+    }
+  };
+  var reject = function(result) {
+    try {
+      aTrap.call(aTrap);
+      promise.reject(result);
+    } catch (x) {
+      promise.reject(result);
+    }
+  };
+  this.then(resolve, reject);
+  return promise;
+};
+
+
+Promise.prototype.toString = function() {
+  var status;
+  switch (this._status) {
+  case Promise.PENDING:
+    status = "pending";
+    break;
+  case Promise.SUCCESS:
+    status = "resolved";
+    break;
+  case Promise.ERROR:
+    status = "rejected";
+    break;
+  default:
+    status = "invalid status: "+this._status;
+  }
+  return "[Promise " + this._id + " (" + status + ")]";
+};
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -144,17 +144,17 @@
 @BINPATH@/components/directory.xpt
 @BINPATH@/components/docshell.xpt
 @BINPATH@/components/dom.xpt
 @BINPATH@/components/dom_apps.xpt
 @BINPATH@/components/dom_base.xpt
 #ifdef MOZ_B2G_RIL
 @BINPATH@/components/dom_telephony.xpt
 @BINPATH@/components/dom_wifi.xpt
-@BINPATH@/components/dom_system_b2g.xpt
+@BINPATH@/components/dom_system_gonk.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
@@ -383,16 +383,18 @@
 @BINPATH@/components/contentAreaDropListener.js
 #ifdef MOZ_B2G_RIL
 @BINPATH@/components/RadioInterfaceLayer.manifest
 @BINPATH@/components/RadioInterfaceLayer.js
 @BINPATH@/components/SmsDatabaseService.manifest
 @BINPATH@/components/SmsDatabaseService.js
 @BINPATH@/components/nsWifiWorker.js
 @BINPATH@/components/nsWifiWorker.manifest
+@BINPATH@/components/nsDOMWifiManager.js
+@BINPATH@/components/nsDOMWifiManager.manifest
 #endif
 @BINPATH@/components/BrowserProfileMigrators.manifest
 @BINPATH@/components/ProfileMigrator.js
 @BINPATH@/components/ChromeProfileMigrator.js
 @BINPATH@/components/FirefoxProfileMigrator.js
 #ifdef XP_MACOSX
 @BINPATH@/components/libalerts.dylib
 #endif
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -924,16 +924,18 @@ xpicleanup@BIN_SUFFIX@
   components/storage-mozStorage.js
 #ifdef MOZ_B2G_RIL
   components/nsTelephonyWorker.manifest
   components/nsTelephonyWorker.js
   components/Telephony.manifest
   components/Telephony.js
   components/nsWifiWorker.js
   components/nsWifiWorker.manifest
+  components/nsDOMWifiManager.js
+  components/nsDOMWifiManager.manifest
 #endif
   components/txEXSLTRegExFunctions.js
   components/Weave.js
   components/Webapps.js
   components/Webapps.manifest
   components/WebContentConverter.js
   defaults/autoconfig/platform.js
   defaults/autoconfig/prefcalls.js
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -320,19 +320,20 @@ browser.menu.showCharacterEncoding=false
 syncPromoNotification.bookmarks.description=You can access your bookmarks on all your devices with %S.\u0020
 # LOCALIZATION NOTE (syncPromoNotification.passwords.label): This appears in
 # the remember password panel.  %S will be replaced by syncBrandShortName.
 # The final space separates this text from the Learn More link.
 syncPromoNotification.passwords.description=You can access your passwords on all your devices with %S.\u0020
 syncPromoNotification.learnMoreLinkText=Learn More
 
 # Telemetry prompt
-# 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?
+# LOCALIZATION NOTE (telemetryOptInPrompt): %1$S will be replaced by
+# brandFullName, and %2$S by the value of the toolkit.telemetry.server_owner
+# preference.
+telemetryOptInPrompt = Will you help improve %1$S by sending information about performance, hardware, usage, and customizations to %2$S?
 telemetryLinkLabel = Learn More
 telemetryYesButtonLabel2 = Yes, I want to help
 telemetryYesButtonAccessKey = Y
 telemetryNoButtonLabel = No
 telemetryNoButtonAccessKey = N
 
 # Webapps notification popup
 webapps.install = Install
--- a/browser/themes/gnomestripe/syncSetup.css
+++ b/browser/themes/gnomestripe/syncSetup.css
@@ -28,18 +28,17 @@ wizardpage {
   text-align: center;
 }
 .wizard-header-label {
   font-size: 24pt;
   font-weight: normal;
 }
 
 .wizard-buttons {
-  border-top: 2px solid #ccd9ea;
-  background-color: #f1f5fb;
+  background-color: rgba(0,0,0,0.1);
   padding: 1em;
 }
 
 .wizard-buttons-separator {
   visibility: collapse;
 }
 
 .wizard-header-icon {
--- a/browser/themes/pinstripe/syncSetup.css
+++ b/browser/themes/pinstripe/syncSetup.css
@@ -28,18 +28,17 @@ wizardpage {
   text-align: center;
 }
 .wizard-header-label {
   font-size: 24pt;
   font-weight: normal;
 }
 
 .wizard-buttons {
-  border-top: 2px solid #ccd9ea;
-  background-color: #f1f5fb;
+  background-color: rgba(0,0,0,0.1);
   padding: 1em;
 }
 
 .wizard-buttons-separator {
   visibility: collapse;
 }
 
 .wizard-header-icon {
--- a/browser/themes/winstripe/browser-aero.css
+++ b/browser/themes/winstripe/browser-aero.css
@@ -61,16 +61,31 @@
   }
 
   #main-window[tabsontop=false]:not([disablechrome]) .tabbrowser-tab[selected=true]:not(:-moz-lwtheme) {
     background-image: @toolbarShadowOnTab@,
                       -moz-linear-gradient(white, @toolbarHighlight@ 50%),
                       -moz-linear-gradient(@customToolbarColor@, @customToolbarColor@);
   }
 
+  #navigator-toolbox[tabsontop=true] #urlbar:not(:-moz-lwtheme),
+  #navigator-toolbox[tabsontop=true] .searchbar-textbox:not(:-moz-lwtheme) {
+    border-color: hsla(210,54%,20%,.25) hsla(210,54%,20%,.27) hsla(210,54%,20%,.3);
+  }
+
+  #navigator-toolbox[tabsontop=true] #urlbar:not(:-moz-lwtheme):not([focused]):hover,
+  #navigator-toolbox[tabsontop=true] .searchbar-textbox:not(:-moz-lwtheme):not([focused]):hover {
+    border-color: hsla(210,54%,20%,.35) hsla(210,54%,20%,.37) hsla(210,54%,20%,.4);
+  }
+
+  #navigator-toolbox[tabsontop=true] #urlbar:not(:-moz-lwtheme)[focused],
+  #navigator-toolbox[tabsontop=true] .searchbar-textbox:not(:-moz-lwtheme)[focused] {
+    border-color: hsla(206,100%,60%,.65) hsla(206,100%,55%,.65) hsla(206,100%,50%,.65);
+  }
+
   #sidebar-splitter {
     border: 0;
     -moz-border-end: 1px solid #A9B7C9;
     min-width: 0;
     width: 3px;
     background-color: transparent;
     -moz-margin-start: -3px;
     position: relative;
--- a/browser/themes/winstripe/syncSetup.css
+++ b/browser/themes/winstripe/syncSetup.css
@@ -28,18 +28,17 @@ wizardpage {
   text-align: center;
 }
 .wizard-header-label {
   font-size: 24pt;
   font-weight: normal;
 }
 
 .wizard-buttons {
-  border-top: 2px solid #ccd9ea;
-  background-color: #f1f5fb;
+  background-color: rgba(0,0,0,0.1);
   padding: 1em;
 }
 
 .wizard-buttons-separator {
   visibility: collapse;
 }
 
 .wizard-header-icon {
--- a/config/system-headers
+++ b/config/system-headers
@@ -1033,20 +1033,22 @@ QtSparql/qsparqlresult.h
 
 #if MOZ_TREE_PIXMAN!=1
 pixman.h
 #endif
 #if MOZ_ENABLE_MEEGOTOUCHSHARE
 shareuiinterface.h
 #endif
 #if MOZ_NATIVE_LIBVPX==1
+vpx/vpx_codec.h
 vpx/vpx_decoder.h
 vpx/vp8dx.h
 #endif
 #ifdef XP_WIN
+vpx/vpx_codec.h
 vpx/vpx_decoder.h
 vpx/vp8dx.h
 sydneyaudio/sydney_audio.h
 vorbis/codec.h
 theora/theoradec.h
 tremor/ivorbiscodec.h
 ogg/ogg.h
 ogg/os_types.h
--- a/configure.in
+++ b/configure.in
@@ -313,19 +313,19 @@ if test -n "$gonkdir" ; then
     LD="$gonk_toolchain"/bin/"$android_tool_prefix"-ld
     AR="$gonk_toolchain"/bin/"$android_tool_prefix"-ar
     RANLIB="$gonk_toolchain"/bin/"$android_tool_prefix"-ranlib
     STRIP="$gonk_toolchain"/bin/"$android_tool_prefix"-strip
 
     STLPORT_CPPFLAGS="-I$gonkdir/ndk/sources/cxx-stl/stlport/stlport/"
     STLPORT_LIBS="-lstlport"
 
-    CPPFLAGS="-DANDROID -I$gonkdir/bionic/libc/include/ -I$gonkdir/bionic/libc/kernel/common -I$gonkdir/bionic/libc/arch-arm/include -I$gonkdir/bionic/libc/kernel/arch-arm -I$gonkdir/bionic/libm/include -I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/hardware/libhardware/include -I$gonkdir/hardware/libhardware_legacy/include -I$gonkdir/system/core/include -I$gonkdir/bionic -I$gonkdir/frameworks/base/include $STLPORT_CPPFLAGS $CPPFLAGS -I$gonkdir/frameworks/base/services/sensorservice"
+    CPPFLAGS="-DANDROID -isystem $gonkdir/bionic/libc/include/ -isystem $gonkdir/bionic/libc/kernel/common -isystem $gonkdir/bionic/libc/arch-arm/include -isystem $gonkdir/bionic/libc/kernel/arch-arm -isystem $gonkdir/bionic/libm/include -I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/hardware/libhardware/include -I$gonkdir/hardware/libhardware_legacy/include -I$gonkdir/system/core/include -isystem $gonkdir/bionic -I$gonkdir/frameworks/base/include $CPPFLAGS -I$gonkdir/frameworks/base/services/sensorservice"
     CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS"
-    CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions $CXXFLAGS"
+    CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions $CXXFLAGS $STLPORT_CPPFLAGS"
     LIBS="$LIBS $STLPORT_LIBS"
 
     dnl Add -llog by default, since we use it all over the place.
     LDFLAGS="-mandroid -L$gonkdir/out/target/product/$GONK_PRODUCT/obj/lib -Wl,-rpath-link=$gonkdir/out/target/product/$GONK_PRODUCT/obj/lib --sysroot=$gonkdir/out/target/product/$GONK_PRODUCT/obj/ -llog $LDFLAGS"
 
     dnl prevent cross compile section from using these flags as host flags
     if test -z "$HOST_CPPFLAGS" ; then
         HOST_CPPFLAGS=" "
@@ -1796,37 +1796,39 @@ if test "$OS_TARGET" = "Android"; then
       ;;
     arm-*)
       ANDROID_CPU_ARCH=armeabi
       ;;
     x86-*)
       ANDROID_CPU_ARCH=x86
       ;;
     esac
-
+fi
+
+if test "$OS_TARGET" = "Android" -a -z "$gonkdir"; then
     if test -n "$MOZ_ANDROID_LIBSTDCXX" ; then
        if test ! -e "$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/libstdc++.a" ; then
           AC_MSG_ERROR([Cannot find path to libstdc++ (NDK version >= 5?)])
        fi
-       STLPORT_CPPFLAGS="-isystem $android_ndk/sources/cxx-stl/gnu-libstdc++/include -isystem $android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/include -D_GLIBCXX_PERMIT_BACKWARD_HASH"
+       STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/include -D_GLIBCXX_PERMIT_BACKWARD_HASH"
        STLPORT_LDFLAGS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH"
        STLPORT_LIBS="-lstdc++"
     elif test -e "$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a" ; then
-       STLPORT_CPPFLAGS="-isystem $android_ndk/sources/cxx-stl/stlport/stlport"
+       STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/stlport/stlport"
        STLPORT_LDFLAGS="-L$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
        STLPORT_LIBS="-lstlport_static"
     elif  test -e "$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a" ; then
-       STLPORT_CPPFLAGS="-isystem $android_ndk/sources/cxx-stl/stlport/stlport"
+       STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/stlport/stlport"
        STLPORT_LDFLAGS="-L$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH"
        STLPORT_LIBS="-lstlport_static"
     elif test "$target" != "arm-android-eabi"; then
        dnl fail if we're not building with NDKr4
        AC_MSG_ERROR([Couldn't find path to stlport in the android ndk])
     fi
-    CPPFLAGS="$CPPFLAGS $STLPORT_CPPFLAGS"
+    CXXFLAGS="$CXXFLAGS $STLPORT_CPPFLAGS"
     LDFLAGS="$LDFLAGS $STLPORT_LDFLAGS"
     LIBS="$LIBS $STLPORT_LIBS"
 fi
 
 dnl ========================================================
 dnl Suppress Clang Argument Warnings
 dnl ========================================================
 if test -n "$CLANG_CC"; then
@@ -9190,17 +9192,16 @@ if test -z "$MOZ_NATIVE_NSPR"; then
       # dladdr is supported by the new linker, even when the system linker doesn't
       # support it. Trick nspr into using dladdr when it's not supported.
       _SAVE_CPPFLAGS="$CPPFLAGS"
       export CPPFLAGS="-include $_topsrcdir/mozglue/linker/dladdr.h $CPPFLAGS"
     fi
     _SAVE_LDFLAGS="$LDFLAGS"
     export LDFLAGS="$LDFLAGS $NSPR_LDFLAGS"
     AC_OUTPUT_SUBDIRS(nsprpub)
-    unset LDFLAGS
     LDFLAGS="$_SAVE_LDFLAGS"
     if test -n "$MOZ_LINKER" -a -z "$MOZ_OLD_LINKER" -a "$ac_cv_func_dladdr" = no; then
       unset CPPFLAGS
       CPPFLAGS="$_SAVE_CFLAGS"
     fi
     ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 fi
 
@@ -9211,32 +9212,30 @@ if test -z "$MOZ_NATIVE_NSPR"; then
        NSPR_LIBS=`./nsprpub/config/nspr-config --prefix=$LIBXUL_DIST --exec-prefix=$MOZ_BUILD_ROOT/dist --libdir=$LIBXUL_DIST/lib --libs`
        $PERL -pi.bak -e "s '^NSPR_LIBS\\s*=.*'NSPR_LIBS = $NSPR_LIBS'" config/autoconf.mk
        NSPR_CFLAGS=`./nsprpub/config/nspr-config --prefix=$LIBXUL_DIST --exec-prefix=$MOZ_BUILD_ROOT/dist --includedir=$LIBXUL_DIST/include/nspr --cflags`
        $PERL -pi.bak -e "s '^NSPR_CFLAGS\\s*=.*'NSPR_CFLAGS = $NSPR_CFLAGS'" config/autoconf.mk
     fi
     rm -f config/autoconf.mk.bak
 fi
 
-if test -n "$direct_nspr_config"; then
-    dnl ========================================================
-    dnl = Setup a nice relatively clean build environment for
-    dnl = sub-configures.
-    dnl ========================================================
-    CC="$_SUBDIR_CC"
-    CXX="$_SUBDIR_CXX"
-    CFLAGS="$_SUBDIR_CFLAGS"
-    CPPFLAGS="$_SUBDIR_CPPFLAGS"
-    CXXFLAGS="$_SUBDIR_CXXFLAGS"
-    LDFLAGS="$_SUBDIR_LDFLAGS"
-    HOST_CC="$_SUBDIR_HOST_CC"
-    HOST_CFLAGS="$_SUBDIR_HOST_CFLAGS"
-    HOST_LDFLAGS="$_SUBDIR_HOST_LDFLAGS"
-    RC=
-fi
+dnl ========================================================
+dnl = Setup a nice relatively clean build environment for
+dnl = sub-configures.
+dnl ========================================================
+CC="$_SUBDIR_CC"
+CXX="$_SUBDIR_CXX"
+CFLAGS="$_SUBDIR_CFLAGS"
+CPPFLAGS="$_SUBDIR_CPPFLAGS"
+CXXFLAGS="$_SUBDIR_CXXFLAGS"
+LDFLAGS="$_SUBDIR_LDFLAGS"
+HOST_CC="$_SUBDIR_HOST_CC"
+HOST_CFLAGS="$_SUBDIR_HOST_CFLAGS"
+HOST_LDFLAGS="$_SUBDIR_HOST_LDFLAGS"
+RC=
 
 # Run the SpiderMonkey 'configure' script.
 dist=$MOZ_BUILD_ROOT/dist
 ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 ac_configure_args="$ac_configure_args --enable-threadsafe"
 if test "$BUILD_CTYPES"; then
     # Build js-ctypes on the platforms we can.
     ac_configure_args="$ac_configure_args --enable-ctypes"
--- a/content/base/public/nsDOMFile.h
+++ b/content/base/public/nsDOMFile.h
@@ -340,17 +340,17 @@ public:
     SetIsProxy();
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMFileList)
 
   NS_DECL_NSIDOMFILELIST
 
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
   nsISupports* GetParentObject()
   {
     return mParent;
   }
 
   void Disconnect()
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -88,18 +88,17 @@ class nsIContent : public nsINode {
 public:
   typedef mozilla::widget::IMEState IMEState;
 
 #ifdef MOZILLA_INTERNAL_API
   // If you're using the external API, the only thing you can know about
   // nsIContent is that it exists with an IID
 
   nsIContent(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsINode(aNodeInfo),
-      mPrimaryFrame(nsnull)
+    : nsINode(aNodeInfo)
   {
     NS_ASSERTION(mNodeInfo,
                  "No nsINodeInfo passed to nsIContent, PREPARE TO CRASH!!!");
   }
 #endif // MOZILLA_INTERNAL_API
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENT_IID)
 
@@ -854,18 +853,22 @@ public:
    * associated with the content than another frame if the one frame contains
    * directly or indirectly the other frame (e.g., when a frame is scrolled
    * there is a scroll frame that contains the frame being scrolled). This
    * frame is always the first continuation.
    *
    * In the case of absolutely positioned elements and floated elements, this
    * frame is the out of flow frame, not the placeholder.
    */
-  nsIFrame* GetPrimaryFrame() const { return mPrimaryFrame; }
+  nsIFrame* GetPrimaryFrame() const
+  {
+    return IsInDoc() ? mPrimaryFrame : nsnull;
+  }
   void SetPrimaryFrame(nsIFrame* aFrame) {
+    NS_ASSERTION(IsInDoc(), "This will end badly!");
     NS_PRECONDITION(!aFrame || !mPrimaryFrame || aFrame == mPrimaryFrame,
                     "Losing track of existing primary frame");
     mPrimaryFrame = aFrame;
   }
 
   /*
    * Returns a new nsISMILAttr that allows the caller to animate the given
    * attribute on this element.
@@ -957,21 +960,16 @@ protected:
 
 private:
   /**
    * Hook for implementing GetClasses.  This is guaranteed to only be
    * called if the NODE_MAY_HAVE_CLASS flag is set.
    */
   virtual const nsAttrValue* DoGetClasses() const = 0;
 
-  /**
-   * Pointer to our primary frame.  Might be null.
-   */
-  nsIFrame* mPrimaryFrame;
-
 public:
 #ifdef DEBUG
   /**
    * List the content (and anything it contains) out to the given
    * file stream. Use aIndent as the base indent during formatting.
    */
   virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0;
 
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -1989,9 +1989,15 @@ NS_NewPluginDocument(nsIDocument** aInst
 inline nsIDocument*
 nsINode::GetOwnerDocument() const
 {
   nsIDocument* ownerDoc = OwnerDoc();
 
   return ownerDoc != this ? ownerDoc : nsnull;
 }
 
+inline nsINode*
+nsINode::OwnerDocAsNode() const
+{
+  return OwnerDoc();
+}
+
 #endif /* nsIDocument_h___ */
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -340,28 +340,37 @@ public:
   }
 
   friend class nsNodeUtils;
   friend class nsNodeWeakReference;
   friend class nsNodeSupportsWeakRefTearoff;
   friend class nsAttrAndChildArray;
 
 #ifdef MOZILLA_INTERNAL_API
+#ifdef _MSC_VER
+#pragma warning(push)
+// Disable annoying warning about 'this' in initializers.
+#pragma warning(disable:4355)
+#endif
   nsINode(already_AddRefed<nsINodeInfo> aNodeInfo)
   : mNodeInfo(aNodeInfo),
     mParent(nsnull),
     mFlags(0),
     mBoolFlags(0),
     mNextSibling(nsnull),
     mPreviousSibling(nsnull),
     mFirstChild(nsnull),
+    mSubtreeRoot(this),
     mSlots(nsnull)
   {
   }
 
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
 #endif
 
   virtual ~nsINode();
 
   /**
    * Bit-flags to pass (or'ed together) to IsNodeOfType()
    */
   enum {
@@ -459,16 +468,22 @@ public:
    * implementations the two are the same.
    */
   nsIDocument *OwnerDoc() const
   {
     return mNodeInfo->GetDocument();
   }
 
   /**
+   * Return the "owner document" of this node as an nsINode*.  Implemented
+   * in nsIDocument.h.
+   */
+  inline nsINode *OwnerDocAsNode() const;
+
+  /**
    * Returns true if the content has an ancestor that is a document.
    *
    * @return whether this content is in a document tree
    */
   bool IsInDoc() const
   {
     return GetBoolFlag(IsInDocument);
   }
@@ -757,16 +772,45 @@ public:
    * @return the parent node
    */
   nsINode* GetElementParent() const
   {
     return mParent && mParent->IsElement() ? mParent : nsnull;
   }
 
   /**
+   * Get the root of the subtree this node belongs to.  This never returns
+   * null.  It may return 'this' (e.g. for document nodes, and nodes that
+   * are the roots of disconnected subtrees).
+   */
+  nsINode* SubtreeRoot() const
+  {
+    // There are three cases of interest here.  nsINodes that are really:
+    // 1. nsIDocument nodes - Are always in the document.
+    // 2. nsIContent nodes - Are either in the document, or mSubtreeRoot
+    //    is updated in BindToTree/UnbindFromTree.
+    // 3. nsIAttribute nodes - Are never in the document, and mSubtreeRoot
+    //    is always 'this' (as set in nsINode's ctor).
+    nsINode* node = IsInDoc() ? OwnerDocAsNode() : mSubtreeRoot;
+    NS_ASSERTION(node, "Should always have a node here!");
+#ifdef DEBUG
+    {
+      const nsINode* slowNode = this;
+      const nsINode* iter = slowNode;
+      while ((iter = iter->GetNodeParent())) {
+        slowNode = iter;
+      }
+
+      NS_ASSERTION(slowNode == node, "These should always be in sync!");
+    }
+#endif
+    return node;
+  }
+
+  /**
    * See nsIDOMEventTarget
    */
   NS_DECL_NSIDOMEVENTTARGET
   using nsIDOMEventTarget::AddEventListener;
   using nsIDOMEventTarget::AddSystemEventListener;
 
   /**
    * Adds a mutation observer to be notified when this node, or any of its
@@ -1358,16 +1402,28 @@ protected:
     { SetBoolFlag(ElementMayHaveContentEditableAttr); }
   bool HasExplicitBaseURI() const { return GetBoolFlag(NodeHasExplicitBaseURI); }
   void SetHasExplicitBaseURI() { SetBoolFlag(NodeHasExplicitBaseURI); }
   void SetHasLockedStyleStates() { SetBoolFlag(ElementHasLockedStyleStates); }
   void ClearHasLockedStyleStates() { ClearBoolFlag(ElementHasLockedStyleStates); }
   bool HasLockedStyleStates() const
     { return GetBoolFlag(ElementHasLockedStyleStates); }
 
+    void SetSubtreeRootPointer(nsINode* aSubtreeRoot)
+  {
+    NS_ASSERTION(aSubtreeRoot, "aSubtreeRoot can never be null!");
+    NS_ASSERTION(!(IsNodeOfType(eCONTENT) && IsInDoc()), "Shouldn't be here!");
+    mSubtreeRoot = aSubtreeRoot;
+  }
+
+  void ClearSubtreeRootPointer()
+  {
+    mSubtreeRoot = nsnull;
+  }
+
 public:
   // Optimized way to get classinfo.
   virtual nsXPCClassInfo* GetClassInfo() = 0;
 
 protected:
 
   // Override this function to create a custom slots class.
   virtual nsINode::nsSlots* CreateSlots();
@@ -1501,16 +1557,24 @@ private:
   // Boolean flags.
   PRUint32 mBoolFlags;
 
 protected:
   nsIContent* mNextSibling;
   nsIContent* mPreviousSibling;
   nsIContent* mFirstChild;
 
+  union {
+    // Pointer to our primary frame.  Might be null.
+    nsIFrame* mPrimaryFrame;
+
+    // Pointer to the root of our subtree.  Might be null.
+    nsINode* mSubtreeRoot;
+  };
+
   // Storage for more members that are usually not needed; allocated lazily.
   nsSlots* mSlots;
 };
 
 
 extern const nsIID kThisPtrOffsetsSID;
 
 // _implClass is the class to use to cast to nsISupports
--- a/content/base/src/nsContentList.cpp
+++ b/content/base/src/nsContentList.cpp
@@ -187,17 +187,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsSimpleContentList)
 NS_INTERFACE_MAP_END_INHERITING(nsBaseContentList)
 
 
 NS_IMPL_ADDREF_INHERITED(nsSimpleContentList, nsBaseContentList)
 NS_IMPL_RELEASE_INHERITED(nsSimpleContentList, nsBaseContentList)
 
 JSObject*
-nsSimpleContentList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+nsSimpleContentList::WrapObject(JSContext *cx, JSObject *scope,
                                 bool *triedToWrap)
 {
   return mozilla::dom::binding::NodeList::create(cx, scope, this, triedToWrap);
 }
 
 // nsFormContentList
 
 nsFormContentList::nsFormContentList(nsIContent *aForm,
@@ -504,18 +504,17 @@ nsContentList::~nsContentList()
 
   if (mDestroyFunc) {
     // Clean up mData
     (*mDestroyFunc)(mData);
   }
 }
 
 JSObject*
-nsContentList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
-                          bool *triedToWrap)
+nsContentList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
   return mozilla::dom::binding::HTMLCollection::create(cx, scope, this,
                                                        triedToWrap);
 }
 
 DOMCI_DATA(ContentList, nsContentList)
 
 // QueryInterface implementation for nsContentList
--- a/content/base/src/nsContentList.h
+++ b/content/base/src/nsContentList.h
@@ -133,17 +133,17 @@ public:
   }
 
   void Reset() {
     mElements.Clear();
   }
 
   virtual PRInt32 IndexOf(nsIContent *aContent, bool aDoFlush);
 
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap) = 0;
 
 protected:
   nsTArray< nsCOMPtr<nsIContent> > mElements;
 };
 
 
 class nsSimpleContentList : public nsBaseContentList
@@ -157,17 +157,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsSimpleContentList,
                                            nsBaseContentList)
 
   virtual nsINode* GetParentObject()
   {
     return mRoot;
   }
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
 private:
   // This has to be a strong reference, the root might go away before the list.
   nsCOMPtr<nsINode> mRoot;
 };
 
 // This class is used only by form element code and this is a static
@@ -288,17 +288,17 @@ public:
                 void* aData,
                 bool aDeep = true,
                 nsIAtom* aMatchAtom = nsnull,
                 PRInt32 aMatchNameSpaceId = kNameSpaceID_None,
                 bool aFuncMayDependOnAttr = true);
   virtual ~nsContentList();
 
   // nsWrapperCache
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
   // nsIDOMHTMLCollection
   NS_DECL_NSIDOMHTMLCOLLECTION
 
   // nsBaseContentList overrides
   virtual PRInt32 IndexOf(nsIContent *aContent, bool aDoFlush);
   virtual PRInt32 IndexOf(nsIContent* aContent);
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -625,17 +625,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsIDOMFileList)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(FileList)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMFileList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMFileList)
 
 JSObject*
-nsDOMFileList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+nsDOMFileList::WrapObject(JSContext *cx, JSObject *scope,
                           bool *triedToWrap)
 {
   return mozilla::dom::binding::FileList::create(cx, scope, this, triedToWrap);
 }
 
 nsIDOMFile*
 nsDOMFileList::GetItemAt(PRUint32 aIndex)
 {
--- a/content/base/src/nsDOMSettableTokenList.cpp
+++ b/content/base/src/nsDOMSettableTokenList.cpp
@@ -75,14 +75,14 @@ nsDOMSettableTokenList::SetValue(const n
   if (!mElement) {
     return NS_OK;
   }
 
   return mElement->SetAttr(kNameSpaceID_None, mAttrAtom, aValue, true);
 }
 
 JSObject*
-nsDOMSettableTokenList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+nsDOMSettableTokenList::WrapObject(JSContext *cx, JSObject *scope,
                                    bool *triedToWrap)
 {
   return mozilla::dom::binding::DOMSettableTokenList::create(cx, scope, this,
                                                              triedToWrap);
 }
--- a/content/base/src/nsDOMSettableTokenList.h
+++ b/content/base/src/nsDOMSettableTokenList.h
@@ -54,17 +54,17 @@ class nsDOMSettableTokenList : public ns
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDOMSETTABLETOKENLIST
 
   NS_FORWARD_NSIDOMDOMTOKENLIST(nsDOMTokenList::);
 
   nsDOMSettableTokenList(nsGenericElement* aElement, nsIAtom* aAttrAtom);
 
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
 protected:
   virtual ~nsDOMSettableTokenList();
 };
 
 #endif // nsDOMSettableTokenList_h___
 
--- a/content/base/src/nsDOMTokenList.cpp
+++ b/content/base/src/nsDOMTokenList.cpp
@@ -304,15 +304,14 @@ nsDOMTokenList::ToString(nsAString& aRes
   }
 
   mElement->GetAttr(kNameSpaceID_None, mAttrAtom, aResult);
 
   return NS_OK;
 }
 
 JSObject*
-nsDOMTokenList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
-                           bool *triedToWrap)
+nsDOMTokenList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
   return mozilla::dom::binding::DOMTokenList::create(cx, scope, this,
                                                      triedToWrap);
 }
 
--- a/content/base/src/nsDOMTokenList.h
+++ b/content/base/src/nsDOMTokenList.h
@@ -53,17 +53,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMTokenList)
   NS_DECL_NSIDOMDOMTOKENLIST
 
   nsDOMTokenList(nsGenericElement* aElement, nsIAtom* aAttrAtom);
 
   void DropReference();
 
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
   nsINode *GetParentObject()
   {
     return mElement;
   }
 
 protected:
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -519,23 +519,30 @@ nsGenericDOMDataNode::BindToTree(nsIDocu
     mParent = aDocument;
   }
   SetParentIsContent(aParent);
 
   // XXXbz sXBL/XBL2 issue!
 
   // Set document
   if (aDocument) {
+    // We no longer need to track the subtree pointer (and in fact we'll assert
+    // if we do this any later).
+    ClearSubtreeRootPointer();
+
     // XXX See the comment in nsGenericElement::BindToTree
     SetInDocument();
     if (mText.IsBidi()) {
       aDocument->SetBidiEnabled();
     }
     // Clear the lazy frame construction bits.
     UnsetFlags(NODE_NEEDS_FRAME | NODE_DESCENDANTS_NEED_FRAMES);
+  } else {
+    // If we're not in the doc, update our subtree pointer.
+    SetSubtreeRootPointer(aParent->SubtreeRoot());
   }
 
   nsNodeUtils::ParentChainChanged(this);
 
   UpdateEditableState(false);
 
   NS_POSTCONDITION(aDocument == GetCurrentDoc(), "Bound to wrong document");
   NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
@@ -565,16 +572,19 @@ nsGenericDOMDataNode::UnbindFromTree(boo
       NS_RELEASE(mParent);
     } else {
       mParent = nsnull;
     }
     SetParentIsContent(false);
   }
   ClearInDocument();
 
+  // Begin keeping track of our subtree root.
+  SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
+
   nsDataSlots *slots = GetExistingDataSlots();
   if (slots) {
     slots->mBindingParent = nsnull;
   }
 
   nsNodeUtils::ParentChainChanged(this);
 }
 
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -214,16 +214,17 @@ nsINode::nsSlots::Unlink()
   }
 }
 
 //----------------------------------------------------------------------
 
 nsINode::~nsINode()
 {
   NS_ASSERTION(!HasSlots(), "nsNodeUtils::LastRelease was not called?");
+  NS_ASSERTION(mSubtreeRoot == this, "Didn't restore state properly?");
 }
 
 void*
 nsINode::GetProperty(PRUint16 aCategory, nsIAtom *aPropertyName,
                      nsresult *aStatus) const
 {
   return OwnerDoc()->PropertyTable(aCategory)->GetProperty(this, aPropertyName,
                                                            aStatus);
@@ -1753,17 +1754,17 @@ NS_INTERFACE_TABLE_HEAD(nsChildContentLi
     NS_INTERFACE_TABLE_ENTRY(nsChildContentList, nsIDOMNodeList)
   NS_OFFSET_AND_INTERFACE_TABLE_END
   NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsChildContentList)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(NodeList)
 NS_INTERFACE_MAP_END
 
 JSObject*
-nsChildContentList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+nsChildContentList::WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
 {
   return mozilla::dom::binding::NodeList::create(cx, scope, this, triedToWrap);
 }
 
 NS_IMETHODIMP
 nsChildContentList::GetLength(PRUint32* aLength)
 {
@@ -3159,25 +3160,32 @@ nsGenericElement::BindToTree(nsIDocument
     // anonymous content that the document is changing.
     // XXXbz ordering issues here?  Probably not, since ChangeDocumentFor is
     // just pretty broken anyway....  Need to get it working.
     // XXXbz XBL doesn't handle this (asserts), and we don't really want
     // to be doing this during parsing anyway... sort this out.    
     //    aDocument->BindingManager()->ChangeDocumentFor(this, nsnull,
     //                                                   aDocument);
 
+    // We no longer need to track the subtree pointer (and in fact we'll assert
+    // if we do this any later).
+    ClearSubtreeRootPointer();
+
     // Being added to a document.
     SetInDocument();
 
     // Unset this flag since we now really are in a document.
     UnsetFlags(NODE_FORCE_XBL_BINDINGS |
                // And clear the lazy frame construction bits.
                NODE_NEEDS_FRAME | NODE_DESCENDANTS_NEED_FRAMES |
                // And the restyle bits
                ELEMENT_ALL_RESTYLE_FLAGS);
+  } else {
+    // If we're not in the doc, update our subtree pointer.
+    SetSubtreeRootPointer(aParent->SubtreeRoot());
   }
 
   // If NODE_FORCE_XBL_BINDINGS was set we might have anonymous children
   // that also need to be told that they are moving.
   nsresult rv;
   if (hadForceXBL) {
     nsBindingManager* bmgr = OwnerDoc()->BindingManager();
 
@@ -3259,16 +3267,19 @@ nsGenericElement::UnbindFromTree(bool aD
       NS_RELEASE(mParent);
     } else {
       mParent = nsnull;
     }
     SetParentIsContent(false);
   }
   ClearInDocument();
 
+  // Begin keeping track of our subtree root.
+  SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
+
   if (document) {
     // Notify XBL- & nsIAnonymousContentCreator-generated
     // anonymous content that the document is changing.
     document->BindingManager()->RemovedFromDocument(this, document);
 
     document->ClearBoxObjectFor(this);
   }
 
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -102,17 +102,17 @@ public:
   {
     SetIsProxy();
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
 
   // nsWrapperCache
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
   // nsIDOMNodeList interface
   NS_DECL_NSIDOMNODELIST
 
   // nsINodeList interface
   virtual PRInt32 IndexOf(nsIContent* aContent);
 
--- a/content/base/src/nsLineBreaker.cpp
+++ b/content/base/src/nsLineBreaker.cpp
@@ -55,26 +55,36 @@ nsLineBreaker::~nsLineBreaker()
 {
   NS_ASSERTION(mCurrentWord.Length() == 0, "Should have Reset() before destruction!");
 }
 
 static void
 SetupCapitalization(const PRUnichar* aWord, PRUint32 aLength,
                     bool* aCapitalization)
 {
-  // Capitalize the first non-punctuation character after a space or start
+  // Capitalize the first alphanumeric character after a space or start
   // of the word.
   // The only space character a word can contain is NBSP.
   bool capitalizeNextChar = true;
   for (PRUint32 i = 0; i < aLength; ++i) {
-    if (capitalizeNextChar && !nsContentUtils::IsFirstLetterPunctuation(aWord[i])) {
-      aCapitalization[i] = true;
-      capitalizeNextChar = false;
+    PRUint32 ch = aWord[i];
+    if (capitalizeNextChar) {
+      if (NS_IS_HIGH_SURROGATE(ch) && i + 1 < aLength &&
+          NS_IS_LOW_SURROGATE(aWord[i + 1])) {
+        ch = SURROGATE_TO_UCS4(ch, aWord[i + 1]);
+      }
+      if (nsContentUtils::IsAlphanumeric(ch)) {
+        aCapitalization[i] = true;
+        capitalizeNextChar = false;
+      }
+      if (!IS_IN_BMP(ch)) {
+        ++i;
+      }
     }
-    if (aWord[i] == 0xA0 /*NBSP*/) {
+    if (ch == 0xA0 /*NBSP*/) {
       capitalizeNextChar = true;
     }
   }
 }
 
 nsresult
 nsLineBreaker::FlushCurrentWord()
 {
--- a/content/base/src/nsTextNode.cpp
+++ b/content/base/src/nsTextNode.cpp
@@ -179,38 +179,37 @@ nsTextNode::CloneDataNode(nsINodeInfo *a
   nsTextNode *it = new nsTextNode(ni.forget());
   if (it && aCloneText) {
     it->mText = mText;
   }
 
   return it;
 }
 
-nsresult
+void
 nsTextNode::BindToAttribute(nsIAttribute* aAttr)
 {
   NS_ASSERTION(!IsInDoc(), "Unbind before binding!");
   NS_ASSERTION(!GetNodeParent(), "Unbind before binding!");
   NS_ASSERTION(HasSameOwnerDoc(aAttr), "Wrong owner document!");
 
   mParent = aAttr;
   SetParentIsContent(false);
   ClearInDocument();
-  return NS_OK;
+  SetSubtreeRootPointer(aAttr->SubtreeRoot());
 }
 
-nsresult
+void
 nsTextNode::UnbindFromAttribute()
 {
   NS_ASSERTION(GetNodeParent(), "Bind before unbinding!");
-  NS_ASSERTION(GetNodeParent() &&
-               GetNodeParent()->IsNodeOfType(nsINode::eATTRIBUTE),
+  NS_ASSERTION(GetNodeParent()->IsNodeOfType(nsINode::eATTRIBUTE),
                "Use this method only to unbind from an attribute!");
   mParent = nsnull;
-  return NS_OK;
+  SetSubtreeRootPointer(this);
 }
 
 nsresult
 nsTextNode::AppendTextForNormalize(const PRUnichar* aBuffer, PRUint32 aLength,
                                    bool aNotify, nsIContent* aNextSibling)
 {
   CharacterDataChangeInfo::Details details = {
     CharacterDataChangeInfo::Details::eMerge, aNextSibling
--- a/content/base/src/nsTextNode.h
+++ b/content/base/src/nsTextNode.h
@@ -69,18 +69,18 @@ public:
   NS_FORWARD_NSIDOMTEXT(nsGenericDOMDataNode::)
 
   // nsINode
   virtual bool IsNodeOfType(PRUint32 aFlags) const;
 
   virtual nsGenericDOMDataNode* CloneDataNode(nsINodeInfo *aNodeInfo,
                                               bool aCloneText) const;
 
-  nsresult BindToAttribute(nsIAttribute* aAttr);
-  nsresult UnbindFromAttribute();
+  void BindToAttribute(nsIAttribute* aAttr);
+  void UnbindFromAttribute();
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   nsresult AppendTextForNormalize(const PRUnichar* aBuffer, PRUint32 aLength,
                                   bool aNotify, nsIContent* aNextSibling);
 
 #ifdef DEBUG
   virtual void List(FILE* out, PRInt32 aIndent) const;
--- a/content/events/src/nsDOMTouchEvent.h
+++ b/content/events/src/nsDOMTouchEvent.h
@@ -144,17 +144,17 @@ public:
   nsDOMTouchList(nsISupports *aParent,
                  nsTArray<nsCOMPtr<nsIDOMTouch> > &aTouches)
    : mPoints(aTouches),
      mParent(aParent)
   {
     SetIsProxy();
   }
 
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
   {
     return mozilla::dom::binding::TouchList::create(cx, scope, this,
                                                     triedToWrap);
   }
 
   nsISupports *GetParentObject()
   {
--- a/content/events/src/nsPaintRequest.h
+++ b/content/events/src/nsPaintRequest.h
@@ -70,17 +70,17 @@ public:
   {
     SetIsProxy();
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsPaintRequestList)
   NS_DECL_NSIDOMPAINTREQUESTLIST
   
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
   {
     return mozilla::dom::binding::PaintRequestList::create(cx, scope, this,
                                                            triedToWrap);
   }
 
   nsISupports* GetParentObject()
   {
--- a/content/events/test/test_eventctors.html
+++ b/content/events/test/test_eventctors.html
@@ -321,20 +321,58 @@ ok(e.type, "hello", "Wrong event type!")
 ok(!e.isTrusted, "Event shouldn't be trusted!");
 ok(e.bubbles, "Event should bubble!");
 ok(e.cancelable, "Event should be cancelable!");
 is(e.detail, 1, "detail should be 1");
 is(e.view, window, "view should be window");
 document.dispatchEvent(e);
 is(receivedEvent, e, "Wrong event!");
 
-// UIEvent
+// StorageEvent
 
 try {
-  e = new UIEvent();
+  e = new StorageEvent();
+} catch(exp) {
+  ex = true;
+}
+ok(ex, "First parameter is required!");
+ex = false;
+
+e = new StorageEvent("hello");
+ok(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.key, "", "key should be ''");
+is(e.oldValue, null, "oldValue should be null");
+is(e.newValue, null, "newValue should be null");
+is(e.url, "", "url should be ''");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+e = new StorageEvent("hello",
+  { bubbles: true, cancelable: true, key: "key",
+    oldValue: "oldValue", newValue: "newValue", url: "url",
+    storageArea: localStorage });
+ok(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(e.bubbles, "Event should bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+is(e.key, "key", "Wrong value");
+is(e.oldValue, "oldValue", "Wrong value");
+is(e.newValue, "newValue", "Wrong value");
+is(e.url, "url", "Wrong value");
+is(e.storageArea, localStorage, "Wrong value");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+// MouseEvent
+
+try {
+  e = new MouseEvent();
 } catch(exp) {
   ex = true;
 }
 ok(ex, "First parameter is required!");
 ex = false;
 
 e = new MouseEvent("hello");
 ok(e.type, "hello", "Wrong event type!");
--- a/content/html/content/src/nsClientRect.cpp
+++ b/content/html/content/src/nsClientRect.cpp
@@ -143,18 +143,17 @@ nsClientRectList::Item(PRUint32 aIndex, 
 
 nsIDOMClientRect*
 nsClientRectList::GetItemAt(PRUint32 aIndex)
 {
   return mArray.SafeObjectAt(aIndex);
 }
 
 JSObject*
-nsClientRectList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
-                             bool *triedToWrap)
+nsClientRectList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
   return mozilla::dom::binding::ClientRectList::create(cx, scope, this,
                                                        triedToWrap);
 }
 
 static double
 RoundFloat(double aValue)
 {
--- a/content/html/content/src/nsClientRect.h
+++ b/content/html/content/src/nsClientRect.h
@@ -75,17 +75,17 @@ public:
     SetIsProxy();
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsClientRectList)
 
   NS_DECL_NSIDOMCLIENTRECTLIST
   
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
   nsISupports* GetParentObject()
   {
     return mParent;
   }
 
   void Append(nsIDOMClientRect* aElement) { mArray.AppendObject(aElement); }
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -145,17 +145,17 @@ public:
    * elements.
    *
    * @param aControls The list of sorted controls[out].
    * @return NS_OK or NS_ERROR_OUT_OF_MEMORY.
    */
   nsresult GetSortedControls(nsTArray<nsGenericHTMLFormElement*>& aControls) const;
 
   // nsWrapperCache
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
   {
     return mozilla::dom::binding::HTMLCollection::create(cx, scope, this,
                                                          triedToWrap);
   }
 
   nsHTMLFormElement* mForm;  // WEAK - the form owns me
 
--- a/content/html/content/src/nsHTMLSelectElement.cpp
+++ b/content/html/content/src/nsHTMLSelectElement.cpp
@@ -2056,17 +2056,17 @@ NS_INTERFACE_TABLE_HEAD(nsHTMLOptionColl
 NS_INTERFACE_MAP_END
 
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHTMLOptionCollection)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHTMLOptionCollection)
 
 
 JSObject*
-nsHTMLOptionCollection::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+nsHTMLOptionCollection::WrapObject(JSContext *cx, JSObject *scope,
                                    bool *triedToWrap)
 {
   return mozilla::dom::binding::HTMLOptionsCollection::create(cx, scope, this,
                                                               triedToWrap);
 }
 
 NS_IMETHODIMP
 nsHTMLOptionCollection::GetLength(PRUint32* aLength)
--- a/content/html/content/src/nsHTMLSelectElement.h
+++ b/content/html/content/src/nsHTMLSelectElement.h
@@ -71,17 +71,17 @@ class nsHTMLOptionCollection: public nsI
                               public nsWrapperCache
 {
 public:
   nsHTMLOptionCollection(nsHTMLSelectElement* aSelect);
   virtual ~nsHTMLOptionCollection();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
   // nsIDOMHTMLOptionsCollection interface
   NS_DECL_NSIDOMHTMLOPTIONSCOLLECTION
 
   // nsIDOMHTMLCollection interface, all its methods are defined in
   // nsIDOMHTMLOptionsCollection
 
--- a/content/html/content/src/nsHTMLTableElement.cpp
+++ b/content/html/content/src/nsHTMLTableElement.cpp
@@ -81,17 +81,17 @@ public:
     return mParent;
   }
 
   NS_IMETHOD    ParentDestroyed();
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TableRowsCollection)
 
   // nsWrapperCache
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
   {
     return mozilla::dom::binding::HTMLCollection::create(cx, scope, this,
                                                          triedToWrap);
   }
 
 protected:
   // Those rows that are not in table sections
--- a/content/svg/content/src/DOMSVGLengthList.cpp
+++ b/content/svg/content/src/DOMSVGLengthList.cpp
@@ -95,18 +95,17 @@ namespace mozilla {
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGLengthList)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGLengthList)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGLengthList)
 NS_INTERFACE_MAP_END
 
 JSObject*
-DOMSVGLengthList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
-                             bool *triedToWrap)
+DOMSVGLengthList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
   return mozilla::dom::binding::SVGLengthList::create(cx, scope, this,
                                                       triedToWrap);
 }
 
 nsIDOMSVGLength*
 DOMSVGLengthList::GetItemAt(PRUint32 aIndex)
 {
--- a/content/svg/content/src/DOMSVGLengthList.h
+++ b/content/svg/content/src/DOMSVGLengthList.h
@@ -97,17 +97,17 @@ public:
     // Our mAList's weak ref to us must be nulled out when we die. If GC has
     // unlinked us using the cycle collector code, then that has already
     // happened, and mAList is null.
     if (mAList) {
       ( IsAnimValList() ? mAList->mAnimVal : mAList->mBaseVal ) = nsnull;
     }
   };
 
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
   nsISupports* GetParentObject()
   {
     return static_cast<nsIContent*>(Element());
   }
 
   /**
--- a/content/svg/content/src/DOMSVGNumberList.cpp
+++ b/content/svg/content/src/DOMSVGNumberList.cpp
@@ -96,18 +96,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGNumberList)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGNumberList)
 NS_INTERFACE_MAP_END
 
 
 JSObject*
-DOMSVGNumberList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
-                             bool *triedToWrap)
+DOMSVGNumberList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
   return mozilla::dom::binding::SVGNumberList::create(cx, scope, this,
                                                       triedToWrap);
 }
 
 nsIDOMSVGNumber*
 DOMSVGNumberList::GetItemAt(PRUint32 aIndex)
 {
--- a/content/svg/content/src/DOMSVGNumberList.h
+++ b/content/svg/content/src/DOMSVGNumberList.h
@@ -96,17 +96,17 @@ public:
     // Our mAList's weak ref to us must be nulled out when we die. If GC has
     // unlinked us using the cycle collector code, then that has already
     // happened, and mAList is null.
     if (mAList) {
       ( IsAnimValList() ? mAList->mAnimVal : mAList->mBaseVal ) = nsnull;
     }
   }
 
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
   nsISupports* GetParentObject()
   {
     return static_cast<nsIContent*>(Element());
   }
 
   /**
--- a/content/svg/content/src/DOMSVGPathSegList.cpp
+++ b/content/svg/content/src/DOMSVGPathSegList.cpp
@@ -108,18 +108,17 @@ DOMSVGPathSegList::~DOMSVGPathSegList()
   // Note we must use GetAnimValKey/GetBaseValKey here, NOT InternalList()!
   void *key = mIsAnimValList ?
     InternalAList().GetAnimValKey() :
     InternalAList().GetBaseValKey();
   sSVGPathSegListTearoffTable.RemoveTearoff(key);
 }
 
 JSObject*
-DOMSVGPathSegList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
-                              bool *triedToWrap)
+DOMSVGPathSegList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
   return mozilla::dom::binding::SVGPathSegList::create(cx, scope, this,
                                                        triedToWrap);
 }
 
 nsIDOMSVGPathSeg*
 DOMSVGPathSegList::GetItemAt(PRUint32 aIndex)
 {
--- a/content/svg/content/src/DOMSVGPathSegList.h
+++ b/content/svg/content/src/DOMSVGPathSegList.h
@@ -83,17 +83,17 @@ class DOMSVGPathSegList : public nsIDOMS
 {
   friend class DOMSVGPathSeg;
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGPathSegList)
   NS_DECL_NSIDOMSVGPATHSEGLIST
 
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
   nsISupports* GetParentObject()
   {
     return static_cast<nsIContent*>(mElement);
   }
 
   /**
--- a/content/svg/content/src/DOMSVGPointList.cpp
+++ b/content/svg/content/src/DOMSVGPointList.cpp
@@ -127,18 +127,17 @@ DOMSVGPointList::~DOMSVGPointList()
   // Note we must use GetAnimValKey/GetBaseValKey here, NOT InternalList()!
   void *key = mIsAnimValList ?
     InternalAList().GetAnimValKey() :
     InternalAList().GetBaseValKey();
   sSVGPointListTearoffTable.RemoveTearoff(key);
 }
 
 JSObject*
-DOMSVGPointList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
-                            bool *triedToWrap)
+DOMSVGPointList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
   return mozilla::dom::binding::SVGPointList::create(cx, scope, this,
                                                      triedToWrap);
 }
 
 nsIDOMSVGPoint*
 DOMSVGPointList::GetItemAt(PRUint32 aIndex)
 {
--- a/content/svg/content/src/DOMSVGPointList.h
+++ b/content/svg/content/src/DOMSVGPointList.h
@@ -83,17 +83,17 @@ class DOMSVGPointList : public nsIDOMSVG
 {
   friend class DOMSVGPoint;
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGPointList)
   NS_DECL_NSIDOMSVGPOINTLIST
 
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
   nsISupports* GetParentObject()
   {
     return static_cast<nsIContent*>(mElement);
   }
 
   /**
--- a/content/svg/content/src/DOMSVGTransformList.cpp
+++ b/content/svg/content/src/DOMSVGTransformList.cpp
@@ -98,17 +98,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGTransformList)
 NS_INTERFACE_MAP_END
 
 //----------------------------------------------------------------------
 // DOMSVGTransformList methods:
 
 JSObject*
-DOMSVGTransformList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+DOMSVGTransformList::WrapObject(JSContext *cx, JSObject *scope,
                                 bool *triedToWrap)
 {
   return mozilla::dom::binding::SVGTransformList::create(cx, scope, this,
                                                          triedToWrap);
 }
 
 nsIDOMSVGTransform*
 DOMSVGTransformList::GetItemAt(PRUint32 aIndex)
--- a/content/svg/content/src/DOMSVGTransformList.h
+++ b/content/svg/content/src/DOMSVGTransformList.h
@@ -92,17 +92,17 @@ public:
     // Our mAList's weak ref to us must be nulled out when we die. If GC has
     // unlinked us using the cycle collector code, then that has already
     // happened, and mAList is null.
     if (mAList) {
       ( IsAnimValList() ? mAList->mAnimVal : mAList->mBaseVal ) = nsnull;
     }
   }
 
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
   nsISupports* GetParentObject()
   {
     return static_cast<nsIContent*>(Element());
   }
 
   /**
--- a/content/xbl/src/nsBindingManager.cpp
+++ b/content/xbl/src/nsBindingManager.cpp
@@ -108,17 +108,17 @@ public:
     return mContent;
   }
 
   PRInt32 GetInsertionPointCount() { return mElements->Length(); }
 
   nsXBLInsertionPoint* GetInsertionPointAt(PRInt32 i) { return static_cast<nsXBLInsertionPoint*>(mElements->ElementAt(i)); }
   void RemoveInsertionPointAt(PRInt32 i) { mElements->RemoveElementAt(i); }
 
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
   {
     return mozilla::dom::binding::NodeList::create(cx, scope, this,
                                                    triedToWrap);
   }
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ANONYMOUS_CONTENT_LIST_IID)
 private:
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -562,16 +562,23 @@ Navigator::JavaEnabled(bool* aReturn)
       *aReturn = true;
       break;
     }
   }
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+Navigator::TaintEnabled(bool *aReturn)
+{
+  *aReturn = false;
+  return NS_OK;
+}
+
 void
 Navigator::RefreshMIMEArray()
 {
   if (mMimeTypes) {
     mMimeTypes->Refresh();
   }
 }
 
@@ -960,18 +967,17 @@ Navigator::GetMozPower(nsIDOMMozPowerMan
   if (!mPowerManager) {
     nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
     NS_ENSURE_TRUE(win, NS_OK);
 
     mPowerManager = new power::PowerManager();
     mPowerManager->Init(win);
   }
 
-  nsCOMPtr<nsIDOMMozPowerManager> power =
-    do_QueryInterface(NS_ISUPPORTS_CAST(nsIDOMMozPowerManager*, mPowerManager));
+  nsCOMPtr<nsIDOMMozPowerManager> power(mPowerManager);
   power.forget(aPower);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 Navigator::RequestWakeLock(const nsAString &aTopic, nsIDOMMozWakeLock **aWakeLock)
 {
--- a/dom/base/Webapps.js
+++ b/dom/base/Webapps.js
@@ -321,25 +321,24 @@ WebappsApplicationMgmt.prototype = {
   get onuninstall() {
     this._onuninstall;
   },
 
   set oninstall(aCallback) {
     if (this.hasPrivileges)
       this._oninstall = aCallback;
     else
-
-      throw new Components.exception("Denied", Cr.NS_ERROR_FAILURE);
+      throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
   },
 
   set onuninstall(aCallback) {
     if (this.hasPrivileges)
       this._onuninstall = aCallback;
     else
-      throw new Components.exception("Denied", Cr.NS_ERROR_FAILURE);
+      throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
   },
 
   receiveMessage: function(aMessage) {
     var msg = aMessage.json;
     let req = this.getRequest(msg.requestID);
     // We want Webapps:Install:Return:OK and Webapps:Uninstall:Return:OK to be boradcasted
     // to all instances of mozApps.mgmt
     if (!((msg.oid == this._id && req) 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1417,19 +1417,16 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   
   NS_DEFINE_CLASSINFO_DATA(GeoPosition, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS) 
   
   NS_DEFINE_CLASSINFO_DATA(GeoPositionCoords, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
-  NS_DEFINE_CLASSINFO_DATA(GeoPositionAddress, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-
   NS_DEFINE_CLASSINFO_DATA(GeoPositionError, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MozBatteryManager, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MozPowerManager, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -4015,20 +4012,16 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(GeoPosition, nsIDOMGeoPosition)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPosition)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(GeoPositionCoords, nsIDOMGeoPositionCoords)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionCoords)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(GeoPositionAddress, nsIDOMGeoPositionAddress)
-     DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionAddress)
-  DOM_CLASSINFO_MAP_END
-
   DOM_CLASSINFO_MAP_BEGIN(GeoPositionError, nsIDOMGeoPositionError)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionError)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MozBatteryManager, nsIDOMMozBatteryManager)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozBatteryManager)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -417,17 +417,16 @@ DOMCI_CLASS(DataContainerEvent)
 // event used for cross-domain message-passing and for server-sent events in
 // HTML5
 DOMCI_CLASS(MessageEvent)
 
 // Geolocation
 DOMCI_CLASS(GeoGeolocation)
 DOMCI_CLASS(GeoPosition)
 DOMCI_CLASS(GeoPositionCoords)
-DOMCI_CLASS(GeoPositionAddress)
 DOMCI_CLASS(GeoPositionError)
 
 DOMCI_CLASS(MozBatteryManager)
 
 DOMCI_CLASS(MozPowerManager)
 DOMCI_CLASS(MozWakeLock)
 
 DOMCI_CLASS(MozSmsManager)
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -384,16 +384,46 @@ nsDOMWindowUtils::SetResolution(float aX
   }
 
   nsIPresShell* presShell = GetPresShell();
   return presShell ? presShell->SetResolution(aXResolution, aYResolution)
                    : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
+nsDOMWindowUtils::SetIsFirstPaint(bool aIsFirstPaint)
+{
+  if (!IsUniversalXPConnectCapable()) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
+  nsIPresShell* presShell = GetPresShell();
+  if (presShell) {
+    presShell->SetIsFirstPaint(aIsFirstPaint);
+    return NS_OK;
+  }
+  return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsDOMWindowUtils::GetIsFirstPaint(bool *aIsFirstPaint)
+{
+  if (!IsUniversalXPConnectCapable()) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
+  nsIPresShell* presShell = GetPresShell();
+  if (presShell) {
+    *aIsFirstPaint = presShell->GetIsFirstPaint();
+    return NS_OK;
+  }
+  return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
 nsDOMWindowUtils::SendMouseEvent(const nsAString& aType,
                                  float aX,
                                  float aY,
                                  PRInt32 aButton,
                                  PRInt32 aClickCount,
                                  PRInt32 aModifiers,
                                  bool aIgnoreRootScrollFrame)
 {
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -296,18 +296,17 @@ public:
   nsPIDOMWindow* GetPrivateParent();
   // callback for close event
   void ReallyCloseWindow();
 
   // nsISupports
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   // nsWrapperCache
-  JSObject *WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
-                       bool *triedToWrap)
+  JSObject *WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
   {
     NS_ASSERTION(IsOuterWindow(),
                  "Inner window supports nsWrapperCache, fix WrapObject!");
     *triedToWrap = true;
     return EnsureInnerWindow() ? GetWrapper() : nsnull;
   }
 
   // nsIScriptGlobalObject
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -3156,16 +3156,54 @@ nsJSContext::CycleCollectNow(nsICycleCol
                                           PR_USEC_PER_MSEC,
                                         sTotalForgetSkippableTime / PR_USEC_PER_MSEC,
                                         sRemovedPurples));
     nsCOMPtr<nsIConsoleService> cs =
       do_GetService(NS_CONSOLESERVICE_CONTRACTID);
     if (cs) {
       cs->LogStringMessage(msg.get());
     }
+
+    NS_NAMED_MULTILINE_LITERAL_STRING(kJSONFmt,
+      NS_LL("{ \"duration\": %llu, ")
+         NS_LL("\"suspected\": %lu, ")
+         NS_LL("\"visited\": { ")
+             NS_LL("\"RCed\": %lu, ")
+             NS_LL("\"GCed\": %lu }, ")
+         NS_LL("\"collected\": { ")
+             NS_LL("\"RCed\": %lu, ")
+             NS_LL("\"GCed\": %lu }, ")
+         NS_LL("\"waiting_for_gc\": %lu, ")
+         NS_LL("\"forced_gc\": %d, ")
+         NS_LL("\"forget_skippable\": { ")
+             NS_LL("\"times_before_cc\": %lu, ")
+             NS_LL("\"min\": %lu, ")
+             NS_LL("\"max\": %lu, ")
+             NS_LL("\"avg\": %lu, ")
+             NS_LL("\"total\": %lu, ")
+             NS_LL("\"removed\": %lu } ")
+       NS_LL("}"));
+    nsString json;
+    json.Adopt(nsTextFormatter::smprintf(kJSONFmt.get(),
+                                        (now - start) / PR_USEC_PER_MSEC, suspected,
+                                        ccResults.mVisitedRefCounted, ccResults.mVisitedGCed,
+                                        ccResults.mFreedRefCounted, ccResults.mFreedGCed,
+                                        sCCollectedWaitingForGC,
+                                        ccResults.mForcedGC,
+                                        sForgetSkippableBeforeCC,
+                                        sMinForgetSkippableTime / PR_USEC_PER_MSEC,
+                                        sMaxForgetSkippableTime / PR_USEC_PER_MSEC,
+                                        (sTotalForgetSkippableTime / cleanups) /
+                                          PR_USEC_PER_MSEC,
+                                        sTotalForgetSkippableTime / PR_USEC_PER_MSEC,
+                                        sRemovedPurples));
+    nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
+    if (observerService) {
+      observerService->NotifyObservers(nsnull, "cycle-collection-statistics", json.get());
+    }
   }
   sMinForgetSkippableTime = PR_UINT32_MAX;
   sMaxForgetSkippableTime = 0;
   sTotalForgetSkippableTime = 0;
   sRemovedPurples = 0;
   sForgetSkippableBeforeCC = 0;
   sCleanupSinceLastGC = true;
   sNeedsFullCC = false;
@@ -3412,35 +3450,63 @@ nsJSContext::KillCCTimer()
 }
 
 void
 nsJSContext::GC(js::gcreason::Reason aReason)
 {
   PokeGC(aReason);
 }
 
+class NotifyGCEndRunnable : public nsRunnable
+{
+  nsString mMessage;
+
+public:
+  NotifyGCEndRunnable(const nsString& aMessage) : mMessage(aMessage) {}
+
+  NS_DECL_NSIRUNNABLE
+};
+
+NS_IMETHODIMP
+NotifyGCEndRunnable::Run()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
+  if (!observerService) {
+    return NS_OK;
+  }
+
+  const jschar oomMsg[3] = { '{', '}', 0 };
+  const jschar *toSend = mMessage.get() ? mMessage.get() : oomMsg;
+  observerService->NotifyObservers(nsnull, "garbage-collection-statistics", toSend);
+
+  return NS_OK;
+}
+
 static void
 DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescription &aDesc)
 {
   NS_ASSERTION(NS_IsMainThread(), "GCs must run on the main thread");
 
-  if (aDesc.logMessage && sPostGCEventsToConsole) {
+  if (aProgress == js::GC_CYCLE_END && sPostGCEventsToConsole) {
     PRTime now = PR_Now();
     PRTime delta = 0;
     if (sFirstCollectionTime) {
       delta = now - sFirstCollectionTime;
     } else {
       sFirstCollectionTime = now;
     }
 
-    NS_NAMED_LITERAL_STRING(kFmt, "GC(T+%.1f) %s");
-    nsString msg;
-    msg.Adopt(nsTextFormatter::smprintf(kFmt.get(),
-                                        double(delta) / PR_USEC_PER_SEC,
-                                        aDesc.logMessage));
+    NS_NAMED_LITERAL_STRING(kFmt, "GC(T+%.1f) ");
+    nsString prefix, gcstats;
+    gcstats.Adopt(aDesc.formatMessage(aRt));
+    prefix.Adopt(nsTextFormatter::smprintf(kFmt.get(),
+                                           double(delta) / PR_USEC_PER_SEC));
+    nsString msg = prefix + gcstats;
     nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
     if (cs) {
       cs->LogStringMessage(msg.get());
     }
   }
 
   // Prevent cycle collections and shrinking during incremental GC.
   if (aProgress == js::GC_CYCLE_BEGIN) {
@@ -3458,16 +3524,21 @@ DOMGCSliceCallback(JSRuntime *aRt, js::G
 
   if (aProgress == js::GC_CYCLE_END) {
     // May need to kill the inter-slice GC timer
     nsJSContext::KillGCTimer();
 
     sCCollectedWaitingForGC = 0;
     sCleanupSinceLastGC = false;
 
+    nsString json;
+    json.Adopt(aDesc.formatJSON(aRt));
+    nsRefPtr<NotifyGCEndRunnable> notify = new NotifyGCEndRunnable(json);
+    NS_DispatchToMainThread(notify);
+
     if (aDesc.isCompartment) {
       // If this is a compartment GC, restart it. We still want
       // a full GC to happen. Compartment GCs usually happen as a
       // result of last-ditch or MaybeGC. In both cases it is
       // probably a time of heavy activity and we want to delay
       // the full GC, but we do want it to happen eventually.
       nsJSContext::PokeGC(js::gcreason::POST_COMPARTMENT);
     }
--- a/dom/base/nsWindowMemoryReporter.cpp
+++ b/dom/base/nsWindowMemoryReporter.cpp
@@ -48,17 +48,17 @@ NS_IMPL_ISUPPORTS1(nsWindowMemoryReporte
 /* static */
 void
 nsWindowMemoryReporter::Init()
 {
   // The memory reporter manager is going to own this object.
   NS_RegisterMemoryMultiReporter(new nsWindowMemoryReporter());
 }
 
-static bool
+static void
 AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr)
 {
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(aWindow->GetExtantDocument());
   nsCOMPtr<nsIURI> uri;
 
   if (doc) {
     uri = doc->GetDocumentURI();
   }
@@ -66,31 +66,29 @@ AppendWindowURI(nsGlobalWindow *aWindow,
   if (!uri) {
     nsIPrincipal *principal = aWindow->GetPrincipal();
 
     if (principal) {
       principal->GetURI(getter_AddRefs(uri));
     }
   }
 
-  if (!uri) {
-    return false;
-  }
-
-  nsCString spec;
-  uri->GetSpec(spec);
+  if (uri) {
+    nsCString spec;
+    uri->GetSpec(spec);
 
-  // A hack: replace forward slashes with '\\' so they aren't
-  // treated as path separators.  Users of the reporters
-  // (such as about:memory) have to undo this change.
-  spec.ReplaceChar('/', '\\');
+    // A hack: replace forward slashes with '\\' so they aren't
+    // treated as path separators.  Users of the reporters
+    // (such as about:memory) have to undo this change.
+    spec.ReplaceChar('/', '\\');
 
-  aStr += spec;
-
-  return true;
+    aStr += spec;
+  } else {
+    aStr += NS_LITERAL_CSTRING("[system]");
+  }
 }
 
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMStyleMallocSizeOf, "windows")
 
 static nsresult
 CollectWindowReports(nsGlobalWindow *aWindow,
                      nsWindowSizes *aWindowTotalSizes,
                      nsIMemoryMultiReporterCallback *aCb,
@@ -99,135 +97,107 @@ CollectWindowReports(nsGlobalWindow *aWi
   // DOM window objects fall into one of three categories:
   // - "active" windows are currently either displayed in an active
   //   tab, or a child of such a window.
   // - "cached" windows are in the fastback cache.
   // - "other" windows are closed (or navigated away from w/o being
   //   cached) yet held alive by either a website or our code. The
   //   latter case may be a memory leak, but not necessarily.
   //
-  // For inner windows we show how much memory the window and its
-  // document etc use, and we report those per URI, where the URI is
-  // the document URI, if available, or the codebase of the principal
-  // in the window. In the case where we're unable to find a URI we're
-  // dealing with a chrome window with no document in it (or
-  // somesuch), and for that we make the URI be the string "[system]".
+  // For each window we show how much memory the window and its
+  // document, etc, use, and we report those per URI, where the URI is
+  // the document URI, if available, or the codebase of the principal in
+  // the window. In the case where we're unable to find a URI we're
+  // dealing with a chrome window with no document in it (or somesuch),
+  // and for that we make the URI be the string "[system]".
   //
-  // For outer windows we simply group them all together and just show
-  // the combined count and amount of memory used, which is generally
-  // a constant amount per window (since all the actual data lives in
-  // the inner window).
+  // Outer windows are lumped in with inner windows, because the amount
+  // of memory used by outer windows is small.
+  //
+  // The path we give to the reporter callback for "active" and "cached"
+  // windows (both inner and outer) is as follows:
   //
-  // The path we give to the reporter callback for inner windows are
-  // as follows:
+  //   explicit/window-objects/top(<top-outer-uri>, id=<top-outer-id>)/<category>/window(<window-uri>)/...
   //
-  //   explicit/window-objects/<category>/top=<top-outer-id> (inner=<top-inner-id>)/inner-window(id=<id>, uri=<uri>)
+  // The path we give for "other" windows is as follows:
+  //
+  //   explicit/window-objects/top(none)/window(<window-uri>)/...
   //
   // Where:
-  // - <category> is active, cached, or other, as described above.
+  // - <category> is "active" or "cached", as described above.
   // - <top-outer-id> is the window id (nsPIDOMWindow::WindowID()) of
   //   the top outer window (i.e. tab, or top level chrome window).
-  // - <top-inner-id> is the window id of the top window's inner
-  //   window.
-  // - <id> is the window id of the inner window in question.
-  // - <uri> is the URI per above description.
+  // - <top-inner-uri> is the URI of the top outer window.  Excepting
+  //   special windows (such as browser.xul or hiddenWindow.html) it's
+  //   what the address bar shows for the tab.
+  // - <window-uri> is the URI of aWindow.
   //
-  // Exposing the window ids is done to get logical grouping in
-  // about:memory, and also for debuggability since one can get to the
-  // nsGlobalWindow for a window id by calling the static method
-  // nsGlobalWindow::GetInnerWindowWithId(id) (or
-  // GetOuterWindowWithId(id) in a debugger.
-  //
-  // For outer windows we simply use:
-  // 
-  //   explicit/window-objects/<category>/outer-windows
-  //
-  // Which gives us simple counts of how many outer windows (and their
-  // combined sizes) per category.
+  // Exposing the top-outer-id ensures that each tab gets its own
+  // sub-tree, even if multiple tabs are showing the same URI.
 
   nsCAutoString windowPath("explicit/window-objects/");
 
-  nsIDocShell *docShell = aWindow->GetDocShell();
-
   nsGlobalWindow *top = aWindow->GetTop();
-  nsWindowSizes windowSizes(DOMStyleMallocSizeOf);
-  aWindow->SizeOfIncludingThis(&windowSizes);
+  windowPath += NS_LITERAL_CSTRING("top(");
+  if (top) {
+    AppendWindowURI(top, windowPath);
+    windowPath += NS_LITERAL_CSTRING(", id=");
+    windowPath.AppendInt(top->WindowID());
+  } else {
+    windowPath += NS_LITERAL_CSTRING("none");
+  }
+  windowPath += NS_LITERAL_CSTRING(")/");
 
-  if (docShell && aWindow->IsFrozen()) {
-    windowPath += NS_LITERAL_CSTRING("cached/");
-  } else if (docShell) {
-    windowPath += NS_LITERAL_CSTRING("active/");
+  nsIDocShell *docShell = aWindow->GetDocShell();
+  if (docShell) {
+    MOZ_ASSERT(top, "'cached' or 'active' window lacks a top window");
+    windowPath += aWindow->IsFrozen() ? NS_LITERAL_CSTRING("cached/")
+                                      : NS_LITERAL_CSTRING("active/");
   } else {
-    windowPath += NS_LITERAL_CSTRING("other/");
+    MOZ_ASSERT(!top, "'other' window has a top window");
   }
 
-  if (aWindow->IsInnerWindow()) {
-    windowPath += NS_LITERAL_CSTRING("top=");
-
-    if (top) {
-      windowPath.AppendInt(top->WindowID());
-
-      nsGlobalWindow *topInner = top->GetCurrentInnerWindowInternal();
-      if (topInner) {
-        windowPath += NS_LITERAL_CSTRING(" (inner=");
-        windowPath.AppendInt(topInner->WindowID());
-        windowPath += NS_LITERAL_CSTRING(")");
-      }
-    } else {
-      windowPath += NS_LITERAL_CSTRING("none");
-    }
+  windowPath += NS_LITERAL_CSTRING("window(");
+  AppendWindowURI(aWindow, windowPath);
+  windowPath += NS_LITERAL_CSTRING(")");
 
-    windowPath += NS_LITERAL_CSTRING("/inner-window(id=");
-    windowPath.AppendInt(aWindow->WindowID());
-    windowPath += NS_LITERAL_CSTRING(", uri=");
-
-    if (!AppendWindowURI(aWindow, windowPath)) {
-      windowPath += NS_LITERAL_CSTRING("[system]");
-    }
-
-    windowPath += NS_LITERAL_CSTRING(")");
-  } else {
-    // Combine all outer windows per section (active/cached/other) as
-    // they basically never contain anything of interest, and are
-    // always pretty much the same size.
-
-    windowPath += NS_LITERAL_CSTRING("outer-windows");
-  }
-
-#define REPORT(_path1, _path2, _amount, _desc)                                \
+#define REPORT(_pathTail, _amount, _desc)                                     \
   do {                                                                        \
     if (_amount > 0) {                                                        \
-        nsCAutoString path(_path1);                                           \
-        path += _path2;                                                       \
+        nsCAutoString path(windowPath);                                       \
+        path += _pathTail;                                                    \
         nsresult rv;                                                          \
         rv = aCb->Callback(EmptyCString(), path, nsIMemoryReporter::KIND_HEAP,\
                       nsIMemoryReporter::UNITS_BYTES, _amount,                \
                       NS_LITERAL_CSTRING(_desc), aClosure);                   \
         NS_ENSURE_SUCCESS(rv, rv);                                            \
     }                                                                         \
   } while (0)
 
-  REPORT(windowPath, "/dom", windowSizes.mDOM,
+  nsWindowSizes windowSizes(DOMStyleMallocSizeOf);
+  aWindow->SizeOfIncludingThis(&windowSizes);
+
+  REPORT("/dom", windowSizes.mDOM,
          "Memory used by a window and the DOM within it.");
   aWindowTotalSizes->mDOM += windowSizes.mDOM;
 
-  REPORT(windowPath, "/style-sheets", windowSizes.mStyleSheets,
+  REPORT("/style-sheets", windowSizes.mStyleSheets,
          "Memory used by style sheets within a window.");
   aWindowTotalSizes->mStyleSheets += windowSizes.mStyleSheets;
 
-  REPORT(windowPath, "/layout/arenas", windowSizes.mLayoutArenas,
+  REPORT("/layout/arenas", windowSizes.mLayoutArenas,
          "Memory used by layout PresShell, PresContext, and other related "
          "areas within a window.");
   aWindowTotalSizes->mLayoutArenas += windowSizes.mLayoutArenas;
 
-  REPORT(windowPath, "/layout/style-sets", windowSizes.mLayoutStyleSets,
+  REPORT("/layout/style-sets", windowSizes.mLayoutStyleSets,
          "Memory used by style sets within a window.");
   aWindowTotalSizes->mLayoutStyleSets += windowSizes.mLayoutStyleSets;
 
-  REPORT(windowPath, "/layout/text-runs", windowSizes.mLayoutTextRuns,
+  REPORT("/layout/text-runs", windowSizes.mLayoutTextRuns,
          "Memory used for text-runs (glyph layout) in the PresShell's frame "
          "tree, within a window.");
   aWindowTotalSizes->mLayoutTextRuns += windowSizes.mLayoutTextRuns;
 
 #undef REPORT
 
   return NS_OK;
 }
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -178,17 +178,17 @@ public:
   /**
    * Wrap the object corresponding to this wrapper cache. If non-null is
    * returned, the object has already been stored in the wrapper cache and the
    * value set in triedToWrap is meaningless. If null is returned then
    * triedToWrap indicates whether an error occurred, if it's false then the
    * object doesn't actually support creating a wrapper through its WrapObject
    * hook.
    */
-  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
   {
     *triedToWrap = false;
     return nsnull;
   }
 
   /**
    * Returns true if the object has a non-gray wrapper.
--- a/dom/contacts/fallback/ContactDB.jsm
+++ b/dom/contacts/fallback/ContactDB.jsm
@@ -20,17 +20,17 @@ 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;
+  this._global = aGlobal;
 }
 
 ContactDB.prototype = {
 
   // Cache the DB
   db: null,
 
   close: function close() {
@@ -49,17 +49,17 @@ ContactDB.prototype = {
     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);
+    let request = this._global.mozIndexedDB.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);
     };
@@ -111,24 +111,32 @@ ContactDB.prototype = {
     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 });
 
+    objectStore.createIndex("nicknameLowerCase",   "search.nickname",   { unique: false, multiEntry: true });
+    objectStore.createIndex("nameLowerCase",       "search.name",       { unique: false, multiEntry: true });
+    objectStore.createIndex("familyNameLowerCase", "search.familyName", { unique: false, multiEntry: true });
+    objectStore.createIndex("givenNameLowerCase",  "search.givenName",  { unique: false, multiEntry: true });
+    objectStore.createIndex("telLowerCase",        "search.tel",        { unique: false, multiEntry: true });
+    objectStore.createIndex("emailLowerCase",      "search.email",      { unique: false, multiEntry: true });
+    objectStore.createIndex("noteLowerCase",       "search.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)
+   *        Type of transaction (e.g. "readwrite")
    * @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.
    */
@@ -166,17 +174,16 @@ ContactDB.prototype = {
             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:      [],
@@ -192,28 +199,51 @@ ContactDB.prototype = {
       bday:            null,
       note:            [],
       impp:            [],
       anniversary:     null,
       sex:             null,
       genderIdentity:  null
     };
 
+    contact.search = {
+      name:            [],
+      honorificPrefix: [],
+      givenName:       [],
+      additionalName:  [],
+      familyName:      [],
+      honorificSuffix: [],
+      nickname:        [],
+      email:           [],
+      category:        [],
+      tel:             [],
+      org:             [],
+      note:            [],
+      impp:            []
+    };
+
     for (let field in aContact.properties) {
       contact.properties[field] = aContact.properties[field];
+      // Add search fields
+      if (aContact.properties[field] && contact.search[field]) {
+        for (let i = 0; i <= aContact.properties[field].length; i++) {
+          if (aContact.properties[field][i])
+            contact.search[field].push(aContact.properties[field][i].toLowerCase());
+        }
+      }
     }
+    debug("contact:" + JSON.stringify(contact));
 
     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;
@@ -229,17 +259,17 @@ ContactDB.prototype = {
     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) {
+    this.newTxn("readwrite", 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!")
@@ -258,24 +288,24 @@ ContactDB.prototype = {
             store.put(contact);
           }
         }
       }.bind(this);
     }.bind(this), successCb, errorCb);
   },
 
   removeContact: function removeContact(aId, aSuccessCb, aErrorCb) {
-    this.newTxn(Ci.nsIIDBTransaction.READ_WRITE, function (txn, store) {
+    this.newTxn("readwrite", 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) {
+    this.newTxn("readwrite", function (txn, store) {
       debug("Going to clear all!");
       store.clear();
     }, aSuccessCb, aErrorCb);
   },
 
   /**
    * @param successCb
    *        Callback function to invoke with result array.
@@ -292,21 +322,19 @@ ContactDB.prototype = {
    *        - 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") {
+    this.newTxn("readonly", function (txn, store) {
+      if (aOptions && (aOptions.filterOp == "equals" || aOptions.filterOp == "contains")) {
         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 + " ");
@@ -329,78 +357,39 @@ ContactDB.prototype = {
     }
 
     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 {
+      } else if (options.filterOp == "equals") {
         debug("Getting index: " + key);
+        // case sensitive
         let index = store.index(key);
         request = index.getAll(options.filterValue, options.filterLimit);
+      } else {
+        // not case sensitive
+        let tmp = options.filterValue.toLowerCase();
+        let range = this._global.IDBKeyRange.bound(tmp, tmp + "\uFFFF");
+        let index = store.index(key + "LowerCase");
+        request = index.getAll(range, 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)
--- a/dom/contacts/tests/test_contacts_basics.html
+++ b/dom/contacts/tests/test_contacts_basics.html
@@ -41,17 +41,17 @@ var adr2 = {
   locality: "locality2",
   region: "region2",
   postalCode: "postal code2",
   countryName: "country2"
 };
 
 var properties1 = {
   name: "Testname1",
-  familyName: "TestFamilyName",
+  familyName: ["TestFamilyName","Wagner"],
   givenName: ["Test1","Test2"],
   nickname: "nicktest",
   tel: ["123456"],
   adr: adr1
 };
 
 var properties2 = {
   name: ["dummyName", "dummyName2"],
@@ -207,16 +207,76 @@ var steps = [
       ok(createResult1.id, "The contact now has an ID.");
       sample_id1 = createResult1.id;
       checkContacts(properties1, createResult1);
       next();
     };
     req.onerror = onFailure;
   },
   function () {
+    ok(true, "Retrieving by substring");
+    var options = {filterBy: ["name"],
+                   filterOp: "contains",
+                   filterValue: properties1.name.substring(0,3)};
+    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 by substring2");
+    var options = {filterBy: ["givenName"],
+                   filterOp: "contains",
+                   filterValue: properties1.givenName[0].substring(0,3)};
+    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 by substring3");
+    var options = {filterBy: ["name", "givenName"],
+                   filterOp: "contains",
+                   filterValue: properties1.givenName[0].substring(0,3)};
+    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 by substring3, Testing multi entry");
+    var options = {filterBy: ["name", "givenName", "familyName"],
+                   filterOp: "contains",
+                   filterValue: properties1.familyName[1].substring(0,3).toLowerCase()};
+    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 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");
@@ -301,32 +361,32 @@ var steps = [
       }
       req2.onerror = onFailure;
     };
     req.onerror = onFailure;
   },
   function () {
     ok(true, "Searching contacts by query");
     var options = {filterBy: ["name", "email"],
-                   filterOp: "icontains",
+                   filterOp: "contains",
                    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",
+                   filterOp: "contains",
                    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();
@@ -424,32 +484,32 @@ var steps = [
       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",
+                   filterOp: "contains",
                    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",
+                   filterOp: "contains",
                    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();
@@ -533,27 +593,41 @@ var steps = [
       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({});
+                   filterOp: "contains",
+                   filterValue: properties1.name[0].substring(0, 4)};
+    req = mozContacts.find(options);
     req.onsuccess = function () {
       ok(req.result.length == 100, "100 Entries.");
       checkContacts(createResult1, req.result[99]);
       next();
     }
     req.onerror = onFailure;
   },
   function () {
+    ok(true, "Retrieving all contacts3");
+    var options = {filterBy: ["name", "givenName", "tel", "email", "note"],
+                   filterOp: "contains",
+                   filterValue: properties1.name[0].substring(0, 4),
+                   filterLimit: 15 };
+    req = mozContacts.find(options);
+    req.onsuccess = function () {
+      ok(req.result.length == 15, "15 Entries.");
+      checkContacts(createResult1, req.result[10]);
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
     ok(true, "Deleting database");
     req = mozContacts.clear();
     req.onsuccess = function () {
       clearTemps();
       next();
     }
     req.onerror = onFailure;
   },
@@ -583,17 +657,17 @@ var steps = [
       ok(cloned.givenName == "Tom", "New Name");
       next();
     }
     req.onerror = onFailure;
   },
   function () {
     ok(true, "Retrieving all contacts");
     var options = {filterBy: ["name"],
-                   filterOp: "icontains",
+                   filterOp: "contains",
                    filterValue: properties2.name[0].substring(0, 4)};
     req = mozContacts.find({});
     req.onsuccess = function () {
       ok(req.result.length == 2, "2 Entries.");
       next();
     }
     req.onerror = onFailure;
   },
--- a/dom/dom-config.mk
+++ b/dom/dom-config.mk
@@ -21,17 +21,17 @@ DOM_SRCDIRS = \
   layout/generic \
   layout/style \
   layout/xul/base/src \
   layout/xul/base/src/tree/src \
   $(NULL)
 
 ifdef MOZ_B2G_RIL
 DOM_SRCDIRS += \
-  dom/system/b2g \
+  dom/system/gonk \
   dom/telephony \
   dom/wifi \
   $(NULL)
 endif
 
 ifdef MOZ_B2G_BT
 DOM_SRCDIRS += dom/bluetooth
 endif
--- a/dom/indexedDB/IDBCursor.cpp
+++ b/dom/indexedDB/IDBCursor.cpp
@@ -458,17 +458,17 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(IDBCurs
 DOMCI_DATA(IDBCursor, IDBCursor)
 DOMCI_DATA(IDBCursorWithValue, IDBCursor)
 
 NS_IMETHODIMP
 IDBCursor::GetDirection(nsAString& aDirection)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  switch(mDirection) {
+  switch (mDirection) {
     case NEXT:
       aDirection.AssignLiteral("next");
       break;
     case NEXT_UNIQUE:
       aDirection.AssignLiteral("nextunique");
       break;
     case PREV:
       aDirection.AssignLiteral("prev");
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -527,17 +527,17 @@ IDBTransaction::GetDb(nsIIDBDatabase** a
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBTransaction::GetMode(nsAString& aMode)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  switch(mMode) {
+  switch (mMode) {
     case READ_ONLY:
       aMode.AssignLiteral("readonly");
       break;
     case READ_WRITE:
       aMode.AssignLiteral("readwrite");
       break;
     case VERSION_CHANGE:
       aMode.AssignLiteral("versionchange");
--- a/dom/interfaces/base/nsIDOMNavigator.idl
+++ b/dom/interfaces/base/nsIDOMNavigator.idl
@@ -34,17 +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 ***** */
 
 #include "domstubs.idl"
 
-[scriptable, uuid(e610c037-db58-4cd7-8ed3-0d7f1422b4d3)]
+[scriptable, uuid(e0737ed5-89c5-4fe3-891e-a75bf3a1bb55)]
 interface nsIDOMNavigator : nsISupports
 {
   readonly attribute DOMString             appCodeName;
   readonly attribute DOMString             appName;
   readonly attribute DOMString             appVersion;
   readonly attribute DOMString             language;
   readonly attribute nsIDOMMimeTypeArray   mimeTypes;
   readonly attribute DOMString             platform;
@@ -57,16 +57,17 @@ interface nsIDOMNavigator : nsISupports
   readonly attribute DOMString             userAgent;
   readonly attribute boolean               cookieEnabled;
   readonly attribute boolean               onLine;
   readonly attribute DOMString             buildID;
   readonly attribute DOMString             doNotTrack;
   readonly attribute nsIDOMMozPowerManager mozPower;
 
   boolean                   javaEnabled();
+  boolean                   taintEnabled();
 
   /**
    * Pulse the device's vibrator, if it has one.  If the device does not have a
    * vibrator, this function does nothing.  If the window is hidden, this
    * function does nothing.
    *
    * mozVibrate takes one argument, which specifies either how long to vibrate
    * for or gives a pattern of vibrator-on/vibrator-off timings.
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -65,17 +65,17 @@ interface nsIDOMEvent;
 interface nsITransferable;
 interface nsIQueryContentEventResult;
 interface nsIDOMWindow;
 interface nsIDOMBlob;
 interface nsIDOMFile;
 interface nsIFile;
 interface nsIDOMTouch;
 
-[scriptable, uuid(73b48170-55d5-11e1-b86c-0800200c9a66)]
+[scriptable, uuid(5740d0fe-9f4e-431f-b8b3-b82f9b7ff4cf)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
    * will stop animating. The attribute's value must be one of the
    * animationMode values from imgIContainer.
@@ -184,16 +184,25 @@ interface nsIDOMWindowUtils : nsISupport
    *   // elsewhere
    *   browser.setViewportScale(2.0, 2.0);
    *
    * The caller of this method must have UniversalXPConnect
    * privileges.
    */
   void setResolution(in float aXResolution, in float aYResolution);
 
+  /**
+   * Whether the next paint should be flagged as the first paint for a document.
+   * This gives a way to track the next paint that occurs after the flag is
+   * set. The flag gets cleared after the next paint.
+   *
+   * Can only be accessed with UniversalXPConnect privileges.
+   */
+  attribute boolean isFirstPaint;
+
   /** Synthesize a mouse event. The event types supported are:
    *    mousedown, mouseup, mousemove, mouseover, mouseout, contextmenu
    *
    * Events are sent in coordinates offset by aX and aY from the window.
    *
    * Note that additional events may be fired as a result of this call. For
    * instance, typically a click event will be fired as a result of a
    * mousedown and mouseup in sequence.
--- a/dom/interfaces/geolocation/Makefile.in
+++ b/dom/interfaces/geolocation/Makefile.in
@@ -44,17 +44,16 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE         = dom
 XPIDL_MODULE   = dom_geolocation
 GRE_MODULE     = 1
 
 XPIDLSRCS =                                    \
             nsIDOMGeoGeolocation.idl           \
             nsIDOMGeoPosition.idl              \
-            nsIDOMGeoPositionAddress.idl       \
             nsIDOMGeoPositionCoords.idl        \
             nsIDOMGeoPositionCallback.idl      \
             nsIDOMGeoPositionError.idl         \
             nsIDOMGeoPositionErrorCallback.idl \
             nsIDOMGeoPositionOptions.idl       \
             nsIDOMNavigatorGeolocation.idl     \
             $(NULL)
 
--- a/dom/interfaces/geolocation/nsIDOMGeoPosition.idl
+++ b/dom/interfaces/geolocation/nsIDOMGeoPosition.idl
@@ -32,18 +32,15 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 
 #include "domstubs.idl"
 #include "nsIDOMGeoPositionCoords.idl"
-#include "nsIDOMGeoPositionAddress.idl"
 
-[scriptable, uuid(23E5269F-4DD7-41C4-B52A-75918694C2DE)]
+[scriptable, uuid(dd9f7e81-0f74-4fb5-b361-37019bf60c3f)]
 interface nsIDOMGeoPosition : nsISupports
 {
   readonly attribute DOMTimeStamp timestamp;
   readonly attribute nsIDOMGeoPositionCoords coords;
-  readonly attribute nsIDOMGeoPositionAddress address;
-
 };
deleted file mode 100644
--- a/dom/interfaces/geolocation/nsIDOMGeoPositionAddress.idl
+++ /dev/null
@@ -1,51 +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 Geolocation.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  Doug Turner <dougt@meer.net>  (Original Author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-
-#include "domstubs.idl"
-
-[scriptable, uuid(93abae10-7024-49eb-8e05-1931343b0ebb)]
-interface nsIDOMGeoPositionAddress : nsISupports
-{
-  readonly attribute DOMString streetNumber;
-  readonly attribute DOMString street;
-  readonly attribute DOMString premises;
-  readonly attribute DOMString city;
-  readonly attribute DOMString county;
-  readonly attribute DOMString region;
-  readonly attribute DOMString country;
-  readonly attribute DOMString postalCode;
-};
--- a/dom/interfaces/html/nsIDOMHTMLDocument.idl
+++ b/dom/interfaces/html/nsIDOMHTMLDocument.idl
@@ -86,18 +86,18 @@ interface nsIDOMHTMLDocument : nsIDOMDoc
   void                      writeln([optional, Null(Stringify)] in DOMString text);
 
   /**
    * Midas additions
    */
   attribute DOMString       designMode;
 
   boolean                   execCommand(in DOMString commandID,
-                                        in boolean doShowUI,
-                                        in DOMString value);
+                                        [optional] in boolean doShowUI,
+                                        [optional] in DOMString value);
 
   // returns true if the help is being shown for command (false if not)
   boolean                   execCommandShowHelp(in DOMString commandID);
 
   // returns true if the command is enabled (false otherwise)
   boolean                   queryCommandEnabled(in DOMString commandID);
   
   // returns true if the command is in a indeterminate state (false otherwise)
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -749,16 +749,26 @@ ContentChild::RecvDeviceMotionChanged(co
     nsCOMPtr<nsIDeviceMotionUpdate> dmu = 
         do_GetService(NS_DEVICE_MOTION_CONTRACTID);
     if (dmu)
         dmu->DeviceMotionChanged(type, x, y, z);
     return true;
 }
 
 bool
+ContentChild::RecvNeedsCalibration()
+{
+    nsCOMPtr<nsIDeviceMotionUpdate> dmu = 
+        do_GetService(NS_DEVICE_MOTION_CONTRACTID);
+    if (dmu)
+        dmu->NeedsCalibration();
+    return true;
+}
+
+bool
 ContentChild::RecvScreenSizeChanged(const gfxIntSize& size)
 {
 #ifdef ANDROID
     mScreenSize = size;
 #else
     NS_RUNTIMEABORT("Message currently only expected on android");
 #endif
   return true;
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -157,16 +157,18 @@ public:
     virtual bool RecvGeolocationUpdate(const GeoPosition& somewhere);
 
     virtual bool RecvAddPermission(const IPC::Permission& permission);
 
     virtual bool RecvDeviceMotionChanged(const long int& type,
                                          const double& x, const double& y,
                                          const double& z);
 
+    virtual bool RecvNeedsCalibration();
+
     virtual bool RecvScreenSizeChanged(const gfxIntSize &size);
 
     virtual bool RecvFlushMemory(const nsString& reason);
 
     virtual bool RecvActivateA11y();
 
     virtual bool RecvGarbageCollect();
     virtual bool RecvCycleCollect();
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1286,11 +1286,17 @@ ContentParent::OnMotionChange(nsIDeviceM
     aDeviceData->GetX(&x);
     aDeviceData->GetY(&y);
     aDeviceData->GetZ(&z);
 
     unused << SendDeviceMotionChanged(type, x, y, z);
     return NS_OK;
 }
 
+NS_IMETHODIMP
+ContentParent::NeedsCalibration() {
+    unused << SendNeedsCalibration();
+    return NS_OK;
+}
+
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -129,16 +129,17 @@ child:
     NotifyAlertsObserver(nsCString topic, nsString data);
 
     GeolocationUpdate(GeoPosition somewhere);
 
     // nsIPermissionManager messages
     AddPermission(Permission permission);
 
     DeviceMotionChanged(long type, double x, double y, double z);
+    NeedsCalibration();
 
     ScreenSizeChanged(gfxIntSize size);
 
     FlushMemory(nsString reason);
 
     GarbageCollect();
     CycleCollect();
     
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -410,19 +410,24 @@ NS_IMPL_ISUPPORTS3(nsPluginInstanceOwner
 nsresult
 nsPluginInstanceOwner::SetInstance(nsNPAPIPluginInstance *aInstance)
 {
   NS_ASSERTION(!mInstance || !aInstance, "mInstance should only be set or unset!");
 
   // If we're going to null out mInstance after use, be sure to call
   // mInstance->InvalidateOwner() here, since it now won't be called
   // from our destructor.  This fixes bug 613376.
-  if (mInstance && !aInstance)
+  if (mInstance && !aInstance) {
     mInstance->InvalidateOwner();
 
+#ifdef MOZ_WIDGET_ANDROID
+    RemovePluginView();
+#endif
+  }
+
   mInstance = aInstance;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::GetWindow(NPWindow *&aWindow)
 {
   NS_ASSERTION(mPluginWindow, "the plugin window object being returned is null");
@@ -743,17 +748,17 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
   nsresult rv = vm->GetRootWidget(getter_AddRefs(widget));            
   if (widget) {
     *pvalue = (void*)widget->GetNativeData(NS_NATIVE_WINDOW);
   } else {
     NS_ASSERTION(widget, "couldn't get doc's widget in getting doc's window handle");
   }
 
   return rv;
-#elif defined(MOZ_WIDGET_GTK2) || defined(MOZ_WIDGET_QT)
+#elif (defined(MOZ_WIDGET_GTK2) || defined(MOZ_WIDGET_QT)) && defined(MOZ_X11)
   // X11 window managers want the toplevel window for WM_TRANSIENT_FOR.
   nsIWidget* win = mObjectFrame->GetNearestWidget();
   if (!win)
     return NS_ERROR_FAILURE;
   *static_cast<Window*>(value) = (long unsigned int)win->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW);
   return NS_OK;
 #else
   return NS_ERROR_NOT_IMPLEMENTED;
@@ -2912,32 +2917,36 @@ void nsPluginInstanceOwner::Paint(gfxCon
                                   const gfxRect& aFrameRect,
                                   const gfxRect& aDirtyRect)
 {
   if (!mInstance || !mObjectFrame || !mPluginDocumentActiveState)
     return;
 
   PRInt32 model = mInstance->GetANPDrawingModel();
 
+  float xResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetXResolution();
+  float yResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetYResolution();
+
+  gfxRect scaledFrameRect = aFrameRect;
+  scaledFrameRect.Scale(xResolution, yResolution);
+
   if (model == kSurface_ANPDrawingModel) {
-    if (!AddPluginView(aFrameRect)) {
+    if (!AddPluginView(scaledFrameRect)) {
       Invalidate();
     }
     return;
   }
 
   if (model == kOpenGL_ANPDrawingModel) {
     if (!mLayer)
       mLayer = new AndroidMediaLayer();
 
-    // FIXME: this is gross
-    float zoomLevel = aFrameRect.width / (float)mPluginWindow->width;
-    mLayer->UpdatePosition(aFrameRect, zoomLevel);
-
-    SendSize((int)aFrameRect.width, (int)aFrameRect.height);
+    mLayer->UpdatePosition(scaledFrameRect, xResolution);
+
+    SendSize((int)scaledFrameRect.width, (int)scaledFrameRect.height);
     return;
   }
 
   if (model != kBitmap_ANPDrawingModel)
     return;
 
 #ifdef ANP_BITMAP_DRAWING_MODEL
   static nsRefPtr<gfxImageSurface> pluginSurface;
--- a/dom/power/PowerManagerService.cpp
+++ b/dom/power/PowerManagerService.cpp
@@ -158,18 +158,17 @@ NS_IMETHODIMP
 PowerManagerService::NewWakeLock(const nsAString &aTopic,
                                  nsIDOMWindow *aWindow,
                                  nsIDOMMozWakeLock **aWakeLock)
 {
   nsRefPtr<WakeLock> wakelock = new WakeLock();
   nsresult rv = wakelock->Init(aTopic, aWindow);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIDOMMozWakeLock> wl =
-    do_QueryInterface(NS_ISUPPORTS_CAST(nsIDOMMozWakeLock*, wakelock));
+  nsCOMPtr<nsIDOMMozWakeLock> wl(wakelock);
   wl.forget(aWakeLock);
 
   return NS_OK;
 }
 
 } // power
 } // dom
 } // mozilla
--- a/dom/sms/src/Makefile.in
+++ b/dom/sms/src/Makefile.in
@@ -94,17 +94,17 @@ LOCAL_INCLUDES = \
 
 # Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend
 # subdirectory (and the ipc one).
 LOCAL_INCLUDES += $(VPATH:%=-I%)
 
 ifdef MOZ_B2G_RIL
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/dom/telephony \
-  -I$(topsrcdir)/dom/system/b2g \
+  -I$(topsrcdir)/dom/system/gonk \
   $(NULL)
 
 EXTRA_COMPONENTS = \
   ril/SmsDatabaseService.js \
   ril/SmsDatabaseService.manifest \
   $(NULL)
 else
 CPPSRCS += \
--- a/dom/sms/src/ril/SmsService.cpp
+++ b/dom/sms/src/ril/SmsService.cpp
@@ -36,17 +36,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/dom/sms/SmsMessage.h"
 #include "SmsService.h"
 #include "SystemWorkerManager.h"
 #include "jsapi.h"
 #include "nsIInterfaceRequestorUtils.h"
 
-using mozilla::dom::telephony::SystemWorkerManager;
+using mozilla::dom::gonk::SystemWorkerManager;
 
 namespace mozilla {
 namespace dom {
 namespace sms {
 
 NS_IMPL_ISUPPORTS1(SmsService, nsISmsService)
 
 SmsService::SmsService()
--- a/dom/src/geolocation/Makefile.in
+++ b/dom/src/geolocation/Makefile.in
@@ -70,23 +70,21 @@ LOCAL_INCLUDES  += $(MOZ_PLATFORM_MAEMO_
 endif
 ifdef MOZ_ENABLE_QTMOBILITY
 LOCAL_INCLUDES  += $(MOZ_QT_CFLAGS) \
                    -I$(topsrcdir)/dom/system/unix \
                    $(NULL)
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),android)
-LOCAL_INCLUDES  += -I$(topsrcdir)/dom/system/android \
-                   $(NULL)
+LOCAL_INCLUDES  += -I$(topsrcdir)/dom/system/android
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gonk)
-LOCAL_INCLUDES  += -I$(topsrcdir)/dom/system/b2g \
-                   $(NULL)
+LOCAL_INCLUDES  += -I$(topsrcdir)/dom/system/gonk
 endif
 
 EXPORTS         += nsGeoPositionIPCSerialiser.h
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
--- a/dom/src/geolocation/nsGeoPosition.cpp
+++ b/dom/src/geolocation/nsGeoPosition.cpp
@@ -36,110 +36,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsGeoPosition.h"
 #include "nsDOMClassInfoID.h"
 
 ////////////////////////////////////////////////////
-// nsGeoPositionAddress
-////////////////////////////////////////////////////
-
-nsGeoPositionAddress::nsGeoPositionAddress(const nsAString &aStreetNumber,
-                                           const nsAString &aStreet,
-                                           const nsAString &aPremises,
-                                           const nsAString &aCity,
-                                           const nsAString &aCounty,
-                                           const nsAString &aRegion,
-                                           const nsAString &aCountry,
-                                           const nsAString &aPostalCode)
-    : mStreetNumber(aStreetNumber)
-    , mStreet(aStreet)
-    , mPremises(aPremises)
-    , mCity(aCity)
-    , mCounty(aCounty)
-    , mRegion(aRegion)
-    , mCountry(aCountry)
-    , mPostalCode(aPostalCode)
-{
-}
-
-nsGeoPositionAddress::~nsGeoPositionAddress()
-{
-}
-
-DOMCI_DATA(GeoPositionAddress, nsGeoPositionAddress)
-
-NS_INTERFACE_MAP_BEGIN(nsGeoPositionAddress)
-NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMGeoPositionAddress)
-NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionAddress)
-NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(GeoPositionAddress)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_THREADSAFE_ADDREF(nsGeoPositionAddress)
-NS_IMPL_THREADSAFE_RELEASE(nsGeoPositionAddress)
-
-NS_IMETHODIMP
-nsGeoPositionAddress::GetStreetNumber(nsAString & aStreetNumber)
-{
-  aStreetNumber = mStreetNumber;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGeoPositionAddress::GetStreet(nsAString & aStreet)
-{
-  aStreet = mStreet;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGeoPositionAddress::GetPremises(nsAString & aPremises)
-{
-  aPremises = mPremises;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGeoPositionAddress::GetCity(nsAString & aCity)
-{
-  aCity = mCity;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGeoPositionAddress::GetCounty(nsAString & aCounty)
-{
-  aCounty = mCounty;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGeoPositionAddress::GetRegion(nsAString & aRegion)
-{
-  aRegion = mRegion;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGeoPositionAddress::GetCountry(nsAString & aCountry)
-{
-  aCountry = mCountry;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGeoPositionAddress::GetPostalCode(nsAString & aPostalCode)
-{
-  aPostalCode = mPostalCode;
-  return NS_OK;
-}
-
-////////////////////////////////////////////////////
 // nsGeoPositionCoords
 ////////////////////////////////////////////////////
 nsGeoPositionCoords::nsGeoPositionCoords(double aLat, double aLong,
                                          double aAlt, double aHError,
                                          double aVError, double aHeading,
                                          double aSpeed)
   : mLat(aLat)
   , mLong(aLong)
@@ -234,21 +140,19 @@ nsGeoPosition::nsGeoPosition(double aLat
 nsGeoPosition::nsGeoPosition(nsIDOMGeoPositionCoords *aCoords,
                              long long aTimestamp) :
     mTimestamp(aTimestamp),
     mCoords(aCoords)
 {
 }
 
 nsGeoPosition::nsGeoPosition(nsIDOMGeoPositionCoords *aCoords,
-                             nsIDOMGeoPositionAddress *aAddress,
                              DOMTimeStamp aTimestamp) :
   mTimestamp(aTimestamp),
-  mCoords(aCoords),
-  mAddress(aAddress)
+  mCoords(aCoords)
 {
 }
 
 nsGeoPosition::~nsGeoPosition()
 {
 }
 
 DOMCI_DATA(GeoPosition, nsGeoPosition)
@@ -270,16 +174,8 @@ nsGeoPosition::GetTimestamp(DOMTimeStamp
 }
 
 NS_IMETHODIMP
 nsGeoPosition::GetCoords(nsIDOMGeoPositionCoords * *aCoords)
 {
   NS_IF_ADDREF(*aCoords = mCoords);
   return NS_OK;
 }
-
-NS_IMETHODIMP
-nsGeoPosition::GetAddress(nsIDOMGeoPositionAddress** aAddress)
-{
-  NS_IF_ADDREF(*aAddress = mAddress);
-  return NS_OK;
-}
-
--- a/dom/src/geolocation/nsGeoPosition.h
+++ b/dom/src/geolocation/nsGeoPosition.h
@@ -38,53 +38,21 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsGeoPosition_h
 #define nsGeoPosition_h
 
 #include "nsAutoPtr.h"
 #include "nsIClassInfo.h"
 #include "nsDOMClassInfoID.h"
-#include "nsIDOMGeoPositionAddress.h"
 #include "nsIDOMGeoPositionCoords.h"
 #include "nsIDOMGeoPosition.h"
 #include "nsString.h"
 
 ////////////////////////////////////////////////////
-// nsGeoPositionAddress
-////////////////////////////////////////////////////
-
-class nsGeoPositionAddress : public nsIDOMGeoPositionAddress
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIDOMGEOPOSITIONADDRESS
-
-  nsGeoPositionAddress( const nsAString &aStreetNumber,
-                        const nsAString &aStreet,
-                        const nsAString &aPremises,
-                        const nsAString &aCity,
-                        const nsAString &aCounty,
-                        const nsAString &aRegion,
-                        const nsAString &aCountry,
-                        const nsAString &aPostalCode);
-
-    ~nsGeoPositionAddress();
-  private:
-    const nsString mStreetNumber;
-    const nsString mStreet;
-    const nsString mPremises;
-    const nsString mCity;
-    const nsString mCounty;
-    const nsString mRegion;
-    const nsString mCountry;
-    const nsString mPostalCode;
-};
-
-////////////////////////////////////////////////////
 // nsGeoPositionCoords
 ////////////////////////////////////////////////////
 
 /**
  * Simple object that holds a single point in space.
  */
 class nsGeoPositionCoords MOZ_FINAL : public nsIDOMGeoPositionCoords
 {
@@ -117,24 +85,18 @@ public:
                 double aVError, double aHeading,
                 double aSpeed, long long aTimestamp);
   
 
   nsGeoPosition(nsIDOMGeoPositionCoords *aCoords,
                 long long aTimestamp);
 
   nsGeoPosition(nsIDOMGeoPositionCoords *aCoords,
-                nsIDOMGeoPositionAddress *aAddress,
                 DOMTimeStamp aTimestamp);
 
-  void SetAddress(nsIDOMGeoPositionAddress *address) {
-    mAddress = address;
-  }
-
 private:
   ~nsGeoPosition();
   long long mTimestamp;
   nsRefPtr<nsIDOMGeoPositionCoords> mCoords;
-  nsRefPtr<nsIDOMGeoPositionAddress> mAddress;
 };
 
 #endif /* nsGeoPosition_h */
 
--- a/dom/src/geolocation/nsGeoPositionIPCSerialiser.h
+++ b/dom/src/geolocation/nsGeoPositionIPCSerialiser.h
@@ -36,109 +36,22 @@
 
 #ifndef dom_src_geolocation_IPC_serialiser
 #define dom_src_geolocation_IPC_serialiser
 
 #include "IPC/IPCMessageUtils.h"
 #include "nsGeoPosition.h"
 #include "nsIDOMGeoPosition.h"
 
-typedef nsIDOMGeoPositionAddress  *GeoPositionAddress;
 typedef nsGeoPositionCoords       *GeoPositionCoords;
 typedef nsIDOMGeoPosition         *GeoPosition;
 
 namespace IPC {
 
 template <>
-struct ParamTraits<GeoPositionAddress>
-{
-  typedef GeoPositionAddress paramType;
-
-  // Function to serialize a geo position address
-  static void Write(Message *aMsg, const paramType& aParam)
-  {
-    bool isNull = !aParam;
-    WriteParam(aMsg, isNull);
-    // If it is null, then we are done
-    if (isNull) return;
-
-    nsString addressLine;
-
-    aParam->GetStreetNumber(addressLine);
-    WriteParam(aMsg, addressLine);
-
-    aParam->GetStreet(addressLine);
-    WriteParam(aMsg, addressLine);
-
-    aParam->GetPremises(addressLine);
-    WriteParam(aMsg, addressLine);
-
-    aParam->GetCity(addressLine);
-    WriteParam(aMsg, addressLine);
-
-    aParam->GetCounty(addressLine);
-    WriteParam(aMsg, addressLine);
-
-    aParam->GetRegion(addressLine);
-    WriteParam(aMsg, addressLine);
-
-    aParam->GetCountry(addressLine);
-    WriteParam(aMsg, addressLine);
-
-    aParam->GetPostalCode(addressLine);
-    WriteParam(aMsg, addressLine);
-  }
-
-  // Function to de-serialize a geoposition
-  static bool Read(const Message* aMsg, void **aIter, paramType* aResult)
-  {
-    // Check if it is the null pointer we have transfered
-    bool isNull;
-    if (!ReadParam(aMsg, aIter, &isNull)) return false;
-
-    if (isNull) {
-      *aResult = 0;
-      return true;
-    }
-
-    // We need somewhere to store the address before we create the object
-    nsString streetNumber;
-    nsString street;
-    nsString premises;
-    nsString city;
-    nsString county;
-    nsString region;
-    nsString country;
-    nsString postalCode;
-
-    // It's not important to us where it fails, but rather if it fails
-    if (!(ReadParam(aMsg, aIter, &streetNumber) &&
-          ReadParam(aMsg, aIter, &street      ) &&
-          ReadParam(aMsg, aIter, &premises    ) &&
-          ReadParam(aMsg, aIter, &city        ) &&
-          ReadParam(aMsg, aIter, &county      ) &&
-          ReadParam(aMsg, aIter, &region      ) &&
-          ReadParam(aMsg, aIter, &country     ) &&
-          ReadParam(aMsg, aIter, &postalCode  ))) return false;
-
-    // We now have all the data
-    *aResult = new nsGeoPositionAddress(streetNumber, /* aStreetNumber */
-                                        street,       /* aStreet       */
-                                        premises,     /* aPremises     */
-                                        city,         /* aCity         */
-                                        county,       /* aCounty       */
-                                        region,       /* aRegion       */
-                                        country,      /* aCountry      */
-                                        postalCode    /* aPostalCode   */
-                                       );
-    return true;
-  }
-} ;
-
-template <>
 struct ParamTraits<GeoPositionCoords>
 {
   typedef GeoPositionCoords paramType;
 
   // Function to serialize a geoposition
   static void Write(Message *aMsg, const paramType& aParam)
   {
     bool isNull = !aParam;
@@ -230,51 +143,43 @@ struct ParamTraits<GeoPosition>
     DOMTimeStamp timeStamp;
     aParam->GetTimestamp(&timeStamp);
     WriteParam(aMsg, timeStamp);
 
     nsCOMPtr<nsIDOMGeoPositionCoords> coords;
     aParam->GetCoords(getter_AddRefs(coords));
     GeoPositionCoords simpleCoords = static_cast<GeoPositionCoords>(coords.get());
     WriteParam(aMsg, simpleCoords);
-
-    nsCOMPtr<nsIDOMGeoPositionAddress> address;
-    aParam->GetAddress(getter_AddRefs(address));
-    GeoPositionAddress simpleAddress = address.get();
-    WriteParam(aMsg, simpleAddress);
   }
 
   // Function to de-serialize a geoposition
   static bool Read(const Message* aMsg, void **aIter, paramType* aResult)
   {
     // Check if it is the null pointer we have transfered
     bool isNull;
     if (!ReadParam(aMsg, aIter, &isNull)) return false;
 
     if (isNull) {
       *aResult = 0;
       return true;
     }
 
     DOMTimeStamp timeStamp;
     GeoPositionCoords coords = nsnull;
-    GeoPositionAddress address;
 
     // It's not important to us where it fails, but rather if it fails
     if (!(   ReadParam(aMsg, aIter, &timeStamp)
-          && ReadParam(aMsg, aIter, &coords   )
-          && ReadParam(aMsg, aIter, &address  ))) {
+          && ReadParam(aMsg, aIter, &coords   ))) {
           // note it is fine to do "delete nsnull" in case coords hasn't
-          // been allocated and we will never have a case where address
-          // gets allocated and we end here
+          // been allocated
           delete coords;
           return false;
       }
 
-    *aResult = new nsGeoPosition(coords, address, timeStamp);
+    *aResult = new nsGeoPosition(coords, timeStamp);
 
     return true;
   };
 
 };
 
 }
 
--- a/dom/system/Makefile.in
+++ b/dom/system/Makefile.in
@@ -57,17 +57,17 @@ ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOL
 DIRS = cocoa
 endif
 
 ifneq (,$(filter android,$(MOZ_WIDGET_TOOLKIT)))
 DIRS = android
 endif
 
 ifdef MOZ_B2G_RIL
-DIRS += b2g
+DIRS += gonk
 endif
 
 CPPSRCS     = \
   nsDeviceMotion.cpp \
   $(NULL)
 
 # We fire the nsDOMDeviceAcceleration
 LOCAL_INCLUDES += -I$(topsrcdir)/content/events/src
@@ -82,16 +82,19 @@ EXTRA_COMPONENTS = \
   GPSDGeolocationProvider.manifest \
   $(NULL)
 endif
 
 EXPORTS     = \
   nsDeviceMotion.h \
   $(NULL)
 
+# We fire the nsDOMDeviceAcceleration
+LOCAL_INCLUDES += -I$(topsrcdir)/content/events/src
+
 include $(topsrcdir)/config/config.mk
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/system/android/Makefile.in
+++ b/dom/system/android/Makefile.in
@@ -54,12 +54,13 @@ include $(topsrcdir)/ipc/chromium/chromi
 
 CPPSRCS     = \
         nsDeviceMotionSystem.cpp \
         AndroidLocationProvider.cpp \
         nsHapticFeedback.cpp \
         $(NULL)
 
 LOCAL_INCLUDES  += -I$(topsrcdir)/dom/src/geolocation \
+                     -I$(topsrcdir)/content/events/src
                      $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
--- a/dom/system/cocoa/Makefile.in
+++ b/dom/system/cocoa/Makefile.in
@@ -44,15 +44,19 @@ include $(DEPTH)/config/autoconf.mk
 MODULE      = dom
 LIBRARY_NAME    = domsystemcocoa_s
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
 
+# We fire the nsDOMDeviceAcceleration
+LOCAL_INCLUDES += -I$(topsrcdir)/content/events/src
+
 include $(topsrcdir)/config/config.mk
 
 CMMSRCS     = \
+        smslib.mm \
         nsDeviceMotionSystem.mm \
         $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/system/cocoa/nsDeviceMotionSystem.mm
+++ b/dom/system/cocoa/nsDeviceMotionSystem.mm
@@ -37,171 +37,60 @@
 #include "nsDeviceMotionSystem.h"
 #include "nsIServiceManager.h"
 #include "stdlib.h"
 
 #include <sys/sysctl.h>
 #include <sys/resource.h>
 #include <sys/vm.h>
 
-#define MODEL_NAME_LENGTH 64
-static char gModelName[MODEL_NAME_LENGTH];
+#import "smslib.h"
+#define MEAN_GRAVITY 9.80665
+#define DEFAULT_SENSOR_POLL 100
 
 nsDeviceMotionSystem::nsDeviceMotionSystem()
 {
 }
 
 nsDeviceMotionSystem::~nsDeviceMotionSystem()
 {
 }
 
-// Data format returned from IOConnectMethodStructureIStructureO.
-// I am not sure what the other bits in this structure are,
-// or if there are any, but this has to be 40 bytes long or
-// the call to read fails.
-//
-// Since we make the SmsData struct larger than any members we plan to access we
-// keep track of the the size of the part of the struct we plan to access for
-// use in bounds checking.
-#define SMSDATA_PADDING_SIZE 34
-typedef struct
-{
-  PRInt16 x;
-  PRInt16 y;
-  PRInt16 z;
-  PRInt8  unknown[SMSDATA_PADDING_SIZE];
-} SmsData;
-#define SMSDATA_USED_SIZE (sizeof(SmsData) - SMSDATA_PADDING_SIZE)
-
 void
 nsDeviceMotionSystem::UpdateHandler(nsITimer *aTimer, void *aClosure)
 {
   nsDeviceMotionSystem *self = reinterpret_cast<nsDeviceMotionSystem *>(aClosure);
   if (!self) {
     NS_ERROR("no self");
     return;
   }
-
-  size_t bufferLen = sizeof(SmsData);
-
-  void * input = malloc(bufferLen);
-  void * output = malloc(bufferLen);
-
-  if (!input || !output)
-    return;
-
-  memset(input, 0, bufferLen);
-  memset(output, 0, bufferLen);
-
-  size_t structureOutputSize = bufferLen;
-#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4)
-  kern_return_t result = ::IOConnectMethodStructureIStructureO(self->mSmsConnection,
-                                                               5, /* Magic number for SMCMotionSensor */
-                                                               bufferLen,
-                                                               (IOByteCount*)&structureOutputSize,
-                                                               input,
-                                                               output);
-#else
-  kern_return_t result = ::IOConnectCallStructMethod((mach_port_t)self->mSmsConnection,
-                                                     5, /* Magic number for SMCMotionSensor */
-                                                     input,
-                                                     bufferLen,
-                                                     output,
-                                                     &structureOutputSize);
-#endif
+  sms_acceleration accel;
+  smsGetData(&accel);
 
-  if ((result != kIOReturnSuccess) || (structureOutputSize < SMSDATA_USED_SIZE)) {
-    free(input);
-    free(output);
-    return;
-  }
-
-  SmsData *data = (SmsData*) output;
-
-  float xf, yf, zf;
-
-  // we want to normalize the return result from the chip to
-  // something between -1 and 1 where 0 is the balance point.
-
-  const int normalizeFactor = 250.5;
-
-  if (!strcmp(gModelName, "MacBookPro5,1")) {
-    xf = ((float)data->x) / normalizeFactor;
-    yf = (((float)data->y) / normalizeFactor) * -1;
-    zf = ((float)data->z) / normalizeFactor;
-  }
-  else if (!strcmp(gModelName, "MacBookPro5,3")) {
-    xf = ((float)data->y) / normalizeFactor;
-    yf = (((float)data->x) / normalizeFactor) * -1;
-    zf = (((float)data->z) / normalizeFactor) * -1;
-  }
-  else
-  {
-    xf = (((float)data->x) / normalizeFactor) * -1;
-    yf = ((float)data->y) / normalizeFactor;
-    zf = ((float)data->z) / normalizeFactor;
-  }
-
-  free(input);
-  free(output);
-
-  self->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION, xf, yf, zf );
+  self->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION,
+			    accel.x * MEAN_GRAVITY,
+			    accel.y * MEAN_GRAVITY,
+			    accel.z * MEAN_GRAVITY);
 }
 
 void nsDeviceMotionSystem::Startup()
 {
-  // we can fail, and that just means the caller will not see any changes.
-
-  mach_port_t port;
-  kern_return_t result = ::IOMasterPort(MACH_PORT_NULL, &port);
-  if (result != kIOReturnSuccess)
-    return;
-
-  CFMutableDictionaryRef  dict = ::IOServiceMatching("SMCMotionSensor");
-  if (!dict)
-    return;
-
-  io_iterator_t iter;
-  result = ::IOServiceGetMatchingServices(port, dict, &iter);
-  if (result != kIOReturnSuccess)
-    return;
-
-  io_object_t device = ::IOIteratorNext(iter);
-
-  ::IOObjectRelease(iter);
-
-  if (!device)
-    return;
-
-  result = ::IOServiceOpen(device, mach_task_self(), 0, &mSmsConnection);
-  ::IOObjectRelease(device);
-
-  if (result != kIOReturnSuccess)
-    return;
-
-  mach_port_deallocate(mach_task_self(), port);
-
-  /* get the version of the hardware we are running on. */
-  int mib[2];
-  size_t len = MODEL_NAME_LENGTH;
-  mib[0] = CTL_HW;
-  mib[1] = HW_MODEL;
-  sysctl(mib, 2, gModelName, &len, NULL, 0);
+  smsStartup(nil, nil);
+  smsLoadCalibration();
 
   mUpdateTimer = do_CreateInstance("@mozilla.org/timer;1");
   if (mUpdateTimer)
     mUpdateTimer->InitWithFuncCallback(UpdateHandler,
                                        this,
-                                       mUpdateInterval,
+                                       DEFAULT_SENSOR_POLL,
                                        nsITimer::TYPE_REPEATING_SLACK);
 }
 
 void nsDeviceMotionSystem::Shutdown()
 {
-  if (mSmsConnection)
-    ::IOServiceClose(mSmsConnection);
-
   if (mUpdateTimer) {
     mUpdateTimer->Cancel();
     mUpdateTimer = nsnull;
   }
+
+  smsShutdown();
 }
 
new file mode 100644
--- /dev/null
+++ b/dom/system/cocoa/smslib.h
@@ -0,0 +1,159 @@
+/*
+ * smslib.h
+ *
+ * SMSLib Sudden Motion Sensor Access Library
+ * Copyright (c) 2010 Suitable Systems
+ * All rights reserved.
+ * 
+ * Developed by: Daniel Griscom
+ *               Suitable Systems
+ *               http://www.suitable.com
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal with the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimers.
+ * 
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimers in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * - Neither the names of Suitable Systems nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this Software without specific prior written permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
+ *
+ * For more information about SMSLib, see
+ *		<http://www.suitable.com/tools/smslib.html>
+ * or contact
+ *		Daniel Griscom
+ *		Suitable Systems
+ *		1 Centre Street, Suite 204
+ *		Wakefield, MA 01880
+ *		(781) 665-0053
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+#define SMSLIB_VERSION "1.8"
+
+#pragma mark Structure definitions
+
+// Structure for specifying a 3-axis acceleration. 0.0 means "zero gravities",
+// 1.0 means "one gravity".
+typedef struct sms_acceleration {
+	float x;		// Right-left acceleration (positive is rightwards)
+	float y;		// Front-rear acceleration (positive is rearwards)
+	float z;		// Up-down acceleration (positive is upwards)
+} sms_acceleration;
+
+// Structure for specifying a calibration.
+typedef struct sms_calibration {
+	float zeros[3];	// Zero points for three axes (X, Y, Z)
+	float onegs[3];	// One gravity values for three axes
+} sms_calibration;
+
+#pragma mark Return value definitions
+
+// These are the return values for accelStartup(), giving the
+// various stages where the most successful attempt at accessing
+// the accelerometer failed. The higher the value, the further along the
+// software progressed before failing. The options are:
+//	- Didn't match model name
+#define SMS_FAIL_MODEL			(-7)
+//	- Failure getting dictionary matching desired services
+#define SMS_FAIL_DICTIONARY		(-6)
+//	- Failure getting list of services
+#define SMS_FAIL_LIST_SERVICES	(-5)
+//	- Failure if list of services is empty. The process generally fails
+//		here if run on a machine without a Sudden Motion Sensor.
+#define SMS_FAIL_NO_SERVICES	(-4)
+//	- Failure if error opening device.
+#define SMS_FAIL_OPENING		(-3)
+//	- Failure if opened, but didn't get a connection
+#define SMS_FAIL_CONNECTION		(-2)
+//	- Failure if couldn't access connction using given function and size. This
+//		is where the process would probably fail with a change in Apple's API.
+//		Driver problems often also cause failures here.
+#define SMS_FAIL_ACCESS			(-1)
+//	- Success!
+#define SMS_SUCCESS				(0)
+
+#pragma mark Function declarations
+
+// This starts up the accelerometer code, trying each possible sensor
+// specification. Note that for logging purposes it
+// takes an object and a selector; the object's selector is then invoked
+// with a single NSString as argument giving progress messages. Example
+// logging method:
+//		- (void)logMessage: (NSString *)theString
+// which would be used in accelStartup's invocation thusly:
+//		result = accelStartup(self, @selector(logMessage:));
+// If the object is nil, then no logging is done. Sets calibation from built-in
+// value table. Returns ACCEL_SUCCESS for success, and other (negative)
+// values for various failures (returns value indicating result of
+// most successful trial).
+int smsStartup(id logObject, SEL logSelector);
+
+// This starts up the library in debug mode, ignoring the actual hardware.
+// Returned data is in the form of 1Hz sine waves, with the X, Y and Z
+// axes 120 degrees out of phase; "calibrated" data has range +/- (1.0/5);
+// "uncalibrated" data has range +/- (256/5). X and Y axes centered on 0.0,
+// Z axes centered on 1 (calibrated) or 256 (uncalibrated). 
+// Don't use smsGetBufferLength or smsGetBufferData. Always returns SMS_SUCCESS.
+int smsDebugStartup(id logObject, SEL logSelector);
+
+// Returns the current calibration values.
+void smsGetCalibration(sms_calibration *calibrationRecord);
+
+// Sets the calibration, but does NOT store it as a preference. If the argument
+// is nil then the current calibration is set from the built-in value table.
+void smsSetCalibration(sms_calibration *calibrationRecord);
+
+// Stores the current calibration values as a stored preference.
+void smsStoreCalibration(void);
+
+// Loads the stored preference values into the current calibration.
+// Returns YES if successful.
+BOOL smsLoadCalibration(void);
+
+// Deletes any stored calibration, and then takes the current calibration values
+// from the built-in value table.
+void smsDeleteCalibration(void);
+
+// Fills in the accel record with calibrated acceleration data. Takes
+// 1-2ms to return a value. Returns 0 if success, error number if failure.
+int smsGetData(sms_acceleration *accel);
+
+// Fills in the accel record with uncalibrated acceleration data.
+// Returns 0 if success, error number if failure.
+int smsGetUncalibratedData(sms_acceleration *accel);
+
+// Returns the length of a raw block of data for the current type of sensor.
+int smsGetBufferLength(void);
+
+// Takes a pointer to accelGetRawLength() bytes; sets those bytes
+// to return value from sensor. Make darn sure the buffer length is right!
+void smsGetBufferData(char *buffer);
+
+// This returns an NSString describing the current calibration in
+// human-readable form. Also include a description of the machine.
+NSString *smsGetCalibrationDescription(void);
+
+// Shuts down the accelerometer.
+void smsShutdown(void);
+
new file mode 100644
--- /dev/null
+++ b/dom/system/cocoa/smslib.mm
@@ -0,0 +1,937 @@
+/*
+ * smslib.m
+ * 
+ * SMSLib Sudden Motion Sensor Access Library
+ * Copyright (c) 2010 Suitable Systems
+ * All rights reserved.
+ * 
+ * Developed by: Daniel Griscom
+ *               Suitable Systems
+ *               http://www.suitable.com
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal with the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimers.
+ * 
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimers in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * - Neither the names of Suitable Systems nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this Software without specific prior written permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
+ *
+ * For more information about SMSLib, see
+ *		<http://www.suitable.com/tools/smslib.html>
+ * or contact
+ *		Daniel Griscom
+ *		Suitable Systems
+ *		1 Centre Street, Suite 204
+ *		Wakefield, MA 01880
+ *		(781) 665-0053
+ *
+ */
+
+#import <IOKit/IOKitLib.h>
+#import <sys/sysctl.h>
+#import <math.h>
+#import "smslib.h"
+
+#pragma mark Internal structures
+
+// Represents a single axis of a type of sensor.
+typedef struct axisStruct {
+	int enabled;				// Non-zero if axis is valid in this sensor
+	int index;					// Location in struct of first byte
+	int size;					// Number of bytes
+	float zerog;				// Value meaning "zero g"
+	float oneg;					// Change in value meaning "increase of one g"
+								// (can be negative if axis sensor reversed)
+} axisStruct;
+
+// Represents the configuration of a type of sensor.
+typedef struct sensorSpec {
+	char *model;				// Prefix of model to be tested
+	char *name;					// Name of device to be read
+	unsigned int function;		// Kernel function index
+	int recordSize;				// Size of record to be sent/received
+	axisStruct axes[3];			// Description of three axes (X, Y, Z)
+} sensorSpec;
+	
+// Configuration of all known types of sensors. The configurations are
+// tried in order until one succeeds in returning data.
+// All default values are set here, but each axis' zerog and oneg values 
+// may be changed to saved (calibrated) values.
+//
+// These values came from SeisMaCalibrate calibration reports. In general I've
+// found the following:
+//	- All Intel-based SMSs have 250 counts per g, centered on 0, but the signs
+//		are different (and in one case two axes are swapped)
+//	- PowerBooks and iBooks all have sensors centered on 0, and reading
+//		50-53 steps per gravity (but with differing polarities!)
+//	- PowerBooks and iBooks of the same model all have the same axis polarities
+//	- PowerBook and iBook access methods are model- and OS version-specific
+//
+// So, the sequence of tests is:
+//	- Try model-specific access methods. Note that the test is for a match to the
+//		beginning of the model name, e.g. the record with model name "MacBook"
+//		matches computer models "MacBookPro1,2" and "MacBook1,1" (and ""
+//		matches any model).
+//	- If no model-specific record's access fails, then try each model-independent
+//		access method in order, stopping when one works.
+static const sensorSpec sensors[] = {
+	// ****** Model-dependent methods ******
+	// The PowerBook5,6 is one of the G4 models that seems to lose
+	// SMS access until the next reboot.
+	{"PowerBook5,6", "IOI2CMotionSensor", 21, 60, {
+			{1, 0, 1, 0,  51.5},
+			{1, 1, 1, 0, -51.5},
+			{1, 2, 1, 0, -51.5}
+		}
+	},
+	// The PowerBook5,7 is one of the G4 models that seems to lose
+	// SMS access until the next reboot.
+	{"PowerBook5,7", "IOI2CMotionSensor", 21, 60, {
+			{1, 0, 1, 0,  51.5},
+			{1, 1, 1, 0,  51.5},
+			{1, 2, 1, 0,  51.5}
+		}
+	},
+	// Access seems to be reliable on the PowerBook5,8
+	{"PowerBook5,8", "PMUMotionSensor", 21, 60, {
+			{1, 0, 1, 0, -51.5},
+			{1, 1, 1, 0,  51.5},
+			{1, 2, 1, 0, -51.5}
+		}
+	},
+	// Access seems to be reliable on the PowerBook5,9
+	{"PowerBook5,9", "PMUMotionSensor", 21, 60, {
+			{1, 0, 1, 0,  51.5},
+			{1, 1, 1, 0, -51.5},
+			{1, 2, 1, 0, -51.5}
+		}
+	},
+	// The PowerBook6,7 is one of the G4 models that seems to lose
+	// SMS access until the next reboot.
+	{"PowerBook6,7", "IOI2CMotionSensor", 21, 60, {
+			{1, 0, 1, 0,  51.5},
+			{1, 1, 1, 0,  51.5},
+			{1, 2, 1, 0,  51.5}
+		}
+	},
+	// The PowerBook6,8 is one of the G4 models that seems to lose
+	// SMS access until the next reboot.
+	{"PowerBook6,8", "IOI2CMotionSensor", 21, 60, {
+			{1, 0, 1, 0,  51.5},
+			{1, 1, 1, 0,  51.5},
+			{1, 2, 1, 0,  51.5}
+		}
+	},
+	// MacBook Pro Core 2 Duo 17". Note the reversed Y and Z axes.
+	{"MacBookPro2,1", "SMCMotionSensor", 5, 40, {
+			{1, 0, 2, 0,  251},
+			{1, 2, 2, 0, -251},
+			{1, 4, 2, 0, -251}
+		}
+	},
+	// MacBook Pro Core 2 Duo 15" AND 17" with LED backlight, introduced June '07.
+	// NOTE! The 17" machines have the signs of their X and Y axes reversed
+	// from this calibration, but there's no clear way to discriminate between
+	// the two machines.
+	{"MacBookPro3,1", "SMCMotionSensor", 5, 40, {
+			{1, 0, 2, 0, -251},
+			{1, 2, 2, 0,  251},
+			{1, 4, 2, 0, -251}
+		}
+	},
+	// ... specs?
+	{"MacBook5,2", "SMCMotionSensor", 5, 40, {
+			{1, 0, 2, 0, -251},
+			{1, 2, 2, 0,  251},
+			{1, 4, 2, 0, -251}
+		}
+	},
+	// ... specs?
+	{"MacBookPro5,1", "SMCMotionSensor", 5, 40, {
+			{1, 0, 2, 0, -251},
+			{1, 2, 2, 0, -251},
+			{1, 4, 2, 0,  251}
+		}
+	},
+	// ... specs?
+	{"MacBookPro5,2", "SMCMotionSensor", 5, 40, {
+			{1, 0, 2, 0, -251},
+			{1, 2, 2, 0, -251},
+			{1, 4, 2, 0,  251}
+		}
+	},
+	// This is speculative, based on a single user's report. Looks like the X and Y axes
+	// are swapped. This is true for no other known Appple laptop.
+	{"MacBookPro5,3", "SMCMotionSensor", 5, 40, {
+			{1, 2, 2, 0, -251},
+			{1, 0, 2, 0, -251},
+			{1, 4, 2, 0, -251}
+		}
+	},
+	// ... specs?
+	{"MacBookPro5,4", "SMCMotionSensor", 5, 40, {
+			{1, 0, 2, 0, -251},
+			{1, 2, 2, 0, -251},
+			{1, 4, 2, 0,  251}
+		}
+	},
+	// ****** Model-independent methods ******
+	// Seen once with PowerBook6,8 under system 10.3.9; I suspect
+	// other G4-based 10.3.* systems might use this
+	{"", "IOI2CMotionSensor", 24, 60, {
+			{1, 0, 1, 0, 51.5},
+			{1, 1, 1, 0, 51.5},
+			{1, 2, 1, 0, 51.5}
+		}
+	},
+	// PowerBook5,6 , PowerBook5,7 , PowerBook6,7 , PowerBook6,8
+	// under OS X 10.4.*
+	{"", "IOI2CMotionSensor", 21, 60, {
+			{1, 0, 1, 0, 51.5},
+			{1, 1, 1, 0, 51.5},
+			{1, 2, 1, 0, 51.5}
+		}
+	},
+	// PowerBook5,8 , PowerBook5,9 under OS X 10.4.*
+	{"", "PMUMotionSensor", 21, 60, {
+			// Each has two out of three gains negative, but it's different
+			// for the different models. So, this will be right in two out
+			// of three axis for either model.
+			{1, 0, 1,  0, -51.5},
+			{1, 1, 1, -6, -51.5},
+			{1, 2, 1,  0, -51.5}
+		}
+	},
+	// All MacBook, MacBookPro models. Hardware (at least on early MacBookPro 15")
+	// is Kionix KXM52-1050 three-axis accelerometer chip. Data is at
+	// http://kionix.com/Product-Index/product-index.htm. Specific MB and MBP models
+	// that use this are: 
+	//		MacBook1,1
+	//		MacBook2,1
+	//		MacBook3,1
+	//		MacBook4,1
+	//		MacBook5,1
+	//		MacBook6,1
+	//		MacBookAir1,1
+	//		MacBookPro1,1
+	//		MacBookPro1,2
+	//		MacBookPro4,1
+	//		MacBookPro5,5
+	{"", "SMCMotionSensor", 5, 40, {
+			{1, 0, 2, 0, 251},
+			{1, 2, 2, 0, 251},
+			{1, 4, 2, 0, 251}
+		}
+	}
+};
+
+#define SENSOR_COUNT (sizeof(sensors)/sizeof(sensorSpec))
+
+#pragma mark Internal prototypes
+
+static int getData(sms_acceleration *accel, int calibrated, id logObject, SEL logSelector);
+static float getAxis(int which, int calibrated);
+static int signExtend(int value, int size);
+static NSString *getModelName(void);
+static NSString *getOSVersion(void);
+static BOOL loadCalibration(void);
+static void storeCalibration(void);
+static void defaultCalibration(void);
+static void deleteCalibration(void);
+static int prefIntRead(NSString *prefName, BOOL *success);
+static void prefIntWrite(NSString *prefName, int prefValue);
+static float prefFloatRead(NSString *prefName, BOOL *success);
+static void prefFloatWrite(NSString *prefName, float prefValue);
+static void prefDelete(NSString *prefName);
+static void prefSynchronize(void);
+// static long getMicroseconds(void);
+float fakeData(NSTimeInterval time);
+
+#pragma mark Static variables
+
+static int debugging = NO;		// True if debugging (synthetic data)
+static io_connect_t connection;	// Connection for reading accel values
+static int running = NO;		// True if we successfully started
+static int sensorNum = 0;		// The current index into sensors[]
+static char *serviceName;		// The name of the current service
+static char *iRecord, *oRecord;	// Pointers to read/write records for sensor
+static int recordSize;			// Size of read/write records
+static unsigned int function;	// Which kernel function should be used
+static float zeros[3];			// X, Y and Z zero calibration values
+static float onegs[3];			// X, Y and Z one-g calibration values
+
+#pragma mark Defines
+
+// Pattern for building axis letter from axis number
+#define INT_TO_AXIS(a) (a == 0 ? @"X" : a == 1 ? @"Y" : @"Z")
+// Name of configuration for given axis' zero (axis specified by integer)
+#define ZERO_NAME(a) [NSString stringWithFormat:@"%@-Axis-Zero", INT_TO_AXIS(a)]
+// Name of configuration for given axis' oneg (axis specified by integer)
+#define ONEG_NAME(a) [NSString stringWithFormat:@"%@-Axis-One-g", INT_TO_AXIS(a)]
+// Name of "Is calibrated" preference
+#define CALIBRATED_NAME (@"Calibrated")
+// Application domain for SeisMac library
+#define APP_ID ((CFStringRef)@"com.suitable.SeisMacLib")
+
+// These #defines make the accelStartup code a LOT easier to read.
+#define LOG(message) \
+	if (logObject) { \
+		[logObject performSelector:logSelector withObject:message]; \
+	}
+#define LOG_ARG(format, var1) \
+	if (logObject) { \
+		[logObject performSelector:logSelector \
+			withObject:[NSString stringWithFormat:format, var1]]; \
+	}
+#define LOG_2ARG(format, var1, var2) \
+	if (logObject) { \
+		[logObject performSelector:logSelector \
+			withObject:[NSString stringWithFormat:format, var1, var2]]; \
+	}
+#define LOG_3ARG(format, var1, var2, var3) \
+	if (logObject) { \
+		[logObject performSelector:logSelector \
+			withObject:[NSString stringWithFormat:format, var1, var2, var3]]; \
+	}
+
+#pragma mark Function definitions
+
+// This starts up the accelerometer code, trying each possible sensor
+// specification. Note that for logging purposes it
+// takes an object and a selector; the object's selector is then invoked
+// with a single NSString as argument giving progress messages. Example
+// logging method:
+//		- (void)logMessage: (NSString *)theString
+// which would be used in accelStartup's invocation thusly:
+//		result = accelStartup(self, @selector(logMessage:));
+// If the object is nil, then no logging is done. Sets calibation from built-in
+// value table. Returns ACCEL_SUCCESS for success, and other (negative)
+// values for various failures (returns value indicating result of
+// most successful trial).
+int smsStartup(id logObject, SEL logSelector) {
+	io_iterator_t iterator;
+	io_object_t device;
+	kern_return_t result;
+	sms_acceleration accel;
+	int failure_result = SMS_FAIL_MODEL;
+		
+	running = NO;
+	debugging = NO;
+	
+	NSString *modelName = getModelName();
+	
+	LOG_ARG(@"Machine model: %@\n", modelName);
+	LOG_ARG(@"OS X version: %@\n", getOSVersion());
+	LOG_ARG(@"Accelerometer library version: %s\n", SMSLIB_VERSION);
+		
+	for (sensorNum = 0; sensorNum < SENSOR_COUNT; sensorNum++) {
+		
+		// Set up all specs for this type of sensor
+		serviceName = sensors[sensorNum].name;
+		recordSize = sensors[sensorNum].recordSize;
+		function = sensors[sensorNum].function;
+		
+		LOG_3ARG(@"Trying service \"%s\" with selector %d and %d byte record:\n",
+				serviceName, function, recordSize);
+		
+		NSString *targetName = [NSString stringWithCString:sensors[sensorNum].model
+												  encoding:NSMacOSRomanStringEncoding];
+		LOG_ARG(@"    Comparing model name to target \"%@\": ", targetName);
+		if ([targetName length] == 0 || [modelName hasPrefix:targetName]) {
+			LOG(@"success.\n");
+		} else {
+			LOG(@"failure.\n");