Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Thu, 15 Mar 2012 17:21:05 -0700
changeset 112287 7d23c3ea2afe4f01716d32f376176036151c6419
parent 112286 49a7d5a3b400157aad17a8cd04dc057734eac4ed (current diff)
parent 92746 2b1950d50397373728c160faba95d980528ae404 (diff)
child 112288 da20de5ab4b87f7042aedf4c8b026368cb98c41e
push idunknown
push userunknown
push dateunknown
milestone14.0a1
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");
+			// Don't need to increment failure_result.
+			continue;
+		}
+		
+		LOG(@"    Fetching dictionary for service: ");
+		CFMutableDictionaryRef dict = IOServiceMatching(serviceName);
+		
+		if (dict) {
+			LOG(@"success.\n");
+		} else {
+			LOG(@"failure.\n");
+			if (failure_result < SMS_FAIL_DICTIONARY) {
+				failure_result = SMS_FAIL_DICTIONARY;
+			}
+			continue;
+		}
+		
+		LOG(@"    Getting list of matching services: ");
+		result = IOServiceGetMatchingServices(kIOMasterPortDefault, 
+										 dict, 
+										 &iterator);
+		
+		if (result == KERN_SUCCESS) {
+			LOG(@"success.\n");
+		} else {
+			LOG_ARG(@"failure, with return value 0x%x.\n", result);
+			if (failure_result < SMS_FAIL_LIST_SERVICES) {
+				failure_result = SMS_FAIL_LIST_SERVICES;
+			}
+			continue;
+		}
+		
+		LOG(@"    Getting first device in list: ");
+		device = IOIteratorNext(iterator);	
+		
+		if (device == 0) {
+			LOG(@"failure.\n");
+			if (failure_result < SMS_FAIL_NO_SERVICES) {
+				failure_result = SMS_FAIL_NO_SERVICES;
+			}
+			continue;
+		} else {
+			LOG(@"success.\n");
+			LOG(@"    Opening device: ");
+		}
+		
+		result = IOServiceOpen(device, mach_task_self(), 0, &connection);
+		
+		if (result != KERN_SUCCESS) {
+			LOG_ARG(@"failure, with return value 0x%x.\n", result);
+			IOObjectRelease(device);
+			if (failure_result < SMS_FAIL_OPENING) {
+				failure_result = SMS_FAIL_OPENING;
+			}
+			continue;
+		} else if (connection == 0) {
+			LOG_ARG(@"'success', but didn't get a connection.\n", result);
+			IOObjectRelease(device);
+			if (failure_result < SMS_FAIL_CONNECTION) {
+				failure_result = SMS_FAIL_CONNECTION;
+			}
+			continue;
+		} else {
+			IOObjectRelease(device);
+			LOG(@"success.\n");
+		}
+		LOG(@"    Testing device.\n");
+		
+		defaultCalibration();
+		
+		iRecord = (char*) malloc(recordSize);
+		oRecord = (char*) malloc(recordSize);
+		
+		running = YES;
+		result = getData(&accel, true, logObject, logSelector);
+		running = NO;
+		
+		if (result) {
+			LOG_ARG(@"    Failure testing device, with result 0x%x.\n", result);
+			free(iRecord);
+			iRecord = 0;
+			free(oRecord);
+			oRecord = 0;
+			if (failure_result < SMS_FAIL_ACCESS) {
+				failure_result = SMS_FAIL_ACCESS;
+			}
+			continue;
+		} else {
+			LOG(@"    Success testing device!\n");
+			running = YES;
+			return SMS_SUCCESS;
+		}
+	}
+	return failure_result;
+}
+
+// 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) {
+	LOG(@"Starting up in debug mode\n&qu