Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Thu, 06 Sep 2012 18:28:59 -0700
changeset 113647 d16c4404e8c4d7f843f58d98c6282fa4bb1ef058
parent 113646 666bf90824f84abf2a7b92b83ea7646cc23671ae (current diff)
parent 111365 233441ff53affd70178ed330d0fea4a5a511826c (diff)
child 113648 54711415fb53b3060cf78ff501dc6e16d958e4da
push id239
push userakeybl@mozilla.com
push dateThu, 03 Jan 2013 21:54:43 +0000
treeherdermozilla-release@3a7b66445659 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/src/atk/AccessibleWrap.cpp
accessible/src/base/nsAccUtils.cpp
accessible/src/base/nsAccUtils.h
accessible/src/base/nsAccessibilityService.cpp
accessible/src/generic/ARIAGridAccessible.cpp
accessible/src/generic/ARIAGridAccessible.h
accessible/src/generic/Accessible.cpp
accessible/src/generic/Accessible.h
accessible/src/generic/DocAccessible.cpp
accessible/src/html/HTMLTableAccessible.cpp
accessible/src/html/HTMLTableAccessible.h
accessible/src/msaa/TextLeafAccessibleWrap.cpp
accessible/src/msaa/TextLeafAccessibleWrap.h
accessible/src/msaa/nsAccessNodeWrap.cpp
accessible/src/xul/XULTreeGridAccessible.cpp
accessible/src/xul/XULTreeGridAccessible.h
browser/base/content/browser.js
browser/base/content/browser.xul
browser/base/content/tabbrowser.xml
browser/components/feeds/src/nsFeedSniffer.cpp
browser/components/shell/src/nsWindowsShellService.cpp
build/macosx/common
config/makefiles/test/check-xpidl.mk
config/makefiles/xpidl.mk
configure.in
content/base/public/nsContentUtils.h
content/base/src/Makefile.in
content/base/src/nsAttrAndChildArray.cpp
content/base/src/nsBlobProtocolHandler.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsCrossSiteListenerProxy.cpp
content/base/src/nsDOMFileReader.cpp
content/base/src/nsDOMFileReader.h
content/base/src/nsDocument.cpp
content/base/src/nsEventSource.cpp
content/base/src/nsFrameLoader.cpp
content/base/src/nsFrameLoader.h
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsGkAtomList.h
content/base/src/nsMappedAttributes.cpp
content/base/src/nsMappedAttributes.h
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsXMLHttpRequest.cpp
content/base/src/nsXMLHttpRequest.h
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/events/src/nsDOMProgressEvent.cpp
content/events/src/nsDOMProgressEvent.h
content/events/src/nsEventStateManager.cpp
content/events/src/nsEventStateManager.h
content/html/content/public/nsHTMLMediaElement.h
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLMediaElement.cpp
content/html/content/src/nsHTMLOptionElement.cpp
content/html/content/src/nsHTMLTableRowElement.cpp
content/html/content/src/nsHTMLTextAreaElement.cpp
content/html/document/src/MediaDocument.cpp
content/html/document/src/nsHTMLDocument.cpp
content/media/MediaResource.cpp
content/svg/content/src/SVGPathData.cpp
content/svg/content/src/nsSVGSVGElement.cpp
content/svg/content/src/nsSVGSVGElement.h
content/xbl/src/nsXBLService.cpp
content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
content/xul/document/src/nsXULDocument.cpp
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
dom/Makefile.in
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsPIDOMWindow.h
dom/base/nsScriptNameSpaceManager.cpp
dom/base/nsScriptNameSpaceManager.h
dom/bindings/Codegen.py
dom/bindings/parser/WebIDL.py
dom/camera/CameraCapabilities.h
dom/camera/CameraControl.cpp
dom/camera/CameraControl.h
dom/camera/CameraPreview.cpp
dom/camera/CameraPreview.h
dom/camera/GonkCameraCapabilities.cpp
dom/camera/GonkCameraPreview.cpp
dom/camera/GonkCameraPreview.h
dom/devicestorage/test/test_diskSpace.html
dom/imptests/webapps/DOMCore/tests/submissions/Ms2ger/test_Range-intersectsNode.html
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/base/nsPluginStreamListenerPeer.cpp
dom/plugins/base/nsPluginTags.h
dom/src/json/nsJSON.cpp
dom/src/jsurl/nsJSProtocolHandler.cpp
dom/tests/mochitest/webapps/apphelper.js
dom/tests/mochitest/webapps/apps/bug_765063.xul
dom/tests/mochitest/webapps/apps/include.html
dom/tests/mochitest/webapps/apps/manifest_with_bom.webapp
dom/tests/mochitest/webapps/apps/manifest_with_bom.webapp^headers^
dom/tests/mochitest/webapps/apps/super_crazy.webapp
dom/tests/mochitest/webapps/apps/super_crazy.webapp^headers^
dom/tests/mochitest/webapps/apps/wild_crazy.webapp
dom/tests/mochitest/webapps/apps/wild_crazy.webapp^headers^
dom/tests/mochitest/webapps/jshelper.js
dom/tests/mochitest/webapps/test_cross_domain.xul
dom/wifi/WifiWorker.js
dom/workers/WorkerScope.cpp
editor/idl/nsIEditorLogging.idl
editor/libeditor/html/nsHTMLEditorLog.cpp
editor/libeditor/html/nsHTMLEditorLog.h
embedding/components/printingui/src/mac/nsPrintProgress.cpp
embedding/components/printingui/src/mac/nsPrintProgress.h
embedding/components/printingui/src/win/nsPrintProgress.cpp
embedding/components/printingui/src/win/nsPrintProgress.h
embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
extensions/pref/autoconfig/src/nsAutoConfig.cpp
gfx/2d/QuartzSupport.mm
gfx/layers/opengl/CanvasLayerOGL.cpp
gfx/layers/opengl/CanvasLayerOGL.h
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.h
gfx/thebes/gfxDWriteFontList.cpp
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFont.h
gfx/thebes/gfxFontUtils.cpp
gfx/thebes/gfxFontUtils.h
gfx/thebes/gfxPangoFonts.cpp
gfx/thebes/gfxPlatform.cpp
image/decoders/icon/mac/nsIconChannelCocoa.mm
image/decoders/icon/os2/nsIconChannel.cpp
image/decoders/icon/win/nsIconChannel.cpp
image/src/SVGDocumentWrapper.cpp
image/src/VectorImage.cpp
image/src/imgLoader.cpp
image/src/imgLoader.h
image/src/imgRequest.cpp
ipc/testshell/XPCShellEnvironment.cpp
js/src/Makefile.in
js/src/config/makefiles/xpidl.mk
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/frontend/ParseNode.h
js/src/frontend/Parser.cpp
js/src/jsarray.cpp
js/src/jscntxt.h
js/src/jsdbgapi.cpp
js/src/jsdbgapi.h
js/src/jsfriendapi.cpp
js/src/jsinterp.cpp
js/src/jsinterpinlines.h
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jspropertycache.cpp
js/src/jsreflect.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jstypedarrayinlines.h
js/src/vm/ScopeObject.cpp
js/xpconnect/idl/nsIXPConnect.idl
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/shell/xpcshell.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCInlines.h
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcpublic.h
js/xpconnect/wrappers/AccessCheck.cpp
js/xpconnect/wrappers/WrapperFactory.cpp
layout/base/FrameLayerBuilder.cpp
layout/base/crashtests/crashtests.list
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsDocumentViewer.cpp
layout/base/nsIPresShell.h
layout/base/nsLayoutUtils.cpp
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/base/nsPresShell.cpp
layout/base/tests/Makefile.in
layout/base/tests/test_reftests_with_caret.html
layout/build/nsLayoutModule.cpp
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsComboboxControlFrame.h
layout/generic/crashtests/crashtests.list
layout/generic/nsFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsHTMLReflowState.cpp
layout/generic/nsIFrame.h
layout/generic/nsLineLayout.cpp
layout/generic/nsObjectFrame.cpp
layout/generic/nsSimplePageSequence.cpp
layout/generic/nsSimplePageSequence.h
layout/generic/nsSubDocumentFrame.cpp
layout/printing/nsPagePrintTimer.cpp
layout/printing/nsPagePrintTimer.h
layout/printing/nsPrintEngine.cpp
layout/reftests/Makefile.in
layout/reftests/bugs/reftest.list
layout/reftests/canvas/reftest.list
layout/style/nsCSSParser.cpp
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsCSSRuleProcessor.cpp
layout/style/nsCSSStyleSheet.cpp
layout/style/nsComputedDOMStyle.cpp
layout/style/nsMediaFeatures.cpp
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/property_database.js
layout/style/ua.css
layout/svg/base/src/nsSVGContainerFrame.cpp
layout/svg/base/src/nsSVGGeometryFrame.cpp
layout/svg/base/src/nsSVGGlyphFrame.cpp
layout/svg/base/src/nsSVGGlyphFrame.h
layout/svg/base/src/nsSVGOuterSVGFrame.cpp
layout/svg/base/src/nsSVGPathGeometryFrame.cpp
layout/svg/base/src/nsSVGUtils.cpp
layout/svg/base/src/nsSVGUtils.h
layout/xul/base/src/nsXULPopupManager.cpp
mobile/android/base/GeckoAppShell.java
mobile/android/base/Makefile.in
mobile/android/chrome/content/browser.js
mobile/xul/app/mobile.js
modules/libjar/nsJARChannel.cpp
modules/libpref/src/init/all.js
netwerk/base/src/nsBaseChannel.cpp
netwerk/base/src/nsFileStreams.cpp
netwerk/base/src/nsFileStreams.h
netwerk/base/src/nsIncrementalDownload.cpp
netwerk/base/src/nsInputStreamPump.cpp
netwerk/base/src/nsProtocolProxyService.cpp
netwerk/base/src/nsSyncStreamListener.cpp
netwerk/base/src/nsURIChecker.cpp
netwerk/cache/nsCacheEntryDescriptor.h
netwerk/cache/nsDiskCacheDevice.cpp
netwerk/cache/nsDiskCacheMap.cpp
netwerk/cache/nsDiskCacheMap.h
netwerk/cache/nsDiskCacheStreams.cpp
netwerk/cache/nsDiskCacheStreams.h
netwerk/protocol/ftp/FTPChannelChild.cpp
netwerk/protocol/ftp/FTPChannelChild.h
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.h
netwerk/protocol/http/HttpChannelParentListener.cpp
netwerk/protocol/http/PHttpChannel.ipdl
netwerk/protocol/http/SpdyStream2.cpp
netwerk/protocol/http/SpdyStream3.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpConnection.cpp
netwerk/protocol/http/nsHttpConnectionInfo.cpp
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/viewsource/nsViewSourceChannel.cpp
netwerk/protocol/websocket/WebSocketChannel.cpp
netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
netwerk/protocol/wyciwyg/WyciwygChannelChild.h
netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
netwerk/streamconv/converters/nsBinHexDecoder.cpp
netwerk/streamconv/converters/nsDirIndexParser.cpp
netwerk/streamconv/converters/nsFTPDirListingConv.cpp
netwerk/streamconv/converters/nsHTTPCompressConv.h
netwerk/streamconv/converters/nsIndexedToHTML.cpp
netwerk/streamconv/converters/nsMultiMixedConv.cpp
netwerk/streamconv/converters/nsMultiMixedConv.h
netwerk/streamconv/converters/nsTXTToHTMLConv.cpp
netwerk/streamconv/converters/nsUnknownDecoder.cpp
netwerk/test/TestCallbacks.cpp
netwerk/test/TestHttp.cpp
netwerk/test/TestPageLoad.cpp
netwerk/test/TestPerf.cpp
netwerk/test/TestProtocols.cpp
netwerk/test/TestRes.cpp
netwerk/test/TestThreadedIO.cpp
parser/html/nsHtml5StreamParser.cpp
parser/htmlparser/src/nsParser.cpp
parser/xml/src/nsSAXXMLReader.cpp
rdf/base/src/nsRDFXMLDataSource.cpp
security/manager/ssl/src/nsNSSComponent.cpp
storage/test/test_AsXXX_helpers.cpp
testing/jetpack/jetpack-location.txt
toolkit/components/aboutmemory/content/aboutMemory.js
toolkit/components/places/AsyncFaviconHelpers.cpp
toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
toolkit/xre/nsNativeAppSupportCocoa.mm
toolkit/xre/nsUpdateDriver.cpp
uriloader/base/nsURILoader.cpp
uriloader/exthandler/ExternalHelperAppParent.cpp
uriloader/exthandler/ExternalHelperAppParent.h
uriloader/exthandler/nsExternalHelperAppService.cpp
uriloader/prefetch/nsOfflineCacheUpdate.cpp
uriloader/prefetch/nsPrefetchService.cpp
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/nsWindow.cpp
widget/windows/nsDataObj.cpp
widget/windows/nsWindow.cpp
widget/xpwidgets/PuppetWidget.h
xpcom/base/nsStackWalk.cpp
xpcom/glue/nsHashKeys.h
xpcom/io/nsMultiplexInputStream.cpp
xpcom/tests/windows/TestCOM.cpp
xpfe/appshell/src/nsAppShellService.cpp
xpfe/components/directory/nsDirectoryViewer.cpp
--- a/accessible/src/atk/AccessibleWrap.cpp
+++ b/accessible/src/atk/AccessibleWrap.cpp
@@ -6,16 +6,17 @@
 
 #include "AccessibleWrap.h"
 
 #include "Accessible-inl.h"
 #include "ApplicationAccessibleWrap.h"
 #include "InterfaceInitFuncs.h"
 #include "nsAccUtils.h"
 #include "nsIAccessibleRelation.h"
+#include "nsIAccessibleTable.h"
 #include "RootAccessible.h"
 #include "nsIAccessibleValue.h"
 #include "nsMai.h"
 #include "nsMaiHyperlink.h"
 #include "nsString.h"
 #include "nsAutoPtr.h"
 #include "prprf.h"
 #include "nsStateMap.h"
--- a/accessible/src/base/FocusManager.cpp
+++ b/accessible/src/base/FocusManager.cpp
@@ -55,17 +55,17 @@ FocusManager::IsFocused(const Accessible
     // accessible creation for temporary about:blank document. Without this
     // peculiarity we would end up with plain implementation based on
     // FocusedAccessible() method call. Make sure this issue is fixed in
     // bug 638465.
     if (focusedNode->OwnerDoc() == aAccessible->GetNode()->OwnerDoc()) {
       DocAccessible* doc = 
         GetAccService()->GetDocAccessible(focusedNode->OwnerDoc());
       return aAccessible ==
-	(doc ? doc->GetAccessibleOrContainer(focusedNode) : nullptr);
+        (doc ? doc->GetAccessibleOrContainer(focusedNode) : nullptr);
     }
   }
   return false;
 }
 
 bool
 FocusManager::IsFocusWithin(const Accessible* aContainer) const
 {
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -18,17 +18,17 @@
 #include "nsIMutableArray.h"
 
 #include "nsIDOMXULContainerElement.h"
 #include "nsIDOMXULSelectCntrlEl.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsWhitespaceTokenizer.h"
 #include "nsComponentManagerUtils.h"
 
-namespace dom = mozilla::dom;
+using namespace mozilla;
 using namespace mozilla::a11y;
 
 void
 nsAccUtils::GetAccAttr(nsIPersistentProperties *aAttributes,
                        nsIAtom *aAttrName, nsAString& aAttrValue)
 {
   aAttrValue.Truncate();
 
@@ -475,66 +475,8 @@ nsAccUtils::MustPrune(Accessible* aAcces
     role == roles::FLAT_EQUATION ||
     role == roles::PASSWORD_TEXT ||
     role == roles::TOGGLE_BUTTON ||
     role == roles::GRAPHIC ||
     role == roles::SLIDER ||
     role == roles::PROGRESSBAR ||
     role == roles::SEPARATOR;
 }
-
-nsresult
-nsAccUtils::GetHeaderCellsFor(nsIAccessibleTable *aTable,
-                              nsIAccessibleTableCell *aCell,
-                              int32_t aRowOrColHeaderCells, nsIArray **aCells)
-{
-  nsresult rv = NS_OK;
-  nsCOMPtr<nsIMutableArray> cells = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  int32_t rowIdx = -1;
-  rv = aCell->GetRowIndex(&rowIdx);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  int32_t colIdx = -1;
-  rv = aCell->GetColumnIndex(&colIdx);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  bool moveToLeft = aRowOrColHeaderCells == eRowHeaderCells;
-
-  // Move to the left or top to find row header cells or column header cells.
-  int32_t index = (moveToLeft ? colIdx : rowIdx) - 1;
-  for (; index >= 0; index--) {
-    int32_t curRowIdx = moveToLeft ? rowIdx : index;
-    int32_t curColIdx = moveToLeft ? index : colIdx;
-
-    nsCOMPtr<nsIAccessible> cell;
-    rv = aTable->GetCellAt(curRowIdx, curColIdx, getter_AddRefs(cell));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsCOMPtr<nsIAccessibleTableCell> tableCellAcc =
-      do_QueryInterface(cell);
-
-    // GetCellAt should always return an nsIAccessibleTableCell (XXX Bug 587529)
-    NS_ENSURE_STATE(tableCellAcc);
-
-    int32_t origIdx = 1;
-    if (moveToLeft)
-      rv = tableCellAcc->GetColumnIndex(&origIdx);
-    else
-      rv = tableCellAcc->GetRowIndex(&origIdx);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (origIdx == index) {
-      // Append original header cells only.
-      uint32_t role = Role(cell);
-      bool isHeader = moveToLeft ?
-        role == nsIAccessibleRole::ROLE_ROWHEADER :
-        role == nsIAccessibleRole::ROLE_COLUMNHEADER;
-
-      if (isHeader)
-        cells->AppendElement(cell, false);
-    }
-  }
-
-  NS_ADDREF(*aCells = cells);
-  return NS_OK;
-}
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsAccUtils_h_
 #define nsAccUtils_h_
 
 #include "nsIAccessible.h"
 #include "nsIAccessibleRole.h"
 #include "nsIAccessibleText.h"
-#include "nsIAccessibleTable.h"
 
 #include "nsAccessibilityService.h"
 #include "nsCoreUtils.h"
 
 #include "mozilla/dom/Element.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDOMNode.h"
@@ -288,37 +287,11 @@ public:
       *aState2 = static_cast<uint32_t>(aState64 >> 31);
   }
 
   /**
    * Return true if the given accessible can't have children. Used when exposing
    * to platform accessibility APIs, should the children be pruned off?
    */
   static bool MustPrune(Accessible* aAccessible);
-
-  /**
-   * Search hint enum constants. Used by GetHeaderCellsFor() method.
-   */
-  enum {
-    // search for row header cells, left direction
-    eRowHeaderCells,
-    // search for column header cells, top direction
-    eColumnHeaderCells
-  };
-
-  /**
-   * Return an array of row or column header cells for the given cell.
-   *
-   * @param aTable                [in] table accessible
-   * @param aCell                 [in] cell accessible within the given table to
-   *                               get header cells
-   * @param aRowOrColHeaderCells  [in] specifies whether column or row header
-   *                               cells are returned (see enum constants
-   *                               above)
-   * @param aCells                [out] array of header cell accessibles
-   */
-  static nsresult GetHeaderCellsFor(nsIAccessibleTable *aTable,
-                                    nsIAccessibleTableCell *aCell,
-                                    int32_t aRowOrColHeaderCells,
-                                    nsIArray **aCells);
 };
 
 #endif
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -1605,22 +1605,19 @@ nsAccessibilityService::CreateHTMLAccess
       return accessible;
     }
 
     Accessible* accessible = new HTMLLinkAccessible(aContent, aDoc);
     NS_IF_ADDREF(accessible);
     return accessible;
   }
 
-  if (tag == nsGkAtoms::dt ||
-      (tag == nsGkAtoms::li &&
-       aFrame->GetType() != nsGkAtoms::blockFrame)) {
-    // Normally for li, it is created by the list item frame (in nsBlockFrame)
-    // which knows about the bullet frame; however, in this case the list item
-    // must have been styled using display: foo
+  if (tag == nsGkAtoms::dt || tag == nsGkAtoms::li) {
+    // Create list item accessible unconditionally by tag name. nsBlockFrame
+    // creates the list item accessible for other elements styled as list items.
     Accessible* accessible = new HTMLLIAccessible(aContent, aDoc);
     NS_IF_ADDREF(accessible);
     return accessible;
   }
 
   if (tag == nsGkAtoms::abbr ||
       tag == nsGkAtoms::acronym ||
       tag == nsGkAtoms::blockquote ||
--- a/accessible/src/generic/ARIAGridAccessible.cpp
+++ b/accessible/src/generic/ARIAGridAccessible.cpp
@@ -540,151 +540,57 @@ ARIAGridCellAccessible::
 
 NS_IMPL_ISUPPORTS_INHERITED1(ARIAGridCellAccessible,
                              HyperTextAccessible,
                              nsIAccessibleTableCell)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibleTableCell
 
-NS_IMETHODIMP
-ARIAGridCellAccessible::GetTable(nsIAccessibleTable** aTable)
+TableAccessible*
+ARIAGridCellAccessible::Table() const
 {
-  NS_ENSURE_ARG_POINTER(aTable);
-  *aTable = nullptr;
-
   Accessible* table = TableFor(Row());
-  if (table)
-    CallQueryInterface(table, aTable);
-
-  return NS_OK;
+  return table ? table->AsTable() : nullptr;
 }
 
-NS_IMETHODIMP
-ARIAGridCellAccessible::GetColumnIndex(int32_t* aColumnIndex)
+uint32_t
+ARIAGridCellAccessible::ColIdx() const
 {
-  NS_ENSURE_ARG_POINTER(aColumnIndex);
-  *aColumnIndex = -1;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  Accessible* row = Parent();
+  Accessible* row = Row();
   if (!row)
-    return NS_OK;
-
-  *aColumnIndex = 0;
+    return 0;
 
   int32_t indexInRow = IndexInParent();
+  uint32_t colIdx = 0;
   for (int32_t idx = 0; idx < indexInRow; idx++) {
     Accessible* cell = row->GetChildAt(idx);
     roles::Role role = cell->Role();
     if (role == roles::GRID_CELL || role == roles::ROWHEADER ||
         role == roles::COLUMNHEADER)
-      (*aColumnIndex)++;
+      colIdx++;
   }
 
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-ARIAGridCellAccessible::GetRowIndex(int32_t* aRowIndex)
-{
-  NS_ENSURE_ARG_POINTER(aRowIndex);
-  *aRowIndex = -1;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  *aRowIndex = RowIndexFor(Row());
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-ARIAGridCellAccessible::GetColumnExtent(int32_t* aExtentCount)
-{
-  NS_ENSURE_ARG_POINTER(aExtentCount);
-  *aExtentCount = 0;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  *aExtentCount = 1;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-ARIAGridCellAccessible::GetRowExtent(int32_t* aExtentCount)
-{
-  NS_ENSURE_ARG_POINTER(aExtentCount);
-  *aExtentCount = 0;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  *aExtentCount = 1;
-  return NS_OK;
+  return colIdx;
 }
 
-NS_IMETHODIMP
-ARIAGridCellAccessible::GetColumnHeaderCells(nsIArray** aHeaderCells)
+uint32_t
+ARIAGridCellAccessible::RowIdx() const
 {
-  NS_ENSURE_ARG_POINTER(aHeaderCells);
-  *aHeaderCells = nullptr;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIAccessibleTable> table;
-  GetTable(getter_AddRefs(table));
-  if (!table)
-    return NS_OK;
-
-  return nsAccUtils::GetHeaderCellsFor(table, this,
-                                       nsAccUtils::eColumnHeaderCells,
-                                       aHeaderCells);
+  return RowIndexFor(Row());
 }
 
-NS_IMETHODIMP
-ARIAGridCellAccessible::GetRowHeaderCells(nsIArray** aHeaderCells)
+bool
+ARIAGridCellAccessible::Selected()
 {
-  NS_ENSURE_ARG_POINTER(aHeaderCells);
-  *aHeaderCells = nullptr;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIAccessibleTable> table;
-  GetTable(getter_AddRefs(table));
-  if (!table)
-    return NS_OK;
-
-  return nsAccUtils::GetHeaderCellsFor(table, this,
-                                       nsAccUtils::eRowHeaderCells,
-                                       aHeaderCells);
-}
+  Accessible* row = Row();
+  if (!row)
+    return false;
 
-NS_IMETHODIMP
-ARIAGridCellAccessible::IsSelected(bool* aIsSelected)
-{
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  Accessible* row = Parent();
-  if (!row || row->Role() != roles::ROW)
-    return NS_OK;
-
-  if (!nsAccUtils::IsARIASelected(row) && !nsAccUtils::IsARIASelected(this))
-    return NS_OK;
-
-  *aIsSelected = true;
-  return NS_OK;
+  return nsAccUtils::IsARIASelected(row) || nsAccUtils::IsARIASelected(this);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible
 
 void
 ARIAGridCellAccessible::ApplyARIAState(uint64_t* aState) const
 {
--- a/accessible/src/generic/ARIAGridAccessible.h
+++ b/accessible/src/generic/ARIAGridAccessible.h
@@ -53,16 +53,17 @@ public:
   virtual void SelectedCells(nsTArray<Accessible*>* aCells);
   virtual void SelectedCellIndices(nsTArray<uint32_t>* aCells);
   virtual void SelectedColIndices(nsTArray<uint32_t>* aCols);
   virtual void SelectedRowIndices(nsTArray<uint32_t>* aRows);
   virtual void SelectCol(uint32_t aColIdx);
   virtual void SelectRow(uint32_t aRowIdx);
   virtual void UnselectCol(uint32_t aColIdx);
   virtual void UnselectRow(uint32_t aRowIdx);
+  virtual Accessible* AsAccessible() { return this; }
 
 protected:
 
   /**
    * Return true if the given row index is valid.
    */
   bool IsValidRow(int32_t aRow);
 
@@ -104,19 +105,20 @@ class ARIAGridCellAccessible : public Hy
 {
 public:
   ARIAGridCellAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessibleTableCell
-  NS_DECL_OR_FORWARD_NSIACCESSIBLETABLECELL_WITH_XPCACCESSIBLETABLECELL
+  NS_FORWARD_NSIACCESSIBLETABLECELL(xpcAccessibleTableCell::)
 
   // Accessible
+  virtual TableCellAccessible* AsTableCell() { return this; }
   virtual void Shutdown();
   virtual void ApplyARIAState(uint64_t* aState) const;
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
 
 protected:
 
   /**
    * Return a containing row.
@@ -131,14 +133,20 @@ protected:
    * Return a table for the given row.
    */
   Accessible* TableFor(Accessible* aRow) const;
 
   /**
    * Return index of the given row.
    */
   int32_t RowIndexFor(Accessible* aRow) const;
+
+  // TableCellAccessible
+  virtual TableAccessible* Table() const MOZ_OVERRIDE;
+  virtual uint32_t ColIdx() const MOZ_OVERRIDE;
+  virtual uint32_t RowIdx() const MOZ_OVERRIDE;
+  virtual bool Selected() MOZ_OVERRIDE;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -2841,17 +2841,31 @@ bool
 Accessible::IsWidget() const
 {
   return false;
 }
 
 bool
 Accessible::IsActiveWidget() const
 {
-  return FocusMgr()->IsFocused(this);
+  if (FocusMgr()->HasDOMFocus(mContent))
+    return true;
+
+  // If text entry of combobox widget has a focus then the combobox widget is
+  // active.
+  if (mRoleMapEntry && mRoleMapEntry->Is(nsGkAtoms::combobox)) {
+    uint32_t childCount = ChildCount();
+    for (uint32_t idx = 0; idx < childCount; idx++) {
+      Accessible* child = mChildren.ElementAt(idx);
+      if (child->Role() == roles::ENTRY)
+        return FocusMgr()->HasDOMFocus(child->GetContent());
+    }
+  }
+
+  return false;
 }
 
 bool
 Accessible::AreItemsOperable() const
 {
   return mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant);
 }
 
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -32,16 +32,17 @@ namespace mozilla {
 namespace a11y {
 
 class EmbeddedObjCollector;
 class HTMLImageMapAccessible;
 class HTMLLIAccessible;
 class ImageAccessible;
 class Relation;
 class TableAccessible;
+class TableCellAccessible;
 class TextLeafAccessible;
 class XULTreeAccessible;
 
 /**
  * Name type flags.
  */
 enum ENameValueFlag {
   /**
@@ -509,16 +510,18 @@ public:
 
   inline bool IsMenuPopup() const { return mFlags & eMenuPopupAccessible; }
 
   inline bool IsRoot() const { return mFlags & eRootAccessible; }
   mozilla::a11y::RootAccessible* AsRoot();
 
   virtual mozilla::a11y::TableAccessible* AsTable() { return nullptr; }
 
+  virtual mozilla::a11y::TableCellAccessible* AsTableCell() { return nullptr; }
+
   inline bool IsTextLeaf() const { return mFlags & eTextLeafAccessible; }
   mozilla::a11y::TextLeafAccessible* AsTextLeaf();
 
   //////////////////////////////////////////////////////////////////////////////
   // ActionAccessible
 
   /**
    * Return the number of actions that can be performed on this accessible.
--- a/accessible/src/generic/DocAccessible.cpp
+++ b/accessible/src/generic/DocAccessible.cpp
@@ -1216,21 +1216,21 @@ DocAccessible::ARIAAttributeChanged(nsIC
                                aContent);
     return;
   }
 }
 
 void
 DocAccessible::ARIAActiveDescendantChanged(nsIContent* aElm)
 {
-  if (FocusMgr()->HasDOMFocus(aElm)) {
+  Accessible* widget = GetAccessible(aElm);
+  if (widget && widget->IsActiveWidget()) {
     nsAutoString id;
     if (aElm->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant, id)) {
-      nsIDocument* DOMDoc = aElm->OwnerDoc();
-      dom::Element* activeDescendantElm = DOMDoc->GetElementById(id);
+      dom::Element* activeDescendantElm = aElm->OwnerDoc()->GetElementById(id);
       if (activeDescendantElm) {
         Accessible* activeDescendant = GetAccessible(activeDescendantElm);
         if (activeDescendant) {
           FocusMgr()->ActiveItemChanged(activeDescendant, false);
           A11YDEBUG_FOCUS_ACTIVEITEMCHANGE_CAUSE("ARIA activedescedant changed",
                                                  activeDescendant)
         }
       }
--- a/accessible/src/generic/Makefile.in
+++ b/accessible/src/generic/Makefile.in
@@ -20,16 +20,17 @@ CPPSRCS = \
   ARIAGridAccessible.cpp \
   BaseAccessibles.cpp \
   DocAccessible.cpp \
   FormControlAccessible.cpp \
   HyperTextAccessible.cpp \
   ImageAccessible.cpp \
   OuterDocAccessible.cpp \
   RootAccessible.cpp \
+  TableCellAccessible.cpp \
   TextLeafAccessible.cpp \
   $(NULL)
 
 EXPORTS_NAMESPACES = mozilla/a11y
 
 EXPORTS_mozilla/a11y = \
   Accessible.h \
   DocAccessible.h \
--- a/accessible/src/generic/TableAccessible.h
+++ b/accessible/src/generic/TableAccessible.h
@@ -170,14 +170,19 @@ public:
    * Unselect the given row leaving other selected rows selected.
    */
   virtual void UnselectRow(uint32_t aRowIdx) {}
 
   /**
    * Return true if the table is probably for layout.
    */
   virtual bool IsProbablyLayoutTable() { return false; }
+
+  /**
+   * Convert the table to an Accessible*.
+   */
+  virtual Accessible* AsAccessible() = 0;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
new file mode 100644
--- /dev/null
+++ b/accessible/src/generic/TableCellAccessible.cpp
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "TableCellAccessible.h"
+
+#include "Accessible-inl.h"
+#include "TableAccessible.h"
+
+using namespace mozilla;
+using namespace mozilla::a11y;
+
+void
+TableCellAccessible::RowHeaderCells(nsTArray<Accessible*>* aCells)
+{
+  uint32_t rowIdx = RowIdx(), colIdx = ColIdx();
+  TableAccessible* table = Table();
+  if (!table)
+    return;
+
+  // Move to the left to find row header cells
+  for (uint32_t curColIdx = colIdx - 1; curColIdx < colIdx; curColIdx--) {
+    Accessible* cell = table->CellAt(rowIdx, curColIdx);
+    if (!cell)
+      continue;
+
+    // CellAt should always return a TableCellAccessible (XXX Bug 587529)
+    TableCellAccessible* tableCell = cell->AsTableCell();
+    NS_ASSERTION(tableCell, "cell should be a table cell!");
+    if (!tableCell)
+      continue;
+
+    // Avoid addding cells multiple times, if this cell spans more columns
+    // we'll get it later.
+    if (tableCell->ColIdx() == curColIdx && cell->Role() == roles::ROWHEADER)
+      aCells->AppendElement(cell);
+  }
+}
+
+void
+TableCellAccessible::ColHeaderCells(nsTArray<Accessible*>* aCells)
+{
+  uint32_t rowIdx = RowIdx(), colIdx = ColIdx();
+  TableAccessible* table = Table();
+  if (!table)
+    return;
+
+  // Move to the left to find row header cells
+  for (uint32_t curRowIdx = rowIdx - 1; curRowIdx < rowIdx; curRowIdx--) {
+    Accessible* cell = table->CellAt(curRowIdx, colIdx);
+    if (!cell)
+      continue;
+
+    // CellAt should always return a TableCellAccessible (XXX Bug 587529)
+    TableCellAccessible* tableCell = cell->AsTableCell();
+    NS_ASSERTION(tableCell, "cell should be a table cell!");
+    if (!tableCell)
+      continue;
+
+    // Avoid addding cells multiple times, if this cell spans more rows
+    // we'll get it later.
+    if (tableCell->RowIdx() == curRowIdx && cell->Role() == roles::COLUMNHEADER)
+      aCells->AppendElement(cell);
+  }
+}
--- a/accessible/src/generic/TableCellAccessible.h
+++ b/accessible/src/generic/TableCellAccessible.h
@@ -10,62 +10,62 @@
 #include "nsTArray.h"
 #include "mozilla/StandardInteger.h"
 
 class Accessible;
 
 namespace mozilla {
 namespace a11y {
 
-  class TableAccessible;
+class TableAccessible;
 
 /**
- * abstract interface implemented by table cell accessibles.
+ * Abstract interface implemented by table cell accessibles.
  */
 class TableCellAccessible
 {
 public:
 
   /**
    * Return the table this cell is in.
    */
-  virtual TableAccessible* Table() { return nullptr; }
+  virtual TableAccessible* Table() const = 0;
 
   /**
-   * Return the Column of the table this cell is in.
+   * Return the column of the table this cell is in.
    */
-  virtual uint32_t ColIdx() { return 0; }
+  virtual uint32_t ColIdx() const = 0;
 
   /**
-   * Return the the row of the table this cell is in.
+   * Return the row of the table this cell is in.
    */
-  virtual uint32_t RowIdx() { return 0; }
+  virtual uint32_t RowIdx() const = 0;
 
   /**
    * Return the column extent of this cell.
    */
-  virtual uint32_t ColExtent() { return 0; }
+  virtual uint32_t ColExtent() const { return 1; }
 
   /**
    * Return the row extent of this cell.
    */
-  virtual uint32_t RowExtent() { return 0; }
+  virtual uint32_t RowExtent() const { return 1; }
 
   /**
    * Return the column header cells for this cell.
    */
-  virtual void ColHeaderCells(nsTArray<Accessible*>* aCells) { }
+  virtual void ColHeaderCells(nsTArray<Accessible*>* aCells);
 
   /**
    * Return the row header cells for this cell.
    */
-  virtual void RowHeaderCells(nsTArray<Accessible*>* aCells) { }
+  virtual void RowHeaderCells(nsTArray<Accessible*>* aCells);
 
   /**
    * Returns true if this cell is selected.
    */
-  virtual bool Selected() { return false; }
+  virtual bool Selected() = 0;
 };
 
-}
-}
+} // namespace a11y
+} // namespace mozilla
 
 #endif // mozilla_a11y_TableCellAccessible_h__
--- a/accessible/src/html/HTMLTableAccessible.cpp
+++ b/accessible/src/html/HTMLTableAccessible.cpp
@@ -55,18 +55,18 @@ HTMLTableCellAccessible::
 
 NS_IMPL_ISUPPORTS_INHERITED1(HTMLTableCellAccessible,
                              HyperTextAccessible,
                              nsIAccessibleTableCell)
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableCellAccessible: Accessible implementation
 
-  void
-  HTMLTableCellAccessible::Shutdown()
+void
+HTMLTableCellAccessible::Shutdown()
 {
   mTableCell = nullptr;
   HyperTextAccessibleWrap::Shutdown();
 }
 
 role
 HTMLTableCellAccessible::NativeRole()
 {
@@ -98,30 +98,26 @@ HTMLTableCellAccessible::GetAttributesIn
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsresult rv = HyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // table-cell-index attribute
-  nsCOMPtr<nsIAccessibleTable> tableAcc(GetTableAccessible());
-  if (!tableAcc)
+  TableAccessible* table = Table();
+  if (!table)
     return NS_OK;
 
   int32_t rowIdx = -1, colIdx = -1;
   rv = GetCellIndexes(rowIdx, colIdx);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  int32_t idx = -1;
-  rv = tableAcc->GetCellIndexAt(rowIdx, colIdx, &idx);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsAutoString stringIdx;
-  stringIdx.AppendInt(idx);
+  stringIdx.AppendInt(table->CellIndexAt(rowIdx, colIdx));
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex, stringIdx);
 
   // abbr attribute
 
   // Pick up object attribute from abbr DOM element (a child of the cell) or
   // from abbr DOM attribute.
   nsAutoString abbrText;
   if (ChildCount() == 1) {
@@ -145,213 +141,133 @@ HTMLTableCellAccessible::GetAttributesIn
     nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::axis, axisText);
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableCellAccessible: nsIAccessibleTableCell implementation
 
-NS_IMETHODIMP
-HTMLTableCellAccessible::GetTable(nsIAccessibleTable** aTable)
+TableAccessible*
+HTMLTableCellAccessible::Table() const
 {
-  NS_ENSURE_ARG_POINTER(aTable);
-  *aTable = nullptr;
+  Accessible* parent = const_cast<HTMLTableCellAccessible*>(this);
+  while ((parent = parent->Parent())) {
+    roles::Role role = parent->Role();
+    if (role == roles::TABLE || role == roles::TREE_TABLE)
+      return parent->AsTable();
+  }
 
-  if (IsDefunct())
-    return NS_OK;
-
-  nsCOMPtr<nsIAccessibleTable> table = GetTableAccessible();
-  table.swap(*aTable);
-
-  return NS_OK;
+  return nullptr;
 }
 
-NS_IMETHODIMP
-HTMLTableCellAccessible::GetColumnIndex(int32_t* aColumnIndex)
+uint32_t
+HTMLTableCellAccessible::ColIdx() const
 {
-  NS_ENSURE_ARG_POINTER(aColumnIndex);
-  *aColumnIndex = -1;
+  nsITableCellLayout* cellLayout = GetCellLayout();
+  NS_ENSURE_TRUE(cellLayout, 0);
 
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsITableCellLayout* cellLayout = GetCellLayout();
-  NS_ENSURE_STATE(cellLayout);
-
-  return cellLayout->GetColIndex(*aColumnIndex);
+  int32_t colIdx = 0;
+  cellLayout->GetColIndex(colIdx);
+  return colIdx > 0 ? static_cast<uint32_t>(colIdx) : 0;
 }
 
-NS_IMETHODIMP
-HTMLTableCellAccessible::GetRowIndex(int32_t* aRowIndex)
+uint32_t
+HTMLTableCellAccessible::RowIdx() const
 {
-  NS_ENSURE_ARG_POINTER(aRowIndex);
-  *aRowIndex = -1;
+  nsITableCellLayout* cellLayout = GetCellLayout();
+  NS_ENSURE_TRUE(cellLayout, 0);
 
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsITableCellLayout* cellLayout = GetCellLayout();
-  NS_ENSURE_STATE(cellLayout);
-
-  return cellLayout->GetRowIndex(*aRowIndex);
+  int32_t rowIdx = 0;
+  cellLayout->GetRowIndex(rowIdx);
+  return rowIdx > 0 ? static_cast<uint32_t>(rowIdx) : 0;
 }
 
-NS_IMETHODIMP
-HTMLTableCellAccessible::GetColumnExtent(int32_t* aExtentCount)
+uint32_t
+HTMLTableCellAccessible::ColExtent() const
 {
-  NS_ENSURE_ARG_POINTER(aExtentCount);
-  *aExtentCount = 1;
-
   int32_t rowIdx = -1, colIdx = -1;
   GetCellIndexes(rowIdx, colIdx);
 
-  nsCOMPtr<nsIAccessibleTable> table = GetTableAccessible();
-  NS_ENSURE_STATE(table);
+  TableAccessible* table = Table();
+  NS_ASSERTION(table, "cell not in a table!");
+  if (!table)
+    return 0;
 
-  return table->GetColumnExtentAt(rowIdx, colIdx, aExtentCount);
+  return table->ColExtentAt(rowIdx, colIdx);
 }
 
-NS_IMETHODIMP
-HTMLTableCellAccessible::GetRowExtent(int32_t* aExtentCount)
+uint32_t
+HTMLTableCellAccessible::RowExtent() const
 {
-  NS_ENSURE_ARG_POINTER(aExtentCount);
-  *aExtentCount = 1;
-
   int32_t rowIdx = -1, colIdx = -1;
   GetCellIndexes(rowIdx, colIdx);
 
-  nsCOMPtr<nsIAccessibleTable> table = GetTableAccessible();
-  NS_ENSURE_STATE(table);
-
-  return table->GetRowExtentAt(rowIdx, colIdx, aExtentCount);
-}
+  TableAccessible* table = Table();
+  NS_ASSERTION(table, "cell not in atable!");
+  if (!table)
+    return 0;
 
-NS_IMETHODIMP
-HTMLTableCellAccessible::GetColumnHeaderCells(nsIArray** aHeaderCells)
-{
-  NS_ENSURE_ARG_POINTER(aHeaderCells);
-  *aHeaderCells = nullptr;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  return GetHeaderCells(nsAccUtils::eColumnHeaderCells, aHeaderCells);
+  return table->RowExtentAt(rowIdx, colIdx);
 }
 
-NS_IMETHODIMP
-HTMLTableCellAccessible::GetRowHeaderCells(nsIArray** aHeaderCells)
+void
+HTMLTableCellAccessible::ColHeaderCells(nsTArray<Accessible*>* aCells)
 {
-  NS_ENSURE_ARG_POINTER(aHeaderCells);
-  *aHeaderCells = nullptr;
+  IDRefsIterator itr(mDoc, mContent, nsGkAtoms::headers);
+  while (Accessible* cell = itr.Next())
+    if (cell->Role() == roles::COLUMNHEADER)
+      aCells->AppendElement(cell);
 
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  return GetHeaderCells(nsAccUtils::eRowHeaderCells, aHeaderCells);
+  if (aCells->IsEmpty())
+    TableCellAccessible::ColHeaderCells(aCells);
 }
 
-NS_IMETHODIMP
-HTMLTableCellAccessible::IsSelected(bool* aIsSelected)
+void
+HTMLTableCellAccessible::RowHeaderCells(nsTArray<Accessible*>* aCells)
 {
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
+  IDRefsIterator itr(mDoc, mContent, nsGkAtoms::headers);
+  while (Accessible* cell = itr.Next())
+    if (cell->Role() == roles::ROWHEADER)
+      aCells->AppendElement(cell);
 
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
+  if (aCells->IsEmpty())
+    TableCellAccessible::RowHeaderCells(aCells);
+}
 
+bool
+HTMLTableCellAccessible::Selected()
+{
   int32_t rowIdx = -1, colIdx = -1;
   GetCellIndexes(rowIdx, colIdx);
 
-  nsCOMPtr<nsIAccessibleTable> table = GetTableAccessible();
-  NS_ENSURE_STATE(table);
+  TableAccessible* table = Table();
+  NS_ENSURE_TRUE(table, false);
 
-  return table->IsCellSelected(rowIdx, colIdx, aIsSelected);
+  return table->IsCellSelected(rowIdx, colIdx);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableCellAccessible: protected implementation
 
-already_AddRefed<nsIAccessibleTable>
-HTMLTableCellAccessible::GetTableAccessible()
+nsITableCellLayout*
+HTMLTableCellAccessible::GetCellLayout() const
 {
-  Accessible* parent = this;
-  while ((parent = parent->Parent())) {
-    roles::Role role = parent->Role();
-    if (role == roles::TABLE || role == roles::TREE_TABLE) {
-      nsIAccessibleTable* tableAcc = nullptr;
-      CallQueryInterface(parent, &tableAcc);
-      return tableAcc;
-    }
-  }
-
-  return nullptr;
-}
-
-nsITableCellLayout*
-HTMLTableCellAccessible::GetCellLayout()
-{
-  nsIFrame *frame = mContent->GetPrimaryFrame();
-  NS_ASSERTION(frame, "The frame cannot be obtaied for HTML table cell.");
-  if (!frame)
-    return nullptr;
-
-  nsITableCellLayout *cellLayout = do_QueryFrame(frame);
-  return cellLayout;
+  return do_QueryFrame(mContent->GetPrimaryFrame());
 }
 
 nsresult
-HTMLTableCellAccessible::GetCellIndexes(int32_t& aRowIndex, int32_t& aColIndex)
+HTMLTableCellAccessible::GetCellIndexes(int32_t& aRowIdx, int32_t& aColIdx) const
 {
   nsITableCellLayout *cellLayout = GetCellLayout();
   NS_ENSURE_STATE(cellLayout);
 
-  return cellLayout->GetCellIndexes(aRowIndex, aColIndex);
+  return cellLayout->GetCellIndexes(aRowIdx, aColIdx);
 }
 
-nsresult
-HTMLTableCellAccessible::GetHeaderCells(int32_t aRowOrColumnHeaderCell,
-                                        nsIArray** aHeaderCells)
-{
-  // Get header cells from @header attribute.
-  IDRefsIterator iter(mDoc, mContent, nsGkAtoms::headers);
-  nsIContent* headerCellElm = iter.NextElem();
-  if (headerCellElm) {
-    nsresult rv = NS_OK;
-    nsCOMPtr<nsIMutableArray> headerCells =
-      do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-    roles::Role desiredRole = static_cast<roles::Role>(-1) ;
-    if (aRowOrColumnHeaderCell == nsAccUtils::eRowHeaderCells)
-      desiredRole = roles::ROWHEADER;
-    else if (aRowOrColumnHeaderCell == nsAccUtils::eColumnHeaderCells)
-      desiredRole = roles::COLUMNHEADER;
-
-    do {
-      Accessible* headerCell = mDoc->GetAccessible(headerCellElm);
-
-      if (headerCell && headerCell->Role() == desiredRole)
-        headerCells->AppendElement(static_cast<nsIAccessible*>(headerCell),
-                                   false);
-    } while ((headerCellElm = iter.NextElem()));
-
-    NS_ADDREF(*aHeaderCells = headerCells);
-    return NS_OK;
-  }
-
-  // Otherwise calculate header cells from hierarchy (see 11.4.3 "Algorithm to
-  // find heading information" of w3c HTML 4.01).
-  nsCOMPtr<nsIAccessibleTable> table = GetTableAccessible();
-  if (table) {
-    return nsAccUtils::GetHeaderCellsFor(table, this, aRowOrColumnHeaderCell,
-                                         aHeaderCells);
-  }
-
-  return NS_OK;
-}
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableHeaderCellAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 HTMLTableHeaderCellAccessible::
   HTMLTableHeaderCellAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   HTMLTableCellAccessible(aContent, aDoc)
--- a/accessible/src/html/HTMLTableAccessible.h
+++ b/accessible/src/html/HTMLTableAccessible.h
@@ -29,46 +29,51 @@ class HTMLTableCellAccessible : public H
 {
 public:
   HTMLTableCellAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessibleTableCell
-  NS_DECL_OR_FORWARD_NSIACCESSIBLETABLECELL_WITH_XPCACCESSIBLETABLECELL
+  NS_FORWARD_NSIACCESSIBLETABLECELL(xpcAccessibleTableCell::)
 
   // Accessible
+  virtual TableCellAccessible* AsTableCell() { return this; }
   virtual void Shutdown();
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
 
+  // TableCellAccessible
+  virtual TableAccessible* Table() const MOZ_OVERRIDE;
+  virtual uint32_t ColIdx() const MOZ_OVERRIDE;
+  virtual uint32_t RowIdx() const MOZ_OVERRIDE;
+  virtual uint32_t ColExtent() const MOZ_OVERRIDE;
+  virtual uint32_t RowExtent() const MOZ_OVERRIDE;
+  virtual void ColHeaderCells(nsTArray<Accessible*>* aCells) MOZ_OVERRIDE;
+  virtual void RowHeaderCells(nsTArray<Accessible*>* aCells) MOZ_OVERRIDE;
+  virtual bool Selected() MOZ_OVERRIDE;
+
 protected:
   /**
    * Return host table accessible.
    */
   already_AddRefed<nsIAccessibleTable> GetTableAccessible();
 
   /**
    * Return nsITableCellLayout of the table cell frame.
    */
-  nsITableCellLayout* GetCellLayout();
+  nsITableCellLayout* GetCellLayout() const;
 
   /**
    * Return row and column indices of the cell.
    */
-  nsresult GetCellIndexes(int32_t& aRowIdx, int32_t& aColIdx);
-
-  /**
-   * Return an array of row or column header cells.
-   */
-  nsresult GetHeaderCells(int32_t aRowOrColumnHeaderCell,
-                          nsIArray **aHeaderCells);
+  nsresult GetCellIndexes(int32_t& aRowIdx, int32_t& aColIdx) const;
 };
 
 
 /**
  * HTML table row/column header accessible (html:th or html:td@scope).
  */
 class HTMLTableHeaderCellAccessible : public HTMLTableCellAccessible
 {
@@ -125,16 +130,17 @@ public:
   virtual void SelectedCellIndices(nsTArray<uint32_t>* aCells);
   virtual void SelectedColIndices(nsTArray<uint32_t>* aCols);
   virtual void SelectedRowIndices(nsTArray<uint32_t>* aRows);
   virtual void SelectCol(uint32_t aColIdx);
   virtual void SelectRow(uint32_t aRowIdx);
   virtual void UnselectCol(uint32_t aColIdx);
   virtual void UnselectRow(uint32_t aRowIdx);
   virtual bool IsProbablyLayoutTable();
+  virtual Accessible* AsAccessible() { return this; }
 
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
   virtual TableAccessible* AsTable() { return this; }
   virtual void Description(nsString& aDescription);
   virtual nsresult GetNameInternal(nsAString& aName);
--- a/accessible/src/msaa/TextLeafAccessibleWrap.cpp
+++ b/accessible/src/msaa/TextLeafAccessibleWrap.cpp
@@ -132,19 +132,19 @@ TextLeafAccessibleWrap::get_unclippedSub
     /* [out] */ int __RPC_FAR *aHeight)
 {
 __try {
   *aX = *aY = *aWidth = *aHeight = 0;
 
   if (IsDefunct())
     return E_FAIL;
 
-  if (NS_FAILED(GetCharacterExtents(aStartIndex, aEndIndex, 
-                                    aX, aY, aWidth, aHeight))) {
-    return NS_ERROR_FAILURE;
+  if (FAILED(GetCharacterExtents(aStartIndex, aEndIndex,
+                                 aX, aY, aWidth, aHeight))) {
+    return E_FAIL;
   }
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return S_OK;
 }
 
 STDMETHODIMP
 TextLeafAccessibleWrap::scrollToSubstring(
@@ -186,33 +186,33 @@ TextLeafAccessibleWrap::GetPointFromOffs
 
   textFrame->GetPointFromOffset(aOffset, &aOutPoint);
   return textFrame;
 }
 
 /*
  * Given an offset, the x, y, width, and height values are filled appropriately.
  */
-nsresult
+HRESULT
 TextLeafAccessibleWrap::GetCharacterExtents(int32_t aStartOffset,
                                             int32_t aEndOffset,
                                             int32_t* aX,
                                             int32_t* aY,
                                             int32_t* aWidth,
                                             int32_t* aHeight)
 {
   *aX = *aY = *aWidth = *aHeight = 0;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsPresContext* presContext = mDoc->PresContext();
 
   nsIFrame *frame = GetFrame();
-  NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(frame, E_FAIL);
 
   nsPoint startPoint, endPoint;
   nsIFrame *startFrame = GetPointFromOffset(frame, aStartOffset, true, startPoint);
   nsIFrame *endFrame = GetPointFromOffset(frame, aEndOffset, false, endPoint);
   if (!startFrame || !endFrame) {
     return E_FAIL;
   }
   
@@ -229,17 +229,17 @@ TextLeafAccessibleWrap::GetCharacterExte
     sum.UnionRect(sum, rect);
   }
 
   *aX      = sum.x;
   *aY      = sum.y;
   *aWidth  = sum.width;
   *aHeight = sum.height;
 
-  return NS_OK;
+  return S_OK;
 }
 
 STDMETHODIMP
 TextLeafAccessibleWrap::get_fontFamily(
     /* [retval][out] */ BSTR __RPC_FAR *aFontFamily)
 {
 __try {
   *aFontFamily = NULL;
--- a/accessible/src/msaa/TextLeafAccessibleWrap.h
+++ b/accessible/src/msaa/TextLeafAccessibleWrap.h
@@ -50,19 +50,19 @@ public:
     virtual HRESULT STDMETHODCALLTYPE scrollToSubstring( 
         /* [in] */ unsigned int startIndex,
         /* [in] */ unsigned int endIndex);
 
     virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_fontFamily( 
         /* [retval][out] */ BSTR __RPC_FAR *fontFamily);
     
   protected:
-    nsresult GetCharacterExtents(int32_t aStartOffset, int32_t aEndOffset,
-                                 int32_t* aX, int32_t* aY, 
-                                 int32_t* aWidth, int32_t* aHeight);
+    HRESULT GetCharacterExtents(int32_t aStartOffset, int32_t aEndOffset,
+                                int32_t* aX, int32_t* aY,
+                                int32_t* aWidth, int32_t* aHeight);
 
     // Return child frame containing offset on success
     nsIFrame* GetPointFromOffset(nsIFrame *aContainingFrame,
                                  int32_t aOffset, bool aPreferNext, nsPoint& aOutPoint);
 };
 
 } // namespace a11y
 } // namespace mozilla
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -51,17 +51,18 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsAccessNod
 
 //-----------------------------------------------------
 // nsIWinAccessNode methods
 //-----------------------------------------------------
 
 NS_IMETHODIMP
 nsAccessNodeWrap::QueryNativeInterface(REFIID aIID, void** aInstancePtr)
 {
-  return QueryInterface(aIID, aInstancePtr);
+  // XXX Wrong for E_NOINTERFACE
+  return static_cast<nsresult>(QueryInterface(aIID, aInstancePtr));
 }
 
 //-----------------------------------------------------
 // IUnknown interface methods - see iunknown.h for documentation
 //-----------------------------------------------------
 
 STDMETHODIMP nsAccessNodeWrap::QueryInterface(REFIID iid, void** ppv)
 {
--- a/accessible/src/xpcom/Makefile.in
+++ b/accessible/src/xpcom/Makefile.in
@@ -13,16 +13,17 @@ include $(DEPTH)/config/autoconf.mk
 MODULE = accessibility
 LIBRARY_NAME = accessibility_xpcom_s
 LIBXUL_LIBRARY = 1
 
 CPPSRCS = \
   nsAccEvent.cpp \
   nsAccessibleRelation.cpp \
   xpcAccessibleTable.cpp \
+  xpcAccessibleTableCell.cpp \
   $(NULL)
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES = \
new file mode 100644
--- /dev/null
+++ b/accessible/src/xpcom/xpcAccessibleTableCell.cpp
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "xpcAccessibleTableCell.h"
+
+#include "Accessible.h"
+#include "TableAccessible.h"
+#include "TableCellAccessible.h"
+
+#include "nsIAccessibleTable.h"
+
+#include "nsComponentManagerUtils.h"
+#include "nsIMutableArray.h"
+
+using namespace mozilla;
+using namespace mozilla::a11y;
+
+nsresult
+xpcAccessibleTableCell::GetTable(nsIAccessibleTable** aTable)
+{
+  NS_ENSURE_ARG_POINTER(aTable);
+  *aTable = nullptr;
+
+  if (!mTableCell)
+    return NS_ERROR_FAILURE;
+
+  TableAccessible* table = mTableCell->Table();
+  if (!table)
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIAccessibleTable> xpcTable =
+    do_QueryInterface(static_cast<nsIAccessible*>(table->AsAccessible()));
+  xpcTable.forget(aTable);
+
+  return NS_OK;
+}
+
+nsresult
+xpcAccessibleTableCell::GetColumnIndex(int32_t* aColIdx)
+{
+  NS_ENSURE_ARG_POINTER(aColIdx);
+  *aColIdx = -1;
+
+  if (!mTableCell)
+    return NS_ERROR_FAILURE;
+
+  *aColIdx = mTableCell->ColIdx();
+  return NS_OK;
+}
+
+nsresult
+xpcAccessibleTableCell::GetRowIndex(int32_t* aRowIdx)
+{
+  NS_ENSURE_ARG_POINTER(aRowIdx);
+  *aRowIdx = -1;
+
+  if (!mTableCell)
+    return NS_ERROR_FAILURE;
+
+  *aRowIdx = mTableCell->RowIdx();
+
+  return NS_OK;
+}
+
+nsresult
+xpcAccessibleTableCell::GetColumnExtent(int32_t* aExtent)
+{
+  NS_ENSURE_ARG_POINTER(aExtent);
+  *aExtent = -1;
+
+  if (!mTableCell)
+    return NS_ERROR_FAILURE;
+
+  *aExtent = mTableCell->ColExtent();
+
+  return NS_OK;
+}
+
+nsresult
+xpcAccessibleTableCell::GetRowExtent(int32_t* aExtent)
+{
+  NS_ENSURE_ARG_POINTER(aExtent);
+  *aExtent = -1;
+
+  if (!mTableCell)
+    return NS_ERROR_FAILURE;
+
+  *aExtent = mTableCell->RowExtent();
+
+  return NS_OK;
+}
+
+nsresult
+xpcAccessibleTableCell::GetColumnHeaderCells(nsIArray** aHeaderCells)
+{
+  NS_ENSURE_ARG_POINTER(aHeaderCells);
+  *aHeaderCells = nullptr;
+
+  if (!mTableCell)
+    return NS_ERROR_FAILURE;
+
+  nsAutoTArray<Accessible*, 10> headerCells;
+  mTableCell->ColHeaderCells(&headerCells);
+
+  nsCOMPtr<nsIMutableArray> cells = do_CreateInstance(NS_ARRAY_CONTRACTID);
+  NS_ENSURE_TRUE(cells, NS_ERROR_FAILURE);
+
+  for (uint32_t idx = 0; idx < headerCells.Length(); idx++) {
+    cells->
+      AppendElement(static_cast<nsIAccessible*>(headerCells.ElementAt(idx)),
+                    false);
+  }
+
+  NS_ADDREF(*aHeaderCells = cells);
+  return NS_OK;
+}
+
+nsresult
+xpcAccessibleTableCell::GetRowHeaderCells(nsIArray** aHeaderCells)
+{
+  NS_ENSURE_ARG_POINTER(aHeaderCells);
+  *aHeaderCells = nullptr;
+
+  if (!mTableCell)
+    return NS_ERROR_FAILURE;
+
+  nsAutoTArray<Accessible*, 10> headerCells;
+  mTableCell->RowHeaderCells(&headerCells);
+
+  nsCOMPtr<nsIMutableArray> cells = do_CreateInstance(NS_ARRAY_CONTRACTID);
+  NS_ENSURE_TRUE(cells, NS_ERROR_FAILURE);
+
+  for (uint32_t idx = 0; idx < headerCells.Length(); idx++) {
+    cells->
+      AppendElement(static_cast<nsIAccessible*>(headerCells.ElementAt(idx)),
+                    false);
+  }
+
+  NS_ADDREF(*aHeaderCells = cells);
+  return NS_OK;
+}
+
+nsresult
+xpcAccessibleTableCell::IsSelected(bool* aSelected)
+{
+  NS_ENSURE_ARG_POINTER(aSelected);
+  *aSelected = false;
+
+  if (!mTableCell)
+    return NS_ERROR_FAILURE;
+
+  *aSelected = mTableCell->Selected();
+
+  return NS_OK;
+}
--- a/accessible/src/xpcom/xpcAccessibleTableCell.h
+++ b/accessible/src/xpcom/xpcAccessibleTableCell.h
@@ -1,37 +1,46 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef MOZILLA_A11Y_XPCOM_XPACESSIBLETABLECELL_H_
-#define MOZILLA_A11Y_XPCOM_XPACESSIBLETABLECELL_H_
+#ifndef mozilla_a11y_xpcom_xpcAccessibletableCell_h_
+#define mozilla_a11y_xpcom_xpcAccessibletableCell_h_
+
+#include "nscore.h"
+
+class nsIAccessibleTable;
+class nsIArray;
 
 namespace mozilla {
 namespace a11y {
+
 class TableAccessible;
 class TableCellAccessible;
-}
-}
 
+/**
+ * This class provides an implementation of the nsIAccessibleTableCell
+ * interface's methods.
+ */
 class xpcAccessibleTableCell
 {
 public:
   xpcAccessibleTableCell(mozilla::a11y::TableCellAccessible* aTableCell) :
     mTableCell(aTableCell) { }
 
+  nsresult GetTable(nsIAccessibleTable** aTable);
+  nsresult GetColumnIndex(int32_t* aColIdx);
+  nsresult GetRowIndex(int32_t* aRowIdx);
+  nsresult GetColumnExtent(int32_t* aExtent);
+  nsresult GetRowExtent(int32_t* aExtent);
+  nsresult GetColumnHeaderCells(nsIArray** aHeaderCells);
+  nsresult GetRowHeaderCells(nsIArray** aHeaderCells);
+  nsresult IsSelected(bool* aSelected);
+
 protected:
   mozilla::a11y::TableCellAccessible* mTableCell;
 };
+} // namespace a11y
+} // namespace mozilla
 
-#define NS_DECL_OR_FORWARD_NSIACCESSIBLETABLECELL_WITH_XPCACCESSIBLETABLECELL \
-  NS_IMETHOD GetTable(nsIAccessibleTable * *aTable); \
-  NS_IMETHOD GetColumnIndex(int32_t *aColumnIndex); \
-  NS_IMETHOD GetRowIndex(int32_t *aRowIndex); \
-  NS_IMETHOD GetColumnExtent(int32_t *aColumnExtent); \
-  NS_IMETHOD GetRowExtent(int32_t *aRowExtent); \
-  NS_IMETHOD GetColumnHeaderCells(nsIArray * *aColumnHeaderCells); \
-  NS_IMETHOD GetRowHeaderCells(nsIArray * *aRowHeaderCells); \
-  NS_IMETHOD IsSelected(bool *_retval ); 
-
-#endif // MOZILLA_A11Y_XPCOM_XPACESSIBLETABLECELL_H_
+#endif // mozilla_a11y_xpcom_xpcAccessibletableCell_h_
--- a/accessible/src/xul/XULListboxAccessible.cpp
+++ b/accessible/src/xul/XULListboxAccessible.cpp
@@ -737,204 +737,112 @@ XULListCellAccessible::
 
 NS_IMPL_ISUPPORTS_INHERITED1(XULListCellAccessible,
                              HyperTextAccessible,
                              nsIAccessibleTableCell)
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULListCellAccessible: nsIAccessibleTableCell implementation
 
-NS_IMETHODIMP
-XULListCellAccessible::GetTable(nsIAccessibleTable** aTable)
+TableAccessible*
+XULListCellAccessible::Table() const
 {
-  NS_ENSURE_ARG_POINTER(aTable);
-  *aTable = nullptr;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
   Accessible* thisRow = Parent();
   if (!thisRow || thisRow->Role() != roles::ROW)
-    return NS_OK;
+    return nullptr;
 
   Accessible* table = thisRow->Parent();
   if (!table || table->Role() != roles::TABLE)
-    return NS_OK;
+    return nullptr;
 
-  CallQueryInterface(table, aTable);
-  return NS_OK;
+  return table->AsTable();
 }
 
-NS_IMETHODIMP
-XULListCellAccessible::GetColumnIndex(int32_t* aColumnIndex)
+uint32_t
+XULListCellAccessible::ColIdx() const
 {
-  NS_ENSURE_ARG_POINTER(aColumnIndex);
-  *aColumnIndex = -1;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
   Accessible* row = Parent();
   if (!row)
-    return NS_OK;
-
-  *aColumnIndex = 0;
+    return 0;
 
   int32_t indexInRow = IndexInParent();
+  uint32_t colIdx = 0;
   for (int32_t idx = 0; idx < indexInRow; idx++) {
     Accessible* cell = row->GetChildAt(idx);
     roles::Role role = cell->Role();
     if (role == roles::CELL || role == roles::GRID_CELL ||
         role == roles::ROWHEADER || role == roles::COLUMNHEADER)
-      (*aColumnIndex)++;
+      colIdx++;
   }
 
-  return NS_OK;
+  return colIdx;
 }
 
-NS_IMETHODIMP
-XULListCellAccessible::GetRowIndex(int32_t* aRowIndex)
+uint32_t
+XULListCellAccessible::RowIdx() const
 {
-  NS_ENSURE_ARG_POINTER(aRowIndex);
-  *aRowIndex = -1;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
   Accessible* row = Parent();
   if (!row)
-    return NS_OK;
+    return 0;
 
   Accessible* table = row->Parent();
   if (!table)
-    return NS_OK;
-
-  *aRowIndex = 0;
+    return 0;
 
   int32_t indexInTable = row->IndexInParent();
+  uint32_t rowIdx = 0;
   for (int32_t idx = 0; idx < indexInTable; idx++) {
     row = table->GetChildAt(idx);
     if (row->Role() == roles::ROW)
-      (*aRowIndex)++;
+      rowIdx++;
   }
 
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-XULListCellAccessible::GetColumnExtent(int32_t* aExtentCount)
-{
-  NS_ENSURE_ARG_POINTER(aExtentCount);
-  *aExtentCount = 0;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  *aExtentCount = 1;
-  return NS_OK;
+  return rowIdx;
 }
 
-NS_IMETHODIMP
-XULListCellAccessible::GetRowExtent(int32_t* aExtentCount)
+void
+XULListCellAccessible::ColHeaderCells(nsTArray<Accessible*>* aCells)
 {
-  NS_ENSURE_ARG_POINTER(aExtentCount);
-  *aExtentCount = 0;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  *aExtentCount = 1;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-XULListCellAccessible::GetColumnHeaderCells(nsIArray** aHeaderCells)
-{
-  NS_ENSURE_ARG_POINTER(aHeaderCells);
-  *aHeaderCells = nullptr;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIAccessibleTable> table;
-  GetTable(getter_AddRefs(table));
-  NS_ENSURE_STATE(table); // we expect to be in a listbox (table)
+  TableAccessible* table = Table();
+  NS_ASSERTION(table, "cell not in a table!");
+  if (!table)
+    return;
 
   // Get column header cell from XUL listhead.
   Accessible* list = nullptr;
 
-  nsRefPtr<Accessible> tableAcc(do_QueryObject(table));
+  Accessible* tableAcc = table->AsAccessible();
   uint32_t tableChildCount = tableAcc->ChildCount();
   for (uint32_t childIdx = 0; childIdx < tableChildCount; childIdx++) {
     Accessible* child = tableAcc->GetChildAt(childIdx);
     if (child->Role() == roles::LIST) {
       list = child;
       break;
     }
   }
 
   if (list) {
-    int32_t colIdx = -1;
-    GetColumnIndex(&colIdx);
-
-    nsIAccessible *headerCell = list->GetChildAt(colIdx);
+    Accessible* headerCell = list->GetChildAt(ColIdx());
     if (headerCell) {
-      nsresult rv = NS_OK;
-      nsCOMPtr<nsIMutableArray> headerCells =
-        do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      headerCells->AppendElement(headerCell, false);
-      NS_ADDREF(*aHeaderCells = headerCells);
-      return NS_OK;
+      aCells->AppendElement(headerCell);
+      return;
     }
   }
 
   // No column header cell from XUL markup, try to get it from ARIA markup.
-  return nsAccUtils::GetHeaderCellsFor(table, this,
-                                       nsAccUtils::eColumnHeaderCells,
-                                       aHeaderCells);
+  TableCellAccessible::ColHeaderCells(aCells);
 }
 
-NS_IMETHODIMP
-XULListCellAccessible::GetRowHeaderCells(nsIArray** aHeaderCells)
+bool
+XULListCellAccessible::Selected()
 {
-  NS_ENSURE_ARG_POINTER(aHeaderCells);
-  *aHeaderCells = nullptr;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIAccessibleTable> table;
-  GetTable(getter_AddRefs(table));
-  NS_ENSURE_STATE(table); // we expect to be in a listbox (table)
+  TableAccessible* table = Table();
+  NS_ENSURE_TRUE(table, false); // we expect to be in a listbox (table)
 
-  // Calculate row header cells from ARIA markup.
-  return nsAccUtils::GetHeaderCellsFor(table, this,
-                                       nsAccUtils::eRowHeaderCells,
-                                       aHeaderCells);
-}
-
-NS_IMETHODIMP
-XULListCellAccessible::IsSelected(bool* aIsSelected)
-{
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIAccessibleTable> table;
-  GetTable(getter_AddRefs(table));
-  NS_ENSURE_STATE(table); // we expect to be in a listbox (table)
-
-  int32_t rowIdx = -1;
-  GetRowIndex(&rowIdx);
-
-  return table->IsRowSelected(rowIdx, aIsSelected);
+  return table->IsRowSelected(RowIdx());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULListCellAccessible. Accessible implementation
 
 void
 XULListCellAccessible::Shutdown()
 {
@@ -952,27 +860,18 @@ nsresult
 XULListCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
 {
   NS_ENSURE_ARG_POINTER(aAttributes);
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   // "table-cell-index" attribute
-  nsCOMPtr<nsIAccessibleTable> table;
-  GetTable(getter_AddRefs(table));
+  TableAccessible* table = Table();
   NS_ENSURE_STATE(table); // we expect to be in a listbox (table)
 
-  int32_t rowIdx = -1;
-  GetRowIndex(&rowIdx);
-  int32_t colIdx = -1;
-  GetColumnIndex(&colIdx);
-
-  int32_t cellIdx = -1;
-  table->GetCellIndexAt(rowIdx, colIdx, &cellIdx);
-
   nsAutoString stringIdx;
-  stringIdx.AppendInt(cellIdx);
+  stringIdx.AppendInt(table->CellIndexAt(RowIdx(), ColIdx()));
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex,
                          stringIdx);
 
   return NS_OK;
 }
--- a/accessible/src/xul/XULListboxAccessible.h
+++ b/accessible/src/xul/XULListboxAccessible.h
@@ -85,16 +85,17 @@ public:
   virtual uint32_t SelectedColCount();
   virtual uint32_t SelectedRowCount();
   virtual void SelectedCells(nsTArray<Accessible*>* aCells);
   virtual void SelectedCellIndices(nsTArray<uint32_t>* aCells);
   virtual void SelectedColIndices(nsTArray<uint32_t>* aCols);
   virtual void SelectedRowIndices(nsTArray<uint32_t>* aRows);
   virtual void SelectRow(uint32_t aRowIdx);
   virtual void UnselectRow(uint32_t aRowIdx);
+  virtual Accessible* AsAccessible() { return this; }
 
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
   virtual void Value(nsString& aValue);
   virtual TableAccessible* AsTable() { return this; }
   virtual a11y::role NativeRole();
@@ -159,20 +160,28 @@ class XULListCellAccessible : public Hyp
 {
 public:
   XULListCellAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessibleTableCell
-  NS_DECL_OR_FORWARD_NSIACCESSIBLETABLECELL_WITH_XPCACCESSIBLETABLECELL
+  NS_FORWARD_NSIACCESSIBLETABLECELL(xpcAccessibleTableCell::)
 
   // Accessible
+  virtual TableCellAccessible* AsTableCell() { return this; }
   virtual void Shutdown();
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
   virtual a11y::role NativeRole();
+
+  // TableCellAccessible
+  virtual TableAccessible* Table() const MOZ_OVERRIDE;
+  virtual uint32_t ColIdx() const MOZ_OVERRIDE;
+  virtual uint32_t RowIdx() const MOZ_OVERRIDE;
+  virtual void ColHeaderCells(nsTArray<Accessible*>* aHeaderCells) MOZ_OVERRIDE;
+  virtual bool Selected() MOZ_OVERRIDE;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/xul/XULTreeGridAccessible.cpp
+++ b/accessible/src/xul/XULTreeGridAccessible.cpp
@@ -495,18 +495,18 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION
                                 XULTreeGridCellAccessible)
 NS_INTERFACE_TABLE_TAIL_INHERITING(LeafAccessible)
 NS_IMPL_ADDREF_INHERITED(XULTreeGridCellAccessible, LeafAccessible)
 NS_IMPL_RELEASE_INHERITED(XULTreeGridCellAccessible, LeafAccessible)
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridCellAccessible: nsIAccessible implementation
 
-  void
-  XULTreeGridCellAccessible::Shutdown()
+void
+XULTreeGridCellAccessible::Shutdown()
 {
   mTableCell = nullptr;
   LeafAccessible::Shutdown();
 }
 
 Accessible*
 XULTreeGridCellAccessible::FocusedChild()
 {
@@ -650,136 +650,65 @@ XULTreeGridCellAccessible::DoAction(uint
   }
 
   return NS_ERROR_INVALID_ARG;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridCellAccessible: nsIAccessibleTableCell implementation
 
-NS_IMETHODIMP
-XULTreeGridCellAccessible::GetTable(nsIAccessibleTable** aTable)
+TableAccessible*
+XULTreeGridCellAccessible::Table() const
 {
-  NS_ENSURE_ARG_POINTER(aTable);
-  *aTable = nullptr;
-
-  if (IsDefunct())
-    return NS_OK;
-
   Accessible* grandParent = mParent->Parent();
   if (grandParent)
-    CallQueryInterface(grandParent, aTable);
-
-  return NS_OK;
-}
+    return grandParent->AsTable();
 
-NS_IMETHODIMP
-XULTreeGridCellAccessible::GetColumnIndex(int32_t* aColumnIndex)
-{
-  NS_ENSURE_ARG_POINTER(aColumnIndex);
-  *aColumnIndex = -1;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  *aColumnIndex = GetColumnIndex();
-  return NS_OK;
+  return nullptr;
 }
 
-NS_IMETHODIMP
-XULTreeGridCellAccessible::GetRowIndex(int32_t* aRowIndex)
+uint32_t
+XULTreeGridCellAccessible::ColIdx() const
 {
-  NS_ENSURE_ARG_POINTER(aRowIndex);
-  *aRowIndex = -1;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
+  uint32_t colIdx = 0;
+  nsCOMPtr<nsITreeColumn> column = mColumn;
+  while ((column = nsCoreUtils::GetPreviousSensibleColumn(column)))
+    colIdx++;
 
-  *aRowIndex = mRow;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-XULTreeGridCellAccessible::GetColumnExtent(int32_t* aExtentCount)
-{
-  NS_ENSURE_ARG_POINTER(aExtentCount);
-  *aExtentCount = 1;
-
-  return NS_OK;
+  return colIdx;
 }
 
-NS_IMETHODIMP
-XULTreeGridCellAccessible::GetRowExtent(int32_t* aExtentCount)
+uint32_t
+XULTreeGridCellAccessible::RowIdx() const
 {
-  NS_ENSURE_ARG_POINTER(aExtentCount);
-  *aExtentCount = 1;
-
-  return NS_OK;
+  return mRow;
 }
 
-NS_IMETHODIMP
-XULTreeGridCellAccessible::GetColumnHeaderCells(nsIArray** aHeaderCells)
+void
+XULTreeGridCellAccessible::ColHeaderCells(nsTArray<Accessible*>* aHeaderCells)
 {
-  NS_ENSURE_ARG_POINTER(aHeaderCells);
-  *aHeaderCells = nullptr;
-
-  if (IsDefunct() || !mDoc)
-    return NS_ERROR_FAILURE;
-
-  nsresult rv = NS_OK;
-  nsCOMPtr<nsIMutableArray> headerCells =
-    do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsCOMPtr<nsIDOMElement> columnElm;
   mColumn->GetElement(getter_AddRefs(columnElm));
 
   nsCOMPtr<nsIContent> columnContent(do_QueryInterface(columnElm));
   Accessible* headerCell = mDoc->GetAccessible(columnContent);
-
   if (headerCell)
-    headerCells->AppendElement(static_cast<nsIAccessible*>(headerCell),
-                               false);
-
-  NS_ADDREF(*aHeaderCells = headerCells);
-  return NS_OK;
+    aHeaderCells->AppendElement(headerCell);
 }
 
-NS_IMETHODIMP
-XULTreeGridCellAccessible::GetRowHeaderCells(nsIArray** aHeaderCells)
+bool
+XULTreeGridCellAccessible::Selected()
 {
-  NS_ENSURE_ARG_POINTER(aHeaderCells);
-  *aHeaderCells = nullptr;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsresult rv = NS_OK;
-  nsCOMPtr<nsIMutableArray> headerCells =
-    do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  NS_ADDREF(*aHeaderCells = headerCells);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-XULTreeGridCellAccessible::IsSelected(bool* aIsSelected)
-{
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
-
-  if (IsDefunct() || !mTreeView)
-    return NS_ERROR_FAILURE;
-
   nsCOMPtr<nsITreeSelection> selection;
   nsresult rv = mTreeView->GetSelection(getter_AddRefs(selection));
-  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_SUCCESS(rv, false);
 
-  return selection->IsSelected(mRow, aIsSelected);
+  bool selected = false;
+  selection->IsSelected(mRow, &selected);
+  return selected;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridCellAccessible: nsAccessNode implementation
 
 void
 XULTreeGridCellAccessible::Init()
 {
@@ -802,35 +731,23 @@ nsresult
 XULTreeGridCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
 {
   NS_ENSURE_ARG_POINTER(aAttributes);
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   // "table-cell-index" attribute
-  Accessible* grandParent = mParent->Parent();
-  if (!grandParent)
-    return NS_OK;
-
-  nsCOMPtr<nsIAccessibleTable> tableAccessible = do_QueryObject(grandParent);
-
-  // XXX - temp fix for crash bug 516047
-  if (!tableAccessible)
+  TableAccessible* table = Table();
+  if (!table)
     return NS_ERROR_FAILURE;
 
-  int32_t colIdx = GetColumnIndex();
-
-  int32_t cellIdx = -1;
-  tableAccessible->GetCellIndexAt(mRow, colIdx, &cellIdx);
-
   nsAutoString stringIdx;
-  stringIdx.AppendInt(cellIdx);
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex,
-                         stringIdx);
+  stringIdx.AppendInt(table->CellIndexAt(mRow, ColIdx()));
+  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex, stringIdx);
 
   // "cycles" attribute
   bool isCycler = false;
   nsresult rv = mColumn->GetCycler(&isCycler);
   if (NS_SUCCEEDED(rv) && isCycler)
     nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::cycles,
                            NS_LITERAL_STRING("true"));
 
@@ -879,43 +796,28 @@ uint64_t
 XULTreeGridCellAccessible::NativeInteractiveState() const
 {
   return states::SELECTABLE;
 }
 
 int32_t
 XULTreeGridCellAccessible::IndexInParent() const
 {
-  return GetColumnIndex();
+  return ColIdx();
 }
 
 Relation
 XULTreeGridCellAccessible::RelationByType(uint32_t aType)
 {
   return Relation();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridCellAccessible: public implementation
 
-int32_t
-XULTreeGridCellAccessible::GetColumnIndex() const
-{
-  int32_t index = 0;
-  nsCOMPtr<nsITreeColumn> column = mColumn;
-  while (true) {
-    column = nsCoreUtils::GetPreviousSensibleColumn(column);
-    if (!column)
-      break;
-    index++;
-  }
-
-  return index;
-}
-
 void
 XULTreeGridCellAccessible::CellInvalidated()
 {
   if (!mTreeView)
     return;
 
   nsAutoString textEquiv;
 
--- a/accessible/src/xul/XULTreeGridAccessible.h
+++ b/accessible/src/xul/XULTreeGridAccessible.h
@@ -44,16 +44,17 @@ public:
   virtual uint32_t SelectedColCount();
   virtual uint32_t SelectedRowCount();
   virtual void SelectedCells(nsTArray<Accessible*>* aCells);
   virtual void SelectedCellIndices(nsTArray<uint32_t>* aCells);
   virtual void SelectedColIndices(nsTArray<uint32_t>* aCols);
   virtual void SelectedRowIndices(nsTArray<uint32_t>* aRows);
   virtual void SelectRow(uint32_t aRowIdx);
   virtual void UnselectRow(uint32_t aRowIdx);
+  virtual Accessible* AsAccessible() { return this; }
 
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
   virtual TableAccessible* AsTable() { return this; }
   virtual a11y::role NativeRole();
 
@@ -142,44 +143,48 @@ public:
 
   NS_IMETHOD GetBounds(int32_t* aX, int32_t* aY,
                        int32_t* aWidth, int32_t* aHeight);
 
   NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
   NS_IMETHOD DoAction(uint8_t aIndex);
 
   // nsIAccessibleTableCell
-  NS_DECL_OR_FORWARD_NSIACCESSIBLETABLECELL_WITH_XPCACCESSIBLETABLECELL
+  NS_FORWARD_NSIACCESSIBLETABLECELL(xpcAccessibleTableCell::)
 
   // nsAccessNode
   virtual void Init();
 
   // Accessible
+  virtual TableCellAccessible* AsTableCell() { return this; }
   virtual void Shutdown();
   virtual ENameValueFlag Name(nsString& aName);
   virtual Accessible* FocusedChild();
   virtual nsresult GetAttributesInternal(nsIPersistentProperties* aAttributes);
   virtual int32_t IndexInParent() const;
   virtual Relation RelationByType(uint32_t aType);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 
+  // TableCellAccessible
+  virtual TableAccessible* Table() const MOZ_OVERRIDE;
+  virtual uint32_t ColIdx() const MOZ_OVERRIDE;
+  virtual uint32_t RowIdx() const MOZ_OVERRIDE;
+  virtual void ColHeaderCells(nsTArray<Accessible*>* aHeaderCells) MOZ_OVERRIDE;
+  virtual void RowHeaderCells(nsTArray<Accessible*>* aCells) MOZ_OVERRIDE { }
+  virtual bool Selected() MOZ_OVERRIDE;
+
   // XULTreeGridCellAccessible
   NS_DECLARE_STATIC_IID_ACCESSOR(XULTREEGRIDCELLACCESSIBLE_IMPL_CID)
 
   /**
-   * Return index of the column.
-   */
-  int32_t GetColumnIndex() const;
-
-  /**
    * Fire name or state change event if the accessible text or value has been
    * changed.
    */
   void CellInvalidated();
 
 protected:
   // Accessible
   virtual Accessible* GetSiblingAtOffset(int32_t aOffset,
--- a/accessible/tests/mochitest/events/test_focus_aria_activedescendant.html
+++ b/accessible/tests/mochitest/events/test_focus_aria_activedescendant.html
@@ -65,16 +65,20 @@ https://bugzilla.mozilla.org/show_bug.cg
 
     var gQueue = null;
     function doTest()
     {
       gQueue = new eventQueue();
 
       gQueue.push(new synthFocus("container", new focusChecker("item1")));
       gQueue.push(new changeARIAActiveDescendant("container", "item2"));
+
+      gQueue.push(new synthFocus("combobox_entry", new focusChecker("combobox_entry")));
+      gQueue.push(new changeARIAActiveDescendant("combobox", "combobox_option2"));
+
       todo(false, "No focus for inserted element, bug 687011");
       //gQueue.push(new insertItemNFocus("container", "item3"));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
@@ -82,19 +86,32 @@ https://bugzilla.mozilla.org/show_bug.cg
 </head>
 <body>
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=429547"
      title="Support aria-activedescendant usage in nsIAccesible::TakeFocus()">
     Mozilla Bug 429547
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=761102"
+     title="Focus may be missed when ARIA active-descendant is changed on active composite widget">
+    Mozilla Bug 761102
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <div role="listbox" aria-activedescendant="item1" id="container" tabindex="1">
     <div role="listitem" id="item1">item1</div>
     <div role="listitem" id="item2">item2</div>
   </div>
+
+  <div role="combobox" id="combobox">
+    <input id="combobox_entry">
+    <ul>
+      <li role="option" id="combobox_option1">option1</li>
+      <li role="option" id="combobox_option2">option2</li>
+    </ul>
+  </div>
 </body>
 </html>
--- a/accessible/tests/mochitest/tree/test_list.html
+++ b/accessible/tests/mochitest/tree/test_list.html
@@ -118,31 +118,63 @@
                 { TEXT_LEAF: [] }
               ] }
             ] }
           ] }
         ] };
 
       testAccessibleTree("list6", tree);
 
+      // li having no display:list-item style
+      var tree =
+        { LIST: [ // ul
+          { LISTITEM: [ // li
+            { TEXT_LEAF: [] },
+          ] },
+          { TEXT_LEAF: [] },
+          { LISTITEM: [ // li
+            { TEXT_LEAF: [] }
+          ] }
+        ] };
+      testAccessibleTree("list7", tree);
+
+      var tree =
+        { LIST: [ // ul
+          { LISTITEM: [ // li
+            { TEXT_LEAF: [] },
+          ] },
+          { LISTITEM: [ // li
+            { TEXT_LEAF: [] }
+          ] }
+        ] };
+      testAccessibleTree("list8", tree);
+
+      // span having display:list-item style
+      testAccessibleTree("list9", discAccTree);
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
 
   <a target="_blank"
      title="Fix O(n^2) access to all the children of a container"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=342045">
     Mozilla Bug 342045
   </a>
   <a target="_blank"
+     title="Wrong accessible is created for HTML:li having block display style"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=507555">
+    Mozilla Bug 507555
+  </a>
+  <a target="_blank"
      title="Bullets of nested not ordered lists have one and the same character."
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=604587">
     Mozilla Bug 604587
   </a>
   <a target="_blank"
      title="Fix list bullets for DL list (crash [@ nsBulletFrame::GetListItemText])"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=629114">
     Mozilla Bug 629114
@@ -188,10 +220,28 @@
 
   <ol id="list6">
     <li>
       <dl id="dl">
         <dt>item1</dt><dd>description</dd>
       </dl>
     </li>
   </ol>
+
+  <!-- display style different than list-item -->
+  <ul id="list7">
+    <li id="l7_li1" style="display:inline-block;">Oranges</li>
+    <li id="l7_li2" style="display:inline-block;">Apples</li>
+  </ul>
+
+  <ul id="list8">
+    <li id="l8_li1" style="display:inline; float:right;">Oranges</li>
+    <li id="l8_li2" style="display:inline; float:right;">Apples</li>
+  </ul>
+
+  <!-- list-item display style -->
+  <ul id="list9">
+    <span id="l9_li1" style="display:list-item">Oranges</span>
+    <span id="l9_li2" style="display:list-item">Apples</span>
+    <span id="l9_li3" style="display:list-item">Bananas</span>
+  </ul>
 </body>
 </html>
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -39,19 +39,19 @@ pref("network.protocol-handler.warn-exte
 pref("network.protocol-handler.warn-external.vnd.youtube", false);
 
 /* http prefs */
 pref("network.http.pipelining", true);
 pref("network.http.pipelining.ssl", true);
 pref("network.http.proxy.pipelining", true);
 pref("network.http.pipelining.maxrequests" , 6);
 pref("network.http.keep-alive.timeout", 600);
-pref("network.http.max-connections", 6);
-pref("network.http.max-persistent-connections-per-server", 4);
-pref("network.http.max-persistent-connections-per-proxy", 4);
+pref("network.http.max-connections", 20);
+pref("network.http.max-persistent-connections-per-server", 6);
+pref("network.http.max-persistent-connections-per-proxy", 20);
 
 // See bug 545869 for details on why these are set the way they are
 pref("network.buffer.cache.count", 24);
 pref("network.buffer.cache.size",  16384);
 
 /* session history */
 pref("browser.sessionhistory.max_total_viewers", 1);
 pref("browser.sessionhistory.max_entries", 50);
@@ -502,17 +502,17 @@ pref("ui.showHideScrollbars", 1);
 
 // Enable the ProcessPriorityManager, and give processes with no visible
 // documents a 1s grace period before they're eligible to be marked as
 // background.
 pref("dom.ipc.processPriorityManager.enabled", true);
 pref("dom.ipc.processPriorityManager.gracePeriodMS", 1000);
 pref("hal.processPriorityManager.gonk.masterOomAdjust", 0);
 pref("hal.processPriorityManager.gonk.foregroundOomAdjust", 1);
-pref("hal.processPriorityManager.gonk.backgroundOomAdjust", 2);
+pref("hal.processPriorityManager.gonk.backgroundOomAdjust", 6);
 pref("hal.processPriorityManager.gonk.masterNice", -1);
 pref("hal.processPriorityManager.gonk.foregroundNice", 0);
 pref("hal.processPriorityManager.gonk.backgroundNice", 10);
 
 #ifndef DEBUG
 // Enable pre-launching content processes for improved startup time
 // (hiding latency).
 pref("dom.ipc.processPrelauch.enabled", true);
@@ -520,8 +520,11 @@ pref("dom.ipc.processPrelauch.enabled", 
 pref("dom.ipc.processPrelauch.delayMs", 1000);
 #endif
 
 // Ignore the "dialog=1" feature in window.open.
 pref("dom.disable_window_open_dialog_feature", true);
 
 // Screen reader support
 pref("accessibility.accessfu.activate", 2);
+
+// Disable native prompt
+pref("browser.prompt.allowNative", false);
--- a/b2g/chrome/content/forms.js
+++ b/b2g/chrome/content/forms.js
@@ -113,23 +113,38 @@ let FormAssistant = {
     let json = msg.json;
     switch (msg.name) {
       case "Forms:Input:Value":
         target.value = json.value;
         break;
 
       case "Forms:Select:Choice":
         let options = target.options;
+        let valueChanged = false;
         if ("index" in json) {
-          options.item(json.index).selected = true;
+          if (options.selectedIndex != json.index) {
+            options.selectedIndex = json.index;
+            valueChanged = true;
+          }
         } else if ("indexes" in json) {
           for (let i = 0; i < options.length; i++) {
-            options.item(i).selected = (json.indexes.indexOf(i) != -1);
+            let newValue = (json.indexes.indexOf(i) != -1);
+            if (options.item(i).selected != newValue) {
+              options.item(i).selected = newValue;
+              valueChanged = true;
+            }
           }
         }
+
+        // only fire onchange event if any selected option is changed
+        if (valueChanged) {
+          let event = content.document.createEvent('HTMLEvents');
+          event.initEvent('change', true, true);
+          target.dispatchEvent(event);
+        }
         break;
     }
   },
 
   observe: function fa_observe(subject, topic, data) {
     switch (topic) {
       case "ime-enabled-state-changed":
         let isOpen = this.isKeyboardOpened;
--- a/b2g/chrome/content/runapp.js
+++ b/b2g/chrome/content/runapp.js
@@ -67,17 +67,17 @@ window.addEventListener('load', function
     let app = findAppWithName(appname);
     if (!app) {
       dump('Could not find app: "' + appname + '". Maybe you meant one of:\n');
       usageAndDie(true);
       return;
     }
 
     let setReq =
-      navigator.mozSettings.getLock().set({'lockscreen.enabled': false});
+      navigator.mozSettings.createLock().set({'lockscreen.enabled': false});
     setReq.onsuccess = function() {
       // give the event loop another turn to disable the lock screen
       window.setTimeout(function() {
         dump('--runapp launching app: ' + app.manifest.name + '\n');
         app.launch();
       }, 0);
     };
     setReq.onerror = function() {
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -30,17 +30,17 @@ var SettingsListener = {
       window.setTimeout(function() { callback(defaultValue); });
       return;
     }
 
     if (!callback || typeof callback !== 'function') {
       throw new Error('Callback is not a function');
     }
 
-    var req = settings.getLock().get(name);
+    var req = settings.createLock().get(name);
     req.addEventListener('success', (function onsuccess() {
       callback(typeof(req.result[name]) != 'undefined' ?
         req.result[name] : defaultValue);
     }));
 
     this._callbacks[name] = callback;
   }
 };
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -504,16 +504,19 @@ var CustomEventManager = {
         break;
       case 'webapps-install-granted':
       case 'webapps-install-denied':
         WebappsHelper.handleEvent(detail);
         break;
       case 'select-choicechange':
         FormsHelper.handleEvent(detail);
         break;
+      case 'system-message-listener-ready':
+        Services.obs.notifyObservers(null, 'system-message-listener-ready', null);
+        break;
     }
   }
 }
 
 var AlertsHelper = {
   _listeners: {},
   _count: 0,
 
new file mode 100644
--- /dev/null
+++ b/b2g/config/mozconfigs/common
@@ -0,0 +1,7 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# This file is included at the top of all b2g mozconfigs
+
+. "$topsrcdir/build/mozconfig.common"
new file mode 100644
--- /dev/null
+++ b/b2g/config/mozconfigs/common.override
@@ -0,0 +1,7 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# This file is included at the bottom of all b2g mozconfigs
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/b2g/config/mozconfigs/gb_armv7a_gecko/debug
+++ b/b2g/config/mozconfigs/gb_armv7a_gecko/debug
@@ -1,8 +1,10 @@
+. "$topsrcdir/b2g/config/mozconfigs/common"
+
 mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-b2g
 
 mk_add_options MOZ_MAKE_FLAGS="-j8"
 
 ac_add_options --enable-application=b2g
 
 ac_add_options --target=arm-android-eabi
 ac_add_options --with-gonk="$topsrcdir/gonk-toolchain"
@@ -10,8 +12,10 @@ ac_add_options --with-gonk-toolchain-pre
 ac_add_options --disable-elf-hack
 ac_add_options --enable-debug-symbols
 ac_add_options --enable-debug
 ac_add_options --with-ccache
 ENABLE_MARIONETTE=1
 
 # Enable dump() from JS.
 export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
+
+. "$topsrcdir/b2g/config/mozconfigs/common.override"
--- a/b2g/config/mozconfigs/gb_armv7a_gecko/nightly
+++ b/b2g/config/mozconfigs/gb_armv7a_gecko/nightly
@@ -1,8 +1,10 @@
+. "$topsrcdir/b2g/config/mozconfigs/common"
+
 mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-b2g
 
 mk_add_options MOZ_MAKE_FLAGS="-j8"
 
 ac_add_options --enable-application=b2g
 
 ac_add_options --target=arm-android-eabi
 ac_add_options --with-gonk="$topsrcdir/gonk-toolchain"
@@ -10,8 +12,10 @@ ac_add_options --with-gonk-toolchain-pre
 ac_add_options --disable-elf-hack
 ac_add_options --enable-debug-symbols
 ac_add_options --enable-profiling
 ac_add_options --with-ccache
 ENABLE_MARIONETTE=1
 
 # Enable dump() from JS.
 export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
+
+. "$topsrcdir/b2g/config/mozconfigs/common.override"
--- a/b2g/config/mozconfigs/ics_armv7a_gecko/debug
+++ b/b2g/config/mozconfigs/ics_armv7a_gecko/debug
@@ -13,8 +13,10 @@ ac_add_options --with-gonk-toolchain-pre
 ac_add_options --disable-elf-hack
 ac_add_options --enable-debug-symbols
 ac_add_options --enable-debug
 #ac_add_options --with-ccache
 ENABLE_MARIONETTE=1
 
 # Enable dump() from JS.
 export CXXFLAGS="-DMOZ_ENABLE_JS_DUMP -include $topsrcdir/gonk-toolchain/gonk-misc/Unicode.h -include $topsrcdir/gonk-toolchain/system/vold/ResponseCode.h"
+
+. "$topsrcdir/b2g/config/mozconfigs/common.override"
--- a/b2g/config/mozconfigs/ics_armv7a_gecko/nightly
+++ b/b2g/config/mozconfigs/ics_armv7a_gecko/nightly
@@ -1,8 +1,10 @@
+. "$topsrcdir/b2g/config/mozconfigs/common"
+
 mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-b2g
 
 mk_add_options MOZ_MAKE_FLAGS="-j8"
 
 ac_add_options --enable-application=b2g
 ac_add_options --enable-b2g-camera
 
 ac_add_options --target=arm-android-eabi
@@ -13,8 +15,10 @@ ac_add_options --with-gonk-toolchain-pre
 ac_add_options --disable-elf-hack
 ac_add_options --enable-debug-symbols
 ac_add_options --enable-profiling
 #ac_add_options --with-ccache
 ENABLE_MARIONETTE=1
 
 # Enable dump() from JS.
 export CXXFLAGS="-DMOZ_ENABLE_JS_DUMP -include $topsrcdir/gonk-toolchain/gonk-misc/Unicode.h -include $topsrcdir/gonk-toolchain/system/vold/ResponseCode.h"
+
+. "$topsrcdir/b2g/config/mozconfigs/common.override"
--- a/b2g/config/mozconfigs/linux32_gecko/nightly
+++ b/b2g/config/mozconfigs/linux32_gecko/nightly
@@ -1,8 +1,10 @@
+. "$topsrcdir/b2g/config/mozconfigs/common"
+
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-codesighs
 ac_add_options --enable-signmar
 
 # Nightlies only since this has a cost in performance
 #ac_add_options --enable-js-diagnostics
 
@@ -31,8 +33,10 @@ mk_add_options MOZ_MAKE_FLAGS="-j4"
 # Use ccache
 ac_add_options --with-ccache=/usr/bin/ccache
 
 #B2G options
 ac_add_options --enable-application=b2g
 ENABLE_MARIONETTE=1
 ac_add_options --disable-elf-hack
 export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
+
+. "$topsrcdir/b2g/config/mozconfigs/common.override"
--- a/b2g/config/mozconfigs/linux64_gecko/nightly
+++ b/b2g/config/mozconfigs/linux64_gecko/nightly
@@ -33,8 +33,10 @@ mk_add_options MOZ_MAKE_FLAGS="-j4"
 # Use ccache
 ac_add_options --with-ccache=/usr/bin/ccache
 
 #B2G options
 ac_add_options --enable-application=b2g
 ENABLE_MARIONETTE=1
 ac_add_options --disable-elf-hack
 export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
+
+. "$topsrcdir/b2g/config/mozconfigs/common.override"
--- a/b2g/config/mozconfigs/macosx64_gecko/nightly
+++ b/b2g/config/mozconfigs/macosx64_gecko/nightly
@@ -1,9 +1,9 @@
-. $topsrcdir/build/macosx/common
+. $topsrcdir/build/macosx/mozconfig.common
 
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-codesighs
 ac_add_options --enable-signmar
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
@@ -21,8 +21,10 @@ ac_add_options --enable-warnings-as-erro
 
 # B2G Stuff
 ac_add_options --enable-application=b2g
 ac_add_options --enable-debug-symbols
 ac_add_options --with-ccache
 ENABLE_MARIONETTE=1
 
 export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
+
+. "$topsrcdir/b2g/config/mozconfigs/common.override"
--- a/b2g/config/mozconfigs/win32_gecko/nightly
+++ b/b2g/config/mozconfigs/win32_gecko/nightly
@@ -1,8 +1,10 @@
+. "$topsrcdir/b2g/config/mozconfigs/common"
+
 # for pgo
 mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) $(MOZ_OBJDIR)/_profile/pgo/profileserver.py'
 
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-jemalloc
 ac_add_options --enable-signmar
 
@@ -22,8 +24,10 @@ else
   . $topsrcdir/build/win32/mozconfig.vs2010
 fi
 
 # B2G Options
 ac_add_options --enable-application=b2g
 ENABLE_MARIONETTE=1
 
 export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
+
+. "$topsrcdir/b2g/config/mozconfigs/common.override"
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -121,42 +121,42 @@ endif #}
 endif #}
 endif #}
 
 ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
 
 libs:: 
 	cp -p $(MOZ_APP_NAME)$(BIN_SUFFIX) $(DIST)/bin/$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
 
-GARBAGE += $(addprefix $(DIST)/bin/defaults/pref/, firefox.js)
+GARBAGE += $(addprefix $(FINAL_TARGET)/defaults/pref/, firefox.js)
 
 endif
 
 endif #} LIBXUL_SDK
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 libs::
-	$(INSTALL) $(IFLAGS1) $(DIST)/branding/mozicon128.png $(DIST)/bin/icons
-	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default16.png  $(DIST)/bin/chrome/icons/default
-	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default32.png  $(DIST)/bin/chrome/icons/default
-	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default48.png  $(DIST)/bin/chrome/icons/default
+	$(INSTALL) $(IFLAGS1) $(DIST)/branding/mozicon128.png $(FINAL_TARGET)/icons
+	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default16.png  $(FINAL_TARGET)/chrome/icons/default
+	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default32.png  $(FINAL_TARGET)/chrome/icons/default
+	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default48.png  $(FINAL_TARGET)/chrome/icons/default
 endif
 
 libs:: $(srcdir)/profile/prefs.js
-	$(INSTALL) $(IFLAGS1) $^ $(DIST)/bin/defaults/profile
+	$(INSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/defaults/profile
 
 ifndef LIBXUL_SDK
 # channel-prefs.js is handled separate from other prefs due to bug 756325
 libs:: $(srcdir)/profile/channel-prefs.js
-	$(NSINSTALL) -D $(DIST)/bin/defaults/pref
-	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(ACDEFINES) $^ > $(DIST)/bin/defaults/pref/channel-prefs.js
+	$(NSINSTALL) -D $(FINAL_TARGET)/defaults/pref
+	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(ACDEFINES) $^ > $(FINAL_TARGET)/defaults/pref/channel-prefs.js
 endif
 
 libs:: $(srcdir)/blocklist.xml
-	$(INSTALL) $(IFLAGS1) $^ $(DIST)/bin
+	$(INSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 
 MAC_APP_NAME = $(MOZ_APP_DISPLAYNAME)
 
 ifdef MOZ_DEBUG
 MAC_APP_NAME := $(MAC_APP_NAME)Debug
 endif
--- a/browser/app/profile/extensions/Makefile.in
+++ b/browser/app/profile/extensions/Makefile.in
@@ -3,17 +3,17 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH      = @DEPTH@
 topsrcdir  = @top_srcdir@
 srcdir     = @srcdir@
 VPATH      = @srcdir@
 
-DISTROEXT = $(call core_abspath,$(DIST))/bin/distribution/extensions
+DISTROEXT = $(call core_abspath,$(FINAL_TARGET))/distribution/extensions
 
 include $(DEPTH)/config/autoconf.mk
 
 DIRS = \
   {972ce4c6-7e08-4474-a285-3208198ce6fd} \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/Makefile.in
+++ b/browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/Makefile.in
@@ -12,14 +12,11 @@ include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 FILES := \
 	install.rdf \
 	$(NULL)
 
 libs::
 	$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(srcdir)/install.rdf.in > install.rdf
-	$(INSTALL) $(FILES) $(DIST)/bin/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
+	$(INSTALL) $(FILES) $(FINAL_TARGET)/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
  
-install::
-	$(SYSINSTALL) $(IFLAGS1) $(FILES) $(DESTDIR)$(mozappdir)/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
-
 GARBAGE += $(FILES)
--- a/browser/base/content/browser-tabPreviews.js
+++ b/browser/base/content/browser-tabPreviews.js
@@ -6,47 +6,58 @@
 #endif
  */
 
 /**
  * Tab previews utility, produces thumbnails
  */
 var tabPreviews = {
   aspectRatio: 0.5625, // 16:9
+
+  get width() {
+    delete this.width;
+    return this.width = Math.ceil(screen.availWidth / 5.75);
+  },
+
+  get height() {
+    delete this.height;
+    return this.height = Math.round(this.width * this.aspectRatio);
+  },
+
   init: function tabPreviews_init() {
     if (this._selectedTab)
       return;
     this._selectedTab = gBrowser.selectedTab;
 
-    this.width = Math.ceil(screen.availWidth / 5.75);
-    this.height = Math.round(this.width * this.aspectRatio);
-
-    window.addEventListener("unload", this, false);
     gBrowser.tabContainer.addEventListener("TabSelect", this, false);
     gBrowser.tabContainer.addEventListener("SSTabRestored", this, false);
   },
-  uninit: function tabPreviews_uninit() {
-    window.removeEventListener("unload", this, false);
-    gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
-    gBrowser.tabContainer.removeEventListener("SSTabRestored", this, false);
-    this._selectedTab = null;
-  },
+
   get: function tabPreviews_get(aTab) {
-    this.init();
+    let uri = aTab.linkedBrowser.currentURI.spec;
 
     if (aTab.__thumbnail_lastURI &&
-        aTab.__thumbnail_lastURI != aTab.linkedBrowser.currentURI.spec) {
+        aTab.__thumbnail_lastURI != uri) {
       aTab.__thumbnail = null;
       aTab.__thumbnail_lastURI = null;
     }
-    return aTab.__thumbnail || this.capture(aTab, !aTab.hasAttribute("busy"));
+
+    if (aTab.__thumbnail)
+      return aTab.__thumbnail;
+
+    if (aTab.getAttribute("pending") == "true") {
+      let img = new Image;
+      img.src = PageThumbs.getThumbnailURL(uri);
+      return img;
+    }
+
+    return this.capture(aTab, !aTab.hasAttribute("busy"));
   },
+
   capture: function tabPreviews_capture(aTab, aStore) {
-    this.init();
-
     var thumbnail = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
     thumbnail.mozOpaque = true;
     thumbnail.height = this.height;
     thumbnail.width = this.width;
 
     var ctx = thumbnail.getContext("2d");
     var win = aTab.linkedBrowser.contentWindow;
     var snippetWidth = win.innerWidth * .6;
@@ -56,16 +67,17 @@ var tabPreviews = {
                    snippetWidth, snippetWidth * this.aspectRatio, "rgb(255,255,255)");
 
     if (aStore) {
       aTab.__thumbnail = thumbnail;
       aTab.__thumbnail_lastURI = aTab.linkedBrowser.currentURI.spec;
     }
     return thumbnail;
   },
+
   handleEvent: function tabPreviews_handleEvent(event) {
     switch (event.type) {
       case "TabSelect":
         if (this._selectedTab &&
             this._selectedTab.parentNode &&
             !this._pendingUpdate) {
           // Generate a thumbnail for the tab that was selected.
           // The timeout keeps the UI snappy and prevents us from generating thumbnails
@@ -78,19 +90,16 @@ var tabPreviews = {
               self.capture(aTab, true);
           }, 2000, this, this._selectedTab);
         }
         this._selectedTab = event.target;
         break;
       case "SSTabRestored":
         this.capture(event.target, true);
         break;
-      case "unload":
-        this.uninit();
-        break;
     }
   }
 };
 
 var tabPreviewPanelHelper = {
   opening: function (host) {
     host.panel.hidden = false;
 
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -414,18 +414,18 @@ window[chromehidden~="toolbar"] toolbar:
   display: none;
 }
 
 /* ::::: Keyboard UI Panel ::::: */
 .KUI-panel-closebutton {
   -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image");
 }
 
-.ctrlTab-preview > html|canvas,
-.allTabs-preview > html|canvas {
+:-moz-any(.ctrlTab-preview, .allTabs-preview) > html|img,
+:-moz-any(.ctrlTab-preview, .allTabs-preview) > html|canvas {
   min-width: inherit;
   max-width: inherit;
   min-height: inherit;
   max-height: inherit;
 }
 
 .ctrlTab-favicon-container,
 .allTabs-favicon-container {
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -141,24 +141,24 @@ XPCOMUtils.defineLazyGetter(this, "Socia
 });
 
 XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs",
   "resource:///modules/PageThumbs.jsm");
 
 #ifdef MOZ_SAFE_BROWSING
 XPCOMUtils.defineLazyGetter(this, "SafeBrowsing", function() {
   let tmp = {};
-  Cu.import("resource://gre/modules/SafeBrowsing.jsm", tmp);
+  Cu.import("resource:///modules/SafeBrowsing.jsm", tmp);
   return tmp.SafeBrowsing;
 });
 #endif
 
 XPCOMUtils.defineLazyGetter(this, "gBrowserNewTabPreloader", function () {
   let tmp = {};
-  Cu.import("resource://gre/modules/BrowserNewTabPreloader.jsm", tmp);
+  Cu.import("resource:///modules/BrowserNewTabPreloader.jsm", tmp);
   return new tmp.BrowserNewTabPreloader();
 });
 
 let gInitialPages = [
   "about:blank",
   "about:newtab",
   "about:home",
   "about:privatebrowsing",
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -394,20 +394,16 @@
                     label="&identity.moreInfoLinkText;"
                     onblur="gIdentityHandler.hideIdentityPopup();"
                     oncommand="gIdentityHandler.handleMoreInfoClick(event);"/>
           </hbox>
         </vbox>
       </hbox>
     </panel>
 
-    <tooltip id="urlTooltip">
-      <label crop="center" flex="1" class="tooltip-label"/>
-    </tooltip>
-
     <panel id="ctrlTab-panel" class="KUI-panel" hidden="true" norestorefocus="true" level="top">
       <hbox>
         <button class="ctrlTab-preview" flex="1"/>
         <button class="ctrlTab-preview" flex="1"/>
         <button class="ctrlTab-preview" flex="1"/>
         <button class="ctrlTab-preview" flex="1"/>
         <button class="ctrlTab-preview" flex="1"/>
         <button class="ctrlTab-preview" flex="1"/>
--- a/browser/base/content/tabbrowser.css
+++ b/browser/base/content/tabbrowser.css
@@ -48,8 +48,18 @@ tabpanels {
 
 .closing-tabs-spacer {
   pointer-events: none;
 }
 
 .tabbrowser-tabs:not(:hover) > .tabbrowser-arrowscrollbox > .closing-tabs-spacer {
   transition: width .15s ease-out;
 }
+
+/**
+ * Optimization for tabs that are restored lazily. We can save a good amount of
+ * memory that to-be-restored tabs would otherwise consume simply by setting
+ * their browsers to 'display: none' as that will prevent them from having to
+ * create a presentation and the like.
+ */
+browser[pending] {
+  display: none;
+}
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -3642,32 +3642,32 @@
               this._dragTime = Date.now();
             if (Date.now() >= this._dragTime + this._dragOverDelay)
               this.selectedItem = tab;
             ind.collapsed = true;
             return;
           }
         }
 
-        var newIndex = this._getDropIndex(event);
         var scrollRect = tabStrip.scrollClientRect;
         var rect = tabStrip.getBoundingClientRect();
         var minMargin = scrollRect.left - rect.left;
         var maxMargin = Math.min(minMargin + scrollRect.width,
                                  scrollRect.right);
         if (!ltr)
           [minMargin, maxMargin] = [this.clientWidth - maxMargin,
                                     this.clientWidth - minMargin];
         var newMargin;
         if (pixelsToScroll) {
           // if we are scrolling, put the drop indicator at the edge
           // so that it doesn't jump while scrolling
           newMargin = (pixelsToScroll > 0) ? maxMargin : minMargin;
         }
         else {
+          let newIndex = this._getDropIndex(event);
           if (newIndex == this.childNodes.length) {
             let tabRect = this.childNodes[newIndex-1].getBoundingClientRect();
             if (ltr)
               newMargin = tabRect.right - rect.left;
             else
               newMargin = rect.right - tabRect.left;
           }
           else {
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -53,18 +53,16 @@
         this._prefs.addObserver("", this, false);
         this.clickSelectsAll = this._prefs.getBoolPref("clickSelectsAll");
         this.doubleClickSelectsAll = this._prefs.getBoolPref("doubleClickSelectsAll");
         this.completeDefaultIndex = this._prefs.getBoolPref("autoFill");
         this.timeout = this._prefs.getIntPref("delay");
         this._formattingEnabled = this._prefs.getBoolPref("formatting.enabled");
         this._mayTrimURLs = this._prefs.getBoolPref("trimURLs");
 
-        this._urlTooltip = document.getElementById("urlTooltip");
-
         this.inputField.controllers.insertControllerAt(0, this._copyCutController);
         this.inputField.addEventListener("mousedown", this, false);
         this.inputField.addEventListener("mousemove", this, false);
         this.inputField.addEventListener("mouseout", this, false);
         this.inputField.addEventListener("overflow", this, false);
         this.inputField.addEventListener("underflow", this, false);
 
         const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@@ -405,36 +403,23 @@
       </method>
 
       <field name="_contentIsCropped">false</field>
 
       <method name="_initURLTooltip">
         <body><![CDATA[
           if (this.focused || !this._contentIsCropped)
             return;
-          if (this._tooltipTimer)
-            clearTimeout(this._tooltipTimer);
-          this._tooltipTimer = setTimeout(function (self) {
-            self._tooltipTimer = 0;
-            var label = self._urlTooltip.firstChild;
-            label.value = self.value;
-            var bO = self.boxObject;
-            self._urlTooltip.maxWidth = bO.width;
-            self._urlTooltip.showPopup(self, bO.screenX, bO.screenY + bO.height, "tooltip");
-          }, 700, this);
+          this.inputField.setAttribute("tooltiptext", this.value);
         ]]></body>
       </method>
 
       <method name="_hideURLTooltip">
         <body><![CDATA[
-          if (this._tooltipTimer) {
-            clearTimeout(this._tooltipTimer);
-            this._tooltipTimer = 0;
-          }
-          this._urlTooltip.hidePopup();
+          this.inputField.removeAttribute("tooltiptext");
         ]]></body>
       </method>
 
       <method name="onDragOver">
         <parameter name="aEvent"/>
         <body>
           var types = aEvent.dataTransfer.types;
           if (types.contains("application/x-moz-file") ||
--- a/browser/components/feeds/src/nsFeedSniffer.cpp
+++ b/browser/components/feeds/src/nsFeedSniffer.cpp
@@ -341,17 +341,17 @@ nsFeedSniffer::AppendSegmentToString(nsI
   nsCString* decodedData = static_cast<nsCString*>(closure);
   decodedData->Append(rawSegment, count);
   *writeCount = count;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFeedSniffer::OnDataAvailable(nsIRequest* request, nsISupports* context,
-                               nsIInputStream* stream, uint32_t offset, 
+                               nsIInputStream* stream, uint64_t offset, 
                                uint32_t count)
 {
   uint32_t read;
   return stream->ReadSegments(AppendSegmentToString, &mDecodedData, count, 
                               &read);
 }
 
 NS_IMETHODIMP
--- a/browser/components/safebrowsing/Makefile.in
+++ b/browser/components/safebrowsing/Makefile.in
@@ -1,14 +1,14 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
-DEPTH     = ../../..
+DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 TEST_DIRS += content/test
 
--- a/browser/components/safebrowsing/content/test/Makefile.in
+++ b/browser/components/safebrowsing/content/test/Makefile.in
@@ -1,18 +1,18 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-DEPTH		= ../../../../..
+DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
-relativesrcdir  = browser/components/safebrowsing/content/test
+relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 # The browser chrome test for bug 415846 doesn't run on Mac because of its
 # bizarre special-and-unique snowflake of a help menu.
 ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 _NON_MAC_BROWSER_TESTS = browser_bug415846.js
--- a/browser/components/sessionstore/src/SessionStore.jsm
+++ b/browser/components/sessionstore/src/SessionStore.jsm
@@ -2982,16 +2982,17 @@ let SessionStoreInternal = {
         this.xulAttributes[name] = true;
 
       browser.__SS_tabStillLoading = true;
 
       // keep the data around to prevent dataloss in case
       // a tab gets closed before it's been properly restored
       browser.__SS_data = tabData;
       browser.__SS_restoreState = TAB_STATE_NEEDS_RESTORE;
+      browser.setAttribute("pending", "true");
       tab.setAttribute("pending", "true");
 
       // Make sure that set/getTabValue will set/read the correct data by
       // wiping out any current value in tab.__SS_extdata.
       delete tab.__SS_extdata;
 
       if (!tabData.entries || tabData.entries.length == 0) {
         // make sure to blank out this tab's content
@@ -3166,16 +3167,17 @@ let SessionStoreInternal = {
     // Make sure that this tab is removed from _tabsToRestore
     this._removeTabFromTabsToRestore(aTab);
 
     // Increase our internal count.
     this._tabsRestoringCount++;
 
     // Set this tab's state to restoring
     browser.__SS_restoreState = TAB_STATE_RESTORING;
+    browser.removeAttribute("pending");
     aTab.removeAttribute("pending");
 
     // Remove the history listener, since we no longer need it once we start restoring
     this._removeSHistoryListener(aTab);
 
     let activeIndex = (tabData.index || tabData.entries.length) - 1;
     if (activeIndex >= tabData.entries.length)
       activeIndex = tabData.entries.length - 1;
@@ -4330,16 +4332,19 @@ let SessionStoreInternal = {
     let browser = aTab.linkedBrowser;
 
     // Keep the tab's previous state for later in this method
     let previousState = browser.__SS_restoreState;
 
     // The browser is no longer in any sort of restoring state.
     delete browser.__SS_restoreState;
 
+    aTab.removeAttribute("pending");
+    browser.removeAttribute("pending");
+
     // We want to decrement window.__SS_tabsToRestore here so that we always
     // decrement it AFTER a tab is done restoring or when a tab gets "reset".
     window.__SS_tabsToRestore--;
 
     // Remove the progress listener if we should.
     this._removeTabsProgressListener(window);
 
     if (previousState == TAB_STATE_RESTORING) {
--- a/browser/components/shell/src/nsWindowsShellService.cpp
+++ b/browser/components/shell/src/nsWindowsShellService.cpp
@@ -608,17 +608,17 @@ nsWindowsShellService::SetDefaultBrowser
     info.pcszClass = NULL;
     info.oaifInFlags = OAIF_FORCE_REGISTRATION | 
                        OAIF_URL_PROTOCOL |
                        OAIF_REGISTER_EXT;
     nsresult rv = DynSHOpenWithDialog(NULL, &info);
     NS_ENSURE_SUCCESS(rv, rv);
     bool isDefaultBrowser = false;
     rv = NS_SUCCEEDED(IsDefaultBrowser(&isDefaultBrowser)) &&
-         isDefaultBrowser ? S_OK : NS_ERROR_FAILURE;
+         isDefaultBrowser ? NS_OK : NS_ERROR_FAILURE;
   }
   return rv;
 }
 
 NS_IMETHODIMP
 nsWindowsShellService::GetShouldCheckDefaultBrowser(bool* aResult)
 {
   NS_ENSURE_ARG_POINTER(aResult);
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/common
@@ -0,0 +1,7 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# This file is included by all browser mozconfigs
+
+. "$topsrcdir/build/mozconfig.common"
--- a/browser/config/mozconfigs/linux32/debug
+++ b/browser/config/mozconfigs/linux32/debug
@@ -17,8 +17,10 @@ mk_add_options MOZ_MAKE_FLAGS="-j4"
 #Use ccache
 ac_add_options --with-ccache=/usr/bin/ccache
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux32/debug-asan
+++ b/browser/config/mozconfigs/linux32/debug-asan
@@ -11,8 +11,10 @@ ac_add_options --enable-valgrind
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux32/l10n-mozconfig
+++ b/browser/config/mozconfigs/linux32/l10n-mozconfig
@@ -1,7 +1,9 @@
 ac_add_options --with-l10n-base=../../l10n-central
 ac_add_options --enable-official-branding
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 
 . $topsrcdir/build/unix/mozconfig.linux
 
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux32/nightly
+++ b/browser/config/mozconfigs/linux32/nightly
@@ -31,8 +31,10 @@ ac_add_options --enable-warnings-as-erro
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
 
 # Use ccache
 ac_add_options --with-ccache=/usr/bin/ccache
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux32/nightly-asan
+++ b/browser/config/mozconfigs/linux32/nightly-asan
@@ -13,8 +13,10 @@ ac_add_options --enable-codesighs
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux32/qt
+++ b/browser/config/mozconfigs/linux32/qt
@@ -21,8 +21,10 @@ ac_add_options --with-ccache=/usr/bin/cc
 # QT Options
 export PKG_CONFIG_PATH=/tools/qt-4.6.3/qt/lib/pkgconfig
 ac_add_options --with-qtdir=/tools/qt-4.6.3/qt
 ac_add_options --enable-default-toolkit=cairo-qt
 ac_add_options --disable-crashreporter
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux32/release
+++ b/browser/config/mozconfigs/linux32/release
@@ -19,8 +19,10 @@ export MOZ_TELEMETRY_REPORTING=1
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux32/rpm
+++ b/browser/config/mozconfigs/linux32/rpm
@@ -24,8 +24,10 @@ mk_add_options PROFILE_GEN_SCRIPT='$(PYT
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
 
 #Use ccache
 ac_add_options --with-ccache=/usr/bin/ccache
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/debug
+++ b/browser/config/mozconfigs/linux64/debug
@@ -17,8 +17,10 @@ mk_add_options MOZ_MAKE_FLAGS="-j4"
 # Use ccache
 ac_add_options --with-ccache=/usr/bin/ccache
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/debug-asan
+++ b/browser/config/mozconfigs/linux64/debug-asan
@@ -11,8 +11,10 @@ ac_add_options --enable-valgrind
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/l10n-mozconfig
+++ b/browser/config/mozconfigs/linux64/l10n-mozconfig
@@ -1,7 +1,9 @@
 ac_add_options --with-l10n-base=../../l10n-central
 ac_add_options --enable-official-branding
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 
 . $topsrcdir/build/unix/mozconfig.linux
 
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/nightly
+++ b/browser/config/mozconfigs/linux64/nightly
@@ -31,8 +31,10 @@ ac_add_options --enable-warnings-as-erro
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
 
 # Use ccache
 ac_add_options --with-ccache=/usr/bin/ccache
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/nightly-asan
+++ b/browser/config/mozconfigs/linux64/nightly-asan
@@ -13,8 +13,10 @@ ac_add_options --enable-codesighs
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/release
+++ b/browser/config/mozconfigs/linux64/release
@@ -19,8 +19,10 @@ export MOZ_TELEMETRY_REPORTING=1
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/rpm
+++ b/browser/config/mozconfigs/linux64/rpm
@@ -24,8 +24,10 @@ mk_add_options PROFILE_GEN_SCRIPT='$(PYT
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
 
 #Use ccache
 ac_add_options --with-ccache=/usr/bin/ccache
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/macosx-universal/nightly
+++ b/browser/config/mozconfigs/macosx-universal/nightly
@@ -21,8 +21,10 @@ mk_add_options MOZ_MAKE_FLAGS="-j12"
 
 ac_add_options --with-macbundlename-prefix=Firefox
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/macosx-universal/release
+++ b/browser/config/mozconfigs/macosx-universal/release
@@ -15,8 +15,10 @@ export MOZ_TELEMETRY_REPORTING=1
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/macosx-universal/shark
+++ b/browser/config/mozconfigs/macosx-universal/shark
@@ -19,8 +19,10 @@ ac_add_options --enable-shark
 ac_add_options --enable-dtrace
 
 # Need this to prevent name conflicts with the normal nightly build packages
 export MOZ_PKG_SPECIAL="shark"
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
 ac_add_options --with-ccache
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/macosx32/debug
+++ b/browser/config/mozconfigs/macosx32/debug
@@ -1,16 +1,19 @@
 . $topsrcdir/build/macosx/mozconfig.leopard
+
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 ac_add_options --enable-signmar
 ENABLE_MARIONETTE=1
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j12"
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 ac_add_options --with-macbundlename-prefix=Firefox
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/macosx64/debug
+++ b/browser/config/mozconfigs/macosx64/debug
@@ -1,9 +1,9 @@
-. $topsrcdir/build/macosx/common
+. $topsrcdir/build/macosx/mozconfig.common
 
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 ac_add_options --enable-accessibility
 ac_add_options --enable-signmar
 ENABLE_MARIONETTE=1
 
 # Enable parallel compiling
@@ -14,8 +14,10 @@ export MOZILLA_OFFICIAL=1
 
 ac_add_options --with-macbundlename-prefix=Firefox
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/macosx64/debug-asan
+++ b/browser/config/mozconfigs/macosx64/debug-asan
@@ -7,8 +7,10 @@ ac_add_options --enable-accessibility
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j12"
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 ac_add_options --with-macbundlename-prefix=Firefox
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/macosx64/l10n-mozconfig
+++ b/browser/config/mozconfigs/macosx64/l10n-mozconfig
@@ -1,5 +1,9 @@
+. "$topsrcdir/browser/config/mozconfigs/common"
+
 ac_add_options --with-l10n-base=../../l10n-central
 ac_add_options --enable-official-branding
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --with-ccache
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/win32/debug
+++ b/browser/config/mozconfigs/win32/debug
@@ -1,8 +1,10 @@
+. "$topsrcdir/browser/config/mozconfigs/common"
+
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 ac_add_options --enable-signmar
 ENABLE_MARIONETTE=1
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
@@ -15,8 +17,10 @@ fi
 if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
   . $topsrcdir/build/win32/mozconfig.vs2010-win64
 else
   . $topsrcdir/build/win32/mozconfig.vs2010
 fi
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/win32/l10n-mozconfig
+++ b/browser/config/mozconfigs/win32/l10n-mozconfig
@@ -1,10 +1,14 @@
+. "$topsrcdir/browser/config/mozconfigs/common"
+
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-official-branding
 ac_add_options --with-l10n-base=../../l10n-central
 
 if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
   . $topsrcdir/build/win32/mozconfig.vs2010-win64
 else
   . $topsrcdir/build/win32/mozconfig.vs2010
 fi
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/win32/nightly
+++ b/browser/config/mozconfigs/win32/nightly
@@ -1,8 +1,10 @@
+. "$topsrcdir/browser/config/mozconfigs/common"
+
 # for pgo
 mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) $(MOZ_OBJDIR)/_profile/pgo/profileserver.py'
 
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-jemalloc
 ac_add_options --enable-signmar
 ac_add_options --enable-profiling
@@ -24,8 +26,10 @@ fi
 if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
   . $topsrcdir/build/win32/mozconfig.vs2010-win64
 else
   . $topsrcdir/build/win32/mozconfig.vs2010
 fi
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/win32/release
+++ b/browser/config/mozconfigs/win32/release
@@ -1,8 +1,10 @@
+. "$topsrcdir/browser/config/mozconfigs/common"
+
 # for pgo
 mk_add_options MOZ_PGO=1
 mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) $(MOZ_OBJDIR)/_profile/pgo/profileserver.py'
 
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-jemalloc
 ac_add_options --enable-official-branding
@@ -21,8 +23,10 @@ fi
 if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
   . $topsrcdir/build/win32/mozconfig.vs2010-win64
 else
   . $topsrcdir/build/win32/mozconfig.vs2010
 fi
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/win64/debug
+++ b/browser/config/mozconfigs/win64/debug
@@ -10,8 +10,10 @@ ENABLE_MARIONETTE=1
 export MOZILLA_OFFICIAL=1
 
 mk_add_options MOZ_MAKE_FLAGS=-j1
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 . $topsrcdir/build/win64/mozconfig.vs2010
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/win64/nightly
+++ b/browser/config/mozconfigs/win64/nightly
@@ -19,8 +19,10 @@ export MOZILLA_OFFICIAL=1
 export MOZ_TELEMETRY_REPORTING=1
 
 mk_add_options MOZ_MAKE_FLAGS=-j1
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 . $topsrcdir/build/win64/mozconfig.vs2010
+
+. "$topsrcdir/build/mozconfig.common.override"
--- a/browser/devtools/commandline/CmdCmd.jsm
+++ b/browser/devtools/commandline/CmdCmd.jsm
@@ -13,17 +13,17 @@ let prefSvc = "@mozilla.org/preferences-
 XPCOMUtils.defineLazyGetter(this, "prefBranch", function() {
   let prefService = Cc[prefSvc].getService(Ci.nsIPrefService);
   return prefService.getBranch(null).QueryInterface(Ci.nsIPrefBranch2);
 });
 
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "console",
-                                  "resource:///modules/devtools/Console.jsm");
+                                  "resource://gre/modules/devtools/Console.jsm");
 
 const PREF_DIR = "devtools.commands.dir";
 
 /**
  * A place to store the names of the commands that we have added as a result of
  * calling refreshAutoCommands(). Used by refreshAutoCommands to remove the
  * added commands.
  */
--- a/browser/devtools/commandline/CmdCookie.jsm
+++ b/browser/devtools/commandline/CmdCookie.jsm
@@ -5,17 +5,17 @@
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 let EXPORTED_SYMBOLS = [ ];
 
 Cu.import("resource:///modules/devtools/gcli.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "console",
-                                  "resource:///modules/devtools/Console.jsm");
+                                  "resource://gre/modules/devtools/Console.jsm");
 
 // We should really be using nsICookieManager so we can read more than just the
 // key/value of cookies. The difficulty is filtering the cookies that are
 // relevant to the current page. See
 // https://github.com/firebug/firebug/blob/master/extension/content/firebug/cookies/cookieObserver.js#L123
 // For details on how this is done with Firebug
 
 /**
--- a/browser/extensions/Makefile.in
+++ b/browser/extensions/Makefile.in
@@ -2,34 +2,34 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH      = @DEPTH@
 topsrcdir  = @top_srcdir@
 srcdir     = @srcdir@
 VPATH      = @srcdir@
 
-CHROMEDIR = $(call core_abspath,$(DIST))/bin/chrome
+CHROMEDIR = $(call core_abspath,$(FINAL_TARGET))/chrome
 
 include $(DEPTH)/config/autoconf.mk
 
 TEST_DIRS += pdfjs/test
 
 include $(topsrcdir)/config/rules.mk
 
 exclude_files = \
   test \
   install.rdf \
   bootstrap.js \
   icon.png \
   icon64.png \
   $(NULL)
 
-$(DIST)/bin/chrome/pdfjs.manifest: $(GLOBAL_DEPS)
+$(FINAL_TARGET)/chrome/pdfjs.manifest: $(GLOBAL_DEPS)
 	printf "manifest pdfjs/chrome.manifest" > $@
 
-libs:: $(DIST)/bin/chrome/pdfjs.manifest
+libs:: $(FINAL_TARGET)/chrome/pdfjs.manifest
 	$(PYTHON) $(topsrcdir)/config/nsinstall.py \
 	  $(srcdir)/pdfjs \
           $(foreach exclude,$(exclude_files), -X $(srcdir)/pdfjs/$(exclude)) \
-          $(DIST)/bin/chrome
+          $(FINAL_TARGET)/chrome
 	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py \
-	  $(DIST)/bin/chrome.manifest "manifest chrome/pdfjs.manifest"
+	  $(FINAL_TARGET)/chrome.manifest "manifest chrome/pdfjs.manifest"
--- a/browser/locales/Makefile.in
+++ b/browser/locales/Makefile.in
@@ -193,27 +193,29 @@ langpack: langpack-$(AB_CD)
 # This is a generic target that will make a langpack, repack ZIP (+tarball)
 # builds, and repack an installer if applicable. It is called from the
 # tinderbox scripts. Alter it with caution.
 
 installers-%: clobber-% langpack-% repackage-win32-installer-% repackage-zip-%
 	@echo "repackaging done"
 
 ifdef MOZ_UPDATER
+# Note that we want updater.ini to be in the top directory, not the browser/
+# subdirectory, because that's where the updater is installed and runs.
 libs:: $(call MERGE_FILE,updater/updater.ini)
 ifeq ($(OS_ARCH),WINNT)
 	cat $< $(srcdir)/../installer/windows/nsis/updater_append.ini | \
 	  sed -e "s/^InfoText=/Info=/" -e "s/^TitleText=/Title=/" | \
 	  sed -e "s/%MOZ_APP_DISPLAYNAME%/$(MOZ_APP_DISPLAYNAME)/" > \
-	  $(FINAL_TARGET)/updater.ini
+	  $(DIST)/bin/updater.ini
 else
 	cat $< | \
 	  sed -e "s/^InfoText=/Info=/" -e "s/^TitleText=/Title=/" | \
 	  sed -e "s/%MOZ_APP_DISPLAYNAME%/$(MOZ_APP_DISPLAYNAME)/" > \
-	  $(FINAL_TARGET)/updater.ini
+	  $(DIST)/bin/updater.ini
 endif
 endif
 
 ifdef MOZ_CRASHREPORTER
 libs:: crashreporter-override.ini
 	$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)
 endif
 
deleted file mode 100644
--- a/build/macosx/common
+++ /dev/null
@@ -1,12 +0,0 @@
-if [ -d "$topsrcdir/clang" ]; then
-    # mozilla-central based build
-    export CC=$topsrcdir/clang/bin/clang
-    export CXX=$topsrcdir/clang/bin/clang++
-elif [ -d "$topsrcdir/../clang" ]; then
-    # comm-central based build
-    export CC=$topsrcdir/../clang/bin/clang
-    export CXX=$topsrcdir/../clang/bin/clang++
-fi
-
-ac_add_options --enable-stdcxx-compat
-ac_add_options --with-ccache
new file mode 100644
--- /dev/null
+++ b/build/macosx/mozconfig.common
@@ -0,0 +1,18 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+. "$topsrcdir/build/mozconfig.common"
+
+if [ -d "$topsrcdir/clang" ]; then
+    # mozilla-central based build
+    export CC=$topsrcdir/clang/bin/clang
+    export CXX=$topsrcdir/clang/bin/clang++
+elif [ -d "$topsrcdir/../clang" ]; then
+    # comm-central based build
+    export CC=$topsrcdir/../clang/bin/clang
+    export CXX=$topsrcdir/../clang/bin/clang++
+fi
+
+ac_add_options --enable-stdcxx-compat
+ac_add_options --with-ccache
--- a/build/macosx/mozconfig.leopard
+++ b/build/macosx/mozconfig.leopard
@@ -1,11 +1,11 @@
-. $topsrcdir/build/macosx/common
+. $topsrcdir/build/macosx/mozconfig.common
 
-# Mac builds don't nomally have to be handled as cross
+# Mac builds don't normally have to be handled as cross
 # compilation, but some of the libraries on the bots
 # (IDL for example) are built only for one arch.
 
 HOST_CC=$CC
 HOST_CXX=$CXX
 
 # These must be set for cross builds, and don't hurt straight builds.
 RANLIB=ranlib
--- a/build/macosx/universal/mozconfig.common
+++ b/build/macosx/universal/mozconfig.common
@@ -7,17 +7,17 @@ mk_add_options MOZ_UNIFY_BDATE=1
 mk_add_options MOZ_POSTFLIGHT_ALL+=build/macosx/universal/flight.mk
 
 # Note, the version (10) is used by libffi's configure.
 ac_add_app_options i386 --target=i386-apple-darwin10
 ac_add_app_options x86_64 --target=x86_64-apple-darwin10
 
 ac_add_options --with-macos-sdk=/Developer/SDKs/MacOSX10.6.sdk
 
-. $topsrcdir/build/macosx/common
+. $topsrcdir/build/macosx/mozconfig.common
 
 # $MOZ_BUILD_APP is only defined when sourced by configure.  That's not a
 # problem, because the variables it affects only need to be set for
 # configure.
 if test -n "$MOZ_BUILD_APP" ; then
 if test "$MOZ_BUILD_APP" = "i386" -o "$MOZ_BUILD_APP" = "x86_64"; then
   TARGET_CPU=$MOZ_BUILD_APP
 
new file mode 100644
--- /dev/null
+++ b/build/mozconfig.common
@@ -0,0 +1,11 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# Common mozconfig for all users
+#
+# Add options to this file that will be inherited by all in-tree mozconfigs.
+# This is useful for eg try builds with nondefault options that apply to all
+# architectures, though note that if you want to override options set in
+# another mozconfig file, you'll need to use mozconfig.common.override instead
+# of this file.
new file mode 100644
--- /dev/null
+++ b/build/mozconfig.common.override
@@ -0,0 +1,11 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# Common mozconfig for all users
+#
+# Add options to this file that will be inherited by all in-tree mozconfigs.
+# This file is included at the *end* of the mozconfigs, and so may be used
+# to override anything done previously.
+#
+# The common expected usage is for try builds with nondefault options.
--- a/build/pymake/pymake/functions.py
+++ b/build/pymake/pymake/functions.py
@@ -766,19 +766,18 @@ class ShellFunction(Function):
     __slots__ = Function.__slots__
 
     def resolve(self, makefile, variables, fd, setting):
         #TODO: call this once up-front somewhere and save the result?
         shell, msys = util.checkmsyscompat()
         cline = self._arguments[0].resolvestr(makefile, variables, setting)
 
         log.debug("%s: running shell command '%s'" % (self.loc, cline))
-        if msys:
-            cline = [shell, "-c", cline]
-        p = subprocess.Popen(cline, env=makefile.env, shell=not msys,
+        cline = [shell, "-c", cline]
+        p = subprocess.Popen(cline, env=makefile.env, shell=False,
                              stdout=subprocess.PIPE, cwd=makefile.workdir)
         stdout, stderr = p.communicate()
 
         stdout = stdout.replace('\r\n', '\n')
         if stdout.endswith('\n'):
             stdout = stdout[:-1]
         stdout = stdout.replace('\n', ' ')
 
--- a/build/pymake/pymake/process.py
+++ b/build/pymake/pymake/process.py
@@ -83,18 +83,18 @@ def call(cline, env, cwd, loc, cb, conte
         else:
             argv = doglobbing(argv, cwd)
 
     if shellreason is not None:
         _log.debug("%s: using shell: %s: '%s'", loc, shellreason, cline)
         if msys:
             if len(cline) > 3 and cline[1] == ':' and cline[2] == '/':
                 cline = '/' + cline[0] + cline[2:]
-            cline = [shell, "-c", cline]
-        context.call(cline, shell=not msys, env=env, cwd=cwd, cb=cb, echo=echo,
+        cline = [shell, "-c", cline]
+        context.call(cline, shell=False, env=env, cwd=cwd, cb=cb, echo=echo,
                      justprint=justprint)
         return
 
     if not len(argv):
         cb(res=0)
         return
 
     if argv[0] == command.makepypath:
--- a/build/unix/mozconfig.linux
+++ b/build/unix/mozconfig.linux
@@ -1,2 +1,4 @@
+. "$topsrcdir/build/mozconfig.common"
+
 CC=/tools/gcc-4.5-0moz3/bin/gcc
 CXX=/tools/gcc-4.5-0moz3/bin/g++
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -15,25 +15,23 @@ include $(DEPTH)/config/autoconf.mk
 # headers, so that we can use it to set up the wrapped system headers.
 VISIBILITY_FLAGS =
 
 # STDCXX_COMPAT is not needed here, and will actually fail because
 # libstdc++-compat is not built yet.
 STDCXX_COMPAT =
 
 ifneq (WINNT,$(HOST_OS_ARCH))
-HOST_PROGRAM	= nsinstall$(HOST_BIN_SUFFIX)
+HOST_PROGRAM	= nsinstall_real$(HOST_BIN_SUFFIX)
 HOST_CSRCS	= nsinstall.c pathsub.c
 endif
 
-TARGETS		= $(HOST_PROGRAM) $(SIMPLE_PROGRAMS)
-
 ifndef CROSS_COMPILE
 ifdef USE_ELF_DYNSTR_GC
-TARGETS		+= elf-dynstr-gc
+export:: elf-dynstr-gc
 # Compiling the above will create dependency files.
 NEED_MDDEPDIR	= 1
 endif
 endif
 
 # IMPORTANT: Disable NSBUILDROOT for this directory only, otherwise we have
 # a recursive rule for finding nsinstall and the Perl scripts.
 ifdef NSBUILDROOT
@@ -44,35 +42,46 @@ ifdef GNU_CC
 MODULE_OPTIMIZE_FLAGS = -O3
 endif
 
 include $(topsrcdir)/config/config.mk
 
 # Do not install util programs
 NO_INSTALL=1
 
+ifneq (WINNT,$(HOST_OS_ARCH))
+# Ensure nsinstall is atomically created
+nsinstall$(HOST_BIN_SUFFIX): $(HOST_PROGRAM)
+	cp $^ $@.tmp
+	mv $@.tmp $@
+
+NSINSTALL_FILES := nsinstall$(HOST_BIN_SUFFIX)
+NSINSTALL_DEST := $(DIST)/bin
+NSINSTALL_TARGET := export
+INSTALL_TARGETS += NSINSTALL
+endif
+
+HEADERS_FILES = \
+	$(DEPTH)/mozilla-config.h \
+	$(srcdir)/nsStaticComponents.h \
+	$(NULL)
+HEADERS_DEST := $(DIST)/include
+HEADERS_TARGET := export
+INSTALL_TARGETS += HEADERS
+
 include $(topsrcdir)/config/rules.mk
 
 HOST_CFLAGS += -DUNICODE -D_UNICODE
 
 ifeq ($(OS_CONFIG),SunOS4.1)
 NSPR_CFLAGS	+= -I$(srcdir)/../nsprpub/pr/include/md
 endif
 
-HEADERS = \
-	$(DEPTH)/mozilla-config.h \
-	$(srcdir)/nsStaticComponents.h \
-	$(NULL)
-
-export:: $(TARGETS) $(HEADERS)
-	$(INSTALL) $(IFLAGS1) $(HEADERS) $(DIST)/include
+export::
 	-$(RM) $(FINAL_LINK_COMPS) $(FINAL_LINK_LIBS) $(FINAL_LINK_COMP_NAMES)
-ifdef HOST_PROGRAM
-	$(INSTALL) $(HOST_PROGRAM) $(DIST)/bin
-endif
 
 # Generate a new buildid every time we "export" in config... that's only
 # supposed to be once per-build!
 export::
 ifdef MOZ_BUILD_DATE
 	printf "%s" $(MOZ_BUILD_DATE) > buildid
 else
 	$(PYTHON) $(topsrcdir)/toolkit/xre/make-platformini.py --print-buildid > buildid
--- a/config/makefiles/target_export.mk
+++ b/config/makefiles/target_export.mk
@@ -22,17 +22,17 @@ export_tier_%:
 #################
 ifdef PARALLEL_DIRS
 export:: $(PARALLEL_DIRS_export)
 
 $(PARALLEL_DIRS_export): %_export: %/Makefile
 	+@$(call SUBMAKE,export,$*)
 endif
 
-export:: $(SUBMAKEFILES) $(MAKE_DIRS) $(if $(XPIDLSRCS),$(IDL_DIR))
+export:: $(SUBMAKEFILES) $(MAKE_DIRS)
 	$(LOOP_OVER_DIRS)
 	$(LOOP_OVER_TOOL_DIRS)
 
 
 #
 # Rule to create list of libraries for final link
 #
 # todo: use pre-req deps rather than conditionals
--- a/config/makefiles/test/Makefile.in
+++ b/config/makefiles/test/Makefile.in
@@ -15,34 +15,31 @@ USE_AUTOTARGETS_MK  = 1
 MAKEUTILS_UNIT_TEST = 1
 include $(topsrcdir)/config/makefiles/makeutils.mk
 
 dir-ts = .deps/test
 check-arglist        = $(dir-ts)/arglist.ts
 check-autotargets    = $(dir-ts)/autotargets_mk.ts
 check-export-targets = $(dir-ts)/export-targets-mk.ts
 check-XinY           = $(dir-ts)/check_XinY_mk.ts
-check-xpidl          = $(dir-ts)/xpidl-mk.ts
 check-tests =\
   $(check-arglist) \
   $(check-autotargets) \
   $(check-export-targets) \
   $(check-XinY) \
-  $(check-xpidl) \
   $(NULL)
 
 
 ##------------------_##
 ##---]  TARGETS  [---##
 ##------------------_##
 all::
 
 clean:
 	$(RM) $(check-tests)
-	@$(MAKE) --no-print-directory -f $(srcdir)/check-xpidl.mk clean-xpidl topsrcdir=$(topsrcdir)
 
 ###########################################################################
 ## Logic processed at compile time so be selective about when to test
 ## $(MAKE) check VERBOSE=1
 ifneq ($(NULL),$(findstring check,$(MAKECMDGOALS))) #
 
 check-preqs =\
   $(call mkdir_deps,$(dir-ts)) \
@@ -119,28 +116,9 @@ check-export-targets-preqs=\
 
 # include then test
 checkup: $(eval include $(srcdir)/check-export-targets.mk)
 
 $(check-export-targets): $(check-export-targets-preqs)
 	@$(TOUCH) $@
 # </CHECK: export-targets.mk>
 
-###########################################################################
-##{ <CHECK: xpidl.mk>
-check-xpidl-preqs=\
-  $(call mkdir_deps,$(dir-ts)) \
-  $(topsrcdir)/config/config.mk \
-  $(topsrcdir)/config/makefiles/makeutils.mk \
-  $(topsrcdir)/config/makefiles/xpidl.mk \
-  $(srcdir)/check-xpidl.mk \
-  $(NULL)
-
-check-xpidl-args =\
-  "topsrcdir=$(topsrcdir)" \
-  "srcdir=$(srcdir)" \
-  $(NULL)
-$(check-xpidl): $(check-xpidl-preqs)
-	$(MAKE) -f $(srcdir)/check-xpidl.mk check-xpidl $(check-xpidl-args)
-	@$(TOUCH) $@
-#} </check-xpidl.mk>
-
 endif #} findstring MAKECMDGOAL
deleted file mode 100644
--- a/config/makefiles/test/check-xpidl.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# -*- makefile -*-
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this file,
-# You can obtain one at http://mozilla.org/MPL/2.0/.
-
-ifdef VERBOSE
-  $(warning loading test)
-endif
-
-# Limit scope, we only need install_cmd= for testing
-INCLUDED_AUTOCONF_MK = 1
-include $(topsrcdir)/config/config.mk
-
-USE_AUTOTARGETS_MK = 1
-include $(topsrcdir)/config/makefiles/makeutils.mk
-
-basedir  = blah
-DIST     = $(basedir)/dist
-DI       = $(DIST)/include
-IDL_DIR  = $(basedir)/idl
-INSTALL := cp
-
-XPIDLSRCS = $(srcdir)/check-xpidl.mk
-
-include $(topsrcdir)/config/makefiles/xpidl.mk
-
-
-$(call requiredfunction,topsrcdir)
-$(call requiredfunction,XPIDL_GEN_DIR)
-
-HIDE=@
-check-xpidl: xpidl-install-src xpidl-install-headers
-	$(HIDE)test -d $(DIST)                   || exit 90
-	$(HIDE)test -f $(DI)/check-xpidl.mk      || exit 91
-	$(HIDE)test -f $(IDL_DIR)/check-xpidl.mk || exit 92
-
-# Declare targets to avoid including rules.mk
-$(DI) $(IDL_DIR):
-	mkdir -p $@
-
-clean-xpidl:
-	$(RM) -r $(basedir)
deleted file mode 100644
--- a/config/makefiles/xpidl.mk
+++ /dev/null
@@ -1,60 +0,0 @@
-# -*- makefile -*-
-# vim:set ts=8 sw=8 sts=8 noet:
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this file,
-# You can obtain one at http://mozilla.org/MPL/2.0/.
-#
-
-# Always declared, general use by:
-# js/xpconnect/tests/idl/Makefile.in:libs
-# toolkit/crashreporter/test/Makefile.in
-XPIDL_GEN_DIR ?= _xpidlgen
-GARBAGE_DIRS  += $(XPIDL_GEN_DIR)
-
-
-###########################################################################
-## Conditional logic
-###########################################################################
-ifndef INCLUDED_XPIDL_MK #{
-  INCLUDED_XPIDL_MK = 1
-
-  ifneq (,$(XPIDLSRCS)) #{
-
-    ifndef NO_DIST_INSTALL #{
-      _xpidl-todo_ += xpidl-install-src
-      _xpidl-todo_ += xpidl-install-headers
-    endif #}
-
-  endif #} XPIDLSRCS
-
-  export:: $(_xpidl-todo_)
-
-  $(call requiredfunction,mkdir_deps)
-endif #} INCLUDED_XPIDL_MK
-
-
-###########################################################################
-## processing targets
-###########################################################################
-ifdef _xpidl-todo_ #{
-
-$(call requiredfunction,install_cmd)
-
-## Logic batch #1
-xpidl-install-src-preqs=\
-  $(XPIDLSRCS) \
-  $(call mkdir_deps,$(IDL_DIR)) \
-  $(NULL)
-
-xpidl-install-src: $(xpidl-install-src-preqs)
-	$(call install_cmd,$(IFLAGS1) $(foreach val,$^,$(call mkdir_stem,$(val))))
-
-xpidl-install-headers-preqs =\
-  $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.h, $(XPIDLSRCS)) \
-  $(call mkdir_deps,$(DIST)/include) \
-  $(NULL)
-xpidl-install-headers: $(xpidl-install-headers-preqs)
-	$(call install_cmd,$(IFLAGS1) $(foreach val,$^,$(call mkdir_stem,$(val))))
-
-endif #} _xpidl-todo_
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -21,20 +21,22 @@ endif
 ifndef INCLUDED_VERSION_MK
 include $(topsrcdir)/config/version.mk
 endif
 
 USE_AUTOTARGETS_MK = 1
 include $(topsrcdir)/config/makefiles/makeutils.mk
 
 ifdef SDK_XPIDLSRCS
-XPIDLSRCS += $(SDK_XPIDLSRCS)
+_EXTRA_XPIDLSRCS := $(filter-out $(XPIDLSRCS),$(SDK_XPIDLSRCS))
+XPIDLSRCS += $(_EXTRA_XPIDLSRCS)
 endif
 ifdef SDK_HEADERS
-EXPORTS += $(SDK_HEADERS)
+_EXTRA_EXPORTS := $(filter-out $(EXPORTS),$(SDK_HEADERS))
+EXPORTS += $(_EXTRA_EXPORTS)
 endif
 
 REPORT_BUILD = $(info $(notdir $<))
 
 ifeq ($(OS_ARCH),OS2)
 EXEC			=
 else
 EXEC			= exec
@@ -983,23 +985,17 @@ endif
 $(CCOBJS): %.$(OBJ_SUFFIX): %.cc
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
 	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
 
 $(CPPOBJS): %.$(OBJ_SUFFIX): %.cpp
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
-ifdef STRICT_CPLUSPLUS_SUFFIX
-	echo "#line 1 \"$*.cpp\"" | cat - $*.cpp > t_$*.cc
-	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) t_$*.cc
-	$(RM) t_$*.cc
-else
 	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
-endif #STRICT_CPLUSPLUS_SUFFIX
 
 $(CMMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
 	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS)
 
 $(CMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m
 	$(REPORT_BUILD)
@@ -1154,25 +1150,29 @@ ifneq ($(XPI_NAME),)
 $(FINAL_TARGET):
 	$(NSINSTALL) -D $@
 
 export:: $(FINAL_TARGET)
 endif
 
 ifndef NO_DIST_INSTALL
 ifneq (,$(EXPORTS))
-export:: $(EXPORTS)
-	$(call install_cmd,$(IFLAGS1) $^ $(DIST)/include)
+EXPORTS_FILES := $(EXPORTS)
+EXPORTS_DEST := $(DIST)/include
+EXPORTS_TARGET := export
+INSTALL_TARGETS += EXPORTS
 endif
 endif # NO_DIST_INSTALL
 
 define EXPORT_NAMESPACE_RULE
 ifndef NO_DIST_INSTALL
-export:: $(EXPORTS_$(namespace))
-	$(call install_cmd,$(IFLAGS1) $$^ $(DIST)/include/$(namespace))
+EXPORTS_$(namespace)_FILES := $$(EXPORTS_$(namespace))
+EXPORTS_$(namespace)_DEST := $$(DIST)/include/$(namespace)
+EXPORTS_$(namespace)_TARGET := export
+INSTALL_TARGETS += EXPORTS_$(namespace)
 endif # NO_DIST_INSTALL
 endef
 
 $(foreach namespace,$(EXPORTS_NAMESPACES),$(eval $(EXPORT_NAMESPACE_RULE)))
 
 ################################################################################
 # Copy each element of PREF_JS_EXPORTS
 
@@ -1198,24 +1198,22 @@ PREF_JS_EXPORTS_FLAGS := $(PREF_PPFLAGS)
 PP_TARGETS += PREF_JS_EXPORTS
 endif
 endif
 
 ################################################################################
 # Copy each element of AUTOCFG_JS_EXPORTS to $(FINAL_TARGET)/defaults/autoconfig
 
 ifneq ($(AUTOCFG_JS_EXPORTS),)
-$(FINAL_TARGET)/defaults/autoconfig::
-	$(NSINSTALL) -D $@
-
 ifndef NO_DIST_INSTALL
-export:: $(AUTOCFG_JS_EXPORTS) $(FINAL_TARGET)/defaults/autoconfig
-	$(call install_cmd,$(IFLAGS1) $^)
+AUTOCFG_JS_EXPORTS_FILES := $(AUTOCFG_JS_EXPORTS)
+AUTOCFG_JS_EXPORTS_DEST := $(FINAL_TARGET)/defaults/autoconfig
+AUTOCFG_JS_EXPORTS_TARGET := export
+INSTALL_TARGETS += AUTOCFG_JS_EXPORTS
 endif
-
 endif
 
 ################################################################################
 # Export the elements of $(XPIDLSRCS)
 # generating .h and .xpt files and moving them to the appropriate places.
 
 ifneq ($(XPIDLSRCS),) #{
 
@@ -1266,66 +1264,59 @@ xpidl-preqs = \
 	  $(LIBXUL_DIST)/sdk/bin/typelib.py $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
 
 # no need to link together if XPIDLSRCS contains only XPIDL_MODULE
 ifneq ($(XPIDL_MODULE).idl,$(strip $(XPIDLSRCS)))
 $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.xpt,$(XPIDLSRCS)) $(GLOBAL_DEPS)
 	$(XPIDL_LINK) $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.xpt,$(XPIDLSRCS))
 endif # XPIDL_MODULE.xpt != XPIDLSRCS
 
-libs:: $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt
 ifndef NO_DIST_INSTALL
-	$(call install_cmd,$(IFLAGS1) $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt $(FINAL_TARGET)/components)
+XPIDL_MODULE_FILES := $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt
+XPIDL_MODULE_DEST := $(FINAL_TARGET)/components
+INSTALL_TARGETS += XPIDL_MODULE
+
 ifndef NO_INTERFACES_MANIFEST
 libs:: $(call mkdir_deps,$(FINAL_TARGET)/components)
 	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/interfaces.manifest "interfaces $(XPIDL_MODULE).xpt"
 	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest "manifest components/interfaces.manifest"
 endif
 endif
 
 GARBAGE_DIRS		+= $(XPIDL_GEN_DIR)
 
-endif #} XPIDLSRCS
-
-
-ifndef INCLUDED_XPIDL_MK
-  include $(topsrcdir)/config/makefiles/xpidl.mk
-endif
-
-
-# General rules for exporting idl files.
-$(IDL_DIR):
-	$(NSINSTALL) -D $@
+ifndef NO_DIST_INSTALL
+XPIDL_HEADERS_FILES := $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.h, $(XPIDLSRCS))
+XPIDL_HEADERS_DEST := $(DIST)/include
+XPIDL_HEADERS_TARGET := export
+INSTALL_TARGETS += XPIDL_HEADERS
 
-export-idl:: $(SUBMAKEFILES) $(MAKE_DIRS)
-
-ifneq ($(XPIDLSRCS),)
-ifndef NO_DIST_INSTALL
-export-idl:: $(XPIDLSRCS) $(IDL_DIR)
-	$(call install_cmd,$(IFLAGS1) $^)
+XPIDLSRCS_FILES := $(XPIDLSRCS)
+XPIDLSRCS_DEST := $(IDL_DIR)
+XPIDLSRCS_TARGET := export
+INSTALL_TARGETS += XPIDLSRCS
 endif
-endif
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
+endif #} XPIDLSRCS
 
 ################################################################################
 # Copy each element of EXTRA_COMPONENTS to $(FINAL_TARGET)/components
 ifneq (,$(filter %.js,$(EXTRA_COMPONENTS) $(EXTRA_PP_COMPONENTS)))
 ifeq (,$(filter %.manifest,$(EXTRA_COMPONENTS) $(EXTRA_PP_COMPONENTS)))
 ifndef NO_JS_MANIFEST
 $(error .js component without matching .manifest. See https://developer.mozilla.org/en/XPCOM/XPCOM_changes_in_Gecko_2.0)
 endif
 endif
 endif
 
 ifdef EXTRA_COMPONENTS
 libs:: $(EXTRA_COMPONENTS)
 ifndef NO_DIST_INSTALL
-	$(call install_cmd,$(IFLAGS1) $^ $(FINAL_TARGET)/components)
+EXTRA_COMPONENTS_FILES := $(EXTRA_COMPONENTS)
+EXTRA_COMPONENTS_DEST := $(FINAL_TARGET)/components
+INSTALL_TARGETS += EXTRA_COMPONENTS
 endif
 
 endif
 
 ifdef EXTRA_PP_COMPONENTS
 ifndef NO_DIST_INSTALL
 EXTRA_PP_COMPONENTS_PATH := $(FINAL_TARGET)/components
 PP_TARGETS += EXTRA_PP_COMPONENTS
@@ -1339,21 +1330,21 @@ libs:: $(call mkdir_deps,$(FINAL_TARGET)
 endif
 
 ################################################################################
 # Copy each element of EXTRA_JS_MODULES to JS_MODULES_PATH, or
 # $(FINAL_TARGET)/modules if that isn't defined.
 JS_MODULES_PATH ?= $(FINAL_TARGET)/modules
 
 ifdef EXTRA_JS_MODULES
-libs:: $(EXTRA_JS_MODULES)
 ifndef NO_DIST_INSTALL
-	$(call install_cmd,$(IFLAGS1) $^ $(JS_MODULES_PATH))
+EXTRA_JS_MODULES_FILES := $(EXTRA_JS_MODULES)
+EXTRA_JS_MODULES_DEST := $(JS_MODULES_PATH)
+INSTALL_TARGETS += EXTRA_JS_MODULES
 endif
-
 endif
 
 ifdef EXTRA_PP_JS_MODULES
 ifndef NO_DIST_INSTALL
 EXTRA_PP_JS_MODULES_PATH := $(JS_MODULES_PATH)
 PP_TARGETS += EXTRA_PP_JS_MODULES
 endif
 endif
@@ -1365,46 +1356,41 @@ endif
 # objdir/_tests/modules/. If TESTING_JS_MODULE_DIR is defined, that path
 # wlll be appended to the output directory.
 
 ifdef TESTING_JS_MODULES
 testmodulesdir = $(DEPTH)/_tests/modules/$(TESTING_JS_MODULE_DIR)
 
 GENERATED_DIRS += $(testmodulesdir)
 
-libs:: $(TESTING_JS_MODULES)
 ifndef NO_DIST_INSTALL
-	$(call install_cmd,$(IFLAGS) $^ $(testmodulesdir))
+TESTING_JS_MODULES_FILES := $(TESTING_JS_MODULES)
+TESTING_JS_MODULES_DEST := $(testmodulesdir)
+INSTALL_TARGETS += TESTING_JS_MODULES
 endif
 
 endif
 
 ################################################################################
 # SDK
 
 ifneq (,$(SDK_LIBRARY))
-$(SDK_LIB_DIR)::
-	$(NSINSTALL) -D $@
-
 ifndef NO_DIST_INSTALL
-libs:: $(SDK_LIBRARY) $(SDK_LIB_DIR)
-	$(call install_cmd,$(IFLAGS2) $^)
+SDK_LIBRARY_FILES := $(SDK_LIBRARY)
+SDK_LIBRARY_DEST := $(SDK_LIB_DIR)
+INSTALL_TARGETS += SDK_LIBRARY
 endif
-
 endif # SDK_LIBRARY
 
 ifneq (,$(strip $(SDK_BINARY)))
-$(SDK_BIN_DIR)::
-	$(NSINSTALL) -D $@
-
 ifndef NO_DIST_INSTALL
-libs:: $(SDK_BINARY) $(SDK_BIN_DIR)
-	$(call install_cmd,$(IFLAGS2) $^)
+SDK_BINARY_FILES := $(SDK_BINARY)
+SDK_BINARY_DEST := $(SDK_BIN_DIR)
+INSTALL_TARGETS += SDK_BINARY
 endif
-
 endif # SDK_BINARY
 
 ################################################################################
 # CHROME PACKAGING
 
 JAR_MANIFEST := $(srcdir)/jar.mn
 
 chrome::
@@ -1530,61 +1516,78 @@ TAGS:: $(CSRCS) $(CPPSRCS) $(HEADERS)
 	$(ETAGS) $(CSRCS) $(CPPSRCS) $(HEADERS)
 endif
 endif
 
 ################################################################################
 # Install/copy rules
 #
 # The INSTALL_TARGETS variable contains a list of all install target
-# categories. Each category defines a list of files, an install destination,
-# and whether the files are executables or not.
+# categories. Each category defines a list of files and executables, and an
+# install destination,
 #
 # FOO_FILES := foo bar
 # FOO_EXECUTABLES := baz
 # FOO_DEST := target_path
 # INSTALL_TARGETS += FOO
+#
+# Additionally, a FOO_TARGET variable may be added to indicate the target for
+# which the files and executables are installed. Default is "libs".
+
+# If we're using binary nsinstall and it's not built yet, fallback to python nsinstall.
+ifneq (,$(filter $(CONFIG_TOOLS)/nsinstall$(HOST_BIN_SUFFIX),$(install_cmd)))
+nsinstall_is_usable = $(if $(wildcard $(CONFIG_TOOLS)/nsinstall$(HOST_BIN_SUFFIX)),$(eval nsinstall_is_usable := yes)yes)
+
+define install_cmd_override
+$(1): install_cmd = $$(if $$(nsinstall_is_usable),$$(INSTALL),$$(NSINSTALL_PY)) $$(1)
+endef
+endif
+
 define install_file_template
-libs:: $(2)/$(notdir $(1))
+$(or $(3),libs):: $(2)/$(notdir $(1))
+$(call install_cmd_override,$(2)/$(notdir $(1)))
 $(2)/$(notdir $(1)): $(1) $$(call mkdir_deps,$(2))
-	$(INSTALL) $(3) $$< $${@D}
+	$$(call install_cmd,$(4) $$< $${@D})
 endef
 $(foreach category,$(INSTALL_TARGETS),\
   $(if $($(category)_DEST),,$(error Missing $(category)_DEST))\
   $(foreach file,$($(category)_FILES),\
-    $(eval $(call install_file_template,$(file),$($(category)_DEST),$(IFLAGS1)))\
+    $(eval $(call install_file_template,$(file),$($(category)_DEST),$($(category)_TARGET),$(IFLAGS1)))\
   )\
   $(foreach file,$($(category)_EXECUTABLES),\
-    $(eval $(call install_file_template,$(file),$($(category)_DEST),$(IFLAGS2)))\
+    $(eval $(call install_file_template,$(file),$($(category)_DEST),$($(category)_TARGET),$(IFLAGS2)))\
   )\
 )
 
 ################################################################################
 # Preprocessing rules
 #
 # The PP_TARGETS variable contains a list of all preprocessing target
 # categories. Each category defines a target path, and optional extra flags
 # like the following:
 #
 # FOO_PATH := target_path
 # FOO_FLAGS := -Dsome_flag
 # PP_TARGETS += FOO
+#
+# Additionally, a FOO_TARGET variable may be added to indicate the target for
+# which the files and executables are installed. Default is "libs".
 
 # preprocess_file_template defines preprocessing rules.
 # $(call preprocess_file_template, source_file, target_path, extra_flags)
 define preprocess_file_template
 $(2)/$(notdir $(1)): $(1) $$(call mkdir_deps,$(2)) $$(GLOBAL_DEPS)
 	$$(RM) $$@
-	$$(PYTHON) $$(topsrcdir)/config/Preprocessor.py $(3) $$(DEFINES) $$(ACDEFINES) $$(XULPPFLAGS) $$< > $$@
-libs:: $(2)/$(notdir $(1))
+	$$(PYTHON) $$(topsrcdir)/config/Preprocessor.py $(4) $$(DEFINES) $$(ACDEFINES) $$(XULPPFLAGS) $$< > $$@
+$(or $(3),libs):: $(2)/$(notdir $(1))
 endef
 
 $(foreach category,$(PP_TARGETS),\
   $(foreach file,$($(category)),\
-    $(eval $(call preprocess_file_template,$(file),$($(category)_PATH),$($(category)_FLAGS)))\
+    $(eval $(call preprocess_file_template,$(file),$($(category)_PATH),$($(category)_TARGET),$($(category)_FLAGS)))\
    )\
  )
 
 ################################################################################
 # Special gmake rules.
 ################################################################################
 
 
--- a/configure.in
+++ b/configure.in
@@ -186,17 +186,17 @@ if test -n "$gonkdir" ; then
     arm)
         ARCH_DIR=arch-arm
         ;;
     i?86)
         ARCH_DIR=arch-x86
         ;;
     esac
 
-    CPPFLAGS="-DANDROID -isystem $gonkdir/bionic/libc/$ARCH_DIR/include -isystem $gonkdir/bionic/libc/include/ -isystem $gonkdir/bionic/libc/kernel/common -isystem $gonkdir/bionic/libc/kernel/$ARCH_DIR -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 -I$gonkdir/system/core/include -isystem $gonkdir/bionic -I$gonkdir/frameworks/base/include -I$gonkdir/external/dbus $CPPFLAGS -I$gonkdir/frameworks/base/services/sensorservice -I$gonkdir/frameworks/base/services/camera -I$gonkdir/system/media/wilhelm/include"
+    CPPFLAGS="-DANDROID -isystem $gonkdir/bionic/libc/$ARCH_DIR/include -isystem $gonkdir/bionic/libc/include/ -isystem $gonkdir/bionic/libc/kernel/common -isystem $gonkdir/bionic/libc/kernel/$ARCH_DIR -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 -I$gonkdir/system/core/include -isystem $gonkdir/bionic -I$gonkdir/frameworks/base/include -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib $CPPFLAGS -I$gonkdir/frameworks/base/services/sensorservice -I$gonkdir/frameworks/base/services/camera -I$gonkdir/system/media/wilhelm/include"
     CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS"
     CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions -Wno-psabi $CXXFLAGS $STLPORT_CPPFLAGS"
     dnl Add -llog by default, since we use it all over the place.
     LIBS="$LIBS -llog $STLPORT_LIBS"
 
     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/ $LDFLAGS"
 
     dnl prevent cross compile section from using these flags as host flags
@@ -3849,48 +3849,49 @@ else
         NSPR_CFLAGS=`"${LIBXUL_DIST}"/sdk/bin/nspr-config --prefix="${LIBXUL_DIST}" --includedir="${LIBXUL_DIST}/include/nspr" --cflags`
         NSPR_LIBS=`"${LIBXUL_DIST}"/sdk/bin/nspr-config --prefix="${LIBXUL_DIST}" --libdir="${LIBXUL_DIST}"/lib --libs`
     fi
 fi
 
 dnl system libevent Support
 dnl ========================================================
 MOZ_ARG_WITH_STRING(system-libevent,
-[  --with-system-libevent=[PFX]
+[  --with-system-libevent[=PFX]
                           Use system libevent [installed at prefix PFX]],
     LIBEVENT_DIR=$withval)
 
 _SAVE_CFLAGS=$CFLAGS
 _SAVE_LDFLAGS=$LDFLAGS
 _SAVE_LIBS=$LIBS
 if test -z "$LIBEVENT_DIR" -o "$LIBEVENT_DIR" = no; then
     MOZ_NATIVE_LIBEVENT=
+elif test "$LIBEVENT_DIR" = yes; then
+    PKG_CHECK_MODULES(MOZ_LIBEVENT, libevent,
+        MOZ_NATIVE_LIBEVENT=1,
+        AC_MSG_ERROR([--with-system-libevent requested but libevent package not found]))
 else
-    if test "${LIBEVENT_DIR}" = "yes"; then
-        LIBEVENT_DIR=/usr
-    fi
     CFLAGS="-I${LIBEVENT_DIR}/include $CFLAGS"
     LDFLAGS="-L${LIBEVENT_DIR}/lib $LDFLAGS"
     MOZ_CHECK_HEADER(event.h,
         [if test ! -f "${LIBEVENT_DIR}/include/event.h"; then
              AC_MSG_ERROR([event.h found, but is not in ${LIBEVENT_DIR}/include])
          fi],
         AC_MSG_ERROR([--with-system-libevent requested but event.h not found]))
     AC_CHECK_LIB(event, event_init,
                  [MOZ_NATIVE_LIBEVENT=1
-                  MOZ_LIBEVENT_INCLUDES="${LIBEVENT_DIR}/include"
+                  MOZ_LIBEVENT_CFLAGS="-I${LIBEVENT_DIR}/include"
                   MOZ_LIBEVENT_LIBS="-L${LIBEVENT_DIR}/lib -levent"],
-                 [MOZ_NATIVE_LIBEVENT= MOZ_LIBEVENT_INCLUDES= MOZ_LIBEVENT_LIBS=])
+                 [MOZ_NATIVE_LIBEVENT= MOZ_LIBEVENT_CFLAGS= MOZ_LIBEVENT_LIBS=])
 fi
 CFLAGS=$_SAVE_CFLAGS
 LDFLAGS=$_SAVE_LDFLAGS
 LIBS=$_SAVE_LIBS
 
 AC_SUBST(MOZ_NATIVE_LIBEVENT)
-AC_SUBST(MOZ_LIBEVENT_INCLUDES)
+AC_SUBST(MOZ_LIBEVENT_CFLAGS)
 AC_SUBST(MOZ_LIBEVENT_LIBS)
 
 dnl ========================================================
 dnl = If NSS was not detected in the system,
 dnl = use the one in the source tree (mozilla/security/nss)
 dnl ========================================================
 
 MOZ_ARG_WITH_BOOL(system-nss,
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -37,16 +37,17 @@ nsContentCID.h \
 nsCopySupport.h \
 nsContentCreatorFunctions.h \
 nsDOMFile.h \
 nsLineBreaker.h \
 nsReferencedElement.h \
 nsTreeSanitizer.h \
 nsXMLNameSpaceMap.h \
 nsIXFormsUtilityService.h \
+nsBlobProtocolHandler.h \
 $(NULL)
 
 EXPORTS_NAMESPACES = mozilla/dom mozilla
 
 EXPORTS_mozilla/dom = \
 		DirectionalityUtils.h \
 		Element.h \
 		FragmentOrElement.h \
new file mode 100644
--- /dev/null
+++ b/content/base/public/nsBlobProtocolHandler.h
@@ -0,0 +1,51 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsBlobProtocolHandler_h
+#define nsBlobProtocolHandler_h
+
+#include "nsIProtocolHandler.h"
+#include "nsIURI.h"
+#include "nsCOMPtr.h"
+
+#define BLOBURI_SCHEME "blob"
+
+class nsIDOMBlob;
+class nsIPrincipal;
+class nsIInputStream;
+
+inline bool IsBlobURI(nsIURI* aUri)
+{
+  bool isBlob;
+  return NS_SUCCEEDED(aUri->SchemeIs(BLOBURI_SCHEME, &isBlob)) && isBlob;
+}
+
+extern nsresult
+NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream);
+
+class nsBlobProtocolHandler : public nsIProtocolHandler
+{
+public:
+  NS_DECL_ISUPPORTS
+
+  // nsIProtocolHandler methods:
+  NS_DECL_NSIPROTOCOLHANDLER
+
+  // nsBlobProtocolHandler methods:
+  nsBlobProtocolHandler() {}
+  virtual ~nsBlobProtocolHandler() {}
+
+  // Methods for managing uri->file mapping
+  static void AddFileDataEntry(nsACString& aUri,
+                               nsIDOMBlob* aFile,
+                               nsIPrincipal* aPrincipal);
+  static void RemoveFileDataEntry(nsACString& aUri);
+  static nsIPrincipal* GetFileDataEntryPrincipal(nsACString& aUri);
+};
+
+#define NS_BLOBPROTOCOLHANDLER_CID \
+{ 0xb43964aa, 0xa078, 0x44b2, \
+  { 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } }
+
+#endif /* nsBlobProtocolHandler_h */
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -13,27 +13,16 @@
 #if defined(XP_WIN) || defined(XP_OS2)
 #include <float.h>
 #endif
 
 #if defined(SOLARIS)
 #include <ieeefp.h>
 #endif
 
-//A trick to handle IEEE floating point exceptions on FreeBSD - E.D.
-#ifdef __FreeBSD__
-#include <ieeefp.h>
-#if !defined(__i386__) && !defined(__x86_64__)
-static fp_except_t allmask = FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP;
-#else
-static fp_except_t allmask = FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP|FP_X_DNML;
-#endif
-static fp_except_t oldmask = fpsetmask(~allmask);
-#endif
-
 #include "nsAString.h"
 #include "nsIStatefulFrame.h"
 #include "nsNodeInfoManager.h"
 #include "nsIXPCScriptable.h"
 #include "nsDataHashtable.h"
 #include "nsIDOMEvent.h"
 #include "nsTArray.h"
 #include "nsReadableUtils.h"
@@ -41,16 +30,18 @@ static fp_except_t oldmask = fpsetmask(~
 #include "nsIDOMNode.h"
 #include "nsHtml5StringParser.h"
 #include "nsIDocument.h"
 #include "nsContentSink.h"
 #include "nsMathUtils.h"
 #include "nsThreadUtils.h"
 #include "nsIContent.h"
 #include "nsCharSeparatedTokenizer.h"
+#include "gfxContext.h"
+#include "gfxFont.h"
 
 #include "mozilla/AutoRestore.h"
 #include "mozilla/GuardObjects.h"
 #include "mozilla/TimeStamp.h"
 
 struct nsNativeKeyEvent; // Don't include nsINativeKeyBindings.h here: it will force strange compilation error!
 
 class nsIDOMScriptObjectFactory;
@@ -108,16 +99,17 @@ class nsIMIMEHeaderParam;
 class nsIObserver;
 class nsPresContext;
 class nsIChannel;
 class nsAutoScriptBlockerSuppressNodeRemoved;
 struct nsIntMargin;
 class nsPIDOMWindow;
 class nsIDocumentLoaderFactory;
 class nsIDOMHTMLInputElement;
+class gfxTextObjectPaint;
 
 namespace mozilla {
 
 class Selection;
 
 namespace layers {
   class LayerManager;
 } // namespace layers
@@ -2078,16 +2070,23 @@ public:
    */
   static void GetSelectionInTextControl(mozilla::Selection* aSelection,
                                         Element* aRoot,
                                         int32_t& aOutStartOffset,
                                         int32_t& aOutEndOffset);
 
   static nsIEditor* GetHTMLEditor(nsPresContext* aPresContext);
 
+  static bool PaintSVGGlyph(Element *aElement, gfxContext *aContext,
+                            gfxFont::DrawMode aDrawMode,
+                            gfxTextObjectPaint *aObjectPaint);
+
+  static bool GetSVGGlyphExtents(Element *aElement, const gfxMatrix& aSVGToAppSpace,
+                                 gfxRect *aResult);
+
 private:
   static bool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
                                 nsIPrincipal* aPrincipal);
 
--- a/content/base/src/FileIOObject.cpp
+++ b/content/base/src/FileIOObject.cpp
@@ -160,17 +160,17 @@ FileIOObject::DoOnStartRequest(nsIReques
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FileIOObject::OnDataAvailable(nsIRequest *aRequest,
                               nsISupports *aContext,
                               nsIInputStream *aInputStream,
-                              uint32_t aOffset,
+                              uint64_t aOffset,
                               uint32_t aCount)
 {
   nsresult rv;
   rv = DoOnDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mTransferred += aCount;
 
--- a/content/base/src/FileIOObject.h
+++ b/content/base/src/FileIOObject.h
@@ -63,17 +63,17 @@ protected:
   // special handling
   NS_IMETHOD DoOnStartRequest(nsIRequest *aRequest, nsISupports *aContext);
   // for onStopRequest
   NS_IMETHOD DoOnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
                              nsresult aStatus, nsAString& aSuccessEvent,
                              nsAString& aTerminationEvent) = 0;
   // and for onDataAvailable
   NS_IMETHOD DoOnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
-                               nsIInputStream *aInputStream, uint32_t aOffset,
+                               nsIInputStream *aInputStream, uint64_t aOffset,
                                uint32_t aCount) = 0;
 
   void StartProgressEventTimer();
   void ClearProgressEventTimer();
   void DispatchError(nsresult rv, nsAString& finalEvent);
   nsresult DispatchProgressEvent(const nsAString& aType);
 
   nsCOMPtr<nsITimer> mProgressNotifier;
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -176,16 +176,17 @@ INCLUDES	+= \
 		-I$(srcdir)/../../../layout/xul/base/src \
 		-I$(srcdir)/../../xul/content/src \
 		-I$(srcdir)/../../xul/document/src \
 		-I$(srcdir)/../../html/content/src \
 		-I$(srcdir)/../../base/src \
 		-I$(srcdir)/../../xbl/src \
 		-I$(srcdir)/../../../layout/generic \
 		-I$(srcdir)/../../../layout/style \
+		-I$(srcdir)/../../../layout/svg/base/src \
 		-I$(srcdir)/../../../dom/base \
 		-I$(srcdir)/../../xml/document/src \
 		-I$(topsrcdir)/xpcom/io \
 		-I$(topsrcdir)/dom/ipc \
 		-I$(topsrcdir)/js/xpconnect/src \
 		-I$(topsrcdir)/caps/include \
 		-I$(topsrcdir)/netwerk/base/src \
 		$(NULL)
--- a/content/base/src/nsAttrAndChildArray.cpp
+++ b/content/base/src/nsAttrAndChildArray.cpp
@@ -559,18 +559,17 @@ nsAttrAndChildArray::SetAndTakeMappedAtt
   bool willAdd = true;
   if (mImpl && mImpl->mMappedAttrs) {
     willAdd = !mImpl->mMappedAttrs->GetAttr(aLocalName);
   }
 
   nsRefPtr<nsMappedAttributes> mapped =
     GetModifiableMapped(aContent, aSheet, willAdd);
 
-  nsresult rv = mapped->SetAndTakeAttr(aLocalName, aValue);
-  NS_ENSURE_SUCCESS(rv, rv);
+  mapped->SetAndTakeAttr(aLocalName, aValue);
 
   return MakeMappedUnique(mapped);
 }
 
 nsresult
 nsAttrAndChildArray::DoSetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet)
 {
   NS_PRECONDITION(mImpl && mImpl->mMappedAttrs,
--- a/content/base/src/nsBlobProtocolHandler.cpp
+++ b/content/base/src/nsBlobProtocolHandler.cpp
@@ -158,18 +158,18 @@ nsBlobProtocolHandler::NewChannel(nsIURI
 #endif
 
   nsCOMPtr<nsIInputStream> stream;
   nsresult rv = info->mFile->GetInternalStream(getter_AddRefs(stream));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIChannel> channel;
   rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
-				uri,
-				stream);
+                                uri,
+                                stream);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsISupports> owner = do_QueryInterface(info->mPrincipal);
 
   nsAutoString type;
   rv = info->mFile->GetType(type);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -190,8 +190,28 @@ nsBlobProtocolHandler::NewChannel(nsIURI
 NS_IMETHODIMP
 nsBlobProtocolHandler::AllowPort(int32_t port, const char *scheme,
                                      bool *_retval)
 {
     // don't override anything.
     *_retval = false;
     return NS_OK;
 }
+
+nsresult
+NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
+{
+  NS_ASSERTION(IsBlobURI(aURI), "Only call this with blob URIs");
+
+  *aStream = nullptr;
+
+  nsCString spec;
+  aURI->GetSpec(spec);
+
+  FileDataInfo* info =
+    GetFileDataInfo(spec);
+
+  if (!info) {
+    return NS_ERROR_DOM_BAD_URI;
+  }
+
+  return info->mFile->GetInternalStream(aStream);
+}
--- a/content/base/src/nsBlobProtocolHandler.h
+++ b/content/base/src/nsBlobProtocolHandler.h
@@ -1,40 +1,51 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsBlobProtocolHandler_h
 #define nsBlobProtocolHandler_h
 
 #include "nsIProtocolHandler.h"
+#include "nsIURI.h"
+#include "nsCOMPtr.h"
 
 #define BLOBURI_SCHEME "blob"
 
 class nsIDOMBlob;
 class nsIPrincipal;
+class nsIInputStream;
+
+inline bool IsBlobURI(nsIURI* aUri)
+{
+  bool isBlob;
+  return NS_SUCCEEDED(aUri->SchemeIs(BLOBURI_SCHEME, &isBlob)) && isBlob;
+}
+
+extern nsresult
+NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream);
 
 class nsBlobProtocolHandler : public nsIProtocolHandler
 {
 public:
   NS_DECL_ISUPPORTS
 
   // nsIProtocolHandler methods:
   NS_DECL_NSIPROTOCOLHANDLER
 
   // nsBlobProtocolHandler methods:
   nsBlobProtocolHandler() {}
   virtual ~nsBlobProtocolHandler() {}
 
   // Methods for managing uri->file mapping
   static void AddFileDataEntry(nsACString& aUri,
-			       nsIDOMBlob* aFile,
+                               nsIDOMBlob* aFile,
                                nsIPrincipal* aPrincipal);
   static void RemoveFileDataEntry(nsACString& aUri);
   static nsIPrincipal* GetFileDataEntryPrincipal(nsACString& aUri);
-  
 };
 
 #define NS_BLOBPROTOCOLHANDLER_CID \
 { 0xb43964aa, 0xa078, 0x44b2, \
   { 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } }
 
 #endif /* nsBlobProtocolHandler_h */
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -117,16 +117,20 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 #include "nsIViewManager.h"
 #include "nsEventStateManager.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsParserConstants.h"
 #include "nsIWebNavigation.h"
 #include "nsILoadContext.h"
 #include "nsTextFragment.h"
 #include "mozilla/Selection.h"
+#include "nsSVGUtils.h"
+#include "nsISVGChildFrame.h"
+#include "nsRenderingContext.h"
+#include "gfxSVGGlyphs.h"
 
 #ifdef IBMBIDI
 #include "nsIBidiKeyboard.h"
 #endif
 #include "nsCycleCollectionParticipant.h"
 
 // for ReportToConsole
 #include "nsIStringBundle.h"
@@ -3593,31 +3597,49 @@ nsContentUtils::ConvertStringFromCharset
 
   nsCOMPtr<nsIUnicodeDecoder> decoder;
   rv = ccm->GetUnicodeDecoder(PromiseFlatCString(aCharset).get(),
                               getter_AddRefs(decoder));
   if (NS_FAILED(rv))
     return rv;
 
   nsPromiseFlatCString flatInput(aInput);
-  int32_t srcLen = flatInput.Length();
-  int32_t dstLen;
-  rv = decoder->GetMaxLength(flatInput.get(), srcLen, &dstLen);
+  int32_t length = flatInput.Length();
+  int32_t outLen;
+  rv = decoder->GetMaxLength(flatInput.get(), length, &outLen);
   if (NS_FAILED(rv))
     return rv;
 
-  PRUnichar *ustr = (PRUnichar *)nsMemory::Alloc((dstLen + 1) *
+  PRUnichar *ustr = (PRUnichar *)nsMemory::Alloc((outLen + 1) *
                                                  sizeof(PRUnichar));
   if (!ustr)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  rv = decoder->Convert(flatInput.get(), &srcLen, ustr, &dstLen);
-  if (NS_SUCCEEDED(rv)) {
+  const char* data = flatInput.get();
+  aOutput.Truncate();
+  for (;;) {
+    int32_t srcLen = length;
+    int32_t dstLen = outLen;
+    rv = decoder->Convert(data, &srcLen, ustr, &dstLen);
+    // Convert will convert the input partially even if the status
+    // indicates a failure.
     ustr[dstLen] = 0;
-    aOutput.Assign(ustr, dstLen);
+    aOutput.Append(ustr, dstLen);
+    if (rv != NS_ERROR_ILLEGAL_INPUT) {
+      break;
+    }
+    // Emit a decode error manually because some decoders
+    // do not support kOnError_Recover (bug 638379)
+    if (srcLen == -1) {
+      decoder->Reset();
+    } else {
+      data += srcLen + 1;
+      length -= srcLen + 1;
+      aOutput.Append(static_cast<PRUnichar>(0xFFFD));
+    }
   }
 
   nsMemory::Free(ustr);
   return rv;
 }
 
 /* static */
 bool
@@ -6922,16 +6944,70 @@ nsContentUtils::JSArrayToAtomArray(JSCon
     if (!a) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     aRetVal.AppendObject(a);
   }
   return NS_OK;
 }
 
+/* static */
+bool
+nsContentUtils::PaintSVGGlyph(Element *aElement, gfxContext *aContext,
+                              gfxFont::DrawMode aDrawMode,
+                              gfxTextObjectPaint *aObjectPaint)
+{
+  nsIFrame *frame = aElement->GetPrimaryFrame();
+  if (!frame) {
+    NS_WARNING("No frame for SVG glyph");
+    return false;
+  }
+
+  nsISVGChildFrame *displayFrame = do_QueryFrame(frame);
+  if (!displayFrame) {
+    NS_WARNING("Non SVG frame for SVG glyph");
+    return false;
+  }
+
+  nsRenderingContext context;
+
+  context.Init(frame->PresContext()->DeviceContext(), aContext);
+  context.AddUserData(&gfxTextObjectPaint::sUserDataKey, aObjectPaint, nullptr);
+
+  nsresult rv = displayFrame->PaintSVG(&context, nullptr);
+  NS_ENSURE_SUCCESS(rv, false);
+
+  return true;
+}
+
+/* static */
+bool
+nsContentUtils::GetSVGGlyphExtents(Element *aElement, const gfxMatrix& aSVGToAppSpace,
+                                   gfxRect *aResult)
+{
+  nsIFrame *frame = aElement->GetPrimaryFrame();
+  if (!frame) {
+    NS_WARNING("No frame for SVG glyph");
+    return false;
+  }
+
+  nsISVGChildFrame *displayFrame = do_QueryFrame(frame);
+  if (!displayFrame) {
+    NS_WARNING("Non SVG frame for SVG glyph");
+    return false;
+  }
+
+  *aResult = displayFrame->GetBBoxContribution(aSVGToAppSpace,
+      nsSVGUtils::eBBoxIncludeFill | nsSVGUtils::eBBoxIncludeFillGeometry |
+      nsSVGUtils::eBBoxIncludeStroke | nsSVGUtils::eBBoxIncludeStrokeGeometry |
+      nsSVGUtils::eBBoxIncludeMarkers);
+
+  return true;
+}
+
 // static
 void
 nsContentUtils::GetSelectionInTextControl(Selection* aSelection,
                                           Element* aRoot,
                                           int32_t& aOutStartOffset,
                                           int32_t& aOutEndOffset)
 {
   MOZ_ASSERT(aSelection && aRoot);
--- a/content/base/src/nsCrossSiteListenerProxy.cpp
+++ b/content/base/src/nsCrossSiteListenerProxy.cpp
@@ -609,17 +609,17 @@ nsCORSListenerProxy::OnStopRequest(nsIRe
   mNewRedirectChannel = nullptr;
   return rv;
 }
 
 NS_IMETHODIMP
 nsCORSListenerProxy::OnDataAvailable(nsIRequest* aRequest,
                                      nsISupports* aContext, 
                                      nsIInputStream* aInputStream,
-                                     uint32_t aOffset,
+                                     uint64_t aOffset,
                                      uint32_t aCount)
 {
   if (!mRequestApproved) {
     return NS_ERROR_DOM_BAD_URI;
   }
   return mOuterListener->OnDataAvailable(aRequest, aContext, aInputStream,
                                          aOffset, aCount);
 }
@@ -1001,17 +1001,17 @@ nsCORSPreflightListener::OnStopRequest(n
 }
 
 /** nsIStreamListener methods **/
 
 NS_IMETHODIMP
 nsCORSPreflightListener::OnDataAvailable(nsIRequest *aRequest,
                                          nsISupports *ctxt,
                                          nsIInputStream *inStr,
-                                         uint32_t sourceOffset,
+                                         uint64_t sourceOffset,
                                          uint32_t count)
 {
   uint32_t totalRead;
   return inStr->ReadSegments(NS_DiscardSegment, nullptr, count, &totalRead);
 }
 
 NS_IMETHODIMP
 nsCORSPreflightListener::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -281,24 +281,27 @@ ReadFuncBinaryString(nsIInputStream* in,
 
   return NS_OK;
 }
 
 nsresult
 nsDOMFileReader::DoOnDataAvailable(nsIRequest *aRequest,
                                    nsISupports *aContext,
                                    nsIInputStream *aInputStream,
-                                   uint32_t aOffset,
+                                   uint64_t aOffset,
                                    uint32_t aCount)
 {
   if (mDataFormat == FILE_AS_BINARY) {
     //Continuously update our binary string as data comes in
     NS_ASSERTION(mResult.Length() == aOffset,
                  "unexpected mResult length");
     uint32_t oldLen = mResult.Length();
+    if (uint64_t(oldLen) + aCount > PR_UINT32_MAX)
+      return NS_ERROR_OUT_OF_MEMORY;
+
     PRUnichar *buf = nullptr;
     mResult.GetMutableData(&buf, oldLen + aCount, fallible_t());
     NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
 
     uint32_t bytesRead = 0;
     aInputStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount,
                                &bytesRead);
     NS_ASSERTION(bytesRead == aCount, "failed to read data");
@@ -306,16 +309,20 @@ nsDOMFileReader::DoOnDataAvailable(nsIRe
   else if (mDataFormat == FILE_AS_ARRAYBUFFER) {
     uint32_t bytesRead = 0;
     aInputStream->Read((char*)JS_GetArrayBufferData(mResultArrayBuffer, NULL) + aOffset,
                        aCount, &bytesRead);
     NS_ASSERTION(bytesRead == aCount, "failed to read data");
   }
   else {
     //Update memory buffer to reflect the contents of the file
+    if (aOffset + aCount > PR_UINT32_MAX) {
+      // PR_Realloc doesn't support over 4GB memory size even if 64-bit OS
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
     mFileData = (char *)PR_Realloc(mFileData, aOffset + aCount);
     NS_ENSURE_TRUE(mFileData, NS_ERROR_OUT_OF_MEMORY);
 
     uint32_t bytesRead = 0;
     aInputStream->Read(mFileData + aOffset, aCount, &bytesRead);
     NS_ASSERTION(bytesRead == aCount, "failed to read data");
 
     mDataLen += aCount;
--- a/content/base/src/nsDOMFileReader.h
+++ b/content/base/src/nsDOMFileReader.h
@@ -52,17 +52,17 @@ public:
                         uint32_t argc, jsval* argv);
 
   // FileIOObject overrides
   NS_IMETHOD DoAbort(nsAString& aEvent);
   NS_IMETHOD DoOnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                              nsresult aStatus, nsAString& aSuccessEvent,
                              nsAString& aTerminationEvent);
   NS_IMETHOD DoOnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
-                               nsIInputStream* aInputStream, uint32_t aOffset,
+                               nsIInputStream* aInputStream, uint64_t aOffset,
                                uint32_t aCount);
 
   nsresult Init();
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsDOMFileReader,
                                                          FileIOObject)
   void RootResultArrayBuffer();
 
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1018,17 +1018,17 @@ nsExternalResourceMap::PendingLoad::Setu
   newLoadGroup.forget(aLoadGroup);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsExternalResourceMap::PendingLoad::OnDataAvailable(nsIRequest* aRequest,
                                                     nsISupports* aContext,
                                                     nsIInputStream* aStream,
-                                                    uint32_t aOffset,
+                                                    uint64_t aOffset,
                                                     uint32_t aCount)
 {
   NS_PRECONDITION(mTargetListener, "Shouldn't be getting called!");
   if (mDisplayDocument->ExternalResourceMap().HaveShutDown()) {
     return NS_BINDING_ABORTED;
   }
   return mTargetListener->OnDataAvailable(aRequest, aContext, aStream, aOffset,
                                           aCount);
--- a/content/base/src/nsEventSource.cpp
+++ b/content/base/src/nsEventSource.cpp
@@ -532,17 +532,17 @@ nsEventSource::StreamReaderFunc(nsIInput
   *aWriteCount = aCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsEventSource::OnDataAvailable(nsIRequest *aRequest,
                                nsISupports *aContext,
                                nsIInputStream *aInputStream,
-                               uint32_t aOffset,
+                               uint64_t aOffset,
                                uint32_t aCount)
 {
   NS_ENSURE_ARG_POINTER(aInputStream);
 
   nsresult rv = CheckHealthOfRequestCallback(aRequest);
   NS_ENSURE_SUCCESS(rv, rv);
 
   uint32_t totalRead;
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -86,16 +86,20 @@
 #include "nsIAppsService.h"
 
 #include "jsapi.h"
 #include "nsHTMLIFrameElement.h"
 #include "nsSandboxFlags.h"
 
 #include "mozilla/dom/StructuredCloneUtils.h"
 
+#ifdef MOZ_XUL
+#include "nsXULPopupManager.h"
+#endif
+
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 typedef FrameMetrics::ViewID ViewID;
 
 class nsAsyncDocShellDestroyer : public nsRunnable
 {
@@ -301,16 +305,17 @@ nsFrameLoader::nsFrameLoader(Element* aO
   , mHideCalled(false)
   , mNetworkCreated(aNetworkCreated)
   , mDelayRemoteDialogs(false)
   , mRemoteBrowserShown(false)
   , mRemoteFrame(false)
   , mClipSubdocument(true)
   , mClampScrollPosition(true)
   , mRemoteBrowserInitialized(false)
+  , mObservingOwnerContent(false)
   , mCurrentRemoteFrame(nullptr)
   , mRemoteBrowser(nullptr)
   , mRenderMode(RENDER_MODE_DEFAULT)
   , mEventMode(EVENT_MODE_NORMAL_DISPATCH)
 {
 }
 
 nsFrameLoader*
@@ -652,52 +657,47 @@ SetTreeOwnerAndChromeEventHandlerOnDocsh
     aItem->GetChildAt(i, getter_AddRefs(item));
     SetTreeOwnerAndChromeEventHandlerOnDocshellTree(item, aOwner, aHandler);
   }
 }
 
 /**
  * Set the type of the treeitem and hook it up to the treeowner.
  * @param aItem the treeitem we're working with
- * @param aOwningContent the content node that owns aItem
  * @param aTreeOwner the relevant treeowner; might be null
  * @param aParentType the nsIDocShellTreeItem::GetType of our parent docshell
  * @param aParentNode if non-null, the docshell we should be added as a child to
  *
  * @return whether aItem is top-level content
  */
-static bool
-AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem, nsIContent* aOwningContent,
-                       nsIDocShellTreeOwner* aOwner, int32_t aParentType,
-                       nsIDocShellTreeNode* aParentNode)
+bool
+nsFrameLoader::AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem,
+                                      nsIDocShellTreeOwner* aOwner,
+                                      int32_t aParentType,
+                                      nsIDocShellTreeNode* aParentNode)
 {
   NS_PRECONDITION(aItem, "Must have docshell treeitem");
-  NS_PRECONDITION(aOwningContent, "Must have owning content");
+  NS_PRECONDITION(mOwnerContent, "Must have owning content");
   
   nsAutoString value;
   bool isContent = false;
-
-  if (aOwningContent->IsXUL()) {
-      aOwningContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
-  } else {
-      aOwningContent->GetAttr(kNameSpaceID_None, nsGkAtoms::mozframetype, value);
-  }
+  mOwnerContent->GetAttr(kNameSpaceID_None, TypeAttrName(), value);
 
   // we accept "content" and "content-xxx" values.
   // at time of writing, we expect "xxx" to be "primary" or "targetable", but
   // someday it might be an integer expressing priority or something else.
 
   isContent = value.LowerCaseEqualsLiteral("content") ||
     StringBeginsWith(value, NS_LITERAL_STRING("content-"),
                      nsCaseInsensitiveStringComparator());
 
   // Force mozbrowser frames to always be typeContent, even if the
   // mozbrowser interfaces are disabled.
   nsCOMPtr<nsIDOMMozBrowserFrame> mozbrowser =
-    do_QueryInterface(aOwningContent);
+    do_QueryInterface(mOwnerContent);
   if (mozbrowser) {
     bool isMozbrowser = false;
     mozbrowser->GetMozbrowser(&isMozbrowser);
     isContent |= isMozbrowser;
   }
 
   if (isContent) {
     // The web shell's type is content.
@@ -720,16 +720,18 @@ AddTreeItemToTreeOwner(nsIDocShellTreeIt
   if (aParentType == nsIDocShellTreeItem::typeChrome && isContent) {
     retval = true;
 
     bool is_primary = value.LowerCaseEqualsLiteral("content-primary");
 
     if (aOwner) {
       bool is_targetable = is_primary ||
         value.LowerCaseEqualsLiteral("content-targetable");
+      mOwnerContent->AddMutationObserver(this);
+      mObservingOwnerContent = true;
       aOwner->ContentShellAdded(aItem, is_primary, is_targetable, value);
     }
   }
 
   return retval;
 }
 
 static bool
@@ -1200,36 +1202,38 @@ nsFrameLoader::SwapWithOtherLoader(nsFra
   otherParentItem->AddChild(ourTreeItem);
 
   // Restore the correct treeowners
   SetTreeOwnerAndChromeEventHandlerOnDocshellTree(ourTreeItem, otherOwner,
                                                   otherChromeEventHandler);
   SetTreeOwnerAndChromeEventHandlerOnDocshellTree(otherTreeItem, ourOwner,
                                                   ourChromeEventHandler);
 
-  AddTreeItemToTreeOwner(ourTreeItem, otherContent, otherOwner,
-                         otherParentType, nullptr);
-  AddTreeItemToTreeOwner(otherTreeItem, ourContent, ourOwner, ourParentType,
-                         nullptr);
+  // Switch the owner content before we start calling AddTreeItemToTreeOwner.
+  // Note that we rely on this to deal with setting mObservingOwnerContent to
+  // false and calling RemoveMutationObserver as needed.
+  SetOwnerContent(otherContent);
+  aOther->SetOwnerContent(ourContent);
+
+  AddTreeItemToTreeOwner(ourTreeItem, otherOwner, otherParentType, nullptr);
+  aOther->AddTreeItemToTreeOwner(otherTreeItem, ourOwner, ourParentType,
+                                 nullptr);
 
   // SetSubDocumentFor nulls out parent documents on the old child doc if a
   // new non-null document is passed in, so just go ahead and remove both
   // kids before reinserting in the parent subdoc maps, to avoid
   // complications.
   ourParentDocument->SetSubDocumentFor(ourContent, nullptr);
   otherParentDocument->SetSubDocumentFor(otherContent, nullptr);
   ourParentDocument->SetSubDocumentFor(ourContent, otherChildDocument);
   otherParentDocument->SetSubDocumentFor(otherContent, ourChildDocument);
 
   ourWindow->SetFrameElementInternal(otherFrameElement);
   otherWindow->SetFrameElementInternal(ourFrameElement);
 
-  SetOwnerContent(otherContent);
-  aOther->SetOwnerContent(ourContent);
-
   nsRefPtr<nsFrameMessageManager> ourMessageManager = mMessageManager;
   nsRefPtr<nsFrameMessageManager> otherMessageManager = aOther->mMessageManager;
   // Swap pointers in child message managers.
   if (mChildMessageManager) {
     nsInProcessTabChildGlobal* tabChild =
       static_cast<nsInProcessTabChildGlobal*>(mChildMessageManager.get());
     tabChild->SetOwner(otherContent);
     tabChild->SetChromeMessageManager(otherMessageManager);
@@ -1378,16 +1382,20 @@ nsFrameLoader::GetDepthTooGreat(bool* aD
 {
   *aDepthTooGreat = mDepthTooGreat;
   return NS_OK;
 }
 
 void
 nsFrameLoader::SetOwnerContent(Element* aContent)
 {
+  if (mObservingOwnerContent) {
+    mObservingOwnerContent = false;
+    mOwnerContent->RemoveMutationObserver(this);
+  }
   mOwnerContent = aContent;
   if (RenderFrameParent* rfp = GetCurrentRemoteFrame()) {
     rfp->OwnerContentChanged(aContent);
   }
 }
 
 bool
 nsFrameLoader::OwnerIsBrowserFrame()
@@ -1554,18 +1562,18 @@ nsFrameLoader::MaybeCreateDocShell()
     parentAsItem->GetItemType(&parentType);
 
     // XXXbz why is this in content code, exactly?  We should handle
     // this some other way.....  Not sure how yet.
     nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
     parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
     NS_ENSURE_STATE(parentTreeOwner);
     mIsTopLevelContent =
-      AddTreeItemToTreeOwner(docShellAsItem, mOwnerContent, parentTreeOwner,
-                             parentType, parentAsNode);
+      AddTreeItemToTreeOwner(docShellAsItem, parentTreeOwner, parentType,
+                             parentAsNode);
 
     // Make sure all shells have links back to the content element
     // in the nearest enclosing chrome shell.
     nsCOMPtr<nsIDOMEventTarget> chromeEventHandler;
 
     if (parentType == nsIDocShellTreeItem::typeChrome) {
       // Our parent shell is a chrome shell. It is therefore our nearest
       // enclosing chrome shell.
@@ -2399,8 +2407,83 @@ nsFrameLoader::SetDetachedSubdocView(nsI
 
 nsIView*
 nsFrameLoader::GetDetachedSubdocView(nsIDocument** aContainerDoc) const
 {
   NS_IF_ADDREF(*aContainerDoc = mContainerDocWhileDetached);
   return mDetachedSubdocViews;
 }
 
+/* virtual */ void
+nsFrameLoader::AttributeChanged(nsIDocument* aDocument,
+                                mozilla::dom::Element* aElement,
+                                int32_t      aNameSpaceID,
+                                nsIAtom*     aAttribute,
+                                int32_t      aModType)
+{
+  MOZ_ASSERT(mObservingOwnerContent);
+  // TODO: Implement ContentShellAdded for remote browsers (bug 658304)
+  MOZ_ASSERT(!mRemoteBrowser);
+
+  if (aNameSpaceID != kNameSpaceID_None || aAttribute != TypeAttrName()) {
+    return;
+  }
+
+  if (aElement != mOwnerContent) {
+    return;
+  }
+
+  // Note: This logic duplicates a lot of logic in
+  // MaybeCreateDocshell.  We should fix that.
+
+  // Notify our enclosing chrome that our type has changed.  We only do this
+  // if our parent is chrome, since in all other cases we're random content
+  // subframes and the treeowner shouldn't worry about us.
+
+  nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
+  if (!docShellAsItem) {
+    return;
+  }
+
+  nsCOMPtr<nsIDocShellTreeItem> parentItem;
+  docShellAsItem->GetParent(getter_AddRefs(parentItem));
+  if (!parentItem) {
+    return;
+  }
+
+  int32_t parentType;
+  parentItem->GetItemType(&parentType);
+
+  if (parentType != nsIDocShellTreeItem::typeChrome) {
+    return;
+  }
+
+  nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
+  parentItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
+  if (!parentTreeOwner) {
+    return;
+  }
+
+  nsAutoString value;
+  aElement->GetAttr(kNameSpaceID_None, TypeAttrName(), value);
+
+  bool is_primary = value.LowerCaseEqualsLiteral("content-primary");
+
+#ifdef MOZ_XUL
+  // when a content panel is no longer primary, hide any open popups it may have
+  if (!is_primary) {
+    nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
+    if (pm)
+      pm->HidePopupsInDocShell(docShellAsItem);
+  }
+#endif
+
+  parentTreeOwner->ContentShellRemoved(docShellAsItem);
+  if (value.LowerCaseEqualsLiteral("content") ||
+      StringBeginsWith(value, NS_LITERAL_STRING("content-"),
+                       nsCaseInsensitiveStringComparator())) {
+    bool is_targetable = is_primary ||
+      value.LowerCaseEqualsLiteral("content-targetable");
+
+    parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary,
+                                       is_targetable, value);
+  }
+}
--- a/content/base/src/nsFrameLoader.h
+++ b/content/base/src/nsFrameLoader.h
@@ -17,23 +17,27 @@
 #include "nsPoint.h"
 #include "nsSize.h"
 #include "nsIURI.h"
 #include "nsAutoPtr.h"
 #include "nsFrameMessageManager.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/Attributes.h"
 #include "FrameMetrics.h"
+#include "nsStubMutationObserver.h"
 
 class nsIURI;
 class nsSubDocumentFrame;
 class nsIView;
 class nsIInProcessContentFrameMessageManager;
 class AutoResetInShow;
 class nsITabParent;
+class nsIDocShellTreeItem;
+class nsIDocShellTreeOwner;
+class nsIDocShellTreeNode;
 
 namespace mozilla {
 namespace dom {
 class PBrowserParent;
 class TabParent;
 }
 
 namespace layout {
@@ -130,17 +134,18 @@ private:
   nsresult Update(const ViewConfig& aConfig);
 
   ViewID mScrollId;
   ViewConfig mConfig;
 };
 
 
 class nsFrameLoader MOZ_FINAL : public nsIFrameLoader,
-                                public nsIContentViewManager
+                                public nsIContentViewManager,
+                                public nsStubMutationObserver
 {
   friend class AutoResetInShow;
   typedef mozilla::dom::PBrowserParent PBrowserParent;
   typedef mozilla::dom::TabParent TabParent;
   typedef mozilla::layout::RenderFrameParent RenderFrameParent;
 
 protected:
   nsFrameLoader(mozilla::dom::Element* aOwner, bool aNetworkCreated);
@@ -161,16 +166,17 @@ public:
 
   static nsFrameLoader* Create(mozilla::dom::Element* aOwner,
                                bool aNetworkCreated);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFrameLoader, nsIFrameLoader)
   NS_DECL_NSIFRAMELOADER
   NS_DECL_NSICONTENTVIEWMANAGER
+  NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
   NS_HIDDEN_(nsresult) CheckForRecursiveLoad(nsIURI* aURI);
   nsresult ReallyStartLoading();
   void Finalize();
   nsIDocShell* GetExistingDocShell() { return mDocShell; }
   nsIDOMEventTarget* GetTabChildGlobalAsEventTarget();
   nsresult CreateStaticClone(nsIFrameLoader* aDest);
 
   /**
@@ -332,19 +338,29 @@ private:
   nsresult ReallyStartLoadingInternal();
 
   // Return true if remote browser created; nothing else to do
   bool TryRemoteBrowser();
 
   // Tell the remote browser that it's now "virtually visible"
   bool ShowRemoteFrame(const nsIntSize& size);
 
+  bool AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem,
+                              nsIDocShellTreeOwner* aOwner,
+                              int32_t aParentType,
+                              nsIDocShellTreeNode* aParentNode);
+
+  nsIAtom* TypeAttrName() const {
+    return mOwnerContent->IsXUL() ? nsGkAtoms::type : nsGkAtoms::mozframetype;
+  }
+
   nsCOMPtr<nsIDocShell> mDocShell;
   nsCOMPtr<nsIURI> mURIToLoad;
   mozilla::dom::Element* mOwnerContent; // WEAK
+
 public:
   // public because a callback needs these.
   nsRefPtr<nsFrameMessageManager> mMessageManager;
   nsCOMPtr<nsIInProcessContentFrameMessageManager> mChildMessageManager;
 private:
   // Stores the root view of the subdocument while the subdocument is being
   // reframed. Used to restore the presentation after reframing.
   nsIView* mDetachedSubdocViews;
@@ -368,16 +384,17 @@ private:
   bool mNetworkCreated : 1;
 
   bool mDelayRemoteDialogs : 1;
   bool mRemoteBrowserShown : 1;
   bool mRemoteFrame : 1;
   bool mClipSubdocument : 1;
   bool mClampScrollPosition : 1;
   bool mRemoteBrowserInitialized : 1;
+  bool mObservingOwnerContent : 1;
 
   // XXX leaking
   nsCOMPtr<nsIObserver> mChildHost;
   RenderFrameParent* mCurrentRemoteFrame;
   TabParent* mRemoteBrowser;
 
   // See nsIFrameLoader.idl.  Short story, if !(mRenderMode &
   // RENDER_MODE_ASYNC_SCROLL), all the fields below are ignored in
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -953,18 +953,17 @@ nsFrameScriptExecutor::InitTabChildGloba
                     (allowXML ? JSOPTION_ALLOW_XML : 0));
   JS_SetVersion(cx, JSVERSION_LATEST);
   JS_SetErrorReporter(cx, ContentScriptErrorReporter);
 
   xpc_LocalizeContext(cx);
 
   JSAutoRequest ar(cx);
   nsIXPConnect* xpc = nsContentUtils::XPConnect();
-  const uint32_t flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES |
-                         nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT;
+  const uint32_t flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES;
 
   
   JS_SetContextPrivate(cx, aScope);
 
   nsresult rv =
     xpc->InitClassesWithNewWrappedGlobal(cx, aScope, mPrincipal,
                                          flags, getter_AddRefs(mGlobal));
   NS_ENSURE_SUCCESS(rv, false);
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -38,16 +38,17 @@ GK_ATOM(mozallowfullscreen, "mozallowful
 GK_ATOM(moztype, "_moz-type")
 GK_ATOM(mozdirty, "_moz_dirty")
 GK_ATOM(mozdonotsend, "moz-do-not-send")
 GK_ATOM(mozeditorbogusnode, "_moz_editor_bogus_node")
 GK_ATOM(mozgeneratedcontentbefore, "_moz_generated_content_before")
 GK_ATOM(mozgeneratedcontentafter, "_moz_generated_content_after")
 GK_ATOM(mozgeneratedcontentimage, "_moz_generated_content_image")
 GK_ATOM(mozquote, "_moz_quote")
+GK_ATOM(_moz_is_glyph, "-moz-is-glyph")
 GK_ATOM(_moz_original_size, "_moz_original_size")
 GK_ATOM(_moz_target, "_moz_target")
 GK_ATOM(_moz_type, "_moz-type")
 GK_ATOM(menuactive, "_moz-menuactive")
 GK_ATOM(_poundDefault, "#default")
 GK_ATOM(_asterix, "*")
 GK_ATOM(a, "a")
 GK_ATOM(abbr, "abbr")
@@ -374,16 +375,18 @@ GK_ATOM(formnovalidate, "formnovalidate"
 GK_ATOM(formtarget, "formtarget")
 GK_ATOM(frame, "frame")
 GK_ATOM(frameborder, "frameborder")
 GK_ATOM(frameset, "frameset")
 GK_ATOM(from, "from")
 GK_ATOM(functionAvailable, "function-available")
 GK_ATOM(generateId, "generate-id")
 GK_ATOM(getter, "getter")
+GK_ATOM(glyphchar, "glyphchar")
+GK_ATOM(glyphid, "glyphid")
 GK_ATOM(grid, "grid")
 GK_ATOM(grippy, "grippy")
 GK_ATOM(group, "group")
 GK_ATOM(groupingSeparator, "grouping-separator")
 GK_ATOM(groupingSize, "grouping-size")
 GK_ATOM(grow, "grow")
 GK_ATOM(gutter, "gutter")
 GK_ATOM(h1, "h1")
--- a/content/base/src/nsMappedAttributes.cpp
+++ b/content/base/src/nsMappedAttributes.cpp
@@ -72,43 +72,40 @@ void* nsMappedAttributes::operator new(s
 #endif
 
   return newAttrs;
 }
 
 NS_IMPL_ISUPPORTS1(nsMappedAttributes,
                    nsIStyleRule)
 
-nsresult
+void
 nsMappedAttributes::SetAndTakeAttr(nsIAtom* aAttrName, nsAttrValue& aValue)
 {
   NS_PRECONDITION(aAttrName, "null name");
 
   uint32_t i;
   for (i = 0; i < mAttrCount && !Attrs()[i].mName.IsSmaller(aAttrName); ++i) {
     if (Attrs()[i].mName.Equals(aAttrName)) {
       Attrs()[i].mValue.Reset();
       Attrs()[i].mValue.SwapValueWith(aValue);
-
-      return NS_OK;
+      return;
     }
   }
 
   NS_ASSERTION(mBufferSize >= mAttrCount + 1, "can't fit attributes");
 
   if (mAttrCount != i) {
     memmove(&Attrs()[i + 1], &Attrs()[i], (mAttrCount - i) * sizeof(InternalAttr));
   }
 
   new (&Attrs()[i].mName) nsAttrName(aAttrName);
   new (&Attrs()[i].mValue) nsAttrValue();
   Attrs()[i].mValue.SwapValueWith(aValue);
   ++mAttrCount;
-
-  return NS_OK;
 }
 
 const nsAttrValue*
 nsMappedAttributes::GetAttr(nsIAtom* aAttrName) const
 {
   NS_PRECONDITION(aAttrName, "null name");
 
   for (uint32_t i = 0; i < mAttrCount; ++i) {
--- a/content/base/src/nsMappedAttributes.h
+++ b/content/base/src/nsMappedAttributes.h
@@ -27,17 +27,17 @@ public:
                      nsMapRuleToAttributesFunc aMapRuleFunc);
 
   // Do not return null.
   void* operator new(size_t size, uint32_t aAttrCount = 1) CPP_THROW_NEW;
   nsMappedAttributes* Clone(bool aWillAddAttr);
 
   NS_DECL_ISUPPORTS
 
-  nsresult SetAndTakeAttr(nsIAtom* aAttrName, nsAttrValue& aValue);
+  void SetAndTakeAttr(nsIAtom* aAttrName, nsAttrValue& aValue);
   const nsAttrValue* GetAttr(nsIAtom* aAttrName) const;
   const nsAttrValue* GetAttr(const nsAString& aAttrName) const;
 
   uint32_t Count() const
   {
     return mAttrCount;
   }
 
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -682,53 +682,47 @@ nsObjectLoadingContent::~nsObjectLoading
     StopPluginInstance();
   }
   DestroyImageLoadingContent();
 }
 
 nsresult
 nsObjectLoadingContent::InstantiatePluginInstance()
 {
-  if (mType != eType_Plugin || mIsLoading) {
-    LOG(("OBJLC [%p]: Not instantiating loading or non-plugin object, type %u",
-         this, mType));
+  if (mInstanceOwner || mType != eType_Plugin || mIsLoading || mInstantiating) {
+    return NS_OK;
+  }
+  
+  nsCOMPtr<nsIContent> thisContent =
+    do_QueryInterface(static_cast<nsIImageLoadingContent *>(this));
+
+  // Flush layout so that the frame is created if possible and the plugin is
+  // initialized with the latest information.
+  nsIDocument* doc = thisContent->GetCurrentDoc();
+  
+  if (!doc || !InActiveDocument(thisContent)) {
+    NS_ERROR("Shouldn't be calling "
+             "InstantiatePluginInstance without an active document");
+    return NS_ERROR_FAILURE;
+  }
+  doc->FlushPendingNotifications(Flush_Layout);
+  
+  if (!thisContent->GetPrimaryFrame()) {
+    LOG(("OBJLC [%p]: Not instantiating plugin with no frame", this));
     return NS_OK;
   }
 
-  // Don't do anything if we already have an active instance.
-  if (mInstanceOwner) {
-    return NS_OK;
-  }
-
-  // Don't allow re-entry into initialization code.
-  if (mInstantiating) {
-    return NS_OK;
-  }
   mInstantiating = true;
   AutoSetInstantiatingToFalse autoInstantiating(this);
 
   // Instantiating an instance can result in script execution, which
   // can destroy this DOM object. Don't allow that for the scope
   // of this method.
   nsCOMPtr<nsIObjectLoadingContent> kungFuDeathGrip = this;
 
-  nsCOMPtr<nsIContent> thisContent =
-    do_QueryInterface(static_cast<nsIImageLoadingContent *>(this));
-  // Flush layout so that the plugin is initialized with the latest information.
-  nsIDocument* doc = thisContent->GetCurrentDoc();
-  if (!doc) {
-    return NS_ERROR_FAILURE;
-  }
-  if (!InActiveDocument(thisContent)) {
-    NS_ERROR("Shouldn't be calling "
-             "InstantiatePluginInstance in an inactive document");
-    return NS_ERROR_FAILURE;
-  }
-  doc->FlushPendingNotifications(Flush_Layout);
-
   nsresult rv = NS_ERROR_FAILURE;
   nsRefPtr<nsPluginHost> pluginHost =
     already_AddRefed<nsPluginHost>(nsPluginHost::GetInst());
 
   if (!pluginHost) {
     NS_NOTREACHED("No pluginhost");
     return NS_ERROR_FAILURE;
   }
@@ -876,17 +870,17 @@ nsObjectLoadingContent::OnStopRequest(ns
 }
 
 
 // nsIStreamListener
 NS_IMETHODIMP
 nsObjectLoadingContent::OnDataAvailable(nsIRequest *aRequest,
                                         nsISupports *aContext,
                                         nsIInputStream *aInputStream,
-                                        uint32_t aOffset, uint32_t aCount)
+                                        uint64_t aOffset, uint32_t aCount)
 {
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
 
   if (aRequest != mChannel) {
     return NS_BINDING_ABORTED;
   }
 
   if (mFinalListener) {
@@ -1724,16 +1718,24 @@ nsObjectLoadingContent::LoadObject(bool 
           break;
         }
 
         // Force a sync state change now, we need the frame created
         NotifyStateChanged(oldType, oldState, true, aNotify);
         oldType = mType;
         oldState = ObjectState();
 
+        if (!thisContent->GetPrimaryFrame()) {
+          // We're un-rendered, and can't instantiate a plugin. HasNewFrame will
+          // re-start us when we can proceed.
+          LOG(("OBJLC [%p]: Aborting load - plugin-type, but no frame", this));
+          CloseChannel();
+          break;
+        }
+        
         rv = pluginHost->NewEmbeddedPluginStreamListener(mURI, this, nullptr,
                                                          getter_AddRefs(mFinalListener));
         if (NS_SUCCEEDED(rv)) {
           // Note that LoadObject is called from mChannel's OnStartRequest
           // when loading with a channel
 
           mSrcStreamLoading = true;
           rv = mFinalListener->OnStartRequest(mChannel, nullptr);
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -269,17 +269,17 @@ nsMultipartProxyListener::OnStopRequest(
 }
 
 /** nsIStreamListener methods **/
 
 NS_IMETHODIMP
 nsMultipartProxyListener::OnDataAvailable(nsIRequest *aRequest,
                                           nsISupports *ctxt,
                                           nsIInputStream *inStr,
-                                          uint32_t sourceOffset,
+                                          uint64_t sourceOffset,
                                           uint32_t count)
 {
   return mDestListener->OnDataAvailable(aRequest, ctxt, inStr, sourceOffset,
                                         count);
 }
 
 /////////////////////////////////////////////
 
@@ -1920,17 +1920,17 @@ bool nsXMLHttpRequest::CreateDOMFile(nsI
   }
   return fromFile;
 }
 
 NS_IMETHODIMP
 nsXMLHttpRequest::OnDataAvailable(nsIRequest *request,
                                   nsISupports *ctxt,
                                   nsIInputStream *inStr,
-                                  uint32_t sourceOffset,
+                                  uint64_t sourceOffset,
                                   uint32_t count)
 {
   NS_ENSURE_ARG_POINTER(inStr);
 
   NS_ABORT_IF_FALSE(mContext.get() == ctxt,"start context different from OnDataAvailable context");
 
   mProgressSinceLastProgressEvent = true;
 
@@ -3883,17 +3883,17 @@ nsHeaderVisitor::VisitHeader(const nsACS
 
 // DOM event class to handle progress notifications
 nsXMLHttpProgressEvent::nsXMLHttpProgressEvent(nsIDOMProgressEvent* aInner,
                                                uint64_t aCurrentProgress,
                                                uint64_t aMaxProgress,
                                                nsPIDOMWindow* aWindow)
   : mWindow(aWindow)
 {
-  mInner = static_cast<nsDOMProgressEvent*>(aInner);
+  mInner = aInner;
   mCurProgress = aCurrentProgress;
   mMaxProgress = aMaxProgress;
 }
 
 nsXMLHttpProgressEvent::~nsXMLHttpProgressEvent()
 {}
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLHttpProgressEvent)
@@ -3913,18 +3913,17 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXMLHtt
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXMLHttpProgressEvent)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXMLHttpProgressEvent)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mInner);
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mWindow);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXMLHttpProgressEvent)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mInner,
-                                                       nsIDOMProgressEvent)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mInner)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mWindow);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMETHODIMP nsXMLHttpProgressEvent::GetInput(nsIDOMLSInput * *aInput)
 {
   *aInput = nullptr;
   return NS_ERROR_NOT_IMPLEMENTED;
 }
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -22,17 +22,17 @@
 #include "nsIHttpHeaderVisitor.h"
 #include "nsIProgressEventSink.h"
 #include "nsCOMArray.h"
 #include "nsJSUtils.h"
 #include "nsTArray.h"
 #include "nsIJSNativeInitializer.h"
 #include "nsIDOMLSProgressEvent.h"
 #include "nsITimer.h"
-#include "nsDOMProgressEvent.h"
+#include "nsIDOMProgressEvent.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsContentUtils.h"
 #include "nsDOMFile.h"
 #include "nsDOMBlobBuilder.h"
 #include "nsIPrincipal.h"
 #include "nsIScriptObjectPrincipal.h"
 
 #include "mozilla/Assertions.h"
@@ -677,19 +677,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXMLHttpProgressEvent, nsIDOMProgressEvent)
   NS_FORWARD_NSIDOMEVENT(mInner->)
   NS_FORWARD_NSIDOMPROGRESSEVENT(mInner->)
   NS_DECL_NSIDOMLSPROGRESSEVENT
 
 protected:
   void WarnAboutLSProgressEvent(nsIDocument::DeprecatedOperations);
 
-  // Use nsDOMProgressEvent so that we can forward
-  // most of the method calls easily.
-  nsRefPtr<nsDOMProgressEvent> mInner;
+  nsCOMPtr<nsIDOMProgressEvent> mInner;
   nsCOMPtr<nsPIDOMWindow> mWindow;
   uint64_t mCurProgress;
   uint64_t mMaxProgress;
 };
 
 class nsXHRParseEndListener : public nsIDOMEventListener
 {
 public:
new file mode 100644
--- /dev/null
+++ b/content/canvas/crashtests/0px-size-font-shadow.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<body>
+<canvas id="canv" width="5" height="5"></canvas>
+<script>
+var canv = document.getElementById("canv");
+var ctx = canv.getContext("2d");
+
+ctx.fillStyle = "red";
+// 0 size font shouldn't assert!
+ctx.font = "0px Arial";
+ctx.shadowColor = '#f00';
+ctx.shadowBlur = 4;
+ctx.fillText("A", 0, 0);
+document.documentElement.className = "";
+</script>
+</body>
+</html>
--- a/content/canvas/crashtests/crashtests.list
+++ b/content/canvas/crashtests/crashtests.list
@@ -1,14 +1,15 @@
 load 360293-1.html
 load 421715-1.html
 load 553938-1.html
 load 647480.html
 load 727547.html
 load 0px-size-font-667225.html
+load 0px-size-font-shadow.html
 load texImage2D.html
 load 729116.html
 load 745699-1.html
 load 746813-1.html
 # this test crashes in a bunch places still
 #load 745818-large-source.html
 load 743499-negative-size.html
 load 767337-1.html
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -57,16 +57,17 @@
 #include "gfxContext.h"
 #include "gfxASurface.h"
 #include "gfxImageSurface.h"
 #include "gfxPlatform.h"
 #include "gfxFont.h"
 #include "gfxBlur.h"
 #include "gfxUtils.h"
 #include "nsRenderingContext.h"
+#include "gfxSVGGlyphs.h"
 
 #include "nsFrameManager.h"
 #include "nsFrameLoader.h"
 #include "nsBidi.h"
 #include "nsBidiPresUtils.h"
 #include "Layers.h"
 #include "CanvasUtils.h"
 #include "nsIMemoryReporter.h"
@@ -2819,25 +2820,30 @@ struct NS_STACK_CLASS nsCanvasBidiProces
                                       nullptr);
             point.x += textRunMetrics.mAdvanceWidth;
             // old code was:
             //   point.x += width * mAppUnitsPerDevPixel;
             // TODO: restore this if/when we move to fractional coords
             // throughout the text layout process
         }
 
+        nsRefPtr<gfxPattern> pattern = mThebes->GetPattern();
+
+        bool isFill = mOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_FILL;
+        SimpleTextObjectPaint objectPaint(isFill ? pattern.get() : nullptr,
+                                          isFill ? nullptr : pattern.get());
+
         mTextRun->Draw(mThebes,
                        point,
-                       mOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_STROKE ?
-                                    gfxFont::GLYPH_STROKE : gfxFont::GLYPH_FILL,
+                       isFill ? gfxFont::GLYPH_FILL : gfxFont::GLYPH_STROKE,
                        0,
                        mTextRun->GetLength(),
                        nullptr,
                        nullptr,
-                       nullptr);
+                       &objectPaint);
     }
 
     // current text run
     nsAutoPtr<gfxTextRun> mTextRun;
 
     // pointer to the context, may not be the canvas's context
     // if an intermediate surface is being used
     gfxContext* mThebes;
@@ -4316,32 +4322,38 @@ static uint8_t g2DContextLayerUserData;
 already_AddRefed<CanvasLayer>
 nsCanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                            CanvasLayer *aOldLayer,
                                            LayerManager *aManager)
 {
     // If we don't have anything to draw, don't bother.
     if (!mValid || !mSurface || mSurface->CairoStatus() || !mThebes ||
         !mSurfaceCreated) {
+        // No DidTransactionCallback will be received, so mark the context clean
+        // now so future invalidations will be dispatched.
+        MarkContextClean();
         return nullptr;
     }
 
     if (!mResetLayer && aOldLayer) {
         CanvasRenderingContext2DUserData* userData =
             static_cast<CanvasRenderingContext2DUserData*>(
                     aOldLayer->GetUserData(&g2DContextLayerUserData));
         if (userData && userData->IsForContext(this)) {
             NS_ADDREF(aOldLayer);
             return aOldLayer;
         }
     }
 
     nsRefPtr<CanvasLayer> canvasLayer = aManager->CreateCanvasLayer();
     if (!canvasLayer) {
         NS_WARNING("CreateCanvasLayer returned null!");
+        // No DidTransactionCallback will be received, so mark the context clean
+        // now so future invalidations will be dispatched.
+        MarkContextClean();
         return nullptr;
     }
     CanvasRenderingContext2DUserData *userData = nullptr;
     if (aBuilder->IsPaintingToWindow()) {
       // Make the layer tell us whenever a transaction finishes (including
       // the current transaction), so we can clear our invalidation state and
       // start invalidating again. We need to do this for the layer that is
       // being painted to a window (there shouldn't be more than one at a time,
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -3211,16 +3211,26 @@ nsCanvasRenderingContext2DAzure::DrawOrM
     }
 
     isRTL = canvasStyle->GetStyleVisibility()->mDirection ==
       NS_STYLE_DIRECTION_RTL;
   } else {
     isRTL = GET_BIDI_OPTION_DIRECTION(document->GetBidiOptions()) == IBMBIDI_TEXTDIRECTION_RTL;
   }
 
+  gfxFontGroup* currentFontStyle = GetCurrentFontStyle();
+  NS_ASSERTION(currentFontStyle, "font group is null");
+
+  if (currentFontStyle->GetStyle()->size == 0.0F) {
+    if (aWidth) {
+      *aWidth = 0;
+    }
+    return NS_OK;
+  }
+
   const ContextState &state = CurrentState();
 
   // This is only needed to know if we can know the drawing bounding box easily.
   bool doDrawShadow = aOp == TEXT_DRAW_OPERATION_FILL && NeedToDrawShadow();
 
   nsCanvasBidiProcessorAzure processor;
 
   GetAppUnitsValues(&processor.mAppUnitsPerDevPixel, nullptr);
@@ -3229,21 +3239,18 @@ nsCanvasRenderingContext2DAzure::DrawOrM
     new gfxContext(gfxPlatform::GetPlatform()->ScreenReferenceSurface());
   Matrix matrix = mTarget->GetTransform();
   processor.mThebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21, matrix._22, matrix._31, matrix._32));
   processor.mCtx = this;
   processor.mOp = aOp;
   processor.mBoundingBox = gfxRect(0, 0, 0, 0);
   processor.mDoMeasureBoundingBox = doDrawShadow || !mIsEntireFrameInvalid;
   processor.mState = &CurrentState();
+  processor.mFontgrp = currentFontStyle;
     
-
-  processor.mFontgrp = GetCurrentFontStyle();
-  NS_ASSERTION(processor.mFontgrp, "font group is null");
-
   nscoord totalWidthCoord;
 
   // calls bidi algo twice since it needs the full text width and the
   // bounding boxes before rendering anything
   nsBidi bidiEngine;
   rv = nsBidiPresUtils::ProcessText(textToDraw.get(),
                                     textToDraw.Length(),
                                     isRTL ? NSBIDI_RTL : NSBIDI_LTR,
@@ -4621,16 +4628,19 @@ nsCanvasRenderingContext2DAzure::SetMozI
 static uint8_t g2DContextLayerUserData;
 
 already_AddRefed<CanvasLayer>
 nsCanvasRenderingContext2DAzure::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                                 CanvasLayer *aOldLayer,
                                                 LayerManager *aManager)
 {
   if (!mValid) {
+    // No DidTransactionCallback will be received, so mark the context clean
+    // now so future invalidations will be dispatched.
+    MarkContextClean();
     return nullptr;
   }
 
   if (mTarget) {
     mTarget->Flush();
   }
 
   if (!mResetLayer && aOldLayer) {
@@ -4641,16 +4651,19 @@ nsCanvasRenderingContext2DAzure::GetCanv
       NS_ADDREF(aOldLayer);
       return aOldLayer;
     }
   }
 
   nsRefPtr<CanvasLayer> canvasLayer = aManager->CreateCanvasLayer();
   if (!canvasLayer) {
     NS_WARNING("CreateCanvasLayer returned null!");
+    // No DidTransactionCallback will be received, so mark the context clean
+    // now so future invalidations will be dispatched.
+    MarkContextClean();
     return nullptr;
   }
   CanvasRenderingContext2DUserDataAzure *userData = nullptr;
   // Make the layer tell us whenever a transaction finishes (including
   // the current transaction), so we can clear our invalidation state and
   // start invalidating again. We need to do this for all layers since
   // callers of DrawWindow may be expecting to receive normal invalidation
   // notifications after this paint.
--- a/content/events/src/Makefile.in
+++ b/content/events/src/Makefile.in
@@ -45,17 +45,16 @@ CPPSRCS		= \
 		nsPrivateTextRange.cpp \
 		nsXMLEventsManager.cpp \
 		nsXMLEventsElement.cpp \
 		nsAsyncDOMEvent.cpp \
 		nsEventDispatcher.cpp \
 		nsIMEStateManager.cpp \
 		nsContentEventHandler.cpp \
 		nsEventListenerService.cpp \
-		nsDOMProgressEvent.cpp \
 		nsDOMDataTransfer.cpp \
 		nsDOMNotifyPaintEvent.cpp \
 		nsDOMNotifyAudioAvailableEvent.cpp \
 		nsDOMSimpleGestureEvent.cpp \
 		nsDOMMozTouchEvent.cpp \
 		nsDOMEventTargetHelper.cpp \
 		nsDOMScrollAreaEvent.cpp \
 		nsDOMTransitionEvent.cpp \
deleted file mode 100644
--- a/content/events/src/nsDOMProgressEvent.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsDOMClassInfoID.h"
-#include "nsDOMProgressEvent.h"
-
-DOMCI_DATA(ProgressEvent, nsDOMProgressEvent)
-
-NS_INTERFACE_MAP_BEGIN(nsDOMProgressEvent)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMProgressEvent)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ProgressEvent)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
-
-NS_IMPL_ADDREF_INHERITED(nsDOMProgressEvent, nsDOMEvent)
-NS_IMPL_RELEASE_INHERITED(nsDOMProgressEvent, nsDOMEvent)
-
-NS_IMETHODIMP
-nsDOMProgressEvent::GetLengthComputable(bool* aLengthComputable)
-{
-  *aLengthComputable = mLengthComputable;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMProgressEvent::GetLoaded(uint64_t* aLoaded)
-{
-  *aLoaded = mLoaded;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMProgressEvent::GetTotal(uint64_t* aTotal)
-{
-  *aTotal = mTotal;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMProgressEvent::InitProgressEvent(const nsAString& aType,
-                                      bool aCanBubble,
-                                      bool aCancelable,
-                                      bool aLengthComputable,
-                                      uint64_t aLoaded,
-                                      uint64_t aTotal)
-{
-  nsresult rv = nsDOMEvent::InitEvent(aType, aCanBubble, aCancelable);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  mLoaded = aLoaded;
-  mLengthComputable = aLengthComputable;
-  mTotal = aTotal;
-
-  return NS_OK;
-}
-
-nsresult
-NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult,
-                       nsPresContext* aPresContext,
-                       nsEvent* aEvent) 
-{
-  nsDOMProgressEvent* it = new nsDOMProgressEvent(aPresContext, aEvent);
-  if (nullptr == it)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  return CallQueryInterface(it, aInstancePtrResult);
-}
deleted file mode 100644
--- a/content/events/src/nsDOMProgressEvent.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsDOMProgressEvent_h__
-#define nsDOMProgressEvent_h__
-
-#include "nsIDOMProgressEvent.h"
-#include "nsDOMEvent.h"
-
-/**
- * Implements the ProgressEvent event, used for progress events from the media
- * elements.
-
- * See http://www.whatwg.org/specs/web-apps/current-work/#progress0 for
- * further details.
- */
-class nsDOMProgressEvent : public nsDOMEvent,
-                           public nsIDOMProgressEvent
-{
-public:
-  nsDOMProgressEvent(nsPresContext* aPresContext, nsEvent* aEvent)
-    : nsDOMEvent(aPresContext, aEvent)
-  {
-  }
-  
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIDOMPROGRESSEVENT
-    
-  // Forward to base class
-  NS_FORWARD_TO_NSDOMEVENT
-
-private:
-  bool    mLengthComputable;
-  uint64_t mLoaded;
-  uint64_t mTotal;
-};
-
-#endif // nsDOMProgressEvent_h__
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -4887,18 +4887,17 @@ nsEventStateManager::UnregisterAccessKey
 {
   if (aContent)
     mAccessKeys.RemoveObject(aContent);
 }
 
 uint32_t
 nsEventStateManager::GetRegisteredAccessKey(nsIContent* aContent)
 {
-  NS_ASSERTION(aContent, "Null pointer passed to GetRegisteredAccessKey");
-  NS_ENSURE_TRUE(aContent, 0);
+  MOZ_ASSERT(aContent);
 
   if (mAccessKeys.IndexOf(aContent) == -1)
     return 0;
 
   nsAutoString accessKey;
   aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, accessKey);
   return accessKey.First();
 }
--- a/content/events/src/nsEventStateManager.h
+++ b/content/events/src/nsEventStateManager.h
@@ -131,17 +131,17 @@ public:
    * @param  aContent  the given element
    * @param  aKey      accesskey
    */
   void UnregisterAccessKey(nsIContent* aContent, uint32_t aKey);
 
   /**
    * Get accesskey registered on the given element or 0 if there is none.
    *
-   * @param  aContent  the given element
+   * @param  aContent  the given element (must not be null)
    * @return           registered accesskey
    */
   uint32_t GetRegisteredAccessKey(nsIContent* aContent);
 
   bool GetAccessKeyLabelPrefix(nsAString& aPrefix);
 
   nsresult SetCursor(int32_t aCursor, imgIContainer* aContainer,
                      bool aHaveHotspot, float aHotspotX, float aHotspotY,
--- a/content/html/content/public/nsHTMLMediaElement.h
+++ b/content/html/content/public/nsHTMLMediaElement.h
@@ -308,16 +308,21 @@ public:
 #endif
 
 #ifdef MOZ_MEDIA_PLUGINS
   static bool IsMediaPluginsEnabled();
   static bool IsMediaPluginsType(const nsACString& aType);
 #endif
 
   /**
+   * Get the mime type for this element.
+   */
+  void GetMimeType(nsCString& aMimeType);
+
+  /**
    * Called when a child source element is added to this media element. This
    * may queue a task to run the select resource algorithm if appropriate.
    */
   void NotifyAddedSource();
 
   /**
    * Called when there's been an error fetching the resource. This decides
    * whether it's appropriate to fire an error event.
@@ -867,11 +872,18 @@ protected:
   // The CORS mode when loading the media element
   mozilla::CORSMode mCORSMode;
 
   // True if the media has an audio track
   bool mHasAudio;
 
   // True if the media's channel's download has been suspended.
   bool mDownloadSuspendedByCache;
+
+  // The Content-Type for this media. When we are sniffing for the Content-Type,
+  // and we are recreating a channel after the initial load, we need that
+  // information to give it as a hint to the channel for it to bypass the
+  // sniffing phase, that would fail because sniffing only works when applied to
+  // the first bytes of the stream.
+  nsCString mMimeType;
 };
 
 #endif
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -1055,19 +1055,34 @@ nsHTMLInputElement::SetValue(const nsASt
       const PRUnichar *name = PromiseFlatString(aValue).get();
       return MozSetFileNameArray(&name, 1);
     }
     else {
       ClearFiles(true);
     }
   }
   else {
-    SetValueInternal(aValue, false, true);
     if (IsSingleLineTextControl(false)) {
-      GetValueInternal(mFocusedValue);
+      // If the value has been set by a script, we basically want to keep the
+      // current change event state. If the element is ready to fire a change
+      // event, we should keep it that way. Otherwise, we should make sure the
+      // element will not fire any event because of the script interaction.
+      //
+      // NOTE: this is currently quite expensive work (too much string
+      // manipulation). We should probably optimize that.
+      nsAutoString currentValue;
+      GetValueInternal(currentValue);
+
+      SetValueInternal(aValue, false, true);
+
+      if (mFocusedValue.Equals(currentValue)) {
+        GetValueInternal(mFocusedValue);
+      }
+    } else {
+      SetValueInternal(aValue, false, true);
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLInputElement::GetList(nsIDOMHTMLElement** aValue)
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -353,19 +353,22 @@ NS_IMETHODIMP nsHTMLMediaElement::MediaL
                                                                    nsresult aStatus)
 {
   if (mNextListener) {
     return mNextListener->OnStopRequest(aRequest, aContext, aStatus);
   }
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
-                                                                     nsIInputStream* aStream, uint32_t aOffset,
-                                                                     uint32_t aCount)
+NS_IMETHODIMP
+nsHTMLMediaElement::MediaLoadListener::OnDataAvailable(nsIRequest* aRequest,
+                                                       nsISupports* aContext,
+                                                       nsIInputStream* aStream,
+                                                       uint64_t aOffset,
+                                                       uint32_t aCount)
 {
   if (!mNextListener) {
     NS_ERROR("Must have a chained listener; OnStartRequest should have canceled this request");
     return NS_BINDING_ABORTED;
   }
   return mNextListener->OnDataAvailable(aRequest, aContext, aStream, aOffset, aCount);
 }
 
@@ -1029,16 +1032,21 @@ nsresult nsHTMLMediaElement::LoadResourc
 
   // Set the media element's CORS mode only when loading a resource
   mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
 
   nsHTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
   if (other) {
     // Clone it.
     nsresult rv = InitializeDecoderAsClone(other->mDecoder);
+    // Get the mimetype from the element we clone, since we will not get it via
+    // the channel, and we won't be able to sniff for it, because we will not
+    // open a channel to get the beginning of the media (it is likely to already
+    // be in the cache).
+    mMimeType = other->mMimeType;
     if (NS_SUCCEEDED(rv))
       return rv;
   }
 
   int16_t shouldLoad = nsIContentPolicy::ACCEPT;
   nsresult rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_MEDIA,
                                           mLoadingSrc,
                                           NodePrincipal(),
@@ -1067,17 +1075,18 @@ nsresult nsHTMLMediaElement::LoadResourc
     channelPolicy->SetLoadType(nsIContentPolicy::TYPE_MEDIA);
   }
   nsCOMPtr<nsIChannel> channel;
   rv = NS_NewChannel(getter_AddRefs(channel),
                      mLoadingSrc,
                      nullptr,
                      loadGroup,
                      nullptr,
-                     nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY,
+                     nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY |
+                     nsIChannel::LOAD_TREAT_APPLICATION_OCTET_STREAM_AS_UNKNOWN,
                      channelPolicy);
   NS_ENSURE_SUCCESS(rv,rv);
 
   // The listener holds a strong reference to us.  This creates a
   // reference cycle, once we've set mChannel, which is manually broken
   // in the listener's OnStartRequest method after it is finished with
   // the element. The cycle will also be broken if we get a shutdown
   // notification before OnStartRequest fires.  Necko guarantees that
@@ -2428,29 +2437,31 @@ nsresult nsHTMLMediaElement::InitializeD
 
 nsresult nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel *aChannel,
                                                          nsIStreamListener **aListener)
 {
   NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set");
   NS_ASSERTION(mDecoder == nullptr, "Shouldn't have a decoder");
 
   nsAutoCString mimeType;
-  aChannel->GetContentType(mimeType);
-
-  nsRefPtr<nsMediaDecoder> decoder = CreateDecoder(mimeType);
+
+  aChannel->GetContentType(mMimeType);
+  NS_ASSERTION(!mMimeType.IsEmpty(), "We should have the Content-Type.");
+
+  nsRefPtr<nsMediaDecoder> decoder = CreateDecoder(mMimeType);
   if (!decoder) {
     nsAutoString src;
     GetCurrentSrc(src);
-    NS_ConvertUTF8toUTF16 mimeUTF16(mimeType);
+    NS_ConvertUTF8toUTF16 mimeUTF16(mMimeType);
     const PRUnichar* params[] = { mimeUTF16.get(), src.get() };
     ReportLoadError("MediaLoadUnsupportedMimeType", params, ArrayLength(params));
     return NS_ERROR_FAILURE;
   }
 
-  LOG(PR_LOG_DEBUG, ("%p Created decoder %p for type %s", this, decoder.get(), mimeType.get()));
+  LOG(PR_LOG_DEBUG, ("%p Created decoder %p for type %s", this, decoder.get(), mMimeType.get()));
 
   MediaResource* resource = MediaResource::Create(decoder, aChannel);
   if (!resource)
     return NS_ERROR_OUT_OF_MEMORY;
 
   // stream successfully created, the stream now owns the channel.
   mChannel = nullptr;
 
@@ -3523,14 +3534,19 @@ NS_IMETHODIMP nsHTMLMediaElement::GetMoz
   NS_ENSURE_SUCCESS(rv, rv);
 
   // If there is no end fragment, or the fragment end is greater than the
   // duration, return the duration.
   *aTime = (mFragmentEnd < 0.0 || mFragmentEnd > duration) ? duration : mFragmentEnd;
   return NS_OK;
 }
 
+void nsHTMLMediaElement::GetMimeType(nsCString& aMimeType)
+{
+  aMimeType = mMimeType;
+}
+
 void nsHTMLMediaElement::NotifyAudioAvailableListener()
 {
   if (mDecoder) {
     mDecoder->NotifyAudioAvailableListener();
   }
 }
--- a/content/html/content/src/nsHTMLOptionElement.cpp
+++ b/content/html/content/src/nsHTMLOptionElement.cpp
@@ -255,17 +255,17 @@ nsHTMLOptionElement::BeforeSetAttr(int32
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsHTMLOptionElement::GetText(nsAString& aText)
 {
   nsAutoString text;
-  nsContentUtils::GetNodeTextContent(this, false, text);
+  nsContentUtils::GetNodeTextContent(this, true, text);
 
   // XXX No CompressWhitespace for nsAString.  Sad.
   text.CompressWhitespace(true, true);
   aText = text;
 
   return NS_OK;
 }
 
--- a/content/html/content/src/nsHTMLTableRowElement.cpp
+++ b/content/html/content/src/nsHTMLTableRowElement.cpp
@@ -55,18 +55,18 @@ public:
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLTableRowElement,
                                                      nsGenericHTMLElement)
 
 protected:
-  nsresult GetSection(nsIDOMHTMLTableSectionElement** aSection);
-  nsresult GetTable(nsIDOMHTMLTableElement** aTable);
+  already_AddRefed<nsIDOMHTMLTableSectionElement> GetSection() const;
+  already_AddRefed<nsIDOMHTMLTableElement> GetTable() const;
   nsRefPtr<nsContentList> mCells;
 };
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(TableRow)
 
 
 nsHTMLTableRowElement::nsHTMLTableRowElement(already_AddRefed<nsINodeInfo> aNodeInfo)
@@ -95,62 +95,54 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION
                                                nsGenericHTMLElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLTableRowElement)
 
 
 NS_IMPL_ELEMENT_CLONE(nsHTMLTableRowElement)
 
 
 // protected method
-nsresult
-nsHTMLTableRowElement::GetSection(nsIDOMHTMLTableSectionElement** aSection)
+already_AddRefed<nsIDOMHTMLTableSectionElement>
+nsHTMLTableRowElement::GetSection() const
 {
-  NS_ENSURE_ARG_POINTER(aSection);
   nsCOMPtr<nsIDOMHTMLTableSectionElement> section =
     do_QueryInterface(GetParent());
-  section.forget(aSection);
-  return NS_OK;
+  return section.forget();
 }
 
 // protected method
-nsresult
-nsHTMLTableRowElement::GetTable(nsIDOMHTMLTableElement** aTable)
+already_AddRefed<nsIDOMHTMLTableElement>
+nsHTMLTableRowElement::GetTable() const
 {
-  NS_ENSURE_ARG_POINTER(aTable);
-  *aTable = nullptr;
-
   nsIContent* parent = GetParent();
   if (!parent) {
-    return NS_OK;
+    return nullptr;
   }
 
   // We may not be in a section
   nsCOMPtr<nsIDOMHTMLTableElement> table = do_QueryInterface(parent);
   if (table) {
-    table.forget(aTable);
-    return NS_OK;
+    return table.forget();
   }
 
   parent = parent->GetParent();
   if (!parent) {
-    return NS_OK;
+    return nullptr;
   }
   table = do_QueryInterface(parent);
-  table.forget(aTable);
-  return NS_OK;
+  return table.forget();
 }
 
 NS_IMETHODIMP
 nsHTMLTableRowElement::GetRowIndex(int32_t* aValue)
 {
   *aValue = -1;
-  nsCOMPtr<nsIDOMHTMLTableElement> table;
-  nsresult rv = GetTable(getter_AddRefs(table));
-  if (NS_FAILED(rv) || !table) {
-    return rv;
+  nsCOMPtr<nsIDOMHTMLTableElement> table = GetTable();
+  if (!table) {
+    return NS_OK;
   }
 
   nsCOMPtr<nsIDOMHTMLCollection> rows;
   table->GetRows(getter_AddRefs(rows));
 
   uint32_t numRows;
   rows->GetLength(&numRows);
 
@@ -162,20 +154,19 @@ nsHTMLTableRowElement::GetRowIndex(int32
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLTableRowElement::GetSectionRowIndex(int32_t* aValue)
 {
   *aValue = -1;
-  nsCOMPtr<nsIDOMHTMLTableSectionElement> section;
-  nsresult rv = GetSection(getter_AddRefs(section));
-  if (NS_FAILED(rv) || !section) {
-    return rv;
+  nsCOMPtr<nsIDOMHTMLTableSectionElement> section = GetSection();
+  if (!section) {
+    return NS_OK;
   }
 
   nsCOMPtr<nsIDOMHTMLCollection> rows;
   section->GetRows(getter_AddRefs(rows));
 
   uint32_t numRows;
   rows->GetLength(&numRows);
   for (uint32_t i = 0; i < numRows; i++) {
--- a/content/html/content/src/nsHTMLTextAreaElement.cpp
+++ b/content/html/content/src/nsHTMLTextAreaElement.cpp
@@ -540,18 +540,32 @@ nsHTMLTextAreaElement::SetValueInternal(
   mState.SetValue(aValue, aUserInput, true);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsHTMLTextAreaElement::SetValue(const nsAString& aValue)
 {
+  // If the value has been set by a script, we basically want to keep the
+  // current change event state. If the element is ready to fire a change
+  // event, we should keep it that way. Otherwise, we should make sure the
+  // element will not fire any event because of the script interaction.
+  //
+  // NOTE: this is currently quite expensive work (too much string
+  // manipulation). We should probably optimize that.
+  nsAutoString currentValue;
+  GetValueInternal(currentValue, true);
+
   SetValueInternal(aValue, false);
-  GetValueInternal(mFocusedValue, true);
+
+  if (mFocusedValue.Equals(currentValue)) {
+    GetValueInternal(mFocusedValue, true);
+  }
+
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsHTMLTextAreaElement::SetUserInput(const nsAString& aValue)
 {
   if (!nsContentUtils::IsCallerTrustedForWrite()) {
     return NS_ERROR_DOM_SECURITY_ERR;
--- a/content/html/content/test/forms/Makefile.in
+++ b/content/html/content/test/forms/Makefile.in
@@ -27,23 +27,24 @@ MOCHITEST_FILES = \
 		test_label_control_attribute.html \
 		test_output_element.html \
 		test_button_attributes_reflection.html \
 		test_textarea_attributes_reflection.html \
 		test_validation.html \
 		test_maxlength_attribute.html \
 		test_datalist_element.html \
 		test_form_attributes_reflection.html \
+		test_option_disabled.html \
 		test_option_index_attribute.html \
+		test_option_text.html \
 		test_progress_element.html \
 		test_form_attribute-1.html \
 		test_form_attribute-2.html \
 		test_form_attribute-3.html \
 		test_form_attribute-4.html \
-		test_option_disabled.html \
 		test_meter_element.html \
 		test_meter_pseudo-classes.html \
 		test_max_attribute.html \
 		test_min_attribute.html \
 		test_step_attribute.html \
 		test_stepup_stepdown.html \
 		test_valueasnumber_attribute.html \
 		test_experimental_forms_pref.html \
--- a/content/html/content/test/forms/test_change_event.html
+++ b/content/html/content/test/forms/test_change_event.html
@@ -101,23 +101,49 @@ https://bugzilla.mozilla.org/show_bug.cg
 
     //focus and blur text input
     input = document.getElementById("input_text");
     input.focus();
     synthesizeKey("f", {});
     input.blur();
     is(textInputChange[0], 2, "text input element should have dispatched change event (2).");
 
+    // value being set while focused
+    input.focus();
+    input.value = 'foo';
+    input.blur();
+    is(textInputChange[0], 2, "text input element should not have dispatched change event (2).");
+
+    // value being set while focused after being modified manually
+    input.focus();
+    synthesizeKey("f", {});
+    input.value = 'bar';
+    input.blur();
+    is(textInputChange[0], 3, "text input element should have dispatched change event (3).");
+
     //focus and blur textarea
     var textarea = document.getElementById("textarea");
     textarea.focus();
     synthesizeKey("f", {});
     textarea.blur();
     is(textareaChange, 1, "Textarea element should have dispatched change event.");
 
+    // value being set while focused
+    textarea.focus();
+    textarea.value = 'foo';
+    textarea.blur();
+    is(textareaChange, 1, "textarea should not have dispatched change event (1).");
+
+    // value being set while focused after being modified manually
+    textarea.focus();
+    synthesizeKey("f", {});
+    textarea.value = 'bar';
+    textarea.blur();
+    is(textareaChange, 2, "textearea should have dispatched change event (2).");
+
     //Non-text input tests:
     for (var i = 0; i < NonTextInputTypes.length; ++i) {
       //button, submit, image and reset input type tests.
       if (i < 4) {
         input = document.getElementById("input_" + NonTextInputTypes[i]);
         input.focus();
         input.click();
         is(NonTextInputChange[i], 0, "Change event shouldn't be dispatched on " + NonTextInputTypes[i] + " input element");
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/forms/test_option_text.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLOptionElement.text</title>
+<link rel=author title=Ms2ger href="mailto:Ms2ger@gmail.com">
+<link rel=help href="http://www.whatwg.org/html/#dom-option-text">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+  var option = document.createElement("option");
+  option.appendChild(document.createElement("font"))
+        .appendChild(document.createTextNode(" font "));
+  assert_equals(option.text, "font");
+});
+</script>
--- a/content/html/document/src/MediaDocument.cpp
+++ b/content/html/document/src/MediaDocument.cpp
@@ -72,17 +72,17 @@ MediaDocumentStreamListener::OnStopReque
 
   return rv;
 }
 
 NS_IMETHODIMP
 MediaDocumentStreamListener::OnDataAvailable(nsIRequest* request,
                                              nsISupports *ctxt,
                                              nsIInputStream *inStr,
-                                             uint32_t sourceOffset,
+                                             uint64_t sourceOffset,
                                              uint32_t count)
 {
   if (mNextStream) {
     return mNextStream->OnDataAvailable(request, ctxt, inStr, sourceOffset, count);
   }
 
   return NS_OK;
 }
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1241,17 +1241,20 @@ nsHTMLDocument::GetCookie(nsAString& aCo
       // Document's principal is not a codebase (may be system), so
       // can't set cookies
 
       return NS_OK;
     }
 
     nsXPIDLCString cookie;
     service->GetCookieString(codebaseURI, mChannel, getter_Copies(cookie));
-    CopyASCIItoUTF16(cookie, aCookie);
+    // CopyUTF8toUTF16 doesn't handle error
+    // because it assumes that the input is valid.
+    nsContentUtils::ConvertStringFromCharset(NS_LITERAL_CSTRING("utf-8"),
+                                             cookie, aCookie);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::SetCookie(const nsAString& aCookie)
 {
@@ -1280,17 +1283,17 @@ nsHTMLDocument::SetCookie(const nsAStrin
 
     if (!codebaseURI) {
       // Document's principal is not a codebase (may be system), so
       // can't set cookies
 
       return NS_OK;
     }
 
-    NS_LossyConvertUTF16toASCII cookie(aCookie);
+    NS_ConvertUTF16toUTF8 cookie(aCookie);
     service->SetCookieString(codebaseURI, prompt, cookie.get(), mChannel);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::Open(const nsAString& aContentTypeOrUrl,
--- a/content/html/document/test/Makefile.in
+++ b/content/html/document/test/Makefile.in
@@ -67,16 +67,18 @@ MOCHITEST_FILES = 	test_bug1682.html \
 		test_bug499092.html \
 		bug499092.xml \
 		bug499092.html \
 		test_bug512367.html \
 		test_bug571981.html \
 		test_bug677495.html \
 		test_bug677495-1.html \
 		test_bug741266.html \
+		test_non-ascii-cookie.html \
+		test_non-ascii-cookie.html^headers^ \
 		$(NULL)
 
 ifneq (mobile,$(MOZ_BUILD_APP))
 MOCHITEST_BROWSER_FILES = \
 		browser_bug592641.js \
 		bug592641_img.jpg \
 		$(NULL)
 endif
new file mode 100644
--- /dev/null
+++ b/content/html/document/test/test_non-ascii-cookie.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=784367
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for non-ASCII document.cookie</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=784367">Mozilla Bug 784367</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for non-ASCII document.cookie **/
+var c = document.cookie;
+is(document.cookie, 'abc=012©ABC\ufffdDEF', "document.cookie should be decoded as UTF-8");
+var newCookie = 'def=∼≩≭≧∯≳≲≣∽≸≸∺≸∠≯≮≥≲≲≯≲∽≡≬≥≲≴∨∱∩∾';
+document.cookie = newCookie;
+is(document.cookie, c + '; ' + newCookie, "document.cookie should be encoded as UTF-8");
+var date1 = new Date();
+date1.setTime(0);
+document.cookie = newCookie + 'def=;expires=' + date1.toGMTString();
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/document/test/test_non-ascii-cookie.html^headers^
@@ -0,0 +1,1 @@
+Set-Cookie: abc=012©ABC©DEF
--- a/content/media/MediaResource.cpp
+++ b/content/media/MediaResource.cpp
@@ -23,16 +23,17 @@
 #include "nsCrossSiteListenerProxy.h"
 #include "nsHTMLMediaElement.h"
 #include "nsError.h"
 #include "nsICachingChannel.h"
 #include "nsURILoader.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "mozilla/Util.h" // for DebugOnly
 #include "nsContentUtils.h"
+#include "nsBlobProtocolHandler.h"
 
 static const uint32_t HTTP_OK_CODE = 200;
 static const uint32_t HTTP_PARTIAL_RESPONSE_CODE = 206;
 
 using namespace mozilla;
 
 ChannelMediaResource::ChannelMediaResource(nsMediaDecoder* aDecoder,
     nsIChannel* aChannel, nsIURI* aURI)
@@ -82,17 +83,17 @@ ChannelMediaResource::Listener::OnStopRe
     return NS_OK;
   return mResource->OnStopRequest(aRequest, aStatus);
 }
 
 nsresult
 ChannelMediaResource::Listener::OnDataAvailable(nsIRequest* aRequest,
                                                 nsISupports* aContext,
                                                 nsIInputStream* aStream,
-                                                uint32_t aOffset,
+                                                uint64_t aOffset,
                                                 uint32_t aCount)
 {
   if (!mResource)
     return NS_OK;
   return mResource->OnDataAvailable(aRequest, aStream, aCount);
 }
 
 nsresult
@@ -699,22 +700,34 @@ ChannelMediaResource::RecreateChannel()
   nsHTMLMediaElement* element = mDecoder->GetMediaElement();
   if (!element) {
     // The decoder is being shut down, so don't bother opening a new channel
     return NS_OK;
   }
   nsCOMPtr<nsILoadGroup> loadGroup = element->GetDocumentLoadGroup();
   NS_ENSURE_TRUE(loadGroup, NS_ERROR_NULL_POINTER);
 
-  return NS_NewChannel(getter_AddRefs(mChannel),
-                       mURI,
-                       nullptr,
-                       loadGroup,
-                       nullptr,
-                       loadFlags);
+  nsresult rv = NS_NewChannel(getter_AddRefs(mChannel),
+                              mURI,
+                              nullptr,
+                              loadGroup,
+                              nullptr,
+                              loadFlags);
+
+  // We have cached the Content-Type, which should not change. Give a hint to
+  // the channel to avoid a sniffing failure, which would be expected because we
+  // are probably seeking in the middle of the bitstream, and sniffing relies
+  // on the presence of a magic number at the beginning of the stream.
+  nsAutoCString contentType;
+  element->GetMimeType(contentType);
+  NS_ASSERTION(!contentType.IsEmpty(),
+      "When recreating a channel, we should know the Content-Type.");
+  mChannel->SetContentType(contentType);
+
+  return rv;
 }
 
 void
 ChannelMediaResource::DoNotifyDataReceived()
 {
   mDataReceivedEvent.Revoke();
   mDecoder->NotifyBytesDownloaded();
 }
@@ -1088,24 +1101,25 @@ nsresult FileMediaResource::Open(nsIStre
   }
 
   nsresult rv = NS_OK;
   if (aStreamListener) {
     // The channel is already open. We need a synchronous stream that
     // implements nsISeekableStream, so we have to find the underlying
     // file and reopen it
     nsCOMPtr<nsIFileChannel> fc(do_QueryInterface(mChannel));
-    if (!fc)
-      return NS_ERROR_UNEXPECTED;
+    if (fc) {
+      nsCOMPtr<nsIFile> file;
+      rv = fc->GetFile(getter_AddRefs(file));
+      NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCOMPtr<nsIFile> file;
-    rv = fc->GetFile(getter_AddRefs(file));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = NS_NewLocalFileInputStream(getter_AddRefs(mInput), file);
+      rv = NS_NewLocalFileInputStream(getter_AddRefs(mInput), file);
+    } else if (IsBlobURI(mURI)) {
+      rv = NS_GetStreamForBlobURI(mURI, getter_AddRefs(mInput));
+    }
   } else {
     // Ensure that we never load a local file from some page on a
     // web server.
     nsHTMLMediaElement* element = mDecoder->GetMediaElement();
     NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
 
     rv = nsContentUtils::GetSecurityManager()->
            CheckLoadURIWithPrincipal(element->NodePrincipal(),
@@ -1245,27 +1259,27 @@ int64_t FileMediaResource::Tell()
   mSeekable->Tell(&offset);
   return offset;
 }
 
 MediaResource*
 MediaResource::Create(nsMediaDecoder* aDecoder, nsIChannel* aChannel)
 {
   NS_ASSERTION(NS_IsMainThread(),
-	             "MediaResource::Open called on non-main thread");
+               "MediaResource::Open called on non-main thread");
 
   // If the channel was redirected, we want the post-redirect URI;
   // but if the URI scheme was expanded, say from chrome: to jar:file:,
   // we want the original URI.
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
   NS_ENSURE_SUCCESS(rv, nullptr);
 
   nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(aChannel);
-  if (fc) {
+  if (fc || IsBlobURI(uri)) {
     return new FileMediaResource(aDecoder, aChannel, uri);
   }
   return new ChannelMediaResource(aDecoder, aChannel, uri);
 }
 
 void MediaResource::MoveLoadsToBackground() {
   NS_ASSERTION(!mLoadInBackground, "Why are you calling this more than once?");
   mLoadInBackground = true;
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -122,16 +122,18 @@ MOCHITEST_FILES = \
 		test_autoplay_contentEditable.html \
 		test_buffered.html \
 		test_bug448534.html \
 		test_bug463162.xhtml \
 		test_decoder_disable.html \
 		test_media_selection.html \
 		test_playback.html \
 		test_seekLies.html \
+		test_media_sniffer.html \
+		contentType.sjs \
 		$(NULL)
 
 $(warning test_error_in_video_document.html is disabled for intermittent failures. Bug 608634)
 
 # Disabled on Windows for frequent intermittent failures
 ifneq ($(OS_ARCH), WINNT)
 MOCHITEST_FILES += \
 		test_streams_element_capture.html \
@@ -207,16 +209,19 @@ MOCHITEST_FILES += \
 		seek.yuv \
 		short-video.ogv \
 		small-shot.ogg \
 		sound.ogg \
 		spacestorm-1000Hz-100ms.ogg \
 		video-overhang.ogg \
 		file_a4_tone.ogg \
 		detodos.opus \
+		short.mp4 \
+		notags.mp3 \
+		id3tags.mp3 \
 		$(NULL)
 
 # Wave sample files
 MOCHITEST_FILES += \
 		big.wav \
 		bogus.wav \
 		r11025_msadpcm_c1.wav \
 		r11025_s16_c1.wav \
new file mode 100644
--- /dev/null
+++ b/content/media/test/contentType.sjs
@@ -0,0 +1,77 @@
+// Parse the query string, and give us the value for a certain key, or false if
+// it does not exist.
+function parseQuery(request, key) {
+  var params = request.queryString.split('?')[0].split('&');
+  for (var j = 0; j < params.length; ++j) {
+    var p = params[j];
+    if (p == key)
+      return true;
+    if (p.indexOf(key + "=") == 0)
+      return p.substring(key.length + 1);
+    if (p.indexOf("=") < 0 && key == "")
+      return p;
+  }
+  return false;
+}
+
+function handleRequest(request, response) {
+  try {
+    // Get the filename to send back.
+    var filename = parseQuery(request, "file");
+
+    const CC = Components.Constructor;
+    const BinaryOutputStream = CC("@mozilla.org/binaryoutputstream;1",
+                                  "nsIBinaryOutputStream",
+                                  "setOutputStream");
+    var file = Components.classes["@mozilla.org/file/directory_service;1"].
+      getService(Components.interfaces.nsIProperties).
+      get("CurWorkD", Components.interfaces.nsILocalFile);
+    var fis  = Components.classes['@mozilla.org/network/file-input-stream;1'].
+      createInstance(Components.interfaces.nsIFileInputStream);
+    var bis  = Components.classes["@mozilla.org/binaryinputstream;1"].
+      createInstance(Components.interfaces.nsIBinaryInputStream);
+    var paths = "tests/content/media/test/" + filename;
+    dump(paths + '\n');
+    var split = paths.split("/");
+    for(var i = 0; i < split.length; ++i) {
+      file.append(split[i]);
+    }
+    fis.init(file, -1, -1, false);
+
+    // handle range requests
+    var partialstart = 0,
+        partialend = file.fileSize - 1;
+    if (request.hasHeader("Range")) {
+      var range = request.getHeader("Range");
+      var parts = range.replace(/bytes=/, "").split("-");
+      var partialstart = parts[0];
+      var partialend = parts[1];
+      if (!partialend.length) {
+        partialend = file.fileSize - 1;
+      }
+      response.setStatusLine(request.httpVersion, 206, "Partial Content");
+      var contentRange = "bytes " + partialstart + "-" + partialend + "/" + file.fileSize;
+      response.setHeader("Content-Range", contentRange);
+    }
+
+    fis.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, partialstart);
+    bis.setInputStream(fis);
+
+    var sendContentType = parseQuery(request, "nomime");
+    if (sendContentType == false) {
+      var contentType = parseQuery(request, "type");
+      if (contentType == false) {
+        // This should not happen.
+        dump("No type specified without having \'nomime\' in parameters.");
+        return;
+      }
+      response.setHeader("Content-Type", contentType, false);
+    }
+    response.setHeader("Content-Length", ""+bis.available(), false);
+
+    var bytes = bis.readBytes(bis.available());
+    response.write(bytes, bytes.length);
+  } catch (e) {
+    dump ("ERROR : " + e + "\n");
+  }
+}
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bad506cf185478c9c903793d11d95f278148e007
GIT binary patch
literal 3530
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
E0HD#jxc~qF
--- a/content/media/test/manifest.js
+++ b/content/media/test/manifest.js
@@ -151,16 +151,29 @@ var gPlayTests = [
   { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 },
 
   { name:"gizmo.mp4", type:"video/mp4", duration:5.0 },
 
   // Invalid file
   { name:"bogus.duh", type:"bogus/duh", duration:Number.NaN }
 ];
 
+// A file for each type we can support.
+var gSnifferTests = [
+  { name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444 },
+  { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.233, size:28942 },
+  { name:"seek.webm", type:"video/webm", duration:3.966, size:215529 },
+  { name:"short.mp4", type:"video/mp4", duration:0.2, size:29435},
+  // A mp3 file without id3 tags.
+  { name:"notags.mp3", type:"audio/mpeg", duration:0.28, size:2506},
+  // A mp3 file with id3 tags.
+  { name:"id3tags.mp3", type:"audio/mpeg", duration:0.28, size:3530},
+  { name:"bogus.duh", type:"bogus/duh" }
+];
+
 // Converts a path/filename to a file:// URI which we can load from disk.
 // Optionally checks whether the file actually exists on disk at the location
 // we've specified.
 function fileUriToSrc(path, mustExist) {
   // android mochitest doesn't support file://
   if (navigator.appVersion.indexOf("Android") != -1)
     return path;
 
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7f298131aa437897eb7ff41b64ddc452ec2a0ef8
GIT binary patch
literal 2506
zc$~e~c~leE9>DRNWC%&vB8Ei;A<7aEF)Shoc0$+@Bt)#S(gJazb|C_`RS_}-*>}aF
zJ?xgvS{1R6y3~Xqix3qlRBde`r7T7zg3yu>av$`RKi+%)zt1^y=KeRo@0_{!3|!#c
z1OF`~;jm!oX0&wa0YL5rW-FXm1gv;}#jzFnE9zF<TJd<r<O;ZA=~-T3zTp9G&R(8L
zxccQWoGk&Mv22hKHUO;UIpjG{|99B`1pn?K9^4pxtQ6qX^fzC4aR~tQefeQeC%<K%
zPYy7*TW23wxYk7uS7(gOdy*_P7Kov+3_&kRgxYDZ86|{_DN?Mbg`qAXT{3c%K?Q)q
zFwsd?O`xf3|9I_ozd+`G-_3Ei^5eL2Oo|hLekzf`8tU4-<Maj`y=Gs(yT?32==cli
zjOF|CD$qANrkI3-rCX0QV~hi^ebtR5Ne<7Wq_aJazW}EX>vKy<rN;%8X4Oz-cm4NA
zR%fq<Vmh1F-rw-)Eq%Day@z0W>E!%7-vO5sj4M6^MPrpvzTameA^pmtp;>jmoaeDN
zjpo;}!=m(#90`mWY`?u|Hs{RxEvap&*sbE|CC+iR#dz9B<`=rx^WJD$Kf~VecvKZV
z$iIep3jLjPzstwQe(CjsZK4tfhv4B0gc)MUTru~;(43QC*HBm>t#KBllT|U}MynOO
zSI-K#SRK16Yd3U?_$kY9D(%50xb{c*>?QoIT+uWw`xi0&IpLME=Od44n={@J=Ilx4
zE35$-*O2K`*w?WfqyzL$jh+~-*jbxed3kPio`aZ^#LL%&n&52;N9$#(_EoyGt3<Ac
z-VzDIECLWPBCRf-RYY!hr0Cjs>Pp}kBR0k<!Z`0P!$73F;o=7(iLZA%-}k^*w!1{#
zv>Kk7c)$_hK?)JSzl@(&lSQV#|3loX!i?unCkJ`MzE1Yu3YyIxjof^vx+vd2YgXS$
z`F2xkXk5HHhZIqkJI<uK7@ykX2OG*!X}YmsCKq;MmOOf*c0nvX(-`f3CK&I?#(}*t
zjPFwiW&Z?K9!SZgz2}u;H|6tV?(rN4Lh&5prp+U~I+@(VK1zF-&|z&r#`86q<hLx2
z*J2p5ZSwV>?^^h!@+MR~=%)(~3jCmJ?K<u`+Jta_T2w+jvo0Szx%un8Gwm-w;RZR=
ztw{ikwAv0ARc<|U`uU-6UQr96rGEJ$61Q2~AbPwRw#}4yYb3q_V%Z-8ZYHT`Sif7f
zujf|+jzF^Bui&1qK38=0*0tCX$)k>%=J}j;_)t+T(;rpKvNl+oSYrTCS<mQRe*Xj|
zqKRX)lkzmC(!Iq<P+43hwK0K?1{;NwVZ#;vt4xK>jH;^(ZId=c#D3C=F|1S-SmG%s
z&AVv!gPqBck2fa5&Ufw6XBWct9$~&=E{?n^1A>ihdQDS?YNQllvNP&K@Z`8hKl=Ur
ziCb$i99VOw>`BCAY4KjmB%kzBEvm99zWA+hHqk(pO%*=wwqLNC$~M<mE?B}Kdzn0&
z`bCUe%l(<w3T1O>hvkswJ{)y0EK+t-M5jGdPHw~)2G>eMJhz<i_&Z3X*L+UUkdw0J
z*f+0lwC1+tTk87C$3HB;%rAEJPTRHq2#mDVp2>>zHR_)b_9M(JHC8~}3|++o7#lrj
zBs|}T))qWuZ&MU0;pcmmil*%;)q4(Yd&i^e>!~*{h(RL2r15JLUU@DS=S=Q6t@|fB
z#)^HKJsqr1U&LE~5H7SNh2{(T-GtJ7R3XL4>ef<ithDp&%mv9B)TM|0*@qlVvh;y_
zSE|bz0#z9_mw?99G1CL$-1k;P*I){@1~36}C(;=FtJ`uA5m4$sP8_cYm+y6+($pG#
zZDd*Vhm-L4n$O|nJMgiTzC~R@5V5TudWn0b%0+*nOsL>c1B5dEO*AB0sV19J3xA3~
zP^szSI=pTUHQ%nMJD2axi8AjhNdhG6?4qWM(Ta|TZ)9RsSI!qO()z4M%K6w{E4>z(
z9}jN}n@GMx+I0V-h?z!J0pmd1V13law4!eH4Mu?1FMsicm-b$L`7XuS>E2W^GVdOx
z3q(t&GX)?wgLb9w_-MeG6<)h&gu}l@dy&J!<sd_ha%jhqrJ#2IrY*C{xp%wSc!R|t
z|9k5+y~A==07)=dpCr84rplAVduzEC6WVM)@eiWYk?~_Zt6nU(QHN#S&84_ZvUE0t
zo!L!H4q7$4P8W_!c&(4`Muoa*IiX~I?d4!wv#Xj$$i?y@w~W)KUD_6djFJv3bxT1Y
zbcs+kAvBUVhqKG7k6`2Ju3v(f@cRLgjR9oMsh23P2ZfP%1h7~sZQFa}HIg!L3|%B3
z_S$^NAlX3&Oq5=&_KIE(S_>#HxX&7z!dv|50_MfMs%ja+AhB<C#AZ8|Co+!djv5fA
z+Uw%X`kZLG7GJ*eHMkJHDYL3$R927FinUUbv5!(+0=ro>hEt&0BEwpGL>t>atmU6C
z)bvt$IJ7xb{1#_uvtQi~x_QC3rx^@{dOWx~_L#?-J_37dh8i)TumkK!4c!iT&!oHc
z&@tT6KKNigDdaZ%YWuKeBrO8Ecc9}n^Cedo!<Tls`m2ZW>cX7{x#x!;Kk!4}o{LyC
zaL*|q_ZGw~2ialdvG-5hNXA@le*0p=t{*&|zyKK|0UYx>rQpQ5L~T$c;mhFf$+gBt
z^O7H;kP_pK91+Q{Q~pbDwX5P2cBc1u2JZQtr=4`wK>6jF7v|IR*}D}ML#Xq2uBER7
zn-2~=EWL7F`9aCTV8RpG&cc?Lb8Ru(e%cXnn2{PSe|@)}N#qa~_6vW0n(9sdbbV<e
z-S(cD?vtjbtvHSjE;iaAvq+q<MV@C0wMo8BTZwhwK!xL{G^cA1gbQwNLfA@ky1f;?
z>eSP-_-#4JHiM%7!uixJz|r*!S<E6}s|lruE`NI{h)x$}5lNmwC(;U+7v@21biwhu
zgwG74n3$N*OifLV@a^=txU`akQBixUYUAProdNsi^z`&n`E_+-&b3w{@6yWejI;Zt
H|AT)6tPzX8
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0b9870bdcb500389b78a84e7feb6cce31fd828b4
GIT binary patch
literal 29435
zc%00;2UJt(`!1SfCp!TW5~4t8Nf4qGfq;mp5fV^o7Nm)Y5Ws>8BPu#kDQR>SP@0uk
zK$>GvL}p|pp(<Fgz#urXL1B;)35XhM?#6L`=YQ@w=bp9hI(MzhTCAPyeETcU_dL)0
zzFz==Kp5_hJr=X~@PTLq0)?2r!oPOWG4{3y1Om7F(5_tw#DVnaonf&E1o94ogoQ8F
zByP57@}6n*y^kNIN<9ksL<F>x>(LizCV*5gacqU^Yf`hN<^^mEf3fZMC^dGsL(kWv
zCV;GAw_N0Xa7zkb!R&$LC5|PsHGnK(j)+AnS#C2$vdO|}VI&K!DN!W86E(6|g%EXB
z5Ai1hdw?3X)Sd&cyYl6K2!aP^jCk73NIGR9AM#J-Dimr`V!rC(3%^aL4Y)f_HTNX6
z3SyYLes~|~cAJ3zn<PA+xsn4p|BMx>Ht>i<<ZAX<;x`csL{ou@cAoRtS}u>L(T&Ye
z)#{B^cTo^~=eux^T`|cKBpMOsyazF6OffvkM=`b@JXYvzA8$%(t?Y@?d3vgPHpe=Z
z4f%&{mJ82paKWO=)f4awrFt>mBDty<DN(3K(&%G}U-|925>2d#UttV1$X1yGO|r$h
z>wCfqLJgv4qVJ7W_ui>?0@tH2cg@3@pibvGPt=oG&a+pJR%kd7GZ7npG{Op!dqD!H
zX}tlA<^d5X>Ayx{VMifF3{BLS*cwbcr+Pp{0wpY(5*j0E=8KwC<A6zY9X!!Xb=VNh
z!Q}7YF}Xf~AizY_AY0t-6goHMx9L>%q(Stwr8S5e7NiHi{s+ImM6!fWMC@FFf=Wdl
z74)k{!8j~`)}Bh7*+QXG0UhM`Ti@q)yRyA^05q7#D-43?Zir>bnivp_bkcXU4!n!5
z+Z9f7)DHAjaEmH&hUyjON~VwE{|?j}Kmb9OFo_hJX^62HwWR0Oz0Ey|-*Nglk}1d*
zEcp&qp)i$7oQ3y=sEXWCj(Q?`CtL8NkpK$2_nm0T^$3_~P4xeBAWi>2fTWxU={q6`
zMC4Q?-1}7~iv=zPnpAJ`KLCihQrC)iSY<FHX^@NQJV#A0LAsY5en#U9cgNWLN)uWe
z=`j}48<5=VKWIT$=BW#C`cyq+PQPjdS%U@SvH+5x4>BSn`=JFI*XCzG=g<QW^SXxy
zn4mUC#o<q?Ib%pH+Ef^hN}FrHAAtF;$RCZq^Jk$b{iMTpPMKr1DRRg;5$5O&)nv{G
zihDMz;Ngrokg5fn%8#w3+NiShegLdorLa7?0{UC_i>(NiWvE_hNTnhj1mmi2FRsQ$
z-+Ku6zwIAz27d^UMFqaaz@%>BD-;W=U|I8)DR{(}aPLi8@G5M%RGT@)p6~lSZTX!;
z-|0lf8^a4d6pZ(ow*p>hIcoI#GQS2G0|NgfXHb1RNgyk$FBD;HFgSRrTzw*OuImik
zIFcZ9q-vt1FhLMQSwvk#!H$2m27~;x>%aMy^1s+t4?WQ4pAnAA6hF8__|B(vSaeJt
zu~!a3&e&8{P7Q6DDvpZ6dcy`H@24Bt!2a<bT>pIqs}nS9)!z}m!^D+c$D%6SuqphF
zlDN9riIPkIfLKvO(I^AW5ATx6c6i%*T_z%@Yv2V$$ap-pf4oS^!hV3Aus>C%P*9}b
zF?;u&q`9Y)Rc6etp#$S0B1nSeveFtfpC7;0rbF=a4-o&w#p+*s$`^{~1w+85sG>aJ
z##JC>2%B1<3p}-0cWefKgY~}@f`{4joj+?T6?RP1nT2dc;s=<niPJ74Sxa^Q8DTY-
zM~PO1XTdW24^;oBWcGcFgYlRSVBxQ~A+B`^rRW)KJa6Cy*g`B8dgQyNX8wzR;{$*A
z_jd`kxF+UMqUIeuMFekbjA1^oaDM!^y2G;jKS2B!m%RVzP3|%;V^Gwfsy2licLOp1
zqh%-lZw>pQj>bPDT#~Zz4oX{h$C8HsKy?z<fr95ql=nLiSYscnda-=LE7(qBc&XTV
zADBdD|HIE-(JfR>!*?E0nC3`Xxt6>SS`bOIQN>#<`G;lyd$a!krw{Ga!2ByhDrgW#
zxo+qe_8+L4VI3&p-~o-%#`A%}#8HuqJq)kPk+l{mf}_a{|KUIUJTRXMgnj4H$$v5d
z2+jnm;7s5_?t*L459U|!!+acmFbPu7?$1XXCz$b<_`JGlc_ED1dAN78lW<y)ftXJV
zoc@`7;JmsB--V`t=dB5xfx^!y;AiS*19kt6c>e~mF0m#iVBrkKoM#3*+Dk+`FY#+*
z7TlQq6H=y#(S{M`Vb}6`HR$@G@3a45F)gx(va|odBwstfb+8syRn`>(?t}leOY;>p
znMf{6AZn@1W1RNPDgTFr=|}J1)n%YK0&S(p1@4-dz|*i5UO-GHPB+e*(D?u78XNq7
zPodeOD)tL0m;R7xqQ~7E$c&kP5&lLq2>VF&*QysifTvuP%n?x9{(bSpN^z*&X|rl&
zXZ3efyYvI_hIV*d^A_6T0J?~9ZXG8}kL!~tgE+W#(STr6JCo6T+)<-@yF0-WMBzm!
zW=O*TSH{WWuGg6FZ0Xag>i^v6imRaD;NIkM@Fx+gI{zDSQ(EPG5nXmtSH|8ywsm?`
zW|z`~cGV;zXEY%e9y=uO`$y=13LyHyJF=or9TdFdKe598o`rpf{&M|&rz~W5S%fkW
zWd)!dD~qbHZQOEgOL57|K%E)`KRh}RM92Jk^B>2AKf1nrG>^wp9^w0PB4x7cQtj}S
zfh<#06fmIrw68ko_TiC8CpVRq)uTPK6nQdu@Sn@}8jS$o<Zc+gfuibd3S&i>An%_`
zVU5O)O;{`7y=wf`55cVT7;UWBK9W^^wB+ro`+}zcA%;i%Qw~#`8bj4V1^mZcE+3FT
zFbR!F#0vRM{G}kL&v_I);dP+K5Mp+G11^I4Pg&B*EH1r^X@VKCdH@~fHw4_6zdsX4
zJO`o(^Qgc2he)2GiA|lUr$6}y*~`Vd1Xq6Mochitz$@To#D&fa*hhRu(Y@CF>oapY
zPgyh$<i+9Q4A;Ks8CZVJ4ZeH6adNkSC`vtF@UIq+nmTlvKKk1I_1oVEKAV|VfE_@+
zYOsX5L>2QZlGv?@Car#~WYMOty2B|w<iO{$4AFf!IFWg-U<ISX4tYfp%CJeQC*G{h
zbA5+_eS*Hk&wj)Os+!=ycaSU8ZvnILzuc5{OL(C(9YCY%lWxQ*6b-B8I>dLM`u0aP
zwog&)_Q!+Y>muWiZ$x>G5E|v~=BwcG=W|zHa0EB-@va`OSMnA(s7OEJone6#d9zrk
z8d%IVm<Rvuh7``hVl;@zb8u7=!%5m#!Dr`h*sQRnaGsOJ%bf0pc{a#w?g6u?X7kmO
zWeY4zd?peO9PV%ev@PYI_kthqJ^05#YtSH*BU%rqZj%@UmxVV<<I1nGClhCyw^f7u
zMeAXmuLf<fA_1BN#~&J|fN~liLd2qQ#&EoL(r}1z1>KNikQyqMvd~M6Qt%Qdx5KG~
zskKS8bSrv*RB)>LuZJ62HDY);Q`j0m01|~lqZp?D;~*^x3#|ny5+?-hJRar+>^6hD
zl3mzL9a&uF9J>c3!F+pS1DaWX@9$K#yo3T<Lk=O3h5Z}$yT@WCj|adpHyD6!gEZK=
zVyVQ*tYp~ZcrNfGaXP_j5fRa~%V9Ig)<Wc1gd@%TL>MO5eiev9jD^l5L7{+vO+xl@
zwXx}{fvmXR+1C`lr?xHJ_5cXDO1N~Qw(4Q1=zrE|ll|4~YM-kE9(sFM-O_O=t!&#U
zQXj#P3`<&MW1-Wxi5FCD%)KBWc{D-sL?dF1<b#?+D|~ga-4ElD+fU|}E{&q;Af$Um
zvbmrNst$TNd(3%s$SDfdmjfHFl;@}eX9$1H8=@M>V>QqnFXde8?>K&AEvc3&zd&0|
z#r2J^7Y!meyyU_$QH1JTPXs3SNqK>!c?Q-=CZ+099<9w^R4+@0DL*@leZu#bR;}L2
zRXFFBW0M2~nAX!%#0!X$AvzocA3QvLOHU%%n?%q#q;}$}^$=?*61o><zUkbS#1yqL
z4}Ml{T*1-yxRCY)nXV!5myFzQixtd%fk#xIf%*TFXi!E~mvS9tEaF!>UlX`5Y05Du
z^%8v)%wTpi1FqwNe$}TJSibNLRTCrSWqxUt@@i0=iyGV~X@DF$NxSYxvr|8M9(2Kb
z;x)Y42!%HqE$Z)B*K~emq@D(MvTo)!22P_E#!z+V;<0J`70Azt(~yE`2C-~rricp=
zKLLZPuiAmDu_MA)6uDmk1<oc_OHWckj3F%JLQX%IAdBmrd*Rp4Z@~Y26$tspJGCBj
zN_2>w%*g!ZReIYBsPPmqC?hjjf0FOT#$Wk5qahkf{M6hN&R011332c^(3m$y3WMgp
z3g8c&CTgfsS$;^X`G->Zah}>tWsZfl?3S3F*KUC`#!)z0DdFCtKupkqV#8-Tc{-_A
zxEA(Ql-f}{g&{6l)F@lQpRAio=LA1AO*&N^c2^~cT$72gchx%IiG8$|7+?9&ZZV>U
zxj^Hb85LA>K=vg*kD@L{)?%NiIz%%0Vj0V3%Ie>4${vG#F}84xF}Ds0CH{&rgXcRx
zhK>`w_l)yZR21&3U92H){()ul4^$8Vv;jg<_jfgn-cuO8!P}M6i=Bi<J{wLmFH*77
zSw5nARdW|>12O`N>q2cq4cT#b1>)-~rybW^Q}|X6<^-TI>dQT|KHAuU4cwc*xcz>)
ziP{7LF5?sL?jFyn>(@Ar7gHoOD&m4B%)F;}3JO1pZB8`xPHa{9j{G|4btHK$LRqzn
zgpgT{dvjf*10HGue+q_kEhcB?>@hhy*g7k3{91kABg@n~Zoi0n)vsYSWxB6f_Dt5w
zw;cTaJl#Gk<|RIo85r-A*z9ZRM=O_OR>-w0pM+f($+3@fQFVa;z-Q6`RL>_mle6{y
z13vHO=27<R2(1-&rs%g@>+A!m5zb3NLef2m%jxVY?Z)}eSx!CLTESIn9mz#17FtAN
zc4s(Uwj{c3xHH-*U0p?4$JKrST7X)5D5!pkT)ZB++uv8m{`}he`qn$C>c}I92HY8w
zIlW<SU5fWoE$0eBvOFtJTO!N;s>|Uk&9s3fV8F$Mti&0k{9>{Ik{AKoiiD`Om)ipb
zQseVoI-rwAG7_Ty-2CmladoGT3cHH+lpPRnb5E&$`_0&H)II2-0k)pMbi=d6frz|=
z<)eQMmPBerE+V{Q;xXE&JM0>BF)3^zh3rBM0t~QI`FcrXC(m8F3>ri(%2VD^ftFTQ
zo{rcCRqx1dq+s0$ak$cG`<A3%`%JdY2~N!c#{1t|S-?Wv6apvTp9=2HMbe8@2A4l`
z8%|#Kx#F43X;3Jl9v;W1me7c*BL-11E9ITKyInp;?4GQgDRKdEbVU|cM3|7`H96Tc
zdSprM?Ss8%i@z54`4zk>9b2}%aNo&hN&txLqib>5pSh5~G)TP}OP4JfiH7T;mR2u1
z?VR5UPEhmly+4gg*<f(RVZ}~1?5iToS%|xZXrV$cFHiVZ$^6^*M*9$9NN_3_8M8|u
z%0<X>sv(ODWj(F*({-KOn=qB9FssdN-5!9o)FRmgWi62-*lQaU$33C{t!~BewtP<d
zm+j`Nle?LLfiy-yn_62?v?Ks{&t5QA-IcZVN2UHhIPwXuf>s3Q;MGK}xtjU21@~pI
zC0F6797Q!z9p!wctLcJdINZI)rp{OW&*mcLbJ|C`d*Y}lI28WqO5P7?fQPvX()NG5
z%7eQKTqc%_vv`i`oPOugNZK-0OvOTpB8DJBIv_tgPoAoNqI0Uc<-9|WAl)EZk^Z#D
z<lwTXQ;m(uw$;6@9jC-2<pyfKPiNPD8(uPd?!Zo)O&6Y2<Lf?RoFe%bk3T%V#;XkR
ztYI{Mkzdm_0b(^3=ws`Q{|%^$X7`Nj`1NKUvTh&S*UYPC`*;Vt?HwVn3ZF8E;p%~h
zr$emvTDYt4-Y%N$KlKx{fTL<bb{!1@ks_bx2)G2!d_`P_&DWdy<?ra9qQ2$)B~PDo
z@*jLD$iyby6jmL+jEQ8L#$R{L_FlnsRx$;Jb(lSt2TxMVJkKrut8GnxG0-W`mR4x<
zWoI`o#@N?VZ(z0?oWHgD?0NqR-DQ$6Ht#yeP(b2(9w{2GxNxD0Gk5P4$|RABy34lY
zU!!yNbZ(HgMaAHGf4$xc1@z2XJ@D(Y^fFo6FRVo1RZySO_DTbWtyIm-UhUp}!ngUH
zRaB{Soe<@DEis*3GP!$l(J6%<94BfiRx5p%Rg_OtzkRMNow&O^@=%+no~0^-Vt67D
zB*;(aDuuZ8ftgKo#;@ZYw1At7BNH0*sZ}(kp6)p%Q_XUP-uStznBI=#e~j6ajx4tH
zEwnPkzALl~l<Dp?%w9%+C=i%@{LQ8F_w)>H-8~t~m!4JZZ+_uoCB|u`?<s+FDOJhA
z)~ntOtzf;0{9U>Zy?J)=WX6R~r~0_BrEgG0Ld0>rfrt*P_s`vjpotjPv`22qGvS?{
z_zF#pj-tK%8LAGFhNA&&E_=^>Y8H&gnbcjyF!fb+gU6mD>voG!bt9#QfbmXB#)!qr
zfSY%ZNPddicwsO?UC=Zz>{l|4e4Z%Sc1n=_P}m$tS-R{~Dsr^NWRyYOII~eS;P{Yf
zITJ*)ub?hMR0E?TOws}=5u@79nX%kjntN>f@pCr0=Aa={{mC~$7E#o>9b7A8rs55g
z2G(lH1m=5p`vt1Mf{OR}zf<c9^Zu*p)TA+24-<J*W=FdJpUOA@t}Oyth8o;4+TZi1
zz-ZAL1&{cG13}xdsjA@l(<)QFPpDL?CKApiW_z%Y`HKNHt|IXxTm>(dIqgx|{y1S^
zp>-fd3>@<ke_@E4WIFgkIYhq)C$z9sXAdr=S|g-;yu(cYO9tHwM@~b4E8EEbSGe$u
zCLDVDbXUVVdvbfl0=WDizZ(&@dS7$>&!2yHzi?$mceeNJ_15m2DfitT4@OuWI<XDZ
z6eJHM?ytu&_Ysp2$NcwlMR7NM%1@bL0(1kUga||`JufdM)aq5CVb#jWm_RyUpds;`
zX->G%Mfh`RQ^LsJC1=|MO81@wkP7J6#XQP70CN@ho}z4FIqy$g5kpyrvEL<rJeDK)
z5TacDIkCRJGi9j=$Cu@Q-M!vmyg2uSTfK&b<<Y;HYc0UwRa5>OxMNxCKrN0S^0dQc
zhgVa@<m-DLE6e@e>$w3UZ5+Zo$`K?K=;VdnH6OFo2c>aqW`Ekh!%Jn?ZZ6oQo?TzP
zjf8wl;wT`k2WtzQqwjK4%eRfkPnG<!eean+>j#;X)!)vPML0cVrsHdvjM*7$YBlYh
zry&1{d!Ze)XexfQSm(jB2feu#1_0TPn1<MXpf}*6mScg_1{#xbFQGJZPXVa;#r<ed
z7c<=v)JjwYh)^LDV?Uoe*_SX}{os<v{*ZzT$W0XlbH!h8KeL-S{oXqfN(H*E{*z_E
z&Dy0lGJE=pQdM;4gDb^)ilex~KS76wu`*_t&GhxhK`*N2dQnyf=KLiMyU9W`9{u)N
zSyKX<qhOLr2?Z3g$MwD3<!)+sa|+LfcO>WJ5gKk;deZl#ARZQQE0Z~6b>B?SRTv`g
ze_i#WHuB!b@mJGzTZD+Cw5k#<WIz`MP;*k3{hF}+<IcF>PSkDo{Yg;y<>o0_H+$*!
z!Hz+Dj39`Zi3t63d1;1I@43yRpUNIGK9x*ehi;(Pa{?<2)wvTmWSGJ-5Zor=-rcZu
zr0Fmk;a^V7eYel9sL!X!k$QKu{6IZXpk=~^YqOh(S61h<?)n_+t;R_z0@?+2{^wiS
zAG~=_l@v!>DwPVLf~dner|$mEkItBkt6&?>5X?P0Q=o?MufG>yE<_8^a5j=V_T!6{
zX-l|xGW|C#=g+6*m%CWl5A+|pnLqj@<5j}{sy3VdNqn2VB<10(<Ucg(1#5Jv-V>3G
z^AlVzcCp;1`U6?PNbb}BKDx#I_rdL-qr>)|1LEKjSZNLq-)tQFuW_xXr=;-P>>1s~
zVb!muTVKz9-d6W%*~#6zb(Abar4|e1%idSf)De}(BKCDG8-HT7qIX|-r@{LTj&d}6
z=c=v!k7Zwqg{mUa<fl*J>pRx*axeUP&}*0EMnqgi72eVt@26XOe$DP9R#QpQ_Ia_|
zC%2gAy^<DsB^YVnrrH~dP(2^}i@Nu@zYN{f<~tTRklDPDAn>WEya*D`?aBl&!jE$7
z>-S}|A3xJmpWc=1pXwS|FFl*!xbZSkkR31C$@v?xlQOA)_Ve>(RT?l5T1U%mH9QSh
zm&9?YFOL3jE#gBiTUj`Lav3)I&esmRr?v~0kQOzaFI?YMzgc<bUE%HgkMYug+nqDC
zMTo*XiPti}^?U#IxLW=B_>ujm^*ZqTDYAjO@+fu$wDV8{LUylp@oaJ8!JIF)`>CHD
z@!OUsIo9*J^b+m)EE6Tvpv%s9HM~Ku|5#S=UX@;Va^`;P`VX!zI@XPp(q{Q#3$=MK
zQ8*^!l7I7A#`#-&x#pks&iB?0tehz5l+v`z_dmW(y$)(}6cWNTrK>n$vtXB}c5jn<
z>seG4d#6-y*RH^JTQ|8V`yt-6$i(CK{%850mVa$%@|->TH@7(ANR}D?x|Ti15NKrU
z;MFklhEd%oXMO*w4LU26x1U+Fscjz_5(aG_#XcSqt^~CLF<d6&3CV4LRo*AypzA*8
z3;|3f?2#<)haf4}jf4~&_?i<HACu5A6}qqP(aoyg-(iNwOjccAZ5YoFsKTdGt{=jq
zEXx`OUw=CBu~MVJ&+(b6RS@*_C&A{j{jE-c?RK^bOC;YDU%Y>h>Q%!?bHT~Dx~97x
zTR;CCM?KJb4kf#Z;X18F?pd_kY%ElsK0CT(%g9tbRo;CwY}1XMEUR8XTN7&q;OcZv
z%zsbrtuXm|@7=fAT7T8p^xOjr?ZlY`)vffTP!+B2@BS-W$CTypr*VE3D&?#yR9n4n
z&N=aqCYM{P%-%0!-sLLY!tZx)p6nl&-=YcI)C-_X{gS>=`CC7|(%(NGSkPab_Jk-G
zrCZUeDJ_FZBgwYMsw=lDM;(YXgd?mrNJ+xZR`jgA6E*nc&hH;bdE4K%Uo5amdE*Bb
z@DCl6$T+1PopX3s-Qt~^%EVO_gt9l+ZcSd@a-3^cKGNEq`v7^6cX&z@V});eKbAD^
z8-4|6G|Jm?S8BGA8AkU)v~xv$OTB0oAPx~}Y=L9EC3DIonzYQ8KcHhF7Ru~>0`p*-
z=hi_bL}Erqc~L`&p4be@SJ2)*rys}T*fK+PeTJaV>^DHoM8czB-y5M<t3(#x+G_BN
z;_jc!d{z2c0MXY`MV1If*iwB!rn-#34%8zigQQ_*aY%)i5{rmjk&B2q!$|X#s|yBP
zd}@$TFAX5_S+#)7z9xaek6h7G_Mn1765^OUON>QoWRWhK$qEU<2P3cGsUWgFOp#Mz
zY!QIG_Qh2Zu82hPWfH8Azab7zY8<mn0mPvz5R;9gzoHzk@KSQ71b@(XpJ$6u6c!rn
z!yA`b<6I%4VuC`{b%BH=Xa?xWZ0kENO;$%iVuHpiF@r7R0Uc`UN<6l0#>pR{FfPU4
zkUt>6HTnPz&}AR6yy~7;F6)v|YJV$}2rFu8y~s#$Q6gEKq%L?6!Z;oY`bYHYemHmp
z7tt2%jDR$+dYieBVYqM{$hirA?+=Nw30OCYIHZDd6e;TpA+-r|MVcuxDnZCjFP9zj
z5x{988n?)uIRkJ~>e<XZg1<<O-2~OU)6uI)CAK^!9SO0?xiW4t37OK1iv^ImBA+j=
zP%_?$Y&P*gWI^r#H04sbxIGB1SbJqD>ZO#3MhK7)mli;Pr_lzshtU@TV^ddbAW8`p
zJF8#=LiU_ekL@aviILDNs>Ym@>w<u|j`-5GATW1d7H2cZ5$eTc;TgonE8~@BfV^&e
z%#=>dmGOxHVl+2jZtVk!@y<BUp)BNZTZ&A<B#OL~Nr;v1s<|t~cdE=r;Xs04Fj1ts
zgk$UDk@ajA9;Da%gDL?BuAWx_5FFh3yet?pKH&>ovHc|?Vj($BFR0SgxSi`Q!nI16
zhGhRzKPORtpP2#YdVrn?5o347M2=W!jMwvKD!tI^1T&_RQcEG0+5|9MhAT)K@?49Y
z<2OTd(Tfye3VIw}%w$#6P&{z-xI_il+pTyp!C&d=S3%Fr5RzEf$q5h8&k5+m$5j9V
zgg$48IZ@+I^Jd$C5;;E33A_U(KxW#4u_3Des2O<%j|{^bi-_7p8S6K15t5B;fRast
zXwaH0NV$SHu7|=P+e1Z&reQf$_cyua+LwK3wzz~eRpcrpEeHJ-Tp<I_`}q~M6w+G$
z0X~n774T02C3F#rG_lY`v5)0P8k!6!3n0;F7CK*>C5uZKmhfCpzxPA36(nQ0+~0?+
z-<qM~2=%3WhA7SxyvnwX;RKN6ki-bbn9vv5m(WkNd-`1oJcASlx=`Z-R|pZ<GSI)Q
zo|sd{D%g(WQcdA*juZMviH*{Ic+*leGueskf`B(?xi^RA%`aIPq0-eA#r;OCM+aQ@
zv>^`wNprQwcv<kaE6<pw+2xCLGlf{b!j7K|-%{1}sT!r+HC_UOJD5-8J5pkiP|w)V
z*`5A_ZwZhlD4~#CaCTA-Sq1TEN|_@SJEt9n_E1ix(OXkwd`5o0E>e-yXKFn0fY_EH
zucDB|Qi8;gG~+~ed)Ge>B{K>^GD`i*w~UT7rbhq^-bsovKb}u50XS8jg&>9mBEn*(
zGW|0f&p?`p_FWu})?CX<@2m=s0B5p%%=w!t<5A1|KV^?stf)r}QKW9AEg@tnG5?tN
zN$@WrX@cHgEZ3@>Dl*CbG;xn#4>(hahbeoD_QeKeon|cgvWb+dTRe7%W9YOS`@HxJ
z^d<Xq%meJpL>C}P)3d_E(81C3+2=<Ba^;40Y`H?g+ks7QEN;x6#*9RMn|c$#u)A5@
zQT5E};q>D{-JpuYYa}}jF1z0hh?Rdivg+!fP<J?#c*JpJ@ts20)hgUD_zl_2v5@LU
z>&+7#dFQpdzlMidS}vfx7rluSJXp0+qw)MpynGR{%i|<k=SbCulqwga>#r`;it6^e
zS(T4;V$By7-(vqcRb7JC^H6F6t^8#laZT@rF5UHLjPZAPv3YUCm%{v4Cx3C0cb1Tm
zIVg+D{-P89Rr0;zY&EN*ch!|<i+F}RzId#y#Ge@L^?O_Be!a#s>dps2j>yXG?J1(v
znbt3zw7c4SnGF;~5sN^g-0x;)?lNIejISEOf|xs;o7n7>>pnp&M)Z$*p2?RZoF9>A
z4m~O)ysseg-<O@IeUl?4Y<CtQgB;skBU&$jBroxagBEM&sCh-D&L(&u;|u^My^>Wq
zDf3!mE7bgpwg_GyMHL3_rDv^14C4b$ns&XrI%1_z9$%??VaoNOEe8I8($6|;&>FM5
z@<?t;UnjF|8m_i)NmXwX7t4u0$Ua<b?pE<RgBp`N`?k4V`w;hd<F)6VF>KJ0NprXv
z=%UPWB>OKu@Im3}w`${im>^NHmn8P(Pf#Wslr?UXhr+sf&wLWk_jt+!4mU)A4w`bW
zv1#fUcM8gTvqxVJhp6N2A41AE9@bvsAu7qC9Cj!HqBVQ=jEP5<ByWxnoR<Ck#Nn2|
z6z53Nw#(710#o))5Ok~5tFF=tHe7V~T3fMMbXDfi2o8x&Z@;K2ngiD`kFiL;7H{N3
zUmU-AetSC}ElDMz1(Xw~G&@E|YkFHA)nkToLbrWB=o8R(9@N0?wk^obxoBf$wBk49
zRaCVgXGwJ3ZLs>rG`F}T;?+qp-S=1`PVI&`Z$Z3$VsfLT%V|6&TuyLYR6KiaLL@h*
z>!)7`vx|S4x%O5}<qn@7{cU~i%taFkU2~^DD;{+UsuH@df6Oc}5?-<kI8%A;l690O
z?n8z@vdjckpiw11>X03v$;m0Zxju1i_7GDV7U{YHdz<)|Z>4|L*(uQ8lkBGaMQyL#
zFWYtRIqt8y8&m%*ov0xOl=KsKBkHZtbo@qa{ySysm8Dt~?-vKufWCL?jXF|#8EM)V
zw^4fC_}i1_cvWP!{-$jUZUfF^C&rFB&Rn>8V`r8_7DwwWvg?dP3FXjD$2?7I@_U-t
z@z#h#F0*e@H8$K&@!oxF!AlcyYi_1jWl(^>!?O?@`KO^-i%Of%eQMVmI*pH@(I4jU
z*JQk!qwO5((10(u@7vf`r!vu*YWiRN?gQQt?^}d+?Btu9h7`YhC!Dj~_hJcYn~mm6
z`_AicPO1U3z{c_oA&eFLR=2`09YHzw^>~lAyErb=U9x#F)+KE5b+3WIHX53v8ZI+l
zhmcRuddsNIh%V(JM&#Hf<(bt}cU_wfC|(b*Mkta-HG7QIEZS1!$Qtm>BUdQwSw@Gw
zlOge*Ny3JgCc_U!2VFKs{?rqdNnILM``hg{)CL<kihS9|6W+YLwbcOQzaccpW5IAy
z*i`Y{GqL!&-TK)+i%e|2+J2tyRfZ01(SMuAX(9$G)><zz{jUSDHO6A+qG)^W@y@li
z0jnc_BgV;(-tas7_{OH@(NDf$%C+|J=6d}DY9`IYx6~GDp<z1<-jS9#X5=_4oiScf
z6=(8Htll+J@uXv4*{xTF+-J#8O{qv|OXl2aoa-&Ir5pcGtrz9{q5az)kjd?Y1N$vn
zq=wiRY912vYnTtSeXW&NPRirJ76HLb5$AL&ZCjrihn6{3<iQH*8p-=D=qi!^ms_Y|
zgl*j}!xF>H+`B^WINj?qs?7&p{@{6Xy@o}Go*`pt1lhjAc=%}i+Qk*#ct;QjL&Sk=
zmQikcKE1J2he8#vA&HAT&uA_d@x0QzaB63&LeBZJQ*#|>87eVaG;%Ys9*9WV@RKsp
zgrps7h@={9Ge0DCrJgX$BwKj+viT-=2BJ=P%%+xq__8eG%GC7_J%t7B<|+Hg`*rL}
zGv1FjwDbLBIp<9~*j$gDyvBeAdui?A@PLF8ciN45<t016BGuCLGk<mT>gdi;mgY1~
z<!E2~s3l&c5HdtMi~u7CrwzZ@Rq%Sx=;A&?N4ws=u6^E}8&%#bI;5d@g5<T+72|u%
zZ5Wy17Vh+co5@Kr;rm+bf7GUNW~NRb7|zJh5cst($~3S#zp`CJ@!D3FRT`iv#5U%g
z&Fs=DQN4Td{NwD-1Sg}(+^BmeyBQ+wxHYexRyVo!{lQ&in#m;jqv$7tJNB9|-gRP|
zhRfE^-Si%*q#yq6rbYR2A_jRs9LsW|raVeC2oF8s^4XD*f6OdX`}tB2fU9SK+e@J}
zUZwTy=|g&poPOCdr$)J@&7rT~``gW&){K;ql8uLhB_|nsV<sKccD*Z3Dcl*i2GLF=
z<{tAFzqsAk^(jqv`tI$)ZRD%#ACwR>`G0V9970FJSF3dEbkAl!`t7&a<UoD!DI;JN
z?N}Cvtbr!05HVk_7__Doxz<m-tHk!Ni9B8rYg$B%!-;w|T|X>n%)RnVAbgfo?~WBz
zpHFH%+j!M=(dvXOmrjk!MH|st#*2#m!;5F=H`-&cs9Rns?*`8T*w*vUu>(&XatNue
zuigy;!y)Yo7xK2R_Al+JAkY=kIcQNA@RHk<G|Rm!KE=4xYvb<}5=cjQ9DR|NK)%gT
z4jr#QID}oiwXb0#!w51P=G7l4oA`WWm4ua5MPQzpTl~`-tcV}1wSgC1PAl^)&4R<<
zuBywsR;zW$zh(F=*;FVyW|LwS?>+kAEYHh^yzi)2EI}$Ego<qd#5FpEkE9bjj_0SU
zH&(&vwOiEe@7CnMDV_I9HRj$d-S46vir`IVR`0kE`37t&><FAdYORc!Sx>SiZg1`=
zH$s&=t#J=#%>24cpOzo7)Y97hrgP)P3NZ+&E~g!|i{B~*4gGGe;!tY6sJ*j(a5l2@
zzHQN#(2S1a4Hx59q5Y5EmStT${AFX}NOOz_H5x~63cR#>#=*n;Om=Fp$!sQ0J{if`
zIC|UyT$|-Zs$}P;d9{e%pPIDRoKfH3dt+x}g-D**sot)>balYRxOV11;1F=ObW@Kx
z+5B1Rh)(fmAI77yvD+V`S2S{e%534$*PS3YBmUr9mF->Rch>FguA~ss0%ir9IyB*G
zB)0uXyKSONM3<KGU&Q#P?Je73-7HUU;kO=M=-2<!*&4^gEoFE}{v-?4er}WhvX~ot
zk-on1)b4dIK8d0j?V^TZV@tAIM;)=H-)W@Gi_A9YyBp|kVi%GXPtNSd1-(To{L6n5
zVW+UZFNW8^Pa8T>k)18q#)d!IuPkcFG`;H<xpc%A<;cdMjZSw=4?yy<L%%m?I5E&#
z=8L=uHrCcgxLD7v%9TEOmRc!l$c%$a&YFvE+3VB?yrvP?@^=gF+DVcsp3{$J5i6Y>
zU(Hd=sA(P)_xfA5UqVmn0A^Fwl)c*`)B<Tk*)2?8-Q`~*ZhtYx#}`eth6Xf@9v_Zm
z5Vg_f3^3Rb+d*s@u5|)DUSE6b6*T>m;?H+n-um#x*5`ZwUY@rgvwIKrLG;Q*@nVf!
zVuyuIB=7mpEv>2qTy9m(_M6>K8@Fq;qHS>ie+^w+zdO?Cr~NKou)|d;5>_J`n}!?H
zP4e&Vk;_ubUal3oT6N!w2n?h*m4tZn@WsouiQV5`iZWhamyaLF!?|o%>xt4-i^${r
zR<6;7Gf|rA2DsI{jOt5_yGRi68P1m0iZhH(M0;Kda5h0_f5b#nKVmj%>w?)l+pB{P
z#WcSWofU6xKfZQxZ}y(L`6HSwToaW_)juApnzLd2uU@EBGa=flnFN$G{C*4>r5^s3
z({xKkOU0{$VWDLTcyoFcMoJ~c6P%BgVv<(}D&72QU=DU|61S6oNRnIvR~>~YqPA?M
z&3*oY^o~duzhDBJ`Fr456j{1kXk<-88(RhOU2SG*$IUQilk2MLWIw3^5;ZJeW%_F%
zOLwvedTWiN*9S?te0)iQ6OP+UMwas6Lee^Yf}Sr#fVx}g23I`}@^bL%Hi)0){Gsfr
zo9?b#kP3+!ZjnDo6QPm<nP-p!gn_I+R4%{+96r-)ezx<6AUxVPe*lq~(Uy}b&jrx*
zFeO&R1rY~%E;L=iDDjqrgG1RSO5lPv26efh%l3#8e#zyRxFg#45g@LnA6&+_$%VKa
zQ!x$j7KV`ONv<Fn{o9Tl1GsP}<m-yez?pOx1XjE%7~7cT{P#v5hz;UQ6w&QsWO_=y
zw>=sWrZiidB@FF{xGtd51*17CudQ&WriG%N`3F*FaHxQ^BcaGl0PQTc8&lZhxb=Qy
zd9H}a5uZ_sbomD!5V9!7YU~EtUSti9rf~Hpp@n1Sf!K0MvT3|GQ#EmaU_^{i^Fj7|
z)A=zuNCCl3044SyUX0NJ0bc=%xNJn9(g6`Oq301ZrxpQeN~kPQK}YPVWr&bNrg63L
zz2`Sdcd=!LPN1mIj0(&sxEvf^<ge5Vw7cu)ZVi%!NZuK^9u<iB@T%lhClvfp?aan3
zO&idA2MS@FpQfJCSP6Y#?{+3PO2g<thCryt17|1z2a=e8RFp2CsZZoP@Q+IgvMBO0
zsI^|VL(M@j>6P*p=g0zLCy&Lr!dn(g2hg@lsURwlh(Q$C#)E#&)`&+64jO?6$#RME
z*nB12C{WCyZLQU~3MN^kYk`0qNiA<dAQ8k+a`49jSy(01%kQPlQ>WYpq2R6=&78vl
zU&6iVM1*sz08))%#e9|l)G$7blu(g!90^6ryBV0LPGaNs$sFS<ctjDREMg`RE#Z12
zc-S;lAalZtjN~hgffF*ZGpL-=bCD8^L^9bb61G1O+wKgp1Ipjx*2(d;6w*h;076+f
z)4^_~+m#TeNF8xCUgRY*CWRy<*&eS`qto*H1MLd~NZNpA{lX7%Nv{&KjG>&0g$tFo
zJlhx+9+32ci1q^rZjLiT=1NBXE|F323?WvWnYM3+B);q7y&Nl08Io!l06YUz5m9kM
zBSZDYh3!HUv3X`7M^QI9uP)+@`vhOX)XIcOz|40cVG%LREMy`4>_xq;0&yWx{=ige
zocX(3A!v=`HmD{8vq)}zXm^?#W`dZB(p4<m*aA^Z0ZXuK$P7iA5*sVA0E)s?>WgHm
z+jvGCfHDGo2%=H7M1L1Oo_!q%a2w>4F%w<_y#6tt-0&d&9zd3uj3;qY<OmA9wG0j@
z(iKu{c?!MIdK`1o4Ml>N`!in=I+3rN*`X^ke?FeXP3ki{&Ul7YJl0R+DoDm@beSGf
z%;)2guRPP`kaJU!tQEdI0|6P8#DNkA5VB~cnLOp10uR!3U$cVoxLr-X2t}k5;*%I@
zM)Aa%44FOyxvh<Ld>+#UmL}{8a<P<%0n<=yY$o46frX>%GdKzk=&KSY&v>GVXq)HC
zoYgjnCKHveF0t{df@g+qlPl;(syTy8WaPr5n!r`}{0SkOUcK7ruk*W#JR5a_HkYM@
zuMT}tjXpRueHF`j6jZj#Wpf}bv?Y<e7i+K5stl3oqbZky_1I(1x$h!6eKz6LULGH)
zid!V8X{R`qtay3)wdZPbWR~;8RqgBm<K^h2Ad}N=^Zzxp^Fd_x5Upd~$pDLO<zC1~
z3Hj}TdwRLX%7u&AnM@+KkGQ5t`Diy!J7S`{<aq9F8P5^?!c@g3bpJ`-Z=u9<=uv$!
z;JvbMzIXe2<(r!0^Oh%tQ_M}wYqM=nEF$mrtwg5@op3H2$CKNx9KkRZwF@7&oZHCM
zBre+BwJGa<S9T@D84j~%;GzdlcVzCnizwbuUqcGqihQ)F7~3EVum44G&y~c>^`6jU
zQpb)Rs#Fe^D+e-Bmf_y2DXajhdpDI7q+WMgsDC}Fb$8mjNts#J(#1H&W3_1XVsXwp
zDCvELE_SAV7W7{IkQG40%$Xl%7yHqp!{V%GH{kus2KZ@Qj54Y&Lo5k<c)I=6$rYtu
zjR&o)i5)r)&eTl*BKLFWul%a<+MTp3P2=|I>fT~-$ac#S4Idh3>dKOOuZS_ayHe>v
z?jqAiv0KdYRxLFmPQ<=#d^dNxmcA!HOM9=z6g6h-dOsz3^`>0rM@psZM!{HjZNREX
zo|9)tVd*bv(d#_WG4_so#WjRp;bMkOIN@{a8!OO)?1xhtE8}ifV*8MFm4ku%h@6@d
zue6k+fm&+(+ER^-Zz{476w(!SCs<aB?s~T#>${6$Pc4>zB<&MWYSuR<U2D#T1Btn$
z{7;|r$J4eoiIl<FscXK(r>^@TXP0NMin2j(UJ<l)4DA+Rni-Gf%BS_Osx9>yOsT_d
zI2t-ykTfmoe~9M|;#`|GQcAJTyByERa<a{42#YtYzUmofTAN6=^}nM?`WS!}h&9Sy
z?v6JlR<bQVZ;wsG)H`=0`mAT%Y)D;Umaff5Y~j628gLzdKK$8uPe<m8w?0IIYTNO&
z%LNU!4wvM5nQHpZ*Pt-8n@!G9=WmUACq;*fwa(*Q-|p$z1XlV{M>F!Nuc|0cM7ctu
z<sXa-Luj+FhBL5;NQcas_5q2~xY=u_;2`#6)kVT$LyppppDY`%GAfonFyD;awfCip
z5~cZUyZ)b1@q<_-{ysV>&ghQvCHD=v;fqHKFrnZ)?rynZyLp4|Mu<&ILm1+(LD&2m
z)-^oy`P!p(qhkwg@pWo*Jfch3y=6S?(-P~Y7^bCH$yZG`8<nc>wu&s~+ON7M`-yj=
zfAkn5tj>PT<+3){G35P1zco{_&`)1ncBj;|$AU6WyYjfH)ag0Rs}Uu$$4fL{U3h!Y
z9>XFp08-w`mwdDj#;>eQGQ@aKoj&YS^T&B`?CA5Myx<(KN}sSPDR*ss-yiaI+i8>D
zhVzFE+wp>`R-yjx+$Tj(gmhJYkSLL|q~KQ52c)*iD$~;$FLiJKQ8%z*IC4#z!B)}V
z;h~vMm#&x^;w%p7vXdo0*8~Ks2x)GoQrY#mxOPWkYV_%X3SBiMBDUa&B>tS}`RMDL
z*x?+`%Y9WY;ed8*!W-)yYz>109RQzcY@aQ0GR-6_J+xlaP^WLVpDhG-N%VsY^xWF+
z2=MD|HtbN9ZLwgkwSJ*$4-1>fi6vrGxJ7Ca)h};5M<u9hC+sZE`Rw+=UbFd~NuTwG
zngUmHN9SJ}(~nd!yj{#)s~BpS?$TmyktR}>=moiWsPe9ZLl#gn@{i$|V_%N^lDW2$
zme4^gvE6Bd+4hWZMkLoXH5xq|IeF`t#dXDr_I1>%7YCmw2#O-AUknnxBv}u$E=PE3
zKc5O$WhTbqV<E#xcPxs44o0-wmr7@VmM6Auk}_h<k%D{*)Mvlt>m8N%8t}vM+WV#V
zBxI&6hA#gcdWx7LiF3D!_{iqY91p%y*~Mp|&IRTt>=<n16)bF+;}OCiEne5b?5C`W
zmc&rWDSKJ?AZ(*8qmmdDRc-M_3(^f(=?ThnIOE<c+^pFC<=c{6?CxAP$To81S0q%#
zkIT6Bq?ctR?G;~J%2J@Xg^Q3!i%(eqfo<HTo3POeHhuk;OxnO0miQk>zR%9uGLv9@
zx@$v&NpEVz`-WcP8RQ_pYf;~!P!XYJmn_QA*@nw2R+ZLwgHzS|o5!Xq8Ot!kjoFIR
z-Rrxk?Yj_S(lvAa^T8$TireRc<SO9#)a0MnMvf_5sXhuKEzzeO?E;CNpDPVKX~&!!
zQSa|cBkzPM`vP<UvqJt2fUu=|T{yzFkWfI&e1XRJJxDeA)9b3^*sAqD?T&@|em(nA
za*n-!AoRAgT~hCScFE;vEBEqJwD<ib0-}nh)H~ujaRsv~##fV7N>{9(JiPUT_@w6!
zw~`50&sEg?k@1awdAWNNH)yOqaxgE(1DANMxb_m=)e|{6KG=9tmK3+`IYRr$G8YZj
zM7du>-CN1QUI%smaFW=0Ynt0#KHvBT>HKG)lmB8Dy)AV8OF{O-k5rAhg%`JwGqqz&
z$cd_N0JA&d%ep7g2O2u|`Y-7fQjAn7{PLX-QtLx!UU<~1wqc2FFDqyq^YuP&yf0$R
zo{DtxkfX;W92-y5%rS`*1A?SH8i2A0Gdwa?j<%iJ*>7aTpq_SB*wIC1kO5!GR9CF{
z+IaA#+TnMjar89vZJT-`G7r=`zZy9fXfDoH*lu^G-LO&SLp<lH7U6cI;bm%oJh3__
zuEO2ROhJ))L|er3WvS|wW*(jd`SjAetj=Y_7qpl7MjK_89w`;%G$C4MRy??J<&~dv
znxJ8#-dC*$X9eK2G8faNITUHEGmw5}IB?t77YeU2?*X=L&@w{y*V`2d!K4g`qg7AA
zYHol2Ike)$kzK*oMtP0=NTRY17~TOnTo}f#qKO1Mulfx<a;v!Uyel6q&NZ_Qs$L`N
z>q-tGH0`@{?F%Bk{-Ak4)kU@;uf~&Pkq&+~$`G%yCX<J<E0%aNR&a8>cd4JXP}Qm@
z&Ujf<mkC!NEmkNfhn&HI4$lSlHMTzfn-#AY_PfbloHo3|EkZZ~+Jux|BS=AUvZmUv
z{t6rny8Twyp)}i!;ylJ%)S)|ft?fA^9bfM(dRFY|8122nzj{q)uKlHuj(virNAeU}
z0WPg^d4&8^Fuzp;@gmneuVJweRW<w|%foNSNzGXeF_B2t9AmCP-<J7*El;1QGQRP~
zOMB`~g#+Wm&&H8KsjeVt?PVaKW%$O+^3ImBmuc%xX*N3OKUa(iy2~zB#aFDaSw;ON
zBxm6x?q^#HLGgM&;=|9~RmXy;OEv`4m?b0#v@al))dt{cXz-n5;oU-OxbXPhrl_G;
zXZ=EAeRBbjva2^;HZ+nf|Lts`R)KPnn7N8{p{VtB`?3Wa_)#bLO*w9~UQsMvbM|)P
zm}5|Z!gFg=l!fG&x9xsH5sClODs{`s*sI=<W~A~6S9H~#YG{e0w6k=l!_?NDY1+2g
zj4+7YxVE6exXADFVy%=%4bOxZJvN?dIx(2CPo6ISHI7BDWo;gNm|f%{8H(Lj2PP&z
zgA3j>vLW}#xa@Ri9HJjut{ry5<2AK}l<+i74beU-p`0r~4!_701m<puu}ImP_9li`
zaYWS4az>1QalOtj-jJ1;L*e{wJnh*qs2B0*Mq5rAkQ4@{e)xQ9x!bznQv8*Q++s}V
zg?1iAbN(Ay+U?GWy;Yh^Y>bfCKOfc*hz+j-9=r2RH*Fid01jt`myOF(FVV;NTnDUm
zc{c;lIX#wpHo&c7eM<Lz-(I7;H95yah(y&Uk(_N^K*{L+en6p^KcM(u{$$7-oG0oF
zvhX;2fFmS<Gr&R=g5!rwhg1Fz3<4Cz0?2j#O(6jlo}f1#w=c&MY!^F|TV8*X&u$6E
zm+7X((lf;ZI^`H#xJ|2Y3n{hqv@i{n{*}p?EFyrU(Ba9fUxR=Sh$3f*TNG?1UAA);
zFa8ZrLfBK{2%HCaCrK9rAT~;fKp#2*x6nAVksq#zCi~9-f;xn%W5#%fik)Rffj&+M
zNYmTN8cf%yrx*i}%#MJ3F#l!oJ|{4M(Vk3DaFg*B0MeDtA#*e{8w)B7WQL|f935?)
z>5n2|;X=~ky8ZxMn4KgFIzk=Ki@fLm2;#v_A88a0Aq>GWjrm*`Yn-}^t`LK^RoY3p
zt~PMR_JuJl&IEYI0DG4+z`ZiYqx!E=5|dP2D>CGDXueZ9T%6J~1s6cR9%3?~oftq`
zlqo_s_utAdc`aM<7uwj&K!xK9iNKt*fQ@IM>3n=}2tnhwiUf589>+}N<N|T}aKR>o
z>%FIVWYHWAje?RxZZ(W8E=RNmmvsf}iQ)iGE)PILbx-_C^yTwY6XUoFT7NkW!OMlX
zLen($Hi2L*2`<`K@Re-x+DZkxEHYQFGz<v&MNAVxGV2Q>6oQ#k#^w@iaO>VdVJf~o
z1>oEgxKt#V^5XCe#GV$J9;9ha)<)r6w??|!JV408hOh(IpuNMS7Firs9og=}!^(IR
zb$LpW906}ids2d_SRW}G<@6onIS47ATLmfXhTep7YkoufN`<3S2ff7wjbp!}Vy6#&
zt4Fxvxb^O?Xj1st(gb+>6G-(Wml;|bNpGthZ7fnlqD05Mv1T~>6%lkmH_ZZxr(2T!
z&%l*2xz<TKf7TR5iNiaQkwU!CFJ~d5K{5X)3OGa@kO5b|2K8GTrO73pI15gWTzQ6+
zA(n=Zec>w-m3^<8;DNo(kQt44L#X-iCX?IdU><dZVsM~%6~h8Yrw|a!-dN-4O%Roo
zD^Mce(%L>wbF~KGi7iA(KslXCRM|n{id}SlQf|HoZM@VtZeh5$tDn=>x;X$<aN>)T
zjrG<wU)(qleK|s*36kXy-Id%TgXdTdDzi!wa29-4jR7R1z-b?k$*~4;OpgG(!~<4U
z2&wG>4vF?uOe+~P9^{4IDPsyI6%c4V191p(1qDF!_bT{!)Aj>^8bTjA05ue`WfbIZ
zq_#O^y*pN<yTz1_wzb;Aa|OvAB6;Eqf`6Jb&OVNzw#Z$7s}=sG#x7V{cvCbnjon>A
z@lZ^}k1a;bAA#_2#(4Mi+;VFPzeI2281IZaCZwHRtrl;z3bB{Bg3mO7nq&<lpbd@B
zvy&$8=pXNg*f>v4Ewa~djSZSa^ymDNwyw3x*vwbxQ-^kj19dl!tMtZ}V)-ij1XC1(
zg~#-}=iy5z2_#h?BXGqGiLKy}>q%KS1cfm}S?ENrM_ZHmEKi`Fs*X~XUERW)*4{NP
z6=}2d+~J404T@xfMh7e!B62RVk-y8uo2fJgECWo_oDl6CGV*t}J<ul4s7L*-$Pbqs
zhyzeKkjS_9qM>b<dUWBj(mzy+x1OZ}Wr~{;`+$*JA5>M5=~F~IJ$<tGNU=EH$PNxg
zZx`cM1v`V5)@aXwrlcgkJY1H#8f}LB;L9K<JTxM+S;l~lNV~{yC9xwPJ8<Pgc-2Vf
z>LPc^8;qHg){Il6lajR%;F)InL&>W>76@%F5ak#A&aWM_j+`o&(^)o=YaacI>~sE%
zB;71V$K!y`ly?(Q!>RgDmYy^VtqVq~cklZHlP?v!(Ikq{&*h$))<vHuoN93>v>;aS
z>!#*v)6*@kiZBGgx_L!)*4{LYdHmub<oWh*PQhm%AFEOCaw;edw8$7Qesik+UUkss
zHNTxR%fivA=e%8%#=1m`&A3k=<F5Y|O0C!K;RAn;3esD;G~EMnS3{Zwq{ecxS4%i^
zM$c@<@c(M$Tfo^&-o6uwBnXML>ewVyT181!OIspAi=Yh>QY>-mqLj93v+9sY)M+c~
z*rSG`1dA4{CnBhpc2`wfrCUJ{*d9V1(m3Qx_y4`uyYK(~-uL?E$~-gA%srF)zUQ8q
z`!{)>Kz052!sEu4WKppPi1n6=***E@2rD7kVPMglG;Q>azGTu#-r*;QIo*_`8)u!e
zgY7s{p<0eO=lkqu+Xd$HNY}#`_MyCiEuT{MV{f3J{&hyNXpJk=@hXzh`sm}ne}SID
z)1Vo$vYUq6P$s_w*$wx1e_6vO`AMH&^Vw(1?^ES51MR3q2)sRcsIz1%BlXJdfT#_#
z@y;*SgL7(ZHr%w&X16!o_XOq?*A}&6)k4(tBNOXBPUj6uPi`@`h;;O*fx~9mIRkx9
z)=clZT!Pc9jV;--B=yI?kxCwZRhB}#JYM_u^Uvavov5SKPmBA_LK17J^>^xyIkOy|
z$|~N@e&atJJp|`Hf1}TXg*}xLEjdCBwnkgSk<??h1Qhg9Poh>6L0lwE7M%`;(H}8C
zuXg^aY>zT(j0$*Mnm2iH46|mxyi2svqb8{=+wIcQuW&xLl7U97pMa&cRUyYPCKfx;
z#_nk@gcF;JORWrf8(N{Ccmx>Q!_Xu9w+&egNxTM!?L2-NVo+Jn5v9E(dDiMf-mX~3
z=7qX%c`MYdVpXF6yQ1UFAc|e>%f!iOsEe>S=M~LjkMF}7-p^L;dk+<71W$i*#j8pF
z1RHm^t9MWX8?Z)u@{ul|RHA4MCp5mU92nf%vgnqI|6S=<=uGzmpUm#A`Q1v7e76W9
z4Xp-kQ?F8155mG4r1<pFmTTVhC&QCUmBluhZ;JO+#iZ<a`3Sr@O<j1FYyj<P+=f;m
zrtEj)YW*avfN4_B3K#c~$F@6XBzpA=1S&gBExie#eTB26-rp@M-J|Yt-jRTm)r1;d
z$DERuLfH@L#1aP(=brgpaLWkJ#((mDRWRhECGzyRe09$eTSrZ9$Y8-0kPjHRZRWCX
ztykoNPLsQLQJP@jSuL$<j;~?i8))x$Zr3@fR>Ze>gMuceaKTmCJ7K=g;Ghn*_+T4-
z4DGkO>42p>9@}Dn`T7ek_PCokbZ9X_fZ&#gl#kJx;X17Zv#|Aug2gS1M6rE?IQ1F&
zJ`y`6e*L4?F-EnS?5I`^U0FNEP~e)MSag4jN9McP3!Gx*h141Ys1Z-b^EsoWMtlwN
zdIB+s+@9I6NBNE_<8F5pBJ8w{XhR4fh11Iv7QrE1xrt&tXJRrAv^|9Hw6J1in|~=Q
zMC}puQHwekVYZ}^!!vM2vXNv|rpR`_R8Bb0{aD&^$$7>f7IywGJE->bG`V*D>dyFr
z;Nl;asvriRt9{_H3^(6Cwm7W|RbxX-Hc&NSoc1nFF_||;zE#GjpXd9Wn(@C7q+yxy
zEHSb)!%aE6+LC&~>8UX@$R3k!JidEFe^)%zl+$b+zeVFhz2l%gomB@h?^ms{@5%YV
zEMM0r`SR+FT$idwaLF#vba}>EwE<f6K{~`MAj}1+@C)YeN^Hs)X`M*5n_2D?+#^pV
z2H`G;@|kekD7LU5A7oX^VM)JAkxKfYdz%yP=|<vU`fW8b-pXw~Wvj6MrY$(lOOkvC
zkY{O?>qvfJfGjW=Dr;x$<L5lT=ym4hJy#JP4_ETMVd?4evkqD*llUxRO3V@}mfY+4
z2ry7q4b*ga#&a1?-M{(dC)N!pV)7le<-^%0ZT3<A&Y#RM*`5kF?!2*k%)Qg@L-<k>
z^%-bRlKIF6ujT3L5SLpMslErUVgmePs#xd|JO&z_jJ#(@0~X?o91p?yi4Jk3qHNPk
zA$ArNJLyjUW-}v3yfl>nrU81u#k|}ewho9<2#)q2>IB3W*?B+)E}+a&h1tqeEv0k6
zZmqC$Pv3XiZmH+xeUB0I*P4sAUtKu;$bgJT&)G|T6GKeH*%KqvO@^k*RuRM~n@gJ!
zJ&D5~NUXuk2mG{1xa7|)5773wkJF3vxmHJTh-IhC>=35_Y#=+@S6f4zi&>_!+cjJ<
zN?1vY0YPmT23pZ&q+YaP?H|YV;`;kO)lu!x%NK&KR?nMq-n*RRfiDpd?2TGkByGNy
z_Do;rMJ<^z=o9F)NnvfSNl}lR`{mjT$oP$qw|Yt<RMmjU!~o~xvk850Kztq!mMRMu
z>jcd0U>(=4(=4c~FAdu={L8NeHL}L7o2{XyadE)zg@PwgZAzG2F?aKS*^jA${1qY5
zuk}vPAgF}(V*{fCVxTL~d_sSJ8Bm~_@FbCAvOMr%vpF;Qhk5yz0l8oxGh(Lm2_|n<
zXgWWe(0|KzsM&xJ<$rQv5-yT+Hf=YTNFmzCveQ))3)rh@v&~uE3&LKaz<>vkVt1Ck
z5MjC(YWoE8`S-R%6=P-S0YcCGkLH2<5AFL=Nk6Qz!vDlT;Ncxl2MY^#{s2=_^)gSj
z^$n!WNgRFcrmYCtp^Ri(<>Wn)cZI#z7d~moKeqD`Su?G47IFjP!r@*|eC^r9Hai1T
z*G7~^q!CwhncMt=lR3EZV}MBfjn6u-*f7<4j-~~Gy%xjWFb_oP{7H$gHUio`ztrX7
zFOWZimWfTf@_IG9gvm~5tB2=0EH0?VN9-=2kNm;HYg}#212@`(GDh)>;Cp)nnQng2
z9{GJeRXEJ49B{u}au%lC``pAPRnP{*iG?|%<%VZzb<4uhqm>}}b*a!O-D38ptVS2e
zQ(r`*tpkxmHx3Q>Kk+a=5W6BtGFCCt?n_&ILBM8H4_fBTM8$o+xgWKk^|nln0`biG
z%xiHy%&F#9kC1WM06u1JTT7ab=AvKUb(T*axG^~NB5@c@Gp&&Q<w+PuPupp)rGi+m
zEsq^RXTDiO<F||h#R?qj?|x)7(7tQBbYiGdIJq|HleeJ$^KM>$7k6Xtb)g*;yp^^h
z%*amH5w|2e@X<)qdmtn1(renOmlxfac4mkr!Jh@YChjU6&K2nP9?b4Css>=`IbzIv
z=;oZ-RI_9a2lB$c)ggf%b@?UH>yFv8mx&%(<mc>%R~uM5@N#;Q@rOblhmSz&qb3tB
zlb@Hi?MJn(-gA)}-5@&zco{>^fFUGbd-6WkQ~FsUUY{DYg%!6Z@AWJ_fO~9~ecEEr
z4|6gaNLoai3?J?^_93M&UUr+9^~dq7&$v&g=}`?qnU9Pyh+O~3WJ26^nK2jdqrFwU
z(3Dif><L)54eO3I^_pjYsQIPnU^$rVC$EGhjh?1ebPed1t>u8PqUR`5!&YDMlFX~0
zrK>DFMHl4eW(J{6FA*MCBT3@Ui3hJRAd}hhRf(PjV9@E%mgt*L4J#L2ZML0qz9!u0
z_o)&vCtY<#^(0RbV^T|LW^Vq|dHJrgqq>nv#vGFj5i%9S$(>AgV=(Psw+|{O%+P%y
z+&He`whbIM*$^h~&EeL$d{lU{h~$wx2db#Kr$V3Ddj?7r`<z*S*K4n~_Wj_%oAJLM
z9LS$-1hFfcrO?@0N$3|q+Py$y_EXs%WTx1_fojYHs?bf0Az(a%fF!7k8TM&foX9!X
zuYu|k1PrN5SrPV%^#YO3ECyWa2og&iK96S;nPf`{sC$s2g6p1?kR)G)<KFO^d-p(@
zljP<_$ZYfS{U$4jWEJV0AIDL#RhMuBjq4yZk^-TLXf#Kp6`!FFBY|}`qN#9XZdW>H
z705DB*J4GIzA;M$&P{PV5v<700!3XDc7fecCU|VNb#jd%Ppzw%yE~MEUqvf{@X>)d
zzzHTEtE9w_#?_&;xY%Q0UN%4vUhnQRFHwgn(2N~owH+yFo}RYy?8%2ilmRx2N0|5$
zcpwb$hN@mF95xhYvehXCxMagYhMgUZ3~pX!NrIQx$?8R9RB{7_^eD&yrra%7w@`o-
ztQ$(Ls|teQVj~<~Ni0deiU1({)f5&n^`*vdW$v9cAK2TU>Tv${Gob{jn~q=?0~iWP
z&jMM!Q-iT=u%V+EPLo8#p+IgE5dt>EB7yglkzEIICcc5Hnic>C9*qLCoGif(gA@)1
zjE@^UivyW~0qHmnldOQ$SKJ^H5(FR)k>H_%!4RxF#5V|;StVrEi8&G$jw2M>NW4Hm
zA=7dt(h;N0MS7K9_QW$0UtHELA((VvJbu-XYiMkEWM0gK!FyP63EmL2oh89<;vjM}
zg~D>MRxreuAcZ2h`IIDuT@dr(m9Ayp&^I{l&Lx$IE&!GZBDK;T`TCJ1NVQC%P7U@X
zg4--5LD}-sbyoKnpN~dRSA;0V+;HfI2-X!2rW4E%rVtV&)&q*4iHOz~eyIqM+@vTF
zj$}zo)cFPqk9!rVl^vogz?7!Y9TiSXy`fnCA#+xQv})3T0eVHQcq~Vl78FDPeBp_{
zzl^g?N(V>`wK<3$_5$_q-~0nrcRSJ-gSf~@bv152!`?+ig!pZ(px_JC`69<gP8V@2
zQUr6N;7lOOO8i)A4YG?RwZp7-S`0FEAkP{3H63Qx|3q<{KT-G?HTfN5CWv8;B7u>P
z0H^>BU^>E_CciMz+HxcbAm&1acJ8PySUVCRDMFIi>i*^CiO|gc5zwy?ONa%;0w6P%
zi$#>(Fa}y(3|9=8e4qwjU|h-(63>wMML`G<(AJ6-I<bQSJwSqy0h7{(;6CE!GJ#EU
zg8r<+^x?)FQ-EUn5p|G#P7_-ch75)XM5@geV66iaU_+)GW{oN>P(?B^3kpp?@<p=Q
za5qe;8O&)y!kZm?rk1V}Uqpa0UQPhWzJdGF>2iQ|npgwn-gOUWLWRS^#9RldNhAig
zC)-J^Az&BPRrN0S*ML<Rqj01WU?&p_h$lfTl~ws??L-m=3kel-a-8!WWsU5~Mdfh|
z$;UG!=lYHB`ptS+OvKzekfo=<{7F0&07uM%6Trw&i3Ubtj|c4ma~3K_uFzVvDMT5W
z9|#Wu=Df9p48kX?$UPU3CQc~4SjN=?NHAj@Z54({VR7~MQV9?Vbe+OgPY#3`9Tx7U
zLrSv&<EVjQfrY}3LpzzwMxpLv5Tsw#1UOMDmyCL7Bm5!Lo5NjR&~{FU^*{|@M$xR)
zDwq*{j<@2XHcNuCCf{aU)Q3!46;xqG&o@*ZGTseDl2@4U2k9nK9S6&(0&)7i<)PA>
z-P@0(Yve)C7_k@!EHUn{{JS@f_mmqa*`X1+4bj_N120cK&<~p}mY#$|Dx$AXNJ=ny
z>`bd023lE<5tW@DfAr?u=rUkJ2GRkk^)7&?v*qFiW{u(aK``sUQ(WE+|E8K$ht2GY
zh1!dq90}7z`6UGD4u7c69$$TO9K@0=7(f^4w#X!hl~AIs2CPfj%GF_5I`p$HYM`ew
zM{HxkDKNR5COGWCyt|AiVw6<t;~tHmz%BKw$wDGTfstn8ZkA<}aY(Gqh8yp?zJTwE
zL`plhqhTu08MX&@8%Fw5mGE>iX(jBjL1f8(P6rNC19l!qrY#CrFWF%d#kQNGtB^e`
zd%%jDK4xpAD`@Pe4ckCrOY_yR6ILNFw3}<kjz%gRie35!pn^f#A<)Tgv_2~{0K)+`
zn1|pEDHN}{)EBuGCnk@&Bn=vsHj_5mAvofA1B49HLeANkzD?-=2sDSQ2D&=<Ufs&w
zx>z|$i!^|`I0o2TfadZUdmwk+i{CSf;I_@pV3IF^TzSu*;p7UOs_wf!VN@3vuslk=
z;DTOxwUBe~;bOTVWnyn=;xTij?I-I;i_|rsty%D_-z)T$^vzpvDynQT-^@42m{+`2
z{(OMddq==q!)pTXLPI@$$Lrs1=K0i_XA}otn`krke7cBH0^s$I-U4St-w+N7fX|@a
zkI@=^9Z;n!>RG-w9n5EMKFVorfNBdM1QrzEtyfN8G-Pges|DtgGI70OOUd?4cj+?6
z2hbN>Og4y5V{E^@Fh({1*>Kc(W|a`GjyHzMQBCf{9Y`D+yu-IN-f-83J*wePT1!Hi
zb-!_b@q3EfQ+g2(sil7k+UEY(9gH!#P;?N7o-RTt%RLYI^EH1g;5wA9wi!jH)IKZO
zTBdyM>@XPVrIE{$`{X?b#k-I9v?ICJPl(5VTlC;;V%}k&-yXyRtAWq7=(FlHiyj-8
zRck;wRbdhhIs3Nvdgd_pM)>`+`sg}ed(;Nlrz+}2U$<<V-r196)!)MfHEQDSD`75d
za7s=(3~xknLT7uFWZ}}?nX2XHuGh#TsX;Xf4d)F>i8Z3tr?U}Ag26@O{1n+GYkOpI
zRw}X!e7|xX<?pADxoL0F{xZ|8CKUrCXU1k5*(TKJ>{s@kWL7D_hs^+MG7fBL!rY7O
z%Mds8M&IYKRjhuEZw?+#w;W(|H8C@Ia`u<y%a>k1m8|+_l^_AO_Z(4u*HEpEV5Nyg
zv{;`qb~^YuFUeTx7AmxfSj$G<a^J~()6>5H4Amh<gLfU!ZwD#70V)UIr={DhKAcCG
zpW|4RRim7v-d<3>owE-zJ)N%;z-<(e2Z^rrF3Oa7*p^|=pNtgFgd}f}r2!I()RNBc
z^9>E&GrYOE@c0+^wI8*Pt?p^;qWYJ1X@C^VuYuH2liOCf%>s=$Vu|wEc4#PMQ4VGg
z>i287tM#-}upb(KBkn$D@pE<GphGXC`#l&3gr6Y}endhGwDXF$p*1ptH>Yl6kR)io
z_sc#d>9vkg@1mG?Z!#9=-(MhWfCL2y9r>~&Qf6J7uYrUL`owi8=i{Y$-WtU`THZYk
zFo1EOpRm02X>72mFe=^=$%Zi>a&#e+%~->>@teHD;h8>h)|mbuTQP06=pR<e{L~Sf
zBdp%4)9d<1`^+oI^~hq4#rvAi(|<wat$lw4t<Eo7cko+)`l-o)c=GT}_v-XQicNR3
z$!(+JFv*cC9?u9M*%pKe8l8>1zUY}1Jt`IxG`j%qf8d@--;yDS!tG(7!aFREm`GCO
zrGqMAOJ-g?QwS31Lh3M{J(RL*OTOJpZk3VkS%>#cjT_z$|8~MAcJo%KlCogai6(?H
zeZd9g!Z#2W>_cg(sEfIUT8N{wZRs0~c14W&KOFgncanSy*dn$If(}Ux2xw^3TBGFE
zgT5!(xbES1clLF9yf9lDTqUC`EiXH_ag)DAThA1d`a`ER$OMq#U^D8|U`UUAl(ukv
z?o$L_-|q`aI#aD1!fP>9iI5!3uSpH2mSi$t66<=eKb1<;lwb=87;ptEf?fh;Ovx*~
z;kFF4D)1iCQAetCs=|si{Z{}h^2``3>hgsOmm3{`F3cz#lQj-82s_YEQX#HgiL1T$
zYiYLAb8A;$f~DB#*S+X9A3EW+DNB2zUDm|b-JwjEoGu5ZOQZ*1Kld<;OumvZc<w|1
zQ}u<TD&+uV(8p1-Cn&eDS8jKc!W|8nB*9(F7)gI(Og&z9h~f#oV9janfa!C@2Vgsr
zX1$+vteCwH+jm_kQYw7lk`{UJtICnC55oBqABH%avW+NjnHTO;zTwvzwGk-Mlg*@A
z@5$-lPG#Heo$o$`|GaZ3BbJ#wwxwBY+QU;(-!(T|@ki$4Qbgt`##^2@Sy=&)q~c6^
z-4b-_Q&sPq1B2zOdt%%nkz@(9>RZ~gTNCdW_cDnnTFZV=j*E!CdN)2X=#uo{p*N;(
zF0-n_(N12`YC_P+S}$uF1L%4=ia}&{Nq@n$6t2TOBUf*21a0r=h`mF9#pD4!G+be<
zKMxhYBOWW#k?p8PfpKAN>|CG9;dGsnKv?LZ!?&863&wwLTmfe8_K$FL$!6buc&YZ%
z-U@5`sMLo=swpz(DgJT9+8pN5WyHkE&Qztk^^WC&(mG#b)9_}~L%Z8YPrGLUrN4ED
zr|aa|`>-Swbxv-_)pGr%=#Vc!#|GRAHvIP07iU~rZYOl-`>3cui?0SUKR!GQ&7A6l
zJu!17D4P+{4i;ZAbE($;Rr%kr+k0BBN|))wGb^0lfW@KDftcZn?)|JY1Rz^E|M*IP
z`+d->4OvQ#2ZG&PZdLg5nv$>DL$$Td-1)De+BSx%Kmk0p4~^=vx0IID>o}0l(@Ta<
z7-D~UxRm8Iw6wt*IMrBlNVR$N=!P21t=g_b@Ft@=bP0mTjQO&d{+@L3%1<Au!~Lq2
zf-%UBg`AyaV!V6=4k=DCG2w<7JA@O_O4z+-$r!WIxub}_FzI-J&~DHGH8O76?r-O9
zi*!zS<v`c$6Nr@ZY2QrrW{c`evk!ES2WR962D!$FF0d;jr6c{2w8P8-<urkqAr6Ct
zSwSO4R*H?v6(T%fjsmi7mXL0r_`wp|B`?uwSTF#N!uKvQ6D~Mub~b!#zmnQl4B9m7
zz4n`Rq66rXaVe-P?d71X1n0R`qy3BeRSd`!yve!Q@Vw6LrhS*iVxoL`CdLA)q#Nhb
zUGVLu7qAhe5!!hM=y7S#$9gC+CCJk9@MRLUm~LdPJ}TfqM>If12Qfb%F4#pAjMN(t
zj@D@0U%1a%*TO-78DPWdwaRPJ+c0@|wP5|1QQp;)0!+Hex#;q*L1>VYnUgTWP=ypf
zf!+S<?R{a>V4iU*SaVRq#36D`O5X*{No^54no><ttuf?nY&Bk8mVVI|lM9{UqCuI9
zHo+73m0&x=wm(~SM}gxJG2||b%JI2+&;*E;?e21Q83;{78OtcnocDd%?gfa<)#a{V
z8U$Ui#7l@w5`cIJ4!dyPvTwHV`ztO%ue?s-U1$lehg2V1QUm)ElB&wAAw{b?GPmMg
zx-fdNv4z1=1T>V+5%i_gr$OwEskp=0PL;Eq`61D3FlEg|>LA#GNw4w06?!Cv;RNFU
z9F)hOF;k*QQ*t`Szs_XJ_(`~}AaV3A>bI%{xYDgxg4n%Z{ytQY?E2pi72=O}H6fmE
zr%ThI!-gCaOFu#bohUU-c13lyS2AJIxqU53`<C$?3rfIZkWl`6eY+m7i|>SLNt<?n
zfLJ<k)tz#IpbpqJ7(@G#;@xRhHFf*_9UyiHgaGEUbJ;EJ$w4?CyMtgs1@iSAENPOn
zHL1WiY_R?~{|RqBc*4B>wtx9x;r!fW)q$^CnD0;dr|UJTvvemVaDb3VCGdsl8W6BZ
zKt(!dFFO4N%p6R`X|qD&^X<l5db{scO}Y}a<xw?`Ff2yG3Q~muS!i5c*;8XAy9lI|
zEB97KfE}2r4gNL8b)eoieisQr`&oT<s{4Wnm}F$80+F<|Bhq#7A3K1LQ6~8WR75^@
zNUWi(!GXQ|bP5dzu0z09VurQ49YFz*lMR7izR?}21Wf6wYX!y80_C!fYVZb%+?eN`
ziyd7RKJ~0~r*<|z0e-v=#a5x)87Sdqdm35s@;8=%UJ_g%2-nXLX1a*4TTqQnzlM^l
z;`PDJ<{*;u!b_n7B+DK3_(yA2u_}N;R}_f|zcJ^?rzinr3RF#$n7GWYs_uO2y^keL
zTT!6s62*R6Lq?G@1wG$i|5xG+x^dnG4M~m>msxW^4fIverOCK)ZIy^`Ks7=9X@EHh
zi!TE9i`R)7kPbB0lGn!F@2H#98Uni=JZuIdfi+CQ`UE?HR&u*5iml2?1fd}qQwS}c
z0%64$z>#*iRsA<07G`dTV?GO~t)0yfUdOB=JK+0#YtSg*$uEGU4p0}-6dLkYG_o6p
zmEbk9{rbU8B)OoG*VhRtqY6qL#a_wD^*Tv*zOXR4?946a3`1~=b0<>?2-XvZn1FJ7
zT8R>exl&%2sw@eSz7dmcI?Po*@NLe742uvm5n!u%F)L{Q+9E>;rG!ctTw^7!AqWte
zPl!~st&or`eN_>4kZD6H(w%!-Yg(GL1r!x8A<Mb!xs#pG7RVSdJm<M7#thAgToDf%
zswg@BS{le!r&u*1K(CiY8!c%xur6&imEc!|fdGd4FdP#YJ}uqV5hX%8LN@m!qicev
z9WW|Rb5cXlsnc|m@)OLD8-smSea5M^N0=-9bELFBp=f8yd1A?yRBc{Qgd;`TsaBkw
z=JgZlc6sS@FdW6Q)0YJ~V1D*Gk%H=KEKWZc2vG(=R>`cN)OuKUa8+D%rpU3}><x^h
zOk(cLV2J2=3@THs=Kv!YWvf;+oejdJem@SusVE(qwpk}Aqw-k}a*-yp2v?eFMh%`b
zzq78*nUF8bSLixTSN71!;x&h7z{-YKbdUYg^PLh|b=AxTj{#5O*N^fiyMJc<*|_Zs
zEe6<W-RXUE&?uHs+xDSJ*AvsCK^{u88f4u{unTC1Q^zF^63$CUxA{3lEjKYt=NY!%
z;+U41L3~pGiOG~!|Ma<Mb|F4Cw&j&9;ejmK<`+HTlN+MDio_osl=lagy?6z3y9hqW
zZM8R#RHyiut!r_hE|uy{5d_P_=SpV}l05Z(S?dt5*-mr<xrI;0t~DTlIb#e5e(pIc
z=<7Pqy?CTDsT;lH_<Bpt$%cKcfSj7!`Mw|Yz8#NlGhzK&oXLn$@*`u8sTQ|>hCa!A
z^*lB<y4fd>PPJWc+05B~PUH5*Fu<R2*CI6!J2^US>8Urv*rekN+Xst#BOK|)3m=cg
z@?QPPf6L10cEehITq~$P<20x_af_V$oN3rHrs{)$a-J|!F6#_`azDr0R`cgYNk|7r
zopmS3^4Y9*%f+mRQl`JK!2dGcPrxrI{KT%97|E;AX%wsm2|3^Y&(?3Gs%{F?Vae&N
zdtjC(9~hGbzEJyZ(g|LAOIEnE<n&h4ugdOPx2P6yDx=J?M<}7dS2sQm!#(nGmW{Sy
ziyX!enXdgV7Ha~<d~L{I*0n_fF9EPaKWZsieQR0Nk)K8lHq{AzLc9}m#ffmP=Kj`z
z9}b(QHrcX-hSpP~u<Xyio$pE9O${Mu3Fpft`pOKujY_it9kZcJ8%wTF#p-XG|F!fT
z<Oi$x1BXFNW34{s)`9$Zf7Qw;ck_%G5Nk3T-hrtco0H5`rh6y0l?Z(8W9tvmixOV{
zh%!U`g_Xo_<UkqTS*Xz}(CQxF(CXsZ=Fhz59mAh^fIdA>_5x&<e0`nz(6qD6k2HZr
z<ZBw9BqK89cWzaEG>f^v%eqr7*B@OnoU`s9*w8skOErsa`*IP}B{AE&X=;-fkfJuR
zUgZm?3-y-S!qb&yKC;)M`6j6wlJ<w-D{6Wt{TnHg9o=fGrRIsaB=mV<SFd%#EB1J6
zx@tnz)BU7xKMvrDp8MN1EUDO`!H8m^6r3iPj7o>y<fXOIO}&UUj%aBVvzqEZnt0)Z
z$;wrW?5P-&boE-GKm3=jO*Czrk4XL6o2_4XJI^+9^S=dO^tM}GKDX=BWLsCeKQ?Pa
zb3QE#AT;?Jm5#LSymrlUxTFRlxDsV_`<)vU(?Kij|D0Z3(?qx%*^)Kqz~*Wl7*&lF
z{km0F)1PKtq~1RiKJGhST-u8Q()cob<GHMDt9xv}##GW!h`D>Q{xs58r;*XqZbu%E
zXYaG6eSV+$SgA#;wVGTi%e>Bc0`VDNJHNv}j)HhW_Zye%fhnu%Z#m~G%=s}61-=y#
zR@NW%ERUCR!5QbAbBc(&?$n<=Z?f3-Tzl&`ue6J@c%}&?88VchZu$c~`61rl-^>@5
z?pks!EjtXQp^Mb4^KFEl(^%R~ebvjTKlb<qklw_}H<!H9TsSOkXo&hDjMnxl^yq5)
z&N#NViyP<-==90=cluxZz2Qs<cSW=Pz|}*>tII`eyP{7$&b;39NRm9}08-!c=hTjE
zeo2^JF5RL*)zsGyT*}b5UcAC&zFP(ZzR^DbsY5AlTHl?h(dsGqRs-m$hC3tWGvETM
zpp~Yw<x|v^1xwfSMYE@Eo;Ty$9g*^nlCi0U_Sb$X&N{Z?TAi5h^Y^2*y}SG9^HZsW
zl`XS>==xUR<}0R;_&k-YwdLx)Ao;?T)o4nV?xghJpLrhJP6&LXk#fZ20*O+0y=V?^
z0E(?dLe23CpV$(LiEsi)u6?VcjNnyG2HXZZUS|Gcdc8XS<i!9C6ftL1U1a9IaGP~Q
z&MpBZjctA&+xF*|uI;`~E5GEqaE7Yw;I?bD!gJdZnd6MxyPVFCU$CU9aU_f#tlp*=
zRpG7f(A8US(ABTBNVxN_l6-%ACa!L`g&1s84xrduE*DWkZ}xVvDfPqz1W4?2APV$6
zh@#puGjM0G{KDbn03-gMM<=Q89-ExU?=|Z5xSrp7!vOJBwpaSqoi#F3F!8Z-o_S+w
zjCprU*T81-uk4y~{7&i^{>f@PbI5tpDlTu-P0zJ5WvS>zbjxDBRIG{J-if*~Wp)$$
zq{t4bA(u;D#pR8SYgdoL>SvGsWjX*|UkF#Hj$Y9U%YHl8*-GmEc(tklk7Z{VCN+GX
zUh{96dQb8U^90HW=c;;R=LpGe)28ekcCS>m9DM4RUUhZ0hhp+~t`N{KV*ZdO{9Y-v
zwv#3ku1g)z^TRp6oosVZ4sBqCcx-06<<R_$2{Q>le)}R5MigtC{fN~c7T}X=u|`T*
zBVHw0D0`%jxJYYegstmG^uMYl`Hvo>nqGejhVSMqCHyq5WnCYy{y?osS8dnbT8Wx?
z=TyY{{L$6oYM*W42{pfo;FJc7yzpZ`7E*6N6?wcy8pdqiV|O3g#q!`Ao$x=*bX~q%
zM8Z@JR|Hc3xcTAPHaC8lSOkn)B<gtv_+33;+{N-Y&(e8ey3FND8%4XecZ{5?P)peO
zNz3<$7xam9k?sbSHseU0J-{-3mvPVZ{YpMNjwYv8rUt=%Urxr5i|&qAFYjF#d4L$&
zZS;=fa3x$QTJvuHu=-Gv^g<<ik)n&a`RoTvgBze@WJq*k@)pkNv%+pi_2s}l5m(S2
z4;J?|kAX(*<`1&{Yt-8s<x-h%@%GK7+Tx-*;N8K{>P+(k?i3XqUj&T*tde&40`h&z
zkyCDZ!sB4$;+s#Oo@PycTqBE)YF~g%d9WjjmCN*ZK>I(NhUih^(J@#CtBl_0kM6xB
zYh2{=2YQM9CiqQI#7mIYZ`fC7_AJ~ZQwKoLkLY_m@#wLTOy4(W7!Y#0yUgw7P|o}5
zJD92RK_`?C2exHy=I2xT*9$(mHF*8Ld)B`w=?6RE#D$?wG5%c+Wd7|jeyK+##2mwJ
z-rnleyg48?t#|6)i@u9*`<>CVw^`N4r?3z2K?>`3c(>zUt?LJFoIHRkHnkXjT$%@6
z^2F>iS#^!tAK)C)V-}U0-9Q-<j5Z66Oh5agSR)o)X0sNdZLcgUC@UcO&Ub;4_baC!
z`!?Kdu)(Vju4T7p_z~;!A&9Tzu6uip9QgVMH>4{%p!3brwX3wMvM5rL@8X5>65`FH
z7KSI<bTB=SPJKk6h~FxOF$ts9E?Z`FQ7&WaKRwy>Eu$|DxnW!Q0U>!A004Q$#>FK9
z0Dzd-#K>^Ke+i&z#pNLY2>AZ_&j9?dRR4ZY1pKc-NfC9T;=)gTzd^ECEGXcx0_LsD
z6;&Y#Cqs@YiUSjl{ml#F|M4vk|67m$AN&BnUnGB5uEmB&g(x!E*zkXs7l2ko2(9Pu
z{Eo=*n3Mlekr)*o@lQfu#eJM>$no%)i0?GOn%Jo0M-`ckiLrlo`cD>&!~a!h5PmY^
z=s#G5pFSCb{Z}3sc`6|^Mv?D1m2fKjA2cno@z#m|gP7lik^o#48Q1@b;=ctQxkAl=
zpomldQa?zceosX+up)K9YW`iM{#{i7WktyjMUPG2xoged@UPB+SU}IYEWn~F7_IPA
z0l=FcA&FtTcUkP(ZGnd<S^)nZ+*1h&r~bha<o~7{6|()a{ChM|l!g6U*?&ZHMP1TA
zcvtj;u>=4#uPe-^ToLywA`JjgXDjMVP9=oJ{U;s3TtOQE0N~dF0Ma!8z-t5m2vvv!
zV4Mz5_&)gb*oeQ=@4@h&1FbNQlOgf(G5=JWSyara1Vy@~HX-i&m*|Iw{N4C(bt^P*
MRG|T@ofi2215^f=E&u=k
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_media_sniffer.html
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: mozStopDownload</title>
+  <meta charset='utf-8'>
+  <script type="text/javascript" src="/MochiKit/Base.js"></script>
+  <script type="text/javascript" src="/MochiKit/DOM.js"></script>
+  <script type="text/javascript" src="/MochiKit/Style.js"></script>
+  <script type="text/javascript" src="/MochiKit/Signal.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+var manager = new MediaTestManager;
+
+function finish_test(element) {
+  if (element.parentNode)
+    element.parentNode.removeChild(element);
+  manager.finished(element.token);
+}
+
+function onApplicationOctetStreamLoaded(e) {
+  var t = e.target;
+  t.removeEventListener('loadedmetadata', onApplicationOctetStreamLoaded);
+  ok(true, "The media loads when served with application/octet-stream.");
+  finish_test(t);
+}
+
+function checkApplicationOctetStream(t) {
+  t.src = t.src.replace("&nomime", "&type=application/octet-stream");
+  t.addEventListener("loadedmetadata", onApplicationOctetStreamLoaded);
+}
+
+function onmetadataloaded(e) {
+  var t = e.target;
+  t.removeEventListener('loadedmetadata', onmetadataloaded)
+  ok(true, "The media loads when served without a Content-Type.");
+  checkApplicationOctetStream(t);
+}
+
+function onerror(e) {
+  var t = e.target;
+  t.removeEventListener('error', onerror);
+  ok(false, "The media could not be loaded." + t.src + "\n");
+  finish_test(t);
+}
+
+function startTest(test, token) {
+  var elemType = /^audio/.test(test.type) ? "audio" : "video";
+  var element = document.createElement(elemType);
+  // This .sjs file serve the media file without Content-Type header, or with a
+  // specific Content-Type header.
+  element.src = 'contentType.sjs?file=' + test.name + "&nomime";
+  element.token = token;
+  element.controls = true;
+  element.preload = "metadata";
+  document.body.appendChild(element);
+  manager.started(token);
+  element.addEventListener("loadedmetadata", onmetadataloaded);
+  element.addEventListener("error", onerror);
+}
+
+manager.runTests(gSnifferTests, startTest);
+</script>
+</pre>
+</body>
+</html>
--- a/content/svg/content/src/SVGPathData.cpp
+++ b/content/svg/content/src/SVGPathData.cpp
@@ -245,25 +245,26 @@ ApproximateZeroLengthSubpathSquareCaps(c
          segType == nsIDOMSVGPathSeg::PATHSEG_CLOSEPATH)) {                   \
       ApproximateZeroLengthSubpathSquareCaps(segStart, aCtx);                 \
     }                                                                         \
   } while(0)
 
 void
 SVGPathData::ConstructPath(gfxContext *aCtx) const
 {
-  if (!mData.Length() || !IsMoveto(SVGPathSegUtils::DecodeType(mData[0]))) {
+  if (mData.IsEmpty() || !IsMoveto(SVGPathSegUtils::DecodeType(mData[0]))) {
     return; // paths without an initial moveto are invalid
   }
 
   bool capsAreSquare = aCtx->CurrentLineCap() == gfxContext::LINE_CAP_SQUARE;
   bool subpathHasLength = false;  // visual length
   bool subpathContainsNonArc = false;
 
-  uint32_t segType, prevSegType = nsIDOMSVGPathSeg::PATHSEG_UNKNOWN;
+  uint32_t segType     = nsIDOMSVGPathSeg::PATHSEG_UNKNOWN;
+  uint32_t prevSegType = nsIDOMSVGPathSeg::PATHSEG_UNKNOWN;
   gfxPoint pathStart(0.0, 0.0); // start point of [sub]path
   gfxPoint segStart(0.0, 0.0);
   gfxPoint segEnd;
   gfxPoint cp1, cp2;            // previous bezier's control points
   gfxPoint tcp1, tcp2;          // temporaries
 
   // Regarding cp1 and cp2: If the previous segment was a cubic bezier curve,
   // then cp2 is its second control point. If the previous segment was a
@@ -480,16 +481,18 @@ SVGPathData::ConstructPath(gfxContext *a
       return; // according to spec we'd use everything up to the bad seg anyway
     }
     i += argCount;
     prevSegType = segType;
     segStart = segEnd;
   }
 
   NS_ABORT_IF_FALSE(i == mData.Length(), "Very, very bad - mData corrupt");
+  NS_ABORT_IF_FALSE(prevSegType == segType,
+                    "prevSegType should be left at the final segType");
 
   MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS;
 }
 
 already_AddRefed<gfxFlattenedPath>
 SVGPathData::ToFlattenedPath(const gfxMatrix& aMatrix) const
 {
   nsRefPtr<gfxContext> tmpCtx =
--- a/content/svg/content/src/crashtests/crashtests.list
+++ b/content/svg/content/src/crashtests/crashtests.list
@@ -30,17 +30,17 @@ load 398926-both-same.svg
 load 398926-fill.svg
 load 398926-stroke.svg
 load 405639-1.svg
 load 406361-1.html
 load 409811-1.html
 load 410659-1.svg
 load 410659-2.svg
 load 410659-3.svg
-load 412104-1.svg
+asserts(0-5) load 412104-1.svg
 load 413174-1.svg
 load 414188-1.svg
 load 427325-1.svg
 load 428228-1.svg
 load 428841-1.svg
 load 435209-1.svg
 load 436418-mpathRoot-1.svg
 load 448244-1.svg
--- a/content/svg/content/src/nsSVGSVGElement.cpp
+++ b/content/svg/content/src/nsSVGSVGElement.cpp
@@ -929,17 +929,17 @@ nsSVGSVGElement::GetViewBoxTransform() c
   return nsSVGUtils::GetViewBoxTransform(this,
                                          viewportWidth, viewportHeight,
                                          viewBox.x, viewBox.y,
                                          viewBox.width, viewBox.height,
                                          GetPreserveAspectRatioWithOverride());
 }
 
 void
-nsSVGSVGElement::ChildrenOnlyTransformChanged(PRUint32 aFlags)
+nsSVGSVGElement::ChildrenOnlyTransformChanged(uint32_t aFlags)
 {
   // Avoid wasteful calls:
   NS_ABORT_IF_FALSE(!(GetPrimaryFrame()->GetStateBits() &
                       NS_STATE_SVG_NONDISPLAY_CHILD),
                     "Non-display SVG frames don't maintain overflow rects");
 
   nsChangeHint changeHint;
 
--- a/content/svg/content/src/nsSVGSVGElement.h
+++ b/content/svg/content/src/nsSVGSVGElement.h
@@ -219,17 +219,17 @@ public:
    * immediate childrens' frames need to be updated. It is called by our own
    * frame when changes (e.g. to currentScale) cause our children-only
    * transform to change.
    *
    * The reason we have this method instead of overriding
    * GetAttributeChangeHint is because we need to act on non-attribute (e.g.
    * currentScale) changes in addition to attribute (e.g. viewBox) changes.
    */
-  void Child