Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Thu, 06 Sep 2012 18:28:59 -0700
changeset 107188 d16c4404e8c4d7f843f58d98c6282fa4bb1ef058
parent 107187 666bf90824f84abf2a7b92b83ea7646cc23671ae (current diff)
parent 104962 233441ff53affd70178ed330d0fea4a5a511826c (diff)
child 107189 54711415fb53b3060cf78ff501dc6e16d958e4da
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
milestone18.0a1
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
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
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.");
+  checkApplicationOctet