Merge mc -> pine draft
authorGregor Wagner <gwagner@mozilla.com>
Fri, 08 Jan 2016 15:51:50 +0100
changeset 388239 6a9ed8e6938b591f7752f5e1a0eb677480eb9d60
parent 388238 d51dac03726168ab1e196e52f9aba0a837b279b4 (current diff)
parent 320094 3f780f4b14acab29b16bc4141a44180a8af9dd08 (diff)
child 388240 18e80e4143f3f4c2bd6875aa2d70a880c8d0f363
push id23132
push userbmo:lissyx+mozillians@lissyx.dyndns.org
push dateFri, 15 Jul 2016 10:07:12 +0000
milestone46.0a1
Merge mc -> pine
b2g/app/b2g.js
b2g/config/gaia.json
b2g/locales/generic/install.rdf
browser/base/content/abouthome/apps.png
browser/base/content/abouthome/apps@2x.png
browser/components/feeds/content/subscribe.css
browser/components/feeds/content/subscribe.xml
browser/components/migration/nsEdgeReadingListExtractor.cpp
browser/components/migration/nsEdgeReadingListExtractor.h
browser/components/migration/nsIEdgeReadingListExtractor.idl
browser/extensions/loop/skin/windows/toolbar-win8.png
browser/extensions/loop/skin/windows/toolbar-win8@2x.png
browser/locales/generic/install.rdf
config/external/nss/nspr-dummy.def
config/external/nss/nss.def
configure.in
db/sqlite3/src/Makefile.in
db/sqlite3/src/sqlite.def
devtools/client/animationinspector/components.js
devtools/client/fontinspector/font-inspector.css
devtools/client/fontinspector/font-inspector.js
devtools/client/fontinspector/font-inspector.xhtml
devtools/client/fontinspector/moz.build
devtools/client/fontinspector/test/.eslintrc
devtools/client/fontinspector/test/OstrichLicense.txt
devtools/client/fontinspector/test/browser.ini
devtools/client/fontinspector/test/browser_fontinspector.html
devtools/client/fontinspector/test/browser_fontinspector.js
devtools/client/fontinspector/test/browser_fontinspector_edit-previews-show-all.js
devtools/client/fontinspector/test/browser_fontinspector_edit-previews.js
devtools/client/fontinspector/test/browser_fontinspector_theme-change.js
devtools/client/fontinspector/test/head.js
devtools/client/fontinspector/test/ostrich-black.ttf
devtools/client/fontinspector/test/ostrich-regular.ttf
devtools/client/fontinspector/test/test_iframe.html
devtools/client/layoutview/moz.build
devtools/client/layoutview/test/.eslintrc
devtools/client/layoutview/test/browser.ini
devtools/client/layoutview/test/browser_layoutview.js
devtools/client/layoutview/test/browser_layoutview_editablemodel.js
devtools/client/layoutview/test/browser_layoutview_editablemodel_allproperties.js
devtools/client/layoutview/test/browser_layoutview_editablemodel_border.js
devtools/client/layoutview/test/browser_layoutview_editablemodel_stylerules.js
devtools/client/layoutview/test/browser_layoutview_guides.js
devtools/client/layoutview/test/browser_layoutview_rotate-labels-on-sides.js
devtools/client/layoutview/test/browser_layoutview_tooltips.js
devtools/client/layoutview/test/browser_layoutview_update-after-navigation.js
devtools/client/layoutview/test/browser_layoutview_update-after-reload.js
devtools/client/layoutview/test/browser_layoutview_update-in-iframes.js
devtools/client/layoutview/test/doc_layoutview_iframe1.html
devtools/client/layoutview/test/doc_layoutview_iframe2.html
devtools/client/layoutview/test/head.js
devtools/client/layoutview/view.js
devtools/client/layoutview/view.xhtml
devtools/client/markupview/html-editor.js
devtools/client/markupview/markup-view.css
devtools/client/markupview/markup-view.js
devtools/client/markupview/markup-view.xhtml
devtools/client/markupview/moz.build
devtools/client/markupview/test/.eslintrc
devtools/client/markupview/test/actor_events_form.js
devtools/client/markupview/test/browser.ini
devtools/client/markupview/test/browser_markupview_anonymous_01.js
devtools/client/markupview/test/browser_markupview_anonymous_02.js
devtools/client/markupview/test/browser_markupview_anonymous_03.js
devtools/client/markupview/test/browser_markupview_anonymous_04.js
devtools/client/markupview/test/browser_markupview_copy_image_data.js
devtools/client/markupview/test/browser_markupview_css_completion_style_attribute.js
devtools/client/markupview/test/browser_markupview_dragdrop_autoscroll.js
devtools/client/markupview/test/browser_markupview_dragdrop_distance.js
devtools/client/markupview/test/browser_markupview_dragdrop_dragRootNode.js
devtools/client/markupview/test/browser_markupview_dragdrop_escapeKeyPress.js
devtools/client/markupview/test/browser_markupview_dragdrop_invalidNodes.js
devtools/client/markupview/test/browser_markupview_dragdrop_reorder.js
devtools/client/markupview/test/browser_markupview_dragdrop_tooltip.js
devtools/client/markupview/test/browser_markupview_events-overflow.js
devtools/client/markupview/test/browser_markupview_events.js
devtools/client/markupview/test/browser_markupview_events_form.js
devtools/client/markupview/test/browser_markupview_events_jquery_1.0.js
devtools/client/markupview/test/browser_markupview_events_jquery_1.1.js
devtools/client/markupview/test/browser_markupview_events_jquery_1.11.1.js
devtools/client/markupview/test/browser_markupview_events_jquery_1.2.js
devtools/client/markupview/test/browser_markupview_events_jquery_1.3.js
devtools/client/markupview/test/browser_markupview_events_jquery_1.4.js
devtools/client/markupview/test/browser_markupview_events_jquery_1.6.js
devtools/client/markupview/test/browser_markupview_events_jquery_1.7.js
devtools/client/markupview/test/browser_markupview_events_jquery_2.1.1.js
devtools/client/markupview/test/browser_markupview_html_edit_01.js
devtools/client/markupview/test/browser_markupview_html_edit_02.js
devtools/client/markupview/test/browser_markupview_html_edit_03.js
devtools/client/markupview/test/browser_markupview_image_tooltip.js
devtools/client/markupview/test/browser_markupview_image_tooltip_mutations.js
devtools/client/markupview/test/browser_markupview_keybindings_01.js
devtools/client/markupview/test/browser_markupview_keybindings_02.js
devtools/client/markupview/test/browser_markupview_keybindings_03.js
devtools/client/markupview/test/browser_markupview_keybindings_04.js
devtools/client/markupview/test/browser_markupview_keybindings_delete_attributes.js
devtools/client/markupview/test/browser_markupview_links_01.js
devtools/client/markupview/test/browser_markupview_links_02.js
devtools/client/markupview/test/browser_markupview_links_03.js
devtools/client/markupview/test/browser_markupview_links_04.js
devtools/client/markupview/test/browser_markupview_links_05.js
devtools/client/markupview/test/browser_markupview_links_06.js
devtools/client/markupview/test/browser_markupview_links_07.js
devtools/client/markupview/test/browser_markupview_load_01.js
devtools/client/markupview/test/browser_markupview_mutation_01.js
devtools/client/markupview/test/browser_markupview_mutation_02.js
devtools/client/markupview/test/browser_markupview_navigation.js
devtools/client/markupview/test/browser_markupview_node_not_displayed_01.js
devtools/client/markupview/test/browser_markupview_node_not_displayed_02.js
devtools/client/markupview/test/browser_markupview_pagesize_01.js
devtools/client/markupview/test/browser_markupview_pagesize_02.js
devtools/client/markupview/test/browser_markupview_remove_xul_attributes.js
devtools/client/markupview/test/browser_markupview_search_01.js
devtools/client/markupview/test/browser_markupview_tag_edit_01.js
devtools/client/markupview/test/browser_markupview_tag_edit_02.js
devtools/client/markupview/test/browser_markupview_tag_edit_03.js
devtools/client/markupview/test/browser_markupview_tag_edit_04.js
devtools/client/markupview/test/browser_markupview_tag_edit_05.js
devtools/client/markupview/test/browser_markupview_tag_edit_06.js
devtools/client/markupview/test/browser_markupview_tag_edit_07.js
devtools/client/markupview/test/browser_markupview_tag_edit_08.js
devtools/client/markupview/test/browser_markupview_tag_edit_09.js
devtools/client/markupview/test/browser_markupview_tag_edit_10.js
devtools/client/markupview/test/browser_markupview_tag_edit_11.js
devtools/client/markupview/test/browser_markupview_tag_edit_12.js
devtools/client/markupview/test/browser_markupview_tag_edit_13-other.js
devtools/client/markupview/test/browser_markupview_textcontent_edit_01.js
devtools/client/markupview/test/browser_markupview_toggle_01.js
devtools/client/markupview/test/browser_markupview_toggle_02.js
devtools/client/markupview/test/browser_markupview_toggle_03.js
devtools/client/markupview/test/browser_markupview_update-on-navigtion.js
devtools/client/markupview/test/doc_markup_anonymous.html
devtools/client/markupview/test/doc_markup_dragdrop.html
devtools/client/markupview/test/doc_markup_dragdrop_autoscroll.html
devtools/client/markupview/test/doc_markup_edit.html
devtools/client/markupview/test/doc_markup_events-overflow.html
devtools/client/markupview/test/doc_markup_events.html
devtools/client/markupview/test/doc_markup_events_form.html
devtools/client/markupview/test/doc_markup_events_jquery.html
devtools/client/markupview/test/doc_markup_flashing.html
devtools/client/markupview/test/doc_markup_links.html
devtools/client/markupview/test/doc_markup_mutation.html
devtools/client/markupview/test/doc_markup_navigation.html
devtools/client/markupview/test/doc_markup_not_displayed.html
devtools/client/markupview/test/doc_markup_pagesize_01.html
devtools/client/markupview/test/doc_markup_pagesize_02.html
devtools/client/markupview/test/doc_markup_search.html
devtools/client/markupview/test/doc_markup_svg_attributes.html
devtools/client/markupview/test/doc_markup_toggle.html
devtools/client/markupview/test/doc_markup_tooltip.png
devtools/client/markupview/test/doc_markup_xul.xul
devtools/client/markupview/test/head.js
devtools/client/markupview/test/helper_attributes_test_runner.js
devtools/client/markupview/test/helper_events_test_runner.js
devtools/client/markupview/test/helper_outerhtml_test_runner.js
devtools/client/markupview/test/lib_jquery_1.0.js
devtools/client/markupview/test/lib_jquery_1.1.js
devtools/client/markupview/test/lib_jquery_1.11.1_min.js
devtools/client/markupview/test/lib_jquery_1.2_min.js
devtools/client/markupview/test/lib_jquery_1.3_min.js
devtools/client/markupview/test/lib_jquery_1.4_min.js
devtools/client/markupview/test/lib_jquery_1.6_min.js
devtools/client/markupview/test/lib_jquery_1.7_min.js
devtools/client/markupview/test/lib_jquery_2.1.1_min.js
devtools/client/shared/observable-object.js
devtools/client/shared/test/browser_observableobject.js
devtools/client/styleinspector/computed-view.js
devtools/client/styleinspector/computedview.xhtml
devtools/client/styleinspector/cssruleview.xhtml
devtools/client/styleinspector/rule-view.js
devtools/client/styleinspector/ruleview.css
devtools/client/styleinspector/test/browser_computedview_browser-styles.js
devtools/client/styleinspector/test/browser_computedview_cycle_color.js
devtools/client/styleinspector/test/browser_computedview_getNodeInfo.js
devtools/client/styleinspector/test/browser_computedview_keybindings_01.js
devtools/client/styleinspector/test/browser_computedview_keybindings_02.js
devtools/client/styleinspector/test/browser_computedview_matched-selectors-toggle.js
devtools/client/styleinspector/test/browser_computedview_matched-selectors_01.js
devtools/client/styleinspector/test/browser_computedview_matched-selectors_02.js
devtools/client/styleinspector/test/browser_computedview_media-queries.js
devtools/client/styleinspector/test/browser_computedview_no-results-placeholder.js
devtools/client/styleinspector/test/browser_computedview_original-source-link.js
devtools/client/styleinspector/test/browser_computedview_pseudo-element_01.js
devtools/client/styleinspector/test/browser_computedview_refresh-on-style-change_01.js
devtools/client/styleinspector/test/browser_computedview_search-filter.js
devtools/client/styleinspector/test/browser_computedview_search-filter_clear.js
devtools/client/styleinspector/test/browser_computedview_search-filter_context-menu.js
devtools/client/styleinspector/test/browser_computedview_search-filter_escape-keypress.js
devtools/client/styleinspector/test/browser_computedview_select-and-copy-styles.js
devtools/client/styleinspector/test/browser_computedview_style-editor-link.js
devtools/client/styleinspector/test/browser_ruleview_add-property-and-reselect.js
devtools/client/styleinspector/test/browser_ruleview_add-property-cancel_01.js
devtools/client/styleinspector/test/browser_ruleview_add-property-cancel_02.js
devtools/client/styleinspector/test/browser_ruleview_add-property-cancel_03.js
devtools/client/styleinspector/test/browser_ruleview_add-property-svg.js
devtools/client/styleinspector/test/browser_ruleview_add-property_01.js
devtools/client/styleinspector/test/browser_ruleview_add-property_02.js
devtools/client/styleinspector/test/browser_ruleview_add-rule_01.js
devtools/client/styleinspector/test/browser_ruleview_add-rule_02.js
devtools/client/styleinspector/test/browser_ruleview_add-rule_03.js
devtools/client/styleinspector/test/browser_ruleview_add-rule_04.js
devtools/client/styleinspector/test/browser_ruleview_add-rule_pseudo_class.js
devtools/client/styleinspector/test/browser_ruleview_authored.js
devtools/client/styleinspector/test/browser_ruleview_colorUnit.js
devtools/client/styleinspector/test/browser_ruleview_colorpicker-and-image-tooltip_01.js
devtools/client/styleinspector/test/browser_ruleview_colorpicker-and-image-tooltip_02.js
devtools/client/styleinspector/test/browser_ruleview_colorpicker-appears-on-swatch-click.js
devtools/client/styleinspector/test/browser_ruleview_colorpicker-commit-on-ENTER.js
devtools/client/styleinspector/test/browser_ruleview_colorpicker-edit-gradient.js
devtools/client/styleinspector/test/browser_ruleview_colorpicker-hides-on-tooltip.js
devtools/client/styleinspector/test/browser_ruleview_colorpicker-multiple-changes.js
devtools/client/styleinspector/test/browser_ruleview_colorpicker-release-outside-frame.js
devtools/client/styleinspector/test/browser_ruleview_colorpicker-revert-on-ESC.js
devtools/client/styleinspector/test/browser_ruleview_colorpicker-swatch-displayed.js
devtools/client/styleinspector/test/browser_ruleview_completion-existing-property_01.js
devtools/client/styleinspector/test/browser_ruleview_completion-existing-property_02.js
devtools/client/styleinspector/test/browser_ruleview_completion-new-property_01.js
devtools/client/styleinspector/test/browser_ruleview_completion-new-property_02.js
devtools/client/styleinspector/test/browser_ruleview_completion-new-property_03.js
devtools/client/styleinspector/test/browser_ruleview_completion-popup-hidden-after-navigation.js
devtools/client/styleinspector/test/browser_ruleview_computed-lists_01.js
devtools/client/styleinspector/test/browser_ruleview_computed-lists_02.js
devtools/client/styleinspector/test/browser_ruleview_content_01.js
devtools/client/styleinspector/test/browser_ruleview_content_02.js
devtools/client/styleinspector/test/browser_ruleview_context-menu-show-mdn-docs-01.js
devtools/client/styleinspector/test/browser_ruleview_context-menu-show-mdn-docs-02.js
devtools/client/styleinspector/test/browser_ruleview_context-menu-show-mdn-docs-03.js
devtools/client/styleinspector/test/browser_ruleview_copy_styles.js
devtools/client/styleinspector/test/browser_ruleview_cssom.js
devtools/client/styleinspector/test/browser_ruleview_cubicbezier-appears-on-swatch-click.js
devtools/client/styleinspector/test/browser_ruleview_cubicbezier-commit-on-ENTER.js
devtools/client/styleinspector/test/browser_ruleview_cubicbezier-revert-on-ESC.js
devtools/client/styleinspector/test/browser_ruleview_custom.js
devtools/client/styleinspector/test/browser_ruleview_cycle-color.js
devtools/client/styleinspector/test/browser_ruleview_edit-property-cancel.js
devtools/client/styleinspector/test/browser_ruleview_edit-property-commit.js
devtools/client/styleinspector/test/browser_ruleview_edit-property-computed.js
devtools/client/styleinspector/test/browser_ruleview_edit-property-increments.js
devtools/client/styleinspector/test/browser_ruleview_edit-property-order.js
devtools/client/styleinspector/test/browser_ruleview_edit-property-remove_01.js
devtools/client/styleinspector/test/browser_ruleview_edit-property-remove_02.js
devtools/client/styleinspector/test/browser_ruleview_edit-property-remove_03.js
devtools/client/styleinspector/test/browser_ruleview_edit-property_01.js
devtools/client/styleinspector/test/browser_ruleview_edit-property_02.js
devtools/client/styleinspector/test/browser_ruleview_edit-property_03.js
devtools/client/styleinspector/test/browser_ruleview_edit-property_04.js
devtools/client/styleinspector/test/browser_ruleview_edit-property_05.js
devtools/client/styleinspector/test/browser_ruleview_edit-property_06.js
devtools/client/styleinspector/test/browser_ruleview_edit-property_07.js
devtools/client/styleinspector/test/browser_ruleview_edit-property_08.js
devtools/client/styleinspector/test/browser_ruleview_edit-selector-commit.js
devtools/client/styleinspector/test/browser_ruleview_edit-selector_01.js
devtools/client/styleinspector/test/browser_ruleview_edit-selector_02.js
devtools/client/styleinspector/test/browser_ruleview_edit-selector_03.js
devtools/client/styleinspector/test/browser_ruleview_edit-selector_04.js
devtools/client/styleinspector/test/browser_ruleview_edit-selector_05.js
devtools/client/styleinspector/test/browser_ruleview_edit-selector_06.js
devtools/client/styleinspector/test/browser_ruleview_editable-field-focus_01.js
devtools/client/styleinspector/test/browser_ruleview_editable-field-focus_02.js
devtools/client/styleinspector/test/browser_ruleview_eyedropper.js
devtools/client/styleinspector/test/browser_ruleview_filtereditor-appears-on-swatch-click.js
devtools/client/styleinspector/test/browser_ruleview_filtereditor-commit-on-ENTER.js
devtools/client/styleinspector/test/browser_ruleview_filtereditor-revert-on-ESC.js
devtools/client/styleinspector/test/browser_ruleview_guessIndentation.js
devtools/client/styleinspector/test/browser_ruleview_inherited-properties_01.js
devtools/client/styleinspector/test/browser_ruleview_inherited-properties_02.js
devtools/client/styleinspector/test/browser_ruleview_inherited-properties_03.js
devtools/client/styleinspector/test/browser_ruleview_keybindings.js
devtools/client/styleinspector/test/browser_ruleview_keyframeLineNumbers.js
devtools/client/styleinspector/test/browser_ruleview_keyframes-rule_01.js
devtools/client/styleinspector/test/browser_ruleview_keyframes-rule_02.js
devtools/client/styleinspector/test/browser_ruleview_lineNumbers.js
devtools/client/styleinspector/test/browser_ruleview_livepreview.js
devtools/client/styleinspector/test/browser_ruleview_mark_overridden_01.js
devtools/client/styleinspector/test/browser_ruleview_mark_overridden_02.js
devtools/client/styleinspector/test/browser_ruleview_mark_overridden_03.js
devtools/client/styleinspector/test/browser_ruleview_mark_overridden_04.js
devtools/client/styleinspector/test/browser_ruleview_mark_overridden_05.js
devtools/client/styleinspector/test/browser_ruleview_mark_overridden_06.js
devtools/client/styleinspector/test/browser_ruleview_mark_overridden_07.js
devtools/client/styleinspector/test/browser_ruleview_mathml-element.js
devtools/client/styleinspector/test/browser_ruleview_media-queries.js
devtools/client/styleinspector/test/browser_ruleview_multiple-properties-duplicates.js
devtools/client/styleinspector/test/browser_ruleview_multiple-properties-priority.js
devtools/client/styleinspector/test/browser_ruleview_multiple-properties-unfinished_01.js
devtools/client/styleinspector/test/browser_ruleview_multiple-properties-unfinished_02.js
devtools/client/styleinspector/test/browser_ruleview_multiple_properties_01.js
devtools/client/styleinspector/test/browser_ruleview_multiple_properties_02.js
devtools/client/styleinspector/test/browser_ruleview_original-source-link.js
devtools/client/styleinspector/test/browser_ruleview_pseudo-element_01.js
devtools/client/styleinspector/test/browser_ruleview_pseudo-element_02.js
devtools/client/styleinspector/test/browser_ruleview_pseudo_lock_options.js
devtools/client/styleinspector/test/browser_ruleview_refresh-no-flicker.js
devtools/client/styleinspector/test/browser_ruleview_refresh-on-attribute-change_01.js
devtools/client/styleinspector/test/browser_ruleview_refresh-on-attribute-change_02.js
devtools/client/styleinspector/test/browser_ruleview_refresh-on-style-change.js
devtools/client/styleinspector/test/browser_ruleview_search-filter-computed-list_01.js
devtools/client/styleinspector/test/browser_ruleview_search-filter-computed-list_02.js
devtools/client/styleinspector/test/browser_ruleview_search-filter-computed-list_03.js
devtools/client/styleinspector/test/browser_ruleview_search-filter-computed-list_04.js
devtools/client/styleinspector/test/browser_ruleview_search-filter-computed-list_expander.js
devtools/client/styleinspector/test/browser_ruleview_search-filter-overridden-property.js
devtools/client/styleinspector/test/browser_ruleview_search-filter_01.js
devtools/client/styleinspector/test/browser_ruleview_search-filter_02.js
devtools/client/styleinspector/test/browser_ruleview_search-filter_03.js
devtools/client/styleinspector/test/browser_ruleview_search-filter_04.js
devtools/client/styleinspector/test/browser_ruleview_search-filter_05.js
devtools/client/styleinspector/test/browser_ruleview_search-filter_06.js
devtools/client/styleinspector/test/browser_ruleview_search-filter_07.js
devtools/client/styleinspector/test/browser_ruleview_search-filter_08.js
devtools/client/styleinspector/test/browser_ruleview_search-filter_09.js
devtools/client/styleinspector/test/browser_ruleview_search-filter_10.js
devtools/client/styleinspector/test/browser_ruleview_search-filter_context-menu.js
devtools/client/styleinspector/test/browser_ruleview_search-filter_escape-keypress.js
devtools/client/styleinspector/test/browser_ruleview_select-and-copy-styles.js
devtools/client/styleinspector/test/browser_ruleview_selector-highlighter_01.js
devtools/client/styleinspector/test/browser_ruleview_selector-highlighter_02.js
devtools/client/styleinspector/test/browser_ruleview_selector-highlighter_03.js
devtools/client/styleinspector/test/browser_ruleview_selector_highlight.js
devtools/client/styleinspector/test/browser_ruleview_strict-search-filter-computed-list_01.js
devtools/client/styleinspector/test/browser_ruleview_strict-search-filter_01.js
devtools/client/styleinspector/test/browser_ruleview_strict-search-filter_02.js
devtools/client/styleinspector/test/browser_ruleview_strict-search-filter_03.js
devtools/client/styleinspector/test/browser_ruleview_style-editor-link.js
devtools/client/styleinspector/test/browser_ruleview_urls-clickable.js
devtools/client/styleinspector/test/browser_ruleview_user-agent-styles-uneditable.js
devtools/client/styleinspector/test/browser_ruleview_user-agent-styles.js
devtools/client/styleinspector/test/browser_ruleview_user-property-reset.js
devtools/client/styleinspector/test/doc_copystyles.css
devtools/client/styleinspector/test/doc_copystyles.html
devtools/client/styleinspector/test/doc_cssom.html
devtools/client/styleinspector/test/doc_custom.html
devtools/client/styleinspector/test/doc_filter.html
devtools/client/styleinspector/test/doc_keyframeLineNumbers.html
devtools/client/styleinspector/test/doc_keyframeanimation.css
devtools/client/styleinspector/test/doc_keyframeanimation.html
devtools/client/styleinspector/test/doc_matched_selectors.html
devtools/client/styleinspector/test/doc_media_queries.html
devtools/client/styleinspector/test/doc_pseudoelement.html
devtools/client/styleinspector/test/doc_ruleLineNumbers.html
devtools/client/styleinspector/test/doc_sourcemaps.css
devtools/client/styleinspector/test/doc_sourcemaps.css.map
devtools/client/styleinspector/test/doc_sourcemaps.html
devtools/client/styleinspector/test/doc_sourcemaps.scss
devtools/client/styleinspector/test/doc_style_editor_link.css
devtools/client/styleinspector/test/doc_test_image.png
devtools/client/styleinspector/test/doc_urls_clickable.css
devtools/client/styleinspector/test/doc_urls_clickable.html
devtools/client/themes/computedview.css
devtools/client/themes/font-inspector.css
devtools/client/themes/layoutview.css
devtools/client/themes/markup-view.css
devtools/client/themes/ruleview.css
devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offests-in-gcd-script.js
devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets-at-end-of-script.js
devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets-in-gcd-script.js
devtools/server/tests/unit/test_setBreakpoint-on-column-with-no-offsets.js
dom/animation/Animation.cpp
dom/animation/Animation.h
dom/animation/test/css-animations/file_timeline-get-animations.html
dom/animation/test/css-animations/test_timeline-get-animations.html
dom/animation/test/css-transitions/file_timeline-get-animations.html
dom/animation/test/css-transitions/test_timeline-get-animations.html
dom/base/Navigator.cpp
dom/base/nsFormData.cpp
dom/base/nsFormData.h
dom/base/test/mochitest.ini
dom/bluetooth/ipc/BluetoothMessageUtils.h
dom/bluetooth/ipc/BluetoothTypes.ipdlh
dom/browser-element/mochitest/file_processingAudioSample.html
dom/browser-element/mochitest/mochitest-oop.ini
dom/browser-element/mochitest/mochitest.ini
dom/canvas/test/mochitest.ini
dom/canvas/test/webgl-mochitest.ini
dom/events/test/mochitest.ini
dom/html/test/mochitest.ini
dom/ipc/TabChild.cpp
dom/media/test/mochitest.ini
dom/media/tests/mochitest/mochitest.ini
dom/plugins/test/mochitest/mochitest.ini
dom/tests/mochitest/general/test_interfaces.html
dom/tests/mochitest/pointerlock/mochitest.ini
dom/workers/RuntimeService.cpp
gfx/harfbuzz/src/Makefile.in
gfx/src/nsRenderingContext.cpp
js/src/gc/GCRuntime.h
js/src/jit-test/tests/arguments/defaults-bug790424.js
js/src/jit-test/tests/arguments/genexpr-1.js
js/src/jit-test/tests/arguments/genexpr-2.js
js/src/jit-test/tests/arguments/genexpr-3.js
js/src/jit-test/tests/arguments/genexpr-4.js
js/src/jit-test/tests/arguments/genexpr-5.js
js/src/jit-test/tests/arguments/genexpr-6.js
js/src/jit-test/tests/asm.js/testBug1100237.js
js/src/jit-test/tests/asm.js/testResize.js
js/src/jit-test/tests/asm.js/testTimeout7-nosignals.js
js/src/jit-test/tests/asm.js/testTimeout7.js
js/src/jit-test/tests/auto-regress/bug487570.js
js/src/jit-test/tests/auto-regress/bug488963.js
js/src/jit-test/tests/auto-regress/bug496270.js
js/src/jit-test/tests/auto-regress/bug589093.js
js/src/jit-test/tests/auto-regress/bug595911.js
js/src/jit-test/tests/auto-regress/bug622318.js
js/src/jit-test/tests/auto-regress/bug691593.js
js/src/jit-test/tests/auto-regress/bug776314.js
js/src/jit-test/tests/auto-regress/bug780405.js
js/src/jit-test/tests/basic/bug510655.js
js/src/jit-test/tests/basic/bug630377.js
js/src/jit-test/tests/basic/bug660538.js
js/src/jit-test/tests/basic/bug790629-1.js
js/src/jit-test/tests/basic/bug790629-2.js
js/src/jit-test/tests/basic/bug790629-3.js
js/src/jit-test/tests/basic/bug790629-4.js
js/src/jit-test/tests/basic/bug864099.js
js/src/jit-test/tests/basic/function-tosource-genexpr.js
js/src/jit-test/tests/basic/testArrayBufferTransfer.js
js/src/jit-test/tests/basic/testArrayComp1.js
js/src/jit-test/tests/basic/testArrayComp2.js
js/src/jit-test/tests/basic/testBug709929.js
js/src/jit-test/tests/basic/testBug773927.js
js/src/jit-test/tests/basic/testGCNewbornGenerator.js
js/src/jit-test/tests/basic/testImplicitArgumentsInGenExprs.js
js/src/jit-test/tests/closures/flat-closure-3.js
js/src/jit-test/tests/closures/incr-exit-3.js
js/src/jit-test/tests/collections/Map-constructor-generator-2.js
js/src/jit-test/tests/collections/Set-constructor-generator-2.js
js/src/jit-test/tests/collections/WeakMap-constructor-generator-2.js
js/src/jit-test/tests/for-of/array-comprehension.js
js/src/jit-test/tests/for-of/array-holes-7.js
js/src/jit-test/tests/for-of/bug-728079-js17-2.js
js/src/jit-test/tests/for-of/bug-728079-js17-3.js
js/src/jit-test/tests/for-of/generators-4.js
js/src/jit-test/tests/generators/star-generator-forin.js
js/src/jit-test/tests/ion/bug956166.js
js/src/jit-test/tests/jaeger/regalloc-1.js
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsweakcache.h
js/src/tests/js1_5/Regress/regress-352009.js
js/src/tests/js1_6/Regress/regress-350417.js
js/src/tests/js1_6/extensions/regress-475144.js
js/src/tests/js1_7/extensions/regress-455982-01.js
js/src/tests/js1_7/extensions/regress-455982-02.js
js/src/tests/js1_7/geniter/evens.js
js/src/tests/js1_7/geniter/regress-345736.js
js/src/tests/js1_7/iterable/regress-412467.js
js/src/tests/js1_7/regress/regress-428706.js
js/src/tests/js1_7/regress/regress-461235.js
js/src/tests/js1_7/regress/regress-461945.js
js/src/tests/js1_8/extensions/regress-385393-01.js
js/src/tests/js1_8/extensions/regress-385393-10.js
js/src/tests/js1_8/extensions/regress-385393-11.js
js/src/tests/js1_8/extensions/regress-452476.js
js/src/tests/js1_8/extensions/regress-455973.js
js/src/tests/js1_8/genexps/arguments-property-access-in-generator.js
js/src/tests/js1_8/genexps/browser.js
js/src/tests/js1_8/genexps/regress-349331.js
js/src/tests/js1_8/genexps/regress-380237-01.js
js/src/tests/js1_8/genexps/regress-380237-02.js
js/src/tests/js1_8/genexps/regress-380237-04.js
js/src/tests/js1_8/genexps/regress-634472.js
js/src/tests/js1_8/genexps/regress-666852.js
js/src/tests/js1_8/genexps/regress-667131.js
js/src/tests/js1_8/regress/regress-463783.js
js/src/tests/js1_8_1/jit/testDeepBailFromNonNative.js
js/src/tests/js1_8_1/regress/regress-452498-038.js
js/src/tests/js1_8_1/regress/regress-452498-052.js
js/src/tests/js1_8_1/regress/regress-452498-068.js
js/src/tests/js1_8_1/regress/regress-452498-098.js
js/src/tests/js1_8_1/regress/regress-452498-099-a.js
js/src/tests/js1_8_1/regress/regress-452498-099.js
js/src/tests/js1_8_1/regress/regress-452498-119.js
js/src/tests/js1_8_1/regress/regress-452498-130.js
js/src/tests/js1_8_1/regress/regress-452498-135-a.js
js/src/tests/js1_8_1/regress/regress-452498-138.js
js/src/tests/js1_8_1/regress/regress-452498-139.js
js/src/tests/js1_8_1/regress/regress-507424.js
js/src/tests/js1_8_1/regress/regress-515885.js
js/src/tests/js1_8_1/strict/generator-eval-arguments.js
js/src/tests/js1_8_5/extensions/regress-627859.js
js/src/tests/js1_8_5/regress/no-array-comprehension-length-limit.js
js/src/tests/js1_8_5/regress/regress-541255-0.js
js/src/tests/js1_8_5/regress/regress-541255-1.js
js/src/tests/js1_8_5/regress/regress-541255-2.js
js/src/tests/js1_8_5/regress/regress-541255-4.js
js/src/tests/js1_8_5/regress/regress-576847.js
js/src/tests/js1_8_5/regress/regress-620750.js
js/src/vm/HelperThreads.cpp
js/src/vm/HelperThreads.h
js/src/vm/Runtime.cpp
js/src/vm/Runtime.h
media/libvpx/vp9/decoder/vp9_decoder.c
memory/replace/logalloc/Makefile.in
mobile/android/base/java/org/mozilla/gecko/dlc/DownloadContentHelper.java
mobile/android/extensions/moz.build
mobile/android/locales/generic/install.rdf
python/mozbuild/mozbuild/action/convert_def_file.py
services/common/tests/unit/test_utils_exceptionStr.js
testing/mozbase/mozdebug/mozdebug/mozdebug.py
testing/web-platform/mozilla/meta/service-workers/service-worker/navigation-redirect.https.html.ini
toolkit/components/downloads/test/browser/mochitest.ini
toolkit/mozapps/extensions/test/browser/browser_debug_button.js
widget/gonk/HwcComposer2D.cpp
xulrunner/installer/windows/Header.bmp
xulrunner/installer/windows/Makefile.in
xulrunner/installer/windows/Watermrk.bmp
xulrunner/installer/windows/moz.build
--- a/.eslintignore
+++ b/.eslintignore
@@ -78,16 +78,17 @@ browser/components/pocket/**
 browser/components/preferences/**
 browser/components/privatebrowsing/**
 browser/components/sessionstore/**
 browser/components/shell/**
 browser/components/tabview/**
 browser/components/translation/**
 browser/components/uitour/**
 browser/extensions/pdfjs/**
+browser/extensions/pocket/content/panels/js/vendor/**
 browser/extensions/shumway/**
 browser/fuel/**
 browser/locales/**
 
 # Loop specific exclusions
 
 # This file currently uses a non-standard (and not on a standards track)
 # if statement within catch.
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,9 +1,13 @@
 {
   // When adding items to this file please check for effects on sub-directories.
   "plugins": [
     "mozilla"
   ],
+  "rules": {
+    "mozilla/components-imports": 1,
+    "mozilla/import-globals-from": 1,
+  },
   "env": {
     "es6": true
   },
 }
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Bug 1082598 - updating Skia
+Bug 1209344 - Remove debug button from about:addons. r=mossop
--- a/Makefile.in
+++ b/Makefile.in
@@ -213,17 +213,16 @@ ifeq (,$(filter-out Linux SunOS,$(OS_ARC
 MAKE_SYM_STORE_ARGS := -c --vcs-info
 DUMP_SYMS_BIN ?= $(DIST)/host/bin/dump_syms
 MAKE_SYM_STORE_PATH := $(DIST)/bin
 endif
 MAKE_SYM_STORE_ARGS += --install-manifest=$(DEPTH)/_build_manifests/install/dist_include,$(DIST)/include
 
 SYM_STORE_SOURCE_DIRS := $(topsrcdir)
 
-ifndef JS_STANDALONE
 include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
 
 ifdef MOZ_SYMBOLS_EXTRA_BUILDID
 EXTRA_BUILDID := -$(MOZ_SYMBOLS_EXTRA_BUILDID)
 endif
 
 SYMBOL_INDEX_NAME = \
   $(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_TARGET)-$(BUILDID)-$(CPU_ARCH)$(EXTRA_BUILDID)-symbols.txt
@@ -256,17 +255,16 @@ endif # MOZ_CRASHREPORTER
 
 uploadsymbols:
 ifdef MOZ_CRASHREPORTER
 ifdef SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE
 	$(PYTHON) -u $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.py '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip'
 else
 	$(SHELL) $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh $(SYMBOL_INDEX_NAME) '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip'
 endif
-endif
 
 # MOZ_SOURCE_STAMP is defined in package-name.mk with a deferred assignment.
 # exporting it makes make run its $(shell) command for each invoked submake,
 # so transform it to an immediate assignment.
 MOZ_SOURCE_STAMP := $(MOZ_SOURCE_STAMP)
 export MOZ_SOURCE_STAMP
 endif
 
--- a/accessible/base/AccEvent.cpp
+++ b/accessible/base/AccEvent.cpp
@@ -99,32 +99,32 @@ AccReorderEvent::IsShowHideEventTarget(c
   return 0;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccHideEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 AccHideEvent::
-  AccHideEvent(Accessible* aTarget, nsINode* aTargetNode, bool aNeedsShutdown) :
-  AccMutationEvent(::nsIAccessibleEvent::EVENT_HIDE, aTarget, aTargetNode),
+  AccHideEvent(Accessible* aTarget, bool aNeedsShutdown) :
+  AccMutationEvent(::nsIAccessibleEvent::EVENT_HIDE, aTarget),
   mNeedsShutdown(aNeedsShutdown)
 {
   mNextSibling = mAccessible->NextSibling();
   mPrevSibling = mAccessible->PrevSibling();
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccShowEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 AccShowEvent::
-  AccShowEvent(Accessible* aTarget, nsINode* aTargetNode) :
-  AccMutationEvent(::nsIAccessibleEvent::EVENT_SHOW, aTarget, aTargetNode)
+  AccShowEvent(Accessible* aTarget) :
+  AccMutationEvent(::nsIAccessibleEvent::EVENT_SHOW, aTarget)
 {
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccTextSelChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
 
--- a/accessible/base/AccEvent.h
+++ b/accessible/base/AccEvent.h
@@ -207,18 +207,17 @@ private:
 
 
 /**
  * Base class for show and hide accessible events.
  */
 class AccMutationEvent: public AccEvent
 {
 public:
-  AccMutationEvent(uint32_t aEventType, Accessible* aTarget,
-                   nsINode* aTargetNode) :
+  AccMutationEvent(uint32_t aEventType, Accessible* aTarget) :
     AccEvent(aEventType, aTarget, eAutoDetect, eCoalesceMutationTextChange)
   {
     // Don't coalesce these since they are coalesced by reorder event. Coalesce
     // contained text change events.
     mParent = mAccessible->Parent();
   }
   virtual ~AccMutationEvent() { }
 
@@ -245,18 +244,17 @@ protected:
 
 
 /**
  * Accessible hide event.
  */
 class AccHideEvent: public AccMutationEvent
 {
 public:
-  AccHideEvent(Accessible* aTarget, nsINode* aTargetNode,
-               bool aNeedsShutdown = true);
+  explicit AccHideEvent(Accessible* aTarget, bool aNeedsShutdown = true);
 
   // Event
   static const EventGroup kEventGroup = eHideEvent;
   virtual unsigned int GetEventGroups() const override
   {
     return AccMutationEvent::GetEventGroups() | (1U << eHideEvent);
   }
 
@@ -276,17 +274,17 @@ protected:
 
 
 /**
  * Accessible show event.
  */
 class AccShowEvent: public AccMutationEvent
 {
 public:
-  AccShowEvent(Accessible* aTarget, nsINode* aTargetNode);
+  explicit AccShowEvent(Accessible* aTarget);
 
   // Event
   static const EventGroup kEventGroup = eShowEvent;
   virtual unsigned int GetEventGroups() const override
   {
     return AccMutationEvent::GetEventGroups() | (1U << eShowEvent);
   }
 };
--- a/accessible/base/NotificationController.cpp
+++ b/accessible/base/NotificationController.cpp
@@ -384,18 +384,20 @@ NotificationController::WillRefresh(mozi
         parentIPCDoc->SendBindChildDoc(ipcDoc, id);
         continue;
       }
 
       ipcDoc = new DocAccessibleChild(childDoc);
       childDoc->SetIPCDoc(ipcDoc);
       nsCOMPtr<nsITabChild> tabChild =
         do_GetInterface(mDocument->DocumentNode()->GetDocShell());
-      static_cast<TabChild*>(tabChild.get())->
-        SendPDocAccessibleConstructor(ipcDoc, parentIPCDoc, id);
+      if (tabChild) {
+        static_cast<TabChild*>(tabChild.get())->
+          SendPDocAccessibleConstructor(ipcDoc, parentIPCDoc, id);
+      }
     }
   }
 
   mObservingState = eRefreshObserving;
   if (!mDocument)
     return;
 
   // Stop further processing if there are no new notifications of any kind or
--- a/accessible/base/StyleInfo.cpp
+++ b/accessible/base/StyleInfo.cpp
@@ -53,16 +53,17 @@ StyleInfo::TextIndent(nsAString& aValue)
   switch (styleCoord.GetUnit()) {
     case eStyleUnit_Coord:
       coordVal = styleCoord.GetCoordValue();
       break;
 
     case eStyleUnit_Percent:
     {
       nsIFrame* frame = mElement->GetPrimaryFrame();
+      MOZ_ASSERT(frame, "frame must be a valid pointer.");
       nsIFrame* containerFrame = frame->GetContainingBlock();
       nscoord percentageBase = containerFrame->GetContentRect().width;
       coordVal = NSCoordSaturatingMultiply(percentageBase,
                                            styleCoord.GetPercentValue());
       break;
     }
 
     case eStyleUnit_Null:
@@ -83,16 +84,17 @@ StyleInfo::TextIndent(nsAString& aValue)
 
   aValue.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(coordVal));
   aValue.AppendLiteral("px");
 }
 
 void
 StyleInfo::Margin(css::Side aSide, nsAString& aValue)
 {
+  MOZ_ASSERT(mElement->GetPrimaryFrame(), " mElement->GetPrimaryFrame() needs to be valid pointer");
   aValue.Truncate();
 
   nscoord coordVal = mElement->GetPrimaryFrame()->GetUsedMargin().Side(aSide);
   aValue.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(coordVal));
   aValue.AppendLiteral("px");
 }
 
 void
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -1506,17 +1506,17 @@ DocAccessible::DoInitialUpdate()
   if (!IsRoot()) {
     RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(Parent());
     ParentDocument()->FireDelayedEvent(reorderEvent);
   }
 
   uint32_t childCount = ChildCount();
   for (uint32_t i = 0; i < childCount; i++) {
     Accessible* child = GetChildAt(i);
-    RefPtr<AccShowEvent> event = new AccShowEvent(child, child->GetContent());
+    RefPtr<AccShowEvent> event = new AccShowEvent(child);
   FireDelayedEvent(event);
   }
 }
 
 void
 DocAccessible::ProcessLoad()
 {
   mLoadState |= eCompletelyLoaded;
@@ -1887,17 +1887,16 @@ DocAccessible::UpdateTreeInternal(Access
   uint32_t updateFlags = eAccessible;
 
   // If a focused node has been shown then it could mean its frame was recreated
   // while the node stays focused and we need to fire focus event on
   // the accessible we just created. If the queue contains a focus event for
   // this node already then it will be suppressed by this one.
   Accessible* focusedAcc = nullptr;
 
-  nsINode* node = aChild->GetNode();
   if (aIsInsert) {
     // Create accessible tree for shown accessible.
     CacheChildrenInSubtree(aChild, &focusedAcc);
 
   } else {
     // Fire menupopup end event before hide event if a menu goes away.
 
     // XXX: We don't look into children of hidden subtree to find hiding
@@ -1909,19 +1908,19 @@ DocAccessible::UpdateTreeInternal(Access
     // handling.
     if (aChild->ARIARole() == roles::MENUPOPUP)
       FireDelayedEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END, aChild);
   }
 
   // Fire show/hide event.
   RefPtr<AccMutationEvent> event;
   if (aIsInsert)
-    event = new AccShowEvent(aChild, node);
+    event = new AccShowEvent(aChild);
   else
-    event = new AccHideEvent(aChild, node);
+    event = new AccHideEvent(aChild);
 
   FireDelayedEvent(event);
   aReorderEvent->AddSubMutationEvent(event);
 
   if (aIsInsert) {
     roles::Role ariaRole = aChild->ARIARole();
     if (ariaRole == roles::MENUPOPUP) {
       // Fire EVENT_MENUPOPUP_START if ARIA menu appears.
@@ -2084,18 +2083,17 @@ DocAccessible::SeizeChild(Accessible* aN
   if (!oldParent) {
     NS_ERROR("No parent? The tree is broken!");
     return false;
   }
 
   int32_t oldIdxInParent = aChild->IndexInParent();
 
   RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(oldParent);
-  RefPtr<AccMutationEvent> hideEvent =
-    new AccHideEvent(aChild, aChild->GetContent(), false);
+  RefPtr<AccMutationEvent> hideEvent = new AccHideEvent(aChild, false);
   reorderEvent->AddSubMutationEvent(hideEvent);
 
   {
     AutoTreeMutation mut(oldParent);
     oldParent->RemoveChild(aChild);
   }
 
   bool isReinserted = false;
@@ -2116,18 +2114,17 @@ DocAccessible::SeizeChild(Accessible* aN
     children->RemoveElement(aChild);
   }
 
   FireDelayedEvent(hideEvent);
   MaybeNotifyOfValueChange(oldParent);
   FireDelayedEvent(reorderEvent);
 
   reorderEvent = new AccReorderEvent(aNewParent);
-  RefPtr<AccMutationEvent> showEvent =
-    new AccShowEvent(aChild, aChild->GetContent());
+  RefPtr<AccMutationEvent> showEvent = new AccShowEvent(aChild);
   reorderEvent->AddSubMutationEvent(showEvent);
 
   FireDelayedEvent(showEvent);
   MaybeNotifyOfValueChange(aNewParent);
   FireDelayedEvent(reorderEvent);
 
   aChild->SetRelocated(true);
   return true;
@@ -2135,30 +2132,28 @@ DocAccessible::SeizeChild(Accessible* aN
 
 void
 DocAccessible::MoveChild(Accessible* aChild, int32_t aIdxInParent)
 {
   NS_PRECONDITION(aChild->Parent(), "No parent?");
 
   Accessible* parent = aChild->Parent();
   RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(parent);
-  RefPtr<AccMutationEvent> hideEvent =
-    new AccHideEvent(aChild, aChild->GetContent(), false);
+  RefPtr<AccMutationEvent> hideEvent = new AccHideEvent(aChild, false);
   reorderEvent->AddSubMutationEvent(hideEvent);
 
   AutoTreeMutation mut(parent);
   parent->RemoveChild(aChild);
 
   parent->InsertChildAt(aIdxInParent, aChild);
   aChild->SetRelocated(true);
 
   FireDelayedEvent(hideEvent);
 
-  RefPtr<AccMutationEvent> showEvent =
-    new AccShowEvent(aChild, aChild->GetContent());
+  RefPtr<AccMutationEvent> showEvent = new AccShowEvent(aChild);
   reorderEvent->AddSubMutationEvent(showEvent);
   FireDelayedEvent(showEvent);
 
   MaybeNotifyOfValueChange(parent);
   FireDelayedEvent(reorderEvent);
 }
 
 void
@@ -2172,18 +2167,17 @@ DocAccessible::PutChildrenBack(nsTArray<
     // If the child is in the tree then remove it from the owner.
     if (child->IsInDocument()) {
       Accessible* owner = child->Parent();
       if (!owner) {
         NS_ERROR("Cannot put the child back. No parent, a broken tree.");
         continue;
       }
       RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(owner);
-      RefPtr<AccMutationEvent> hideEvent =
-        new AccHideEvent(child, child->GetContent(), false);
+      RefPtr<AccMutationEvent> hideEvent = new AccHideEvent(child, false);
       reorderEvent->AddSubMutationEvent(hideEvent);
 
       {
         AutoTreeMutation mut(owner);
         owner->RemoveChild(child);
         child->SetRelocated(false);
       }
 
--- a/accessible/html/HTMLImageMapAccessible.cpp
+++ b/accessible/html/HTMLImageMapAccessible.cpp
@@ -116,17 +116,17 @@ HTMLImageMapAccessible::UpdateChildAreas
       mDoc->BindToDocument(area, aria::GetRoleMap(areaContent));
 
       if (!InsertChildAt(idx, area)) {
         mDoc->UnbindFromDocument(area);
         break;
       }
 
       if (aDoFireEvents) {
-        RefPtr<AccShowEvent> event = new AccShowEvent(area, areaContent);
+        RefPtr<AccShowEvent> event = new AccShowEvent(area);
         mDoc->FireDelayedEvent(event);
         reorderEvent->AddSubMutationEvent(event);
       }
 
       treeChanged = true;
     }
   }
 
--- a/accessible/html/HTMLListAccessible.cpp
+++ b/accessible/html/HTMLListAccessible.cpp
@@ -106,17 +106,17 @@ HTMLLIAccessible::UpdateBullet(bool aHas
   AutoTreeMutation mut(this);
 
   DocAccessible* document = Document();
   if (aHasBullet) {
     mBullet = new HTMLListBulletAccessible(mContent, mDoc);
     document->BindToDocument(mBullet, nullptr);
     InsertChildAt(0, mBullet);
 
-    RefPtr<AccShowEvent> event = new AccShowEvent(mBullet, mBullet->GetContent());
+    RefPtr<AccShowEvent> event = new AccShowEvent(mBullet);
     mDoc->FireDelayedEvent(event);
     reorderEvent->AddSubMutationEvent(event);
   } else {
     RefPtr<AccHideEvent> event = new AccHideEvent(mBullet, mBullet->GetContent());
     mDoc->FireDelayedEvent(event);
     reorderEvent->AddSubMutationEvent(event);
 
     RemoveChild(mBullet);
--- a/b2g/app/B2GLoader.cpp
+++ b/b2g/app/B2GLoader.cpp
@@ -18,16 +18,17 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 
 #include <dlfcn.h>
 
 #include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
+#include "mozilla/UniquePtr.h"
 
 #define ASSERT(x) if (!(x)) { MOZ_CRASH(); }
 
 // Functions being loaded by XPCOMGlue
 XRE_ProcLoaderServiceRunType XRE_ProcLoaderServiceRun;
 XRE_ProcLoaderClientInitType XRE_ProcLoaderClientInit;
 XRE_ProcLoaderPreloadType XRE_ProcLoaderPreload;
 extern XRE_CreateAppDataType XRE_CreateAppData;
@@ -60,21 +61,21 @@ GetDirnameSlash(const char *aPath, char 
   strncpy(aOutDir, aPath, cpsz);
   aOutDir[cpsz] = 0;
   return cpsz;
 }
 
 static bool
 GetXPCOMPath(const char *aProgram, char *aOutPath, int aMaxLen)
 {
-  nsAutoArrayPtr<char> progBuf(new char[aMaxLen]);
-  nsresult rv = mozilla::BinaryPath::Get(aProgram, progBuf);
+  auto progBuf = mozilla::MakeUnique<char[]>(aMaxLen);
+  nsresult rv = mozilla::BinaryPath::Get(aProgram, progBuf.get());
   NS_ENSURE_SUCCESS(rv, false);
 
-  int len = GetDirnameSlash(progBuf, aOutPath, aMaxLen);
+  int len = GetDirnameSlash(progBuf.get(), aOutPath, aMaxLen);
   NS_ENSURE_TRUE(!!len, false);
 
   NS_ENSURE_TRUE((len + sizeof(XPCOM_DLL)) < (unsigned)aMaxLen, false);
   char *afterSlash = aOutPath + len;
   strcpy(afterSlash, XPCOM_DLL);
   return true;
 }
 
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -355,21 +355,21 @@ pref("browser.safebrowsing.downloads.ena
 pref("browser.safebrowsing.downloads.remote.enabled", true);
 pref("browser.safebrowsing.downloads.remote.timeout_ms", 10000);
 pref("browser.safebrowsing.debug", false);
 
 pref("browser.safebrowsing.provider.google.lists", "goog-badbinurl-shavar,goog-downloadwhite-digest256,goog-phish-shavar,goog-malware-shavar,goog-unwanted-shavar");
 pref("browser.safebrowsing.provider.google.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
 pref("browser.safebrowsing.provider.google.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
 pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
-pref("browser.safebrowsing.provider.google.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
 
 pref("browser.safebrowsing.reportPhishMistakeURL", "https://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%&url=");
 pref("browser.safebrowsing.reportPhishURL", "https://%LOCALE%.phish-report.mozilla.com/?hl=%LOCALE%&url=");
 pref("browser.safebrowsing.reportMalwareMistakeURL", "https://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%&url=");
+pref("browser.safebrowsing.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
 
 pref("browser.safebrowsing.id", "Firefox");
 
 // Tables for application reputation.
 pref("urlclassifier.downloadBlockTable", "goog-badbinurl-shavar");
 
 // The number of random entries to send with a gethash request.
 pref("urlclassifier.gethashnoise", 4);
@@ -687,17 +687,16 @@ pref("layout.css.scroll-snap.enabled", t
 
 // Enable the ProcessPriorityManager, and give processes with no visible
 // documents a 1s grace period before they're eligible to be marked as
 // background. Background processes that are perceivable due to playing
 // media are given a longer grace period to accomodate changing tracks, etc.
 pref("dom.ipc.processPriorityManager.enabled", true);
 pref("dom.ipc.processPriorityManager.backgroundGracePeriodMS", 1000);
 pref("dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS", 5000);
-pref("dom.ipc.processPriorityManager.memoryPressureGracePeriodMS", 3000);
 pref("dom.ipc.processPriorityManager.temporaryPriorityLockMS", 5000);
 
 // Number of different background/foreground levels for background/foreground
 // processes.  We use these different levels to force the low-memory killer to
 // kill processes in a LRU order.
 pref("dom.ipc.processPriorityManager.BACKGROUND.LRUPoolLevels", 5);
 pref("dom.ipc.processPriorityManager.BACKGROUND_PERCEIVABLE.LRUPoolLevels", 4);
 
@@ -775,17 +774,22 @@ pref("hal.gonk.COMPOSITOR.nice", -4);
 
 // Fire a memory pressure event when the system has less than Xmb of memory
 // remaining.  You should probably set this just above Y.KillUnderKB for
 // the highest priority class Y that you want to make an effort to keep alive.
 // (For example, we want BACKGROUND_PERCEIVABLE to stay alive.)  If you set
 // this too high, then we'll send out a memory pressure event every Z seconds
 // (see below), even while we have processes that we would happily kill in
 // order to free up memory.
-pref("hal.processPriorityManager.gonk.notifyLowMemUnderKB", 14336);
+pref("gonk.notifyHardLowMemUnderKB", 14336);
+
+// Fire a memory pressure event when the system has less than Xmb of memory
+// remaining and then switch to the hard trigger, see above.  This should be
+// placed above the BACKGROUND priority class.
+pref("gonk.notifySoftLowMemUnderKB", 43008);
 
 // We wait this long before polling the memory-pressure fd after seeing one
 // memory pressure event.  (When we're not under memory pressure, we sit
 // blocked on a poll(), and this pref has no effect.)
 pref("gonk.systemMemoryPressureRecoveryPollMS", 5000);
 
 // Enable pre-launching content processes for improved startup time
 // (hiding latency).
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -839,19 +839,16 @@ var CustomEventManager = {
 
     switch(detail.type) {
       case 'webapps-install-granted':
       case 'webapps-install-denied':
       case 'webapps-uninstall-granted':
       case 'webapps-uninstall-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;
       case 'captive-portal-login-cancel':
         CaptivePortalLoginHelper.handleEvent(detail);
         break;
       case 'inputmethod-update-layouts':
       case 'inputregistry-add':
--- a/b2g/components/AlertsService.js
+++ b/b2g/components/AlertsService.js
@@ -61,33 +61,46 @@ AlertsService.prototype = {
       case "xpcom-shutdown":
         Services.obs.removeObserver(this, "xpcom-shutdown");
         cpmm.removeMessageListener(kMessageAppNotificationReturn, this);
         break;
     }
   },
 
   // nsIAlertsService
+  showAlert: function(aAlert, aAlertListener) {
+    if (!aAlert) {
+      return;
+    }
+    cpmm.sendAsyncMessage(kMessageAlertNotificationSend, {
+      imageURL: aAlert.imageURL,
+      title: aAlert.title,
+      text: aAlert.text,
+      clickable: aAlert.textClickable,
+      cookie: aAlert.cookie,
+      listener: aAlertListener,
+      id: aAlert.name,
+      dir: aAlert.dir,
+      lang: aAlert.lang,
+      dataStr: aAlert.data,
+      inPrivateBrowsing: aAlert.inPrivateBrowsing
+    });
+  },
+
   showAlertNotification: function(aImageUrl, aTitle, aText, aTextClickable,
                                   aCookie, aAlertListener, aName, aBidi,
                                   aLang, aDataStr, aPrincipal,
                                   aInPrivateBrowsing) {
-    cpmm.sendAsyncMessage(kMessageAlertNotificationSend, {
-      imageURL: aImageUrl,
-      title: aTitle,
-      text: aText,
-      clickable: aTextClickable,
-      cookie: aCookie,
-      listener: aAlertListener,
-      id: aName,
-      dir: aBidi,
-      lang: aLang,
-      dataStr: aDataStr,
-      inPrivateBrowsing: aInPrivateBrowsing
-    });
+    let alert = Cc["@mozilla.org/alert-notification;1"].
+      createInstance(Ci.nsIAlertNotification);
+
+    alert.init(aName, aImageUrl, aTitle, aText, aTextClickable, aCookie,
+               aBidi, aLang, aDataStr, aPrincipal, aInPrivateBrowsing);
+
+    this.showAlert(alert, aAlertListener);
   },
 
   closeAlert: function(aName) {
     cpmm.sendAsyncMessage(kMessageAlertNotificationClose, {
       name: aName
     });
   },
 
--- a/b2g/components/PersistentDataBlock.jsm
+++ b/b2g/components/PersistentDataBlock.jsm
@@ -59,19 +59,19 @@ function debug(str) {
 }
 
 function toHexString(data) {
   function toHexChar(charCode) {
     return ("0" + charCode.toString(16).slice(-2));
   }
   let hexString = "";
   if (typeof data === "string") {
-    hexString = [toHexChar(data.charCodeAt(i)) for (i in data)].join("");
+    hexString = Array.from(data, (c, i) => toHexChar(data.charCodeAt(i))).join("");
   } else if (typeof data === "array") {
-    hexString = [toHexChar(data[i]) for (i in data)].join("");
+    hexString = data.map(toHexChar).join("");
   }
   return hexString;
 }
 
 function arr2bstr(arr) {
   let bstr = "";
   for (let i = 0; i < arr.length; i++) {
     bstr += String.fromCharCode(arr[i]);
@@ -382,17 +382,17 @@ this.PersistentDataBlock = {
     let partition;
     return this._computeDigest().then(_digest => {
       digest = _digest;
       return OS.File.open(this._dataBlockFile, {write:true, existing:true, append:false});
     }).then(_partition => {
       partition = _partition;
       return partition.setPosition(DIGEST_OFFSET, OS.File.POS_START);
     }).then(() => {
-      return partition.write(new Uint8Array([digest.calculated.charCodeAt(i) for (i in digest.calculated)]));
+      return partition.write(new Uint8Array(Array.from(digest.calculated, (c, i) => digest.calculated.charCodeAt(i))));
     }).then(bytesWrittenLength => {
       if (bytesWrittenLength != DIGEST_SIZE_BYTES) {
         log("_computeAndWriteDigest: Error writting digest to partition!. Expected: " + DIGEST_SIZE_BYTES + " Written: " + bytesWrittenLength);
         return Promise.reject();
       }
       return partition.close();
     }).then(() => {
       debug("_computeAndWriteDigest: digest written to partition");
--- a/b2g/components/test/unit/file_persistentdatablock.js
+++ b/b2g/components/test/unit/file_persistentdatablock.js
@@ -27,19 +27,19 @@ function log(str) {
 }
 
 function toHexString(data) {
   function toHexChar(charCode) {
     return ("0" + charCode.toString(16).slice(-2));
   }
   let hexString = "";
   if (typeof data === "string") {
-    hexString = [toHexChar(data.charCodeAt(i)) for (i in data)].join("");
+    hexString = Array.from(data, (c, i) => toHexChar(data.charCodeAt(i))).join("");
   } else if (typeof data === "array") {
-    hexString = [toHexChar(data[i]) for (i in data)].join("");
+    hexString = data.map(toHexChar).join("");
   }
   return hexString;
 }
 
 function _prepareConfig(_args) {
   let args = _args || {};
   // This digest has been previously calculated given the data to be written later, and setting the OEM Unlocked Enabled byte
   // to 1. If we need different values, some tests will fail because this precalculated digest won't be valid then.
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -16,31 +16,31 @@
   <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
   <!--original fetch url was git://github.com/mozilla/-->
   <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1899109c9fd9b9e2244155c4b9e966c0a48368fc"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="887a1d7f2ab601fc40b923b4e16e6b9b48fc982e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="b516c3e0f6770d8acb6b4dff18b39e19cb4e4731"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5e96ed318db1ba8037eb402724bc052240ac9e05"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/>
   <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
@@ -115,17 +115,17 @@
   <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="f0c3b4edf597c40aae4ea311575f39c8bcf203df"/>
   <project name="platform/libcore" path="libcore" revision="baf7d8068dd501cfa338d3a8b1b87216d6ce0571"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="50c4430e32849530ced32680fd6ee98963b3f7ac"/>
   <project name="platform/ndk" path="ndk" revision="e58ef003be4306bb53a8c11331146f39e4eab31f"/>
   <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="c739cffa6394c06e099ea48879a20341b6163338"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="c792f0bd9fff7aea2887c60bbb3a9bbdb534ffa3"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="69d524e80cdf3981006627c65ac85f3a871238a3"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
-  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="570531db9e81a871c421b27025ae558022b1015a"/>
+  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bb356d6505f914347690c8143dbd03af427dd07e"/>
   <project name="platform/system/extras" path="system/extras" revision="576f57b6510de59c08568b53c0fb60588be8689e"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform/system/netd" path="system/netd" revision="a6531f7befb49b1c81bc0de7e51c5482b308e1c5"/>
   <project name="platform/system/security" path="system/security" revision="ee8068b9e7bfb2770635062fc9c2035be2142bd8"/>
   <project name="platform/system/vold" path="system/vold" revision="42fa2a0f14f965970a4b629a176bbd2666edf017"/>
   <project name="platform/external/curl" path="external/curl" revision="e68addd988448959ea8157c5de637346b4180c33"/>
   <project name="platform/external/icu4c" path="external/icu4c" revision="d3ec7428eb276db43b7ed0544e09344a6014806c"/>
   <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="76c4bf4bc430a1b8317f2f21ef735867733e50cc"/>
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -16,31 +16,31 @@
   <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
   <!--original fetch url was git://github.com/mozilla/-->
   <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1899109c9fd9b9e2244155c4b9e966c0a48368fc"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="887a1d7f2ab601fc40b923b4e16e6b9b48fc982e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="b516c3e0f6770d8acb6b4dff18b39e19cb4e4731"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5e96ed318db1ba8037eb402724bc052240ac9e05"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="83760d213fb3bec7b4117d266fcfbf6fe2ba14ab"/>
   <project name="device/common" path="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30"/>
@@ -121,17 +121,17 @@
   <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="68b0c269fd1889f47ecfb9119c05281e9b6db0af"/>
   <project name="platform/libcore" path="libcore" revision="e195beab082c09217318fc19250caeaf4c1bd800"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="feeb36c2bd4adfe285f98f5de92e0f3771b2c115"/>
   <project name="platform/ndk" path="ndk" revision="e58ef003be4306bb53a8c11331146f39e4eab31f"/>
   <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="c739cffa6394c06e099ea48879a20341b6163338"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="c792f0bd9fff7aea2887c60bbb3a9bbdb534ffa3"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="cfcef469537869947abb9aa1d656774cc2678d4c"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
-  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="570531db9e81a871c421b27025ae558022b1015a"/>
+  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bb356d6505f914347690c8143dbd03af427dd07e"/>
   <project name="platform/system/extras" path="system/extras" revision="10e78a05252b3de785f88c2d0b9ea8a428009c50"/>
   <project name="platform/system/media" path="system/media" revision="188b3e51e0a2ce1e16dc8067edef7be3d2365ad9"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform/system/netd" path="system/netd" revision="3ae56364946d4a5bf5a5f83f12f9a45a30398e33"/>
   <project name="platform/system/security" path="system/security" revision="ee8068b9e7bfb2770635062fc9c2035be2142bd8"/>
   <project name="platform/system/vold" path="system/vold" revision="fe12a9e2268da653d1cd4c39ec89a42211d22f25"/>
   <!--original fetch url was http://sprdsource.spreadtrum.com:8085/b2g/android-->
   <remote fetch="https://git.mozilla.org/external/sprd-aosp" name="sprd-aosp"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -16,17 +16,17 @@
   <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
   <!--original fetch url was git://github.com/mozilla/-->
   <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1899109c9fd9b9e2244155c4b9e966c0a48368fc"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="887a1d7f2ab601fc40b923b4e16e6b9b48fc982e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk-specific things and forks -->
   <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
   <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <copyfile dest="Makefile" src="core/root.mk"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -16,37 +16,37 @@
   <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
   <!--original fetch url was git://github.com/mozilla/-->
   <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1899109c9fd9b9e2244155c4b9e966c0a48368fc"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="887a1d7f2ab601fc40b923b4e16e6b9b48fc982e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="b516c3e0f6770d8acb6b4dff18b39e19cb4e4731"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5e96ed318db1ba8037eb402724bc052240ac9e05"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="1342fd7b4b000ac3e76a5dfe111a0de9d710b4c8"/>
-  <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" revision="78948bc4d41c9657d7e2a1a84a21fa2a0eee2504"/>
+  <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" revision="4bbd73cde5ebfdf6d75e4de83901700a3675b6fe"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="1b26ad444462ccbd97f6319565b4735f7bd779e5"/>
   <project name="device/common" path="device/common" revision="4e1a38704dcfadef60ed2da3cfeba02a56b069d2"/>
   <project name="device/sample" path="device/sample" revision="b045905b46c8b4ee630d0c2aee7db63eaec722d9"/>
   <project name="platform/abi/cpp" path="abi/cpp" revision="fa873799be5cf200f1d1d32a63953949c9dcdda8"/>
   <project name="platform/bionic" path="bionic" revision="0d910c2a305f6b223b7b879a4532df1d0ec73030"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="b279a60d33785df6d08065a2b082eeecb64af759"/>
   <project name="platform/external/aac" path="external/aac" revision="67e322018c4ae56213dec4083f1e37cf7e087a05"/>
   <project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="72573746f78ed1bce49e93737f33d0248ee6da97"/>
@@ -123,17 +123,17 @@
   <project name="platform/libcore" path="libcore" revision="3552ed1686d04a65b85e56ccc24ff3fcf77725e6"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="4792069e90385889b0638e97ae62c67cdf274e22"/>
   <project name="platform/ndk" path="ndk" revision="7666b97bbaf1d645cdd6b4430a367b7a2bb53369"/>
   <project name="platform/prebuilts/misc" path="prebuilts/misc" revision="f6ab40b3257abc07741188fd173ac392575cc8d2"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="e52099755d0bd3a579130eefe8e58066cc6c0cb6"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="842e33e43a55ea44833b9e23e4d180fa17c843af"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5db24726f0f42124304195a6bdea129039eeeaeb"/>
   <project name="platform/system/bluetooth" path="system/bluetooth" revision="930ae098543881f47eac054677726ee4b998b2f8"/>
-  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="570531db9e81a871c421b27025ae558022b1015a"/>
+  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bb356d6505f914347690c8143dbd03af427dd07e"/>
   <project name="platform_system_core" path="system/core" remote="b2g" revision="542d1f59dc331b472307e5bd043101d14d5a3a3e"/>
   <project name="platform/system/extras" path="system/extras" revision="18c1180e848e7ab8691940481f5c1c8d22c37b3e"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform/system/media" path="system/media" revision="d90b836f66bf1d9627886c96f3a2d9c3007fbb80"/>
   <project name="platform/system/netd" path="system/netd" revision="56112dd7b811301b718d0643a82fd5cac9522073"/>
   <project name="platform/system/security" path="system/security" revision="f48ff68fedbcdc12b570b7699745abb6e7574907"/>
   <project name="platform/system/vold" path="system/vold" revision="8de05d4a52b5a91e7336e6baa4592f945a6ddbea"/>
   <default remote="caf" revision="refs/tags/android-4.3_r2.1" sync-j="4"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -16,30 +16,30 @@
   <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
   <!--original fetch url was git://github.com/mozilla/-->
   <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1899109c9fd9b9e2244155c4b9e966c0a48368fc"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="887a1d7f2ab601fc40b923b4e16e6b9b48fc982e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="b516c3e0f6770d8acb6b4dff18b39e19cb4e4731"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5e96ed318db1ba8037eb402724bc052240ac9e05"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/>
   <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
@@ -119,30 +119,30 @@
   <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="01f436c51dc68aec7cc1c85fda6e6792b2a95066"/>
   <project name="platform/libcore" path="libcore" revision="9877ade9617bb0db6e59aa2a54719a9bc92600f3"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="46c96ace65eb1ccab05bf15b9bf8e53e443039af"/>
   <project name="platform/ndk" path="ndk" revision="cb5519af32ae7b4a9c334913a612462ecd04c5d0"/>
   <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="c739cffa6394c06e099ea48879a20341b6163338"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="6aa61f8557a22039a30b42b7f283996381fd625d"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="b562b01c93de9578d5db537b6a602a38e1aaa0ce"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="387f03e815f57d536dd922706db1622bddba8d81"/>
-  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="570531db9e81a871c421b27025ae558022b1015a"/>
+  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bb356d6505f914347690c8143dbd03af427dd07e"/>
   <project name="platform/system/extras" path="system/extras" revision="5356165f67f4a81c2ef28671c13697f1657590df"/>
   <project name="platform/system/media" path="system/media" revision="be0e2fe59a8043fa5200f75697df9220a99abe9d"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform/system/netd" path="system/netd" revision="36704b0da24debcab8090156568ac236315036bb"/>
   <project name="platform/system/security" path="system/security" revision="583374f69f531ba68fc3dcbff1f74893d2a96406"/>
   <project name="platform/system/vold" path="system/vold" revision="d4455b8cf361f8353e8aebac15ffd64b4aedd2b9"/>
   <project name="platform/external/icu4c" path="external/icu4c" remote="aosp" revision="b4c6379528887dc25ca9991a535a8d92a61ad6b6"/>
   <project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="2da3a2d5100f8afa1229bb50aa2a29ea0aaf8417"/>
   <project name="platform_system_core" path="system/core" remote="b2g" revision="8586f55fe4b015911b48e731b69c592ad82a0807"/>
   <default remote="caf" revision="refs/tags/android-4.4.2_r1" sync-j="4"/>
   <!-- Emulator specific things -->
   <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/>
-  <project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="58800ecb50e4e41cfb0a36cb43c82b73fb3612e5"/>
+  <project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="49f5591508df408fab7d7d8322681b004a2750f3"/>
   <project name="platform_bionic" path="bionic" remote="b2g" revision="3e85c4683c121530c1c3a48c696a569bf5f587e2"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="39bdda3051dd1d96da3ab369bc654290cb8d463c"/>
   <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="f37bd545063039e30a92f2550ae78c0e6e4e2d08"/>
   <project name="platform_external_wpa_supplicant_8" path="external/wpa_supplicant_8" remote="b2g" revision="0c6a6547cd1fd302fa2b0f6e375654df36bf0ec4"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="c0dd0098328f3992e1ca09d6d4355729243863d5"/>
   <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="5f4b68c799927b6e078f987b12722c3a6ccd4a45"/>
   <project name="platform/development" path="development" revision="5968ff4e13e0d696ad8d972281fc27ae5a12829b"/>
   <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="6a1bb59af65b6485b1090522f66fac95c3f9e22c"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -16,30 +16,30 @@
   <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
   <!--original fetch url was git://github.com/mozilla/-->
   <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1899109c9fd9b9e2244155c4b9e966c0a48368fc"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="887a1d7f2ab601fc40b923b4e16e6b9b48fc982e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- B2G specific things. -->
-  <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
+  <project name="platform_build" path="build" remote="b2g" revision="be4b291a90b371b41b62ade68c31ad173bb87baa">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="b516c3e0f6770d8acb6b4dff18b39e19cb4e4731"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5e96ed318db1ba8037eb402724bc052240ac9e05"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="8af5ff6f5dced9eb5a8127459df6c75d24342204"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="30915518fa7ea07166efedc191a4f40aef516fe7"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="96eee58e3389fb05a835310d6a06a6ba4486097a"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="7c8a46698171aa2e0be09edb43d15a6acf832770"/>
   <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="24b2038be8a636fd4a5d21f0abae1e466b07bcf7"/>
@@ -127,32 +127,32 @@
   <project name="platform/external/zopfli" path="external/zopfli" revision="8b994159cf3fc74a58e42fca72bc6849e6027912"/>
   <project name="platform/frameworks/native" path="frameworks/native" revision="c39bd4ee1f4b3ef92bf7a45824b77703f40a5fd4"/>
   <project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="2293192ed15b88ebe962fb5377dd197200e6472b"/>
   <project name="platform/hardware/libhardware" path="hardware/libhardware" revision="f5feb2aa2047fbaf13be448fe8d06bff3ccf7b84"/>
   <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="8d075b4d5e9e032b18fbc8b5def63827d1b4a30d"/>
   <project name="platform/libcore" path="libcore" revision="bdec7d684c083760bef7bc4ba2429cceccaaf7d0"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="27bcc086236cedd31c056303e255c6d0ea3d4a50"/>
   <project name="platform/ndk" path="ndk" revision="42e85f81cc6c74af145056ee80b06e520cccb9a7"/>
-  <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="179d485578c6907c0daf343a3bd7bc53b5e137a1"/>
+  <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="25b96077aeae7bd0e3a5e7c284fb636664337013"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="1d080491f26dfdfd76d5bbc3e6b40c660e8565af"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="61a10cbd19d6b7fc052a8cb92dfa1b37b93754f3"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="9e892a67a01671f312c76b0880dedaa6ba478148"/>
-  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="570531db9e81a871c421b27025ae558022b1015a"/>
+  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bb356d6505f914347690c8143dbd03af427dd07e"/>
   <project name="platform/system/extras" path="system/extras" revision="47fa016e2248b80aebd5928402c7409f8e0ca64e"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform/system/media" path="system/media" revision="70bfebc66d9c6a4c614a8c7efde90e8e7e1d8641"/>
   <project name="platform/system/netd" path="system/netd" revision="d113f0ceefa9ce29eb3c86e2d23c7417a70b4048"/>
   <project name="platform/system/security" path="system/security" revision="94e1617f6f2bc2286d005e79cffa6bf0721b06b3"/>
   <project name="platform/system/vold" path="system/vold" revision="c065e301e38ea0c241164e2a373e1ecefbeaf2ec"/>
-  <project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="6971327dda6bead878724ac1c767ee2d23a2a9e1"/>
-  <project name="platform_frameworks_base" path="frameworks/base" remote="b2g" revision="04e26ebdc36ca83f4ee3e9e2082b3fcf04c5b971"/>
-  <project name="platform_frameworks_wilhelm" path="frameworks/wilhelm" remote="b2g" revision="0dbf5baafadf6d233c0a29e392fa3293f0121673"/>
-  <project name="platform_system_core" path="system/core" remote="b2g" revision="f594bc64eacac490857748b1139ffcb34c856bbd"/>
-  <project name="platform_external_sepolicy" path="external/sepolicy" remote="b2g" revision="3f6be48a46c54dd8cacaf216ab5b145de5ffefd2"/>
+  <project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="479a404164986b3e95212eecdae7e67da4fba9ed"/>
+  <project name="platform_frameworks_base" path="frameworks/base" remote="b2g" revision="10592803994aa01fa3dc0d0bd36d0d29f006d779"/>
+  <project name="platform_frameworks_wilhelm" path="frameworks/wilhelm" remote="b2g" revision="174bb44bb9af7583e6337e1e1b6cc18d0217ae82"/>
+  <project name="platform_system_core" path="system/core" remote="b2g" revision="1b8322b228f717ff2a4d48fa8b44240d8e3f62bc"/>
+  <project name="platform_external_sepolicy" path="external/sepolicy" remote="b2g" revision="246c603d9fe181fa8893af7293dbc63e870fe5e0"/>
   <default remote="caf" revision="refs/tags/android-5.1.0_r1" sync-j="4"/>
   <!-- Emulator specific things -->
   <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="fe7df1bc8dd0fd71571505d7be1c31a4ad1e40fb"/>
   <project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="dc8c7896562bf63190befb3e6b21310a4b7144fa"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="59e434cbecc02653f44cedeb2ef5cc88dc8bb61b"/>
   <project name="platform_external_wpa_supplicant_8" path="external/wpa_supplicant_8" remote="b2g" revision="cbda29a58abc4ea1f7f4611fe354ab67b606219d"/>
   <project name="platform/development" path="development" revision="0c51f6e0aa2ee57fcb75ec3b2ff6bf754cece63e"/>
   <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="2c0d193349c55337e37196a7f2d5cef37753ed3e"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -16,17 +16,17 @@
   <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
   <!--original fetch url was git://github.com/mozilla/-->
   <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1899109c9fd9b9e2244155c4b9e966c0a48368fc"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="887a1d7f2ab601fc40b923b4e16e6b9b48fc982e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk-specific things and forks -->
   <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
   <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <copyfile dest="Makefile" src="core/root.mk"/>
--- a/b2g/config/flame-kk/config.json
+++ b/b2g/config/flame-kk/config.json
@@ -37,17 +37,17 @@
         ["{workdir}/gecko/tools/rb/fix_stack_using_bpsyms.py", "gecko/tools/rb/"]
     ],
     "env": {
         "VARIANT": "userdebug",
         "MOZILLA_OFFICIAL": "1",
         "MOZ_TELEMETRY_REPORTING": "1",
         "B2G_UPDATE_CHANNEL": "nightly",
         "GAIA_KEYBOARD_LAYOUTS": "en,pt-BR,es,de,fr,pl,zh-Hans-Pinyin,zh-Hant-Zhuyin,en-Dvorak",
-        "FOTA_FINGERPRINTS": "qcom/flame/flame:4.4.2/KOT49H/eng.cltbld.20150527.043015:userdebug/test-keys"
+        "FOTA_FINGERPRINTS": "qcom/flame/flame:4.4.2/KOT49H/eng.cltbld.20150527.043015:userdebug/test-keys,qcom/flame/flame:4.4.2/KOT49H/eng.naoki.20151216.105618:userdebug/test-keys"
     },
     "b2g_manifest": "flame-kk.xml",
     "b2g_manifest_intree": true,
     "additional_source_tarballs": ["backup-flame.tar.xz"],
     "gecko_l10n_root": "https://hg.mozilla.org/l10n-central",
     "gaia": {
         "l10n": {
             "vcs": "hgtool",
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -16,31 +16,31 @@
   <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
   <!--original fetch url was git://github.com/mozilla/-->
   <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1899109c9fd9b9e2244155c4b9e966c0a48368fc"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="887a1d7f2ab601fc40b923b4e16e6b9b48fc982e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="b516c3e0f6770d8acb6b4dff18b39e19cb4e4731"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5e96ed318db1ba8037eb402724bc052240ac9e05"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/>
   <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
@@ -114,17 +114,17 @@
   <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="f0c3b4edf597c40aae4ea311575f39c8bcf203df"/>
   <project name="platform/libcore" path="libcore" revision="baf7d8068dd501cfa338d3a8b1b87216d6ce0571"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="50c4430e32849530ced32680fd6ee98963b3f7ac"/>
   <project name="platform/ndk" path="ndk" revision="e58ef003be4306bb53a8c11331146f39e4eab31f"/>
   <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="c739cffa6394c06e099ea48879a20341b6163338"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="c792f0bd9fff7aea2887c60bbb3a9bbdb534ffa3"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="69d524e80cdf3981006627c65ac85f3a871238a3"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
-  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="570531db9e81a871c421b27025ae558022b1015a"/>
+  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bb356d6505f914347690c8143dbd03af427dd07e"/>
   <project name="platform/system/extras" path="system/extras" revision="576f57b6510de59c08568b53c0fb60588be8689e"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform/system/netd" path="system/netd" revision="a6531f7befb49b1c81bc0de7e51c5482b308e1c5"/>
   <project name="platform/system/security" path="system/security" revision="ee8068b9e7bfb2770635062fc9c2035be2142bd8"/>
   <project name="platform/system/vold" path="system/vold" revision="42fa2a0f14f965970a4b629a176bbd2666edf017"/>
   <project name="platform/external/curl" path="external/curl" revision="e68addd988448959ea8157c5de637346b4180c33"/>
   <project name="platform/external/icu4c" path="external/icu4c" revision="d3ec7428eb276db43b7ed0544e09344a6014806c"/>
   <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="76c4bf4bc430a1b8317f2f21ef735867733e50cc"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "1899109c9fd9b9e2244155c4b9e966c0a48368fc", 
+        "git_revision": "887a1d7f2ab601fc40b923b4e16e6b9b48fc982e", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "cfb223aa835d5bf17ec0fd03f873b6788a149edb", 
+    "revision": "bf690aa3ffa8c291b77efda90c45ffff8f3b6778", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4-kk/sources.xml
+++ b/b2g/config/nexus-4-kk/sources.xml
@@ -16,31 +16,31 @@
   <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
   <!--original fetch url was git://github.com/mozilla/-->
   <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1899109c9fd9b9e2244155c4b9e966c0a48368fc"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="887a1d7f2ab601fc40b923b4e16e6b9b48fc982e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="b516c3e0f6770d8acb6b4dff18b39e19cb4e4731"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5e96ed318db1ba8037eb402724bc052240ac9e05"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/>
   <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
@@ -121,17 +121,17 @@
   <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="01f436c51dc68aec7cc1c85fda6e6792b2a95066"/>
   <project name="platform/libcore" path="libcore" revision="9877ade9617bb0db6e59aa2a54719a9bc92600f3"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="46c96ace65eb1ccab05bf15b9bf8e53e443039af"/>
   <project name="platform/ndk" path="ndk" revision="cb5519af32ae7b4a9c334913a612462ecd04c5d0"/>
   <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="c739cffa6394c06e099ea48879a20341b6163338"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="6aa61f8557a22039a30b42b7f283996381fd625d"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="b562b01c93de9578d5db537b6a602a38e1aaa0ce"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="387f03e815f57d536dd922706db1622bddba8d81"/>
-  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="570531db9e81a871c421b27025ae558022b1015a"/>
+  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bb356d6505f914347690c8143dbd03af427dd07e"/>
   <project name="platform/system/extras" path="system/extras" revision="5356165f67f4a81c2ef28671c13697f1657590df"/>
   <project name="platform/system/media" path="system/media" revision="be0e2fe59a8043fa5200f75697df9220a99abe9d"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform/system/netd" path="system/netd" revision="36704b0da24debcab8090156568ac236315036bb"/>
   <project name="platform/system/security" path="system/security" revision="583374f69f531ba68fc3dcbff1f74893d2a96406"/>
   <project name="platform/system/vold" path="system/vold" revision="d4455b8cf361f8353e8aebac15ffd64b4aedd2b9"/>
   <project name="platform/external/icu4c" path="external/icu4c" remote="aosp" revision="b4c6379528887dc25ca9991a535a8d92a61ad6b6"/>
   <project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="2da3a2d5100f8afa1229bb50aa2a29ea0aaf8417"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -16,38 +16,38 @@
   <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
   <!--original fetch url was git://github.com/mozilla/-->
   <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1899109c9fd9b9e2244155c4b9e966c0a48368fc"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="887a1d7f2ab601fc40b923b4e16e6b9b48fc982e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="b516c3e0f6770d8acb6b4dff18b39e19cb4e4731"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5e96ed318db1ba8037eb402724bc052240ac9e05"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="1342fd7b4b000ac3e76a5dfe111a0de9d710b4c8"/>
-  <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" revision="78948bc4d41c9657d7e2a1a84a21fa2a0eee2504"/>
+  <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" revision="4bbd73cde5ebfdf6d75e4de83901700a3675b6fe"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="1b26ad444462ccbd97f6319565b4735f7bd779e5"/>
   <project name="device/common" path="device/common" revision="4e1a38704dcfadef60ed2da3cfeba02a56b069d2"/>
   <project name="device/sample" path="device/sample" revision="b045905b46c8b4ee630d0c2aee7db63eaec722d9"/>
   <project name="platform/abi/cpp" path="abi/cpp" revision="fa873799be5cf200f1d1d32a63953949c9dcdda8"/>
   <project name="platform/bionic" path="bionic" revision="0d910c2a305f6b223b7b879a4532df1d0ec73030"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="b279a60d33785df6d08065a2b082eeecb64af759"/>
   <project name="platform/external/aac" path="external/aac" revision="67e322018c4ae56213dec4083f1e37cf7e087a05"/>
   <project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="72573746f78ed1bce49e93737f33d0248ee6da97"/>
@@ -124,17 +124,17 @@
   <project name="platform/libcore" path="libcore" revision="3552ed1686d04a65b85e56ccc24ff3fcf77725e6"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="4792069e90385889b0638e97ae62c67cdf274e22"/>
   <project name="platform/ndk" path="ndk" revision="7666b97bbaf1d645cdd6b4430a367b7a2bb53369"/>
   <project name="platform/prebuilts/misc" path="prebuilts/misc" revision="f6ab40b3257abc07741188fd173ac392575cc8d2"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="e52099755d0bd3a579130eefe8e58066cc6c0cb6"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="842e33e43a55ea44833b9e23e4d180fa17c843af"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5db24726f0f42124304195a6bdea129039eeeaeb"/>
   <project name="platform/system/bluetooth" path="system/bluetooth" revision="930ae098543881f47eac054677726ee4b998b2f8"/>
-  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="570531db9e81a871c421b27025ae558022b1015a"/>
+  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bb356d6505f914347690c8143dbd03af427dd07e"/>
   <project name="platform_system_core" path="system/core" remote="b2g" revision="542d1f59dc331b472307e5bd043101d14d5a3a3e"/>
   <project name="platform/system/extras" path="system/extras" revision="18c1180e848e7ab8691940481f5c1c8d22c37b3e"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform/system/media" path="system/media" revision="d90b836f66bf1d9627886c96f3a2d9c3007fbb80"/>
   <project name="platform/system/netd" path="system/netd" revision="56112dd7b811301b718d0643a82fd5cac9522073"/>
   <project name="platform/system/security" path="system/security" revision="f48ff68fedbcdc12b570b7699745abb6e7574907"/>
   <project name="platform/system/vold" path="system/vold" revision="8de05d4a52b5a91e7336e6baa4592f945a6ddbea"/>
   <default remote="caf" revision="refs/tags/android-4.3_r2.1" sync-j="4"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -16,31 +16,31 @@
   <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
   <!--original fetch url was git://github.com/mozilla/-->
   <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1899109c9fd9b9e2244155c4b9e966c0a48368fc"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="887a1d7f2ab601fc40b923b4e16e6b9b48fc982e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- B2G specific things. -->
-  <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
+  <project name="platform_build" path="build" remote="b2g" revision="be4b291a90b371b41b62ade68c31ad173bb87baa">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="b516c3e0f6770d8acb6b4dff18b39e19cb4e4731"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5e96ed318db1ba8037eb402724bc052240ac9e05"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="8af5ff6f5dced9eb5a8127459df6c75d24342204"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="30915518fa7ea07166efedc191a4f40aef516fe7"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="96eee58e3389fb05a835310d6a06a6ba4486097a"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="7c8a46698171aa2e0be09edb43d15a6acf832770"/>
   <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="24b2038be8a636fd4a5d21f0abae1e466b07bcf7"/>
@@ -128,32 +128,32 @@
   <project name="platform/external/zopfli" path="external/zopfli" revision="8b994159cf3fc74a58e42fca72bc6849e6027912"/>
   <project name="platform/frameworks/native" path="frameworks/native" revision="c39bd4ee1f4b3ef92bf7a45824b77703f40a5fd4"/>
   <project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="2293192ed15b88ebe962fb5377dd197200e6472b"/>
   <project name="platform/hardware/libhardware" path="hardware/libhardware" revision="f5feb2aa2047fbaf13be448fe8d06bff3ccf7b84"/>
   <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="8d075b4d5e9e032b18fbc8b5def63827d1b4a30d"/>
   <project name="platform/libcore" path="libcore" revision="bdec7d684c083760bef7bc4ba2429cceccaaf7d0"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="27bcc086236cedd31c056303e255c6d0ea3d4a50"/>
   <project name="platform/ndk" path="ndk" revision="42e85f81cc6c74af145056ee80b06e520cccb9a7"/>
-  <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="179d485578c6907c0daf343a3bd7bc53b5e137a1"/>
+  <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="25b96077aeae7bd0e3a5e7c284fb636664337013"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="1d080491f26dfdfd76d5bbc3e6b40c660e8565af"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="61a10cbd19d6b7fc052a8cb92dfa1b37b93754f3"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="9e892a67a01671f312c76b0880dedaa6ba478148"/>
-  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="570531db9e81a871c421b27025ae558022b1015a"/>
+  <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bb356d6505f914347690c8143dbd03af427dd07e"/>
   <project name="platform/system/extras" path="system/extras" revision="47fa016e2248b80aebd5928402c7409f8e0ca64e"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform/system/media" path="system/media" revision="70bfebc66d9c6a4c614a8c7efde90e8e7e1d8641"/>
   <project name="platform/system/netd" path="system/netd" revision="d113f0ceefa9ce29eb3c86e2d23c7417a70b4048"/>
   <project name="platform/system/security" path="system/security" revision="94e1617f6f2bc2286d005e79cffa6bf0721b06b3"/>
   <project name="platform/system/vold" path="system/vold" revision="c065e301e38ea0c241164e2a373e1ecefbeaf2ec"/>
-  <project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="6971327dda6bead878724ac1c767ee2d23a2a9e1"/>
-  <project name="platform_frameworks_base" path="frameworks/base" remote="b2g" revision="04e26ebdc36ca83f4ee3e9e2082b3fcf04c5b971"/>
-  <project name="platform_frameworks_wilhelm" path="frameworks/wilhelm" remote="b2g" revision="0dbf5baafadf6d233c0a29e392fa3293f0121673"/>
-  <project name="platform_system_core" path="system/core" remote="b2g" revision="f594bc64eacac490857748b1139ffcb34c856bbd"/>
-  <project name="platform_external_sepolicy" path="external/sepolicy" remote="b2g" revision="3f6be48a46c54dd8cacaf216ab5b145de5ffefd2"/>
+  <project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="479a404164986b3e95212eecdae7e67da4fba9ed"/>
+  <project name="platform_frameworks_base" path="frameworks/base" remote="b2g" revision="10592803994aa01fa3dc0d0bd36d0d29f006d779"/>
+  <project name="platform_frameworks_wilhelm" path="frameworks/wilhelm" remote="b2g" revision="174bb44bb9af7583e6337e1e1b6cc18d0217ae82"/>
+  <project name="platform_system_core" path="system/core" remote="b2g" revision="1b8322b228f717ff2a4d48fa8b44240d8e3f62bc"/>
+  <project name="platform_external_sepolicy" path="external/sepolicy" remote="b2g" revision="246c603d9fe181fa8893af7293dbc63e870fe5e0"/>
   <default remote="caf" revision="refs/tags/android-5.1.0_r1" sync-j="4"/>
   <!-- Nexus 5 specific things -->
   <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="fe7df1bc8dd0fd71571505d7be1c31a4ad1e40fb"/>
   <project name="device-hammerhead" path="device/lge/hammerhead" remote="b2g" revision="1401762a4eea0b92141e8ff3100f93e9d6556fc8"/>
   <project name="device_lge_hammerhead-kernel" path="device/lge/hammerhead-kernel" remote="b2g" revision="8b3ffcfdd3d3852eca5488628f8bb2a08acbffa7"/>
   <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="5d0ae53d9588c3d70c005aec9be94af9a534de16"/>
   <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="c15b6e266136cd0cdd9b94d0bbed1962d9dd6672"/>
   <project name="platform/hardware/broadcom/libbt" path="hardware/broadcom/libbt" revision="399fe3d3c8f38c599a56becddc456133e62a5d70"/>
--- a/b2g/gaia/Makefile.in
+++ b/b2g/gaia/Makefile.in
@@ -14,9 +14,9 @@ GAIA_OPTIONS := $(if MOZ_B2GDROID, \
 
 GENERATED_DIRS += $(DIST)/bin/$(GAIA_PATH)
 
 include $(topsrcdir)/config/rules.mk
 
 libs::
 	+$(MAKE) -j1 -C $(GAIADIR) clean
 	+$(GAIA_OPTIONS) $(MAKE) -j1 -C $(GAIADIR) profile
-	(cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(abspath $(DIST))/bin/$(GAIA_PATH) && tar -xf -)
+	(cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(ABS_DIST)/bin/$(GAIA_PATH) && tar -xf -)
--- a/b2g/locales/Makefile.in
+++ b/b2g/locales/Makefile.in
@@ -14,55 +14,55 @@ SUBMAKEFILES += \
 # build non-default locales to non-default dist/ locations. Be aware!
 
 PWD := $(CURDIR)
 
 # These are defaulted to be compatible with the files the wget-en-US target
 # pulls. You may override them if you provide your own files. You _must_
 # override them when MOZ_PKG_PRETTYNAMES is defined - the defaults will not
 # work in that case.
-ZIP_IN ?= $(_ABS_DIST)/$(PACKAGE)
-WIN32_INSTALLER_IN ?= $(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
+ZIP_IN ?= $(ABS_DIST)/$(PACKAGE)
+WIN32_INSTALLER_IN ?= $(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
 RETRIEVE_WINDOWS_INSTALLER = 1
 
 MOZ_LANGPACK_EID=langpack-$(AB_CD)@b2g.mozilla.org
 
 L10N_PREF_JS_EXPORTS = $(call MERGE_FILE,b2g-l10n.js)
 L10N_PREF_JS_EXPORTS_PATH = $(FINAL_TARGET)/$(PREF_DIR)
 L10N_PREF_JS_EXPORTS_FLAGS = $(PREF_PPFLAGS) --silence-missing-directive-warnings
 PP_TARGETS += L10N_PREF_JS_EXPORTS
 
 ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT)))
-MOZ_PKG_MAC_DSSTORE=$(_ABS_DIST)/branding/dsstore
-MOZ_PKG_MAC_BACKGROUND=$(_ABS_DIST)/branding/background.png
-MOZ_PKG_MAC_ICON=$(_ABS_DIST)/branding/disk.icns
+MOZ_PKG_MAC_DSSTORE=$(ABS_DIST)/branding/dsstore
+MOZ_PKG_MAC_BACKGROUND=$(ABS_DIST)/branding/background.png
+MOZ_PKG_MAC_ICON=$(ABS_DIST)/branding/disk.icns
 MOZ_PKG_MAC_EXTRA=--symlink '/Applications:/ '
 endif
 
 ifeq (WINNT,$(OS_ARCH))
 UNINSTALLER_PACKAGE_HOOK = $(RM) -r $(STAGEDIST)/uninstall; \
     $(NSINSTALL) -D $(STAGEDIST)/uninstall; \
     cp ../installer/windows/l10ngen/helper.exe $(STAGEDIST)/uninstall; \
-    $(RM) $(_ABS_DIST)/l10n-stage/setup.exe; \
-    cp ../installer/windows/l10ngen/setup.exe $(_ABS_DIST)/l10n-stage; \
+    $(RM) $(ABS_DIST)/l10n-stage/setup.exe; \
+    cp ../installer/windows/l10ngen/setup.exe $(ABS_DIST)/l10n-stage; \
     $(NULL)
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 include $(topsrcdir)/toolkit/locales/l10n.mk
 
 $(STAGEDIST): $(DIST)/branding
 
 $(DIST)/branding:
 	$(NSINSTALL) -D $@
 
 libs::
 	@if test -f '$(LOCALE_SRCDIR)/existing-profile-defaults.js'; then \
-	  $(PYTHON) -m mozbuild.action.preprocessor $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(MOZ_DEBUG_DEFINES) \
+	  $(PYTHON) -m mozbuild.action.preprocessor $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) \
 	    $(LOCALE_SRCDIR)/existing-profile-defaults.js -o $(FINAL_TARGET)/defaults/existing-profile-defaults.js; \
 	fi
 
 NO_JA_JP_MAC_AB_CD := $(if $(filter ja-JP-mac, $(AB_CD)),ja,$(AB_CD))
 
 libs-%:
 	$(NSINSTALL) -D $(DIST)/install
 	@$(MAKE) -C ../../toolkit/locales libs-$*
@@ -70,17 +70,17 @@ libs-%:
 	@$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=$(PREF_DIR)
 	@$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales AB_CD=$* XPI_NAME=locale-$*
 
 # Tailored target to just add the chrome processing for multi-locale builds
 chrome-%:
 	@$(MAKE) chrome AB_CD=$*
 	@$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales chrome AB_CD=$*
 
-repackage-win32-installer: WIN32_INSTALLER_OUT=$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
+repackage-win32-installer: WIN32_INSTALLER_OUT=$(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
 repackage-win32-installer: $(call ESCAPE_SPACE,$(WIN32_INSTALLER_IN)) $(SUBMAKEFILES) libs-$(AB_CD)
 	@echo 'Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT).'
 	$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY) export
 	$(MAKE) -C ../installer/windows CONFIG_DIR=l10ngen l10ngen/setup.exe l10ngen/7zSD.sfx
 	$(MAKE) repackage-zip \
 	  AB_CD=$(AB_CD) \
 	  MOZ_PKG_FORMAT=SFX7Z \
 	  ZIP_IN='$(WIN32_INSTALLER_IN)' \
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -85,23 +85,23 @@ endif
 LPROJ := Contents/Resources/$(LPROJ_ROOT).lproj
 
 clean clobber repackage::
 	$(RM) -r $(dist_dest)
 
 MAC_BUNDLE_VERSION = $(shell $(PYTHON) $(srcdir)/macversion.py --version=$(MOZ_APP_VERSION) --buildid=$(DEPTH)/config/buildid)
 
 .PHONY: repackage
-tools repackage:: $(PROGRAM)
+tools repackage:: $(DIST)/bin/$(MOZ_APP_NAME)
 	$(MKDIR) -p $(dist_dest)/Contents/MacOS
 	$(MKDIR) -p $(dist_dest)/$(LPROJ)
 	rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents $(dist_dest) --exclude English.lproj
 	rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(dist_dest)/$(LPROJ)
 	sed -e 's/%APP_VERSION%/$(MOZ_APP_VERSION)/' -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' -e 's/%MOZ_MACBUNDLE_ID%/$(MOZ_MACBUNDLE_ID)/' -e 's/%MAC_BUNDLE_VERSION%/$(MAC_BUNDLE_VERSION)/' $(srcdir)/macbuild/Contents/Info.plist.in > $(dist_dest)/Contents/Info.plist
 	sed -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(dist_dest)/$(LPROJ)/InfoPlist.strings
 	rsync -a --exclude-from='$(srcdir)/macbuild/Contents/MacOS-files.in' $(DIST)/bin/ $(dist_dest)/Contents/Resources
 	rsync -a --include-from='$(srcdir)/macbuild/Contents/MacOS-files.in' --exclude '*' $(DIST)/bin/ $(dist_dest)/Contents/MacOS
-	$(RM) $(dist_dest)/Contents/MacOS/$(PROGRAM)
-	rsync -aL $(PROGRAM) $(dist_dest)/Contents/MacOS
+	$(RM) $(dist_dest)/Contents/MacOS/$(MOZ_APP_NAME)
+	rsync -aL $(DIST)/bin/$(MOZ_APP_NAME) $(dist_dest)/Contents/MacOS
 	cp -RL $(DIST)/branding/firefox.icns $(dist_dest)/Contents/Resources/firefox.icns
 	cp -RL $(DIST)/branding/document.icns $(dist_dest)/Contents/Resources/document.icns
 	printf APPLMOZB > $(dist_dest)/Contents/PkgInfo
 endif
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -953,21 +953,22 @@ pref("browser.safebrowsing.downloads.ena
 pref("browser.safebrowsing.downloads.remote.enabled", true);
 pref("browser.safebrowsing.downloads.remote.timeout_ms", 10000);
 pref("browser.safebrowsing.debug", false);
 
 pref("browser.safebrowsing.provider.google.lists", "goog-badbinurl-shavar,goog-downloadwhite-digest256,goog-phish-shavar,goog-malware-shavar,goog-unwanted-shavar");
 pref("browser.safebrowsing.provider.google.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
 pref("browser.safebrowsing.provider.google.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
 pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
-pref("browser.safebrowsing.provider.google.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
 
 pref("browser.safebrowsing.reportPhishMistakeURL", "https://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%&url=");
 pref("browser.safebrowsing.reportPhishURL", "https://%LOCALE%.phish-report.mozilla.com/?hl=%LOCALE%&url=");
 pref("browser.safebrowsing.reportMalwareMistakeURL", "https://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%&url=");
+pref("browser.safebrowsing.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
+
 #ifdef MOZILLA_OFFICIAL
 // Normally the "client ID" sent in updates is appinfo.name, but for
 // official Firefox releases from Mozilla we use a special identifier.
 pref("browser.safebrowsing.id", "navclient-auto-ffox");
 #endif
 
 // Name of the about: page contributed by safebrowsing to handle display of error
 // pages on phishing/malware hits.  (bug 399233)
@@ -1009,18 +1010,16 @@ pref("browser.selfsupport.url", "https:/
 pref("browser.sessionstore.resume_from_crash", true);
 pref("browser.sessionstore.resume_session_once", false);
 
 // minimal interval between two save operations in milliseconds
 pref("browser.sessionstore.interval", 15000);
 // on which sites to save text data, POSTDATA and cookies
 // 0 = everywhere, 1 = unencrypted sites, 2 = nowhere
 pref("browser.sessionstore.privacy_level", 0);
-// the same as browser.sessionstore.privacy_level, but for saving deferred session data
-pref("browser.sessionstore.privacy_level_deferred", 1);
 // how many tabs can be reopened (per window)
 pref("browser.sessionstore.max_tabs_undo", 10);
 // how many windows can be reopened (per session) - on non-OS X platforms this
 // pref may be ignored when dealing with pop-up windows to ensure proper startup
 pref("browser.sessionstore.max_windows_undo", 3);
 // number of crashes that can occur before the about:sessionrestore page is displayed
 // (this pref has no effect if more than 6 hours have passed since the last crash)
 pref("browser.sessionstore.max_resumed_crashes", 1);
@@ -1400,18 +1399,18 @@ pref("security.mixed_content.block_activ
 pref("security.insecure_password.ui.enabled", true);
 #else
 pref("security.insecure_password.ui.enabled", false);
 #endif
 
 // 1 = allow MITM for certificate pinning checks.
 pref("security.cert_pinning.enforcement_level", 1);
 
-// 2 = allow SHA-1 only before 2016-01-01
-pref("security.pki.sha1_enforcement_level", 2);
+// 0 = allow SHA-1
+pref("security.pki.sha1_enforcement_level", 0);
 
 // Required blocklist freshness for OneCRL OCSP bypass
 // (default is 1.25x extensions.blocklist.interval, or 30 hours)
 pref("security.onecrl.maximum_staleness_in_seconds", 108000);
 
 // Override the Gecko-default value of false for Firefox.
 pref("plain_text.wrap_long_lines", true);
 
@@ -1497,17 +1496,18 @@ pref("ui.key.menuAccessKeyFocuses", true
 #endif
 
 // Encrypted media extensions.
 pref("media.eme.enabled", true);
 pref("media.eme.apiVisible", true);
 
 // Decode using Gecko Media Plugins in <video>, if a system decoder is not
 // availble and the preferred GMP is available.
-pref("media.gmp.decoder.enabled", true);
+// NOTE: Disabled until Bug 1236756 is fixed by Adobe.
+pref("media.gmp.decoder.enabled", false);
 
 // If decoding-via-GMP is turned on for <video>, use Adobe's GMP for decoding,
 // if it's available. Note: We won't fallback to another GMP if Adobe's is not
 // installed.
 pref("media.gmp.decoder.aac", 2);
 pref("media.gmp.decoder.h264", 2);
 
 // Whether we should run a test-pattern through EME GMPs before assuming they'll
@@ -1542,18 +1542,16 @@ pref("experiments.enabled", true);
 pref("experiments.manifest.fetchIntervalSeconds", 86400);
 pref("experiments.manifest.uri", "https://telemetry-experiment.cdn.mozilla.net/manifest/v1/firefox/%VERSION%/%CHANNEL%");
 // Whether experiments are supported by the current application profile.
 pref("experiments.supported", true);
 
 // Enable GMP support in the addon manager.
 pref("media.gmp-provider.enabled", true);
 
-pref("browser.apps.URL", "https://marketplace.firefox.com/discovery/");
-
 #ifdef NIGHTLY_BUILD
 pref("browser.polaris.enabled", false);
 pref("privacy.trackingprotection.ui.enabled", false);
 #endif
 pref("privacy.trackingprotection.introCount", 0);
 pref("privacy.trackingprotection.introURL", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/tracking-protection/start/");
 
 // Enable Contextual Identity Containers
@@ -1568,27 +1566,23 @@ pref("browser.tabs.remote.autostart.2", 
 #endif
 
 // For the about:tabcrashed page
 pref("browser.tabs.crashReporting.sendReport", true);
 pref("browser.tabs.crashReporting.includeURL", false);
 pref("browser.tabs.crashReporting.emailMe", false);
 pref("browser.tabs.crashReporting.email", "");
 
-#ifdef NIGHTLY_BUILD
 #ifndef MOZ_MULET
 pref("layers.async-pan-zoom.enabled", true);
 #endif
-#endif
 
-#ifdef E10S_TESTING_ONLY
 // Enable e10s add-on interposition by default.
 pref("extensions.interposition.enabled", true);
 pref("extensions.interposition.prefetching", true);
-#endif
 
 pref("browser.defaultbrowser.notificationbar", false);
 
 // How often to check for CPOW timeouts. CPOWs are only timed out by
 // the hang monitor.
 pref("dom.ipc.cpow.timeout", 500);
 
 // Enable e10s hang monitoring (slow script checking and plugin hang
@@ -1612,23 +1606,23 @@ pref("reader.parse-node-limit", 0);
 pref("reader.errors.includeURLs", true);
 
 pref("view_source.tab", true);
 
 pref("dom.serviceWorkers.enabled", true);
 pref("dom.serviceWorkers.interception.enabled", true);
 pref("dom.serviceWorkers.openWindow.enabled", true);
 
-#ifndef RELEASE_BUILD
 // Enable Push API.
 pref("dom.push.enabled", true);
-#endif
 
 // These are the thumbnail width/height set in about:newtab.
 // If you change this, ENSURE IT IS THE SAME SIZE SET
 // by about:newtab. These values are in CSS pixels.
 pref("toolkit.pageThumbs.minWidth", 280);
 pref("toolkit.pageThumbs.minHeight", 190);
 
 #ifdef NIGHTLY_BUILD
 // Enable speech synthesis, only Nightly for now
 pref("media.webspeech.synth.enabled", true);
 #endif
+
+pref("browser.esedbreader.loglevel", "Error");
--- a/browser/base/content/abouthome/aboutHome.css
+++ b/browser/base/content/abouthome/aboutHome.css
@@ -306,20 +306,16 @@ body[narrow] #restorePreviousSession {
 #bookmarks::before {
   content: url("chrome://browser/content/abouthome/bookmarks.png");
 }
 
 #history::before {
   content: url("chrome://browser/content/abouthome/history.png");
 }
 
-#apps::before {
-  content: url("chrome://browser/content/abouthome/apps.png");
-}
-
 #addons::before {
   content: url("chrome://browser/content/abouthome/addons.png");
 }
 
 #sync::before {
   content: url("chrome://browser/content/abouthome/sync.png");
 }
 
@@ -410,20 +406,16 @@ body[narrow] #restorePreviousSession::be
   #bookmarks::before {
     content: url("chrome://browser/content/abouthome/bookmarks@2x.png");
   }
 
   #history::before {
     content: url("chrome://browser/content/abouthome/history@2x.png");
   }
 
-  #apps::before {
-    content: url("chrome://browser/content/abouthome/apps@2x.png");
-  }
-
   #addons::before {
     content: url("chrome://browser/content/abouthome/addons@2x.png");
   }
 
   #sync::before {
     content: url("chrome://browser/content/abouthome/sync@2x.png");
   }
 
--- a/browser/base/content/abouthome/aboutHome.xhtml
+++ b/browser/base/content/abouthome/aboutHome.xhtml
@@ -58,17 +58,16 @@
       </div>
     </div>
     <div class="spacer"/>
 
     <div id="launcher">
       <button class="launchButton" id="downloads">&abouthome.downloadsButton.label;</button>
       <button class="launchButton" id="bookmarks">&abouthome.bookmarksButton.label;</button>
       <button class="launchButton" id="history">&abouthome.historyButton.label;</button>
-      <button class="launchButton" id="apps">&abouthome.appsButton2.label;</button>
       <button class="launchButton" id="addons">&abouthome.addonsButton.label;</button>
       <button class="launchButton" id="sync">&abouthome.syncButton.label;</button>
 #ifdef XP_WIN
       <button class="launchButton" id="settings">&abouthome.preferencesButtonWin.label;</button>
 #else
       <button class="launchButton" id="settings">&abouthome.preferencesButtonUnix.label;</button>
 #endif
       <div id="restorePreviousSessionSeparator"/>
deleted file mode 100644
index 79fc95d49ff1c848c71a2686885ecdf758a9a32d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index cbe7a6d5364a3bd173d1c680981777e30f84c16e..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/base/content/browser-feeds.js
+++ b/browser/base/content/browser-feeds.js
@@ -12,22 +12,22 @@ var FeedHandler = {
    * or when the user clicks the feed button when the page contains multiple
    * feeds.
    * Builds a menu of unique feeds associated with the page, and if there
    * is only one, shows the feed inline in the browser window.
    * @param   container
    *          The feed list container (menupopup or subview) to be populated.
    * @param   isSubview
    *          Whether we're creating a subview (true) or menu (false/undefined)
-   * @returns true if the menu/subview should be shown, false if there was only
+   * @return  true if the menu/subview should be shown, false if there was only
    *          one feed and the feed should be shown inline in the browser
    *          window (do not show the menupopup/subview).
    */
-  buildFeedList: function(container, isSubview) {
-    var feeds = gBrowser.selectedBrowser.feeds;
+  buildFeedList(container, isSubview) {
+    let feeds = gBrowser.selectedBrowser.feeds;
     if (!isSubview && feeds == null) {
       // XXX hack -- menu opening depends on setting of an "open"
       // attribute, and the menu refuses to open if that attribute is
       // set (because it thinks it's already open).  onpopupshowing gets
       // called after the attribute is unset, and it doesn't get unset
       // if we return false.  so we unset it here; otherwise, the menu
       // refuses to work past this point.
       container.parentNode.removeAttribute("open");
@@ -40,21 +40,21 @@ var FeedHandler = {
         continue;
       container.removeChild(node);
     }
 
     if (!feeds || feeds.length <= 1)
       return false;
 
     // Build the menu showing the available feed choices for viewing.
-    var itemNodeType = isSubview ? "toolbarbutton" : "menuitem";
+    let itemNodeType = isSubview ? "toolbarbutton" : "menuitem";
     for (let feedInfo of feeds) {
-      var item = document.createElement(itemNodeType);
-      var baseTitle = feedInfo.title || feedInfo.href;
-      var labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
+      let item = document.createElement(itemNodeType);
+      let baseTitle = feedInfo.title || feedInfo.href;
+      let labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
       item.setAttribute("label", labelStr);
       item.setAttribute("feed", feedInfo.href);
       item.setAttribute("tooltiptext", feedInfo.href);
       item.setAttribute("crop", "center");
       let className = "feed-" + itemNodeType;
       if (isSubview) {
         className += " subviewbutton";
       }
@@ -72,33 +72,33 @@ var FeedHandler = {
    *   4. Page has multiple feeds and user selects from Subscribe submenu
    * @param   href
    *          The feed to subscribe to. May be null, in which case the
    *          event target's feed attribute is examined.
    * @param   event
    *          The event this method is handling. Used to decide where
    *          to open the preview UI. (Optional, unless href is null)
    */
-  subscribeToFeed: function(href, event) {
+  subscribeToFeed(href, event) {
     // Just load the feed in the content area to either subscribe or show the
     // preview UI
     if (!href)
       href = event.target.getAttribute("feed");
     urlSecurityCheck(href, gBrowser.contentPrincipal,
                      Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
-    var feedURI = makeURI(href, document.characterSet);
+    let feedURI = makeURI(href, document.characterSet);
     // Use the feed scheme so X-Moz-Is-Feed will be set
     // The value doesn't matter
     if (/^https?$/.test(feedURI.scheme))
       href = "feed:" + href;
     this.loadFeed(href, event);
   },
 
-  loadFeed: function(href, event) {
-    var feeds = gBrowser.selectedBrowser.feeds;
+  loadFeed(href, event) {
+    let feeds = gBrowser.selectedBrowser.feeds;
     try {
       openUILink(href, event, { ignoreAlt: true });
     }
     finally {
       // We might default to a livebookmarks modal dialog,
       // so reset that if the user happens to click it again
       gBrowser.selectedBrowser.feeds = feeds;
     }
@@ -113,24 +113,24 @@ var FeedHandler = {
     delete this._feedMenupopup;
     return this._feedMenupopup = document.getElementById("multipleFeedsMenuState");
   },
 
   /**
    * Update the browser UI to show whether or not feeds are available when
    * a page is loaded or the user switches tabs to a page that has feeds.
    */
-  updateFeeds: function() {
+  updateFeeds() {
     if (this._updateFeedTimeout)
       clearTimeout(this._updateFeedTimeout);
 
-    var feeds = gBrowser.selectedBrowser.feeds;
-    var haveFeeds = feeds && feeds.length > 0;
+    let feeds = gBrowser.selectedBrowser.feeds;
+    let haveFeeds = feeds && feeds.length > 0;
 
-    var feedButton = document.getElementById("feed-button");
+    let feedButton = document.getElementById("feed-button");
     if (feedButton) {
       if (haveFeeds) {
         feedButton.removeAttribute("disabled");
       } else {
         feedButton.setAttribute("disabled", "true");
       }
     }
 
@@ -147,37 +147,206 @@ var FeedHandler = {
     } else {
       this._feedMenuitem.setAttribute("feed", feeds[0].href);
       this._feedMenuitem.removeAttribute("disabled");
       this._feedMenuitem.removeAttribute("hidden");
       this._feedMenupopup.setAttribute("hidden", "true");
     }
   },
 
-  addFeed: function(link, browserForLink) {
+  addFeed(link, browserForLink) {
     if (!browserForLink.feeds)
       browserForLink.feeds = [];
 
     browserForLink.feeds.push({ href: link.href, title: link.title });
 
     // If this addition was for the current browser, update the UI. For
     // background browsers, we'll update on tab switch.
     if (browserForLink == gBrowser.selectedBrowser) {
       // Batch updates to avoid updating the UI for multiple onLinkAdded events
       // fired within 100ms of each other.
       if (this._updateFeedTimeout)
         clearTimeout(this._updateFeedTimeout);
       this._updateFeedTimeout = setTimeout(this.updateFeeds.bind(this), 100);
     }
   },
 
+   /**
+   * Get the human-readable display name of a file. This could be the
+   * application name.
+   * @param   file
+   *          A nsIFile to look up the name of
+   * @return  The display name of the application represented by the file.
+   */
+  _getFileDisplayName(file) {
+    switch (AppConstants.platform) {
+      case "win":
+        if (file instanceof Ci.nsILocalFileWin) {
+          try {
+            return file.getVersionInfoField("FileDescription");
+          } catch (e) {}
+        }
+        break;
+      case "macosx":
+        if (file instanceof Ci.nsILocalFileMac) {
+          try {
+            return file.bundleDisplayName;
+          } catch (e) {}
+        }
+        break;
+    }
+
+    return file.leafName;
+  },
+
+  chooseClientApp(aTitle, aPrefName, aBrowser) {
+    let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+
+    fp.init(window, aTitle, Ci.nsIFilePicker.modeOpen);
+    fp.appendFilters(Ci.nsIFilePicker.filterApps);
+
+    fp.open((aResult) => {
+      if (aResult == Ci.nsIFilePicker.returnOK) {
+        let selectedApp = fp.file;
+        if (selectedApp) {
+          // XXXben - we need to compare this with the running instance
+          //          executable just don't know how to do that via script
+          // XXXmano TBD: can probably add this to nsIShellService
+          let appName = "";
+          switch (AppConstants.platform) {
+            case "win":
+              appName = AppConstants.MOZ_APP_NAME + ".exe";
+              break;
+            case "macosx":
+              appName = AppConstants.MOZ_MACBUNDLE_NAME;
+              break;
+            default:
+              appName = AppConstants.MOZ_APP_NAME + "-bin";
+              break;
+          }
+
+          if (fp.file.leafName != appName) {
+            Services.prefs.setComplexValue(aPrefName, Ci.nsILocalFile, selectedApp);
+            aBrowser.messageManager.sendAsyncMessage("FeedWriter:SetApplicationLauncherMenuItem",
+                                                    { name: this._getFileDisplayName(selectedApp),
+                                                      type: "SelectedAppMenuItem" });
+          }
+        }
+      }
+    });
+
+  },
+
+  executeClientApp(aSpec, aTitle, aSubtitle, aFeedHandler) {
+    // aFeedHandler is either "default", indicating the system default reader, or a pref-name containing
+    // an nsILocalFile pointing to the feed handler's executable.
+
+    let clientApp = null;
+    if (aFeedHandler == "default") {
+      clientApp = Cc["@mozilla.org/browser/shell-service;1"]
+                    .getService(Ci.nsIShellService)
+                    .defaultFeedReader;
+    } else {
+      clientApp = Services.prefs.getComplexValue(aFeedHandler, Ci.nsILocalFile);
+    }
+
+    // For the benefit of applications that might know how to deal with more
+    // URLs than just feeds, send feed: URLs in the following format:
+    //
+    // http urls: replace scheme with feed, e.g.
+    // http://foo.com/index.rdf -> feed://foo.com/index.rdf
+    // other urls: prepend feed: scheme, e.g.
+    // https://foo.com/index.rdf -> feed:https://foo.com/index.rdf
+    let feedURI = NetUtil.newURI(aSpec);
+    if (feedURI.schemeIs("http")) {
+      feedURI.scheme = "feed";
+      aSpec = feedURI.spec;
+    } else {
+      aSpec = "feed:" + aSpec;
+    }
+
+    // Retrieving the shell service might fail on some systems, most
+    // notably systems where GNOME is not installed.
+    try {
+      let ss = Cc["@mozilla.org/browser/shell-service;1"]
+                 .getService(Ci.nsIShellService);
+      ss.openApplicationWithURI(clientApp, aSpec);
+    } catch(e) {
+      // If we couldn't use the shell service, fallback to using a
+      // nsIProcess instance
+      let p = Cc["@mozilla.org/process/util;1"]
+                .createInstance(Ci.nsIProcess);
+      p.init(clientApp);
+      p.run(false, [aSpec], 1);
+    }
+  },
+
   init() {
+    window.messageManager.addMessageListener("FeedWriter:ChooseClientApp", this);
+    window.messageManager.addMessageListener("FeedWriter:RequestClientAppName", this);
+    window.messageManager.addMessageListener("FeedWriter:SetFeedCharPref", this);
+    window.messageManager.addMessageListener("FeedWriter:SetFeedComplexString", this);
     window.messageManager.addMessageListener("FeedWriter:ShownFirstRun", this);
+
+    Services.ppmm.addMessageListener("FeedConverter:ExecuteClientApp", this);
+  },
+
+  uninit() {
+    Services.ppmm.removeMessageListener("FeedConverter:ExecuteClientApp", this);
   },
 
   receiveMessage(msg) {
     switch (msg.name) {
+      case "FeedWriter:ChooseClientApp":
+        this.chooseClientApp(msg.data.title, msg.data.prefName, msg.target);
+        break;
+      case "FeedWriter:RequestClientAppName":
+        let selectedClientApp;
+        try {
+          selectedClientApp = Services.prefs.getComplexValue(msg.data.feedTypePref, Ci.nsILocalFile);
+        } catch (ex) {
+          // Just do nothing, then we won't bother populating
+        }
+
+        let defaultClientApp = null;
+        try {
+          // This can sometimes not exist
+          defaultClientApp = Cc["@mozilla.org/browser/shell-service;1"]
+                               .getService(Ci.nsIShellService)
+                               .defaultFeedReader;
+        } catch(ex) {
+          // Just do nothing, then we don't bother populating
+        }
+
+        if (selectedClientApp && selectedClientApp.exists()) {
+          if (defaultClientApp && selectedClientApp.path != defaultClientApp.path) {
+            // Only set the default menu item if it differs from the selected one
+            msg.target.messageManager
+               .sendAsyncMessage("FeedWriter:SetApplicationLauncherMenuItem",
+                                { name: this._getFileDisplayName(defaultClientApp),
+                                  type: "DefaultAppMenuItem" });
+          }
+          msg.target.messageManager
+             .sendAsyncMessage("FeedWriter:SetApplicationLauncherMenuItem",
+                              { name: this._getFileDisplayName(selectedClientApp),
+                                type: "SelectedAppMenuItem" });
+        }
+        break;
       case "FeedWriter:ShownFirstRun":
         Services.prefs.setBoolPref("browser.feeds.showFirstRunUI", false);
         break;
+      case "FeedWriter:SetFeedCharPref":
+        Services.prefs.setCharPref(msg.data.pref, msg.data.value);
+        break;
+      case "FeedWriter:SetFeedComplexString": {
+        let supportsString = Cc["@mozilla.org/supports-string;1"].
+                             createInstance(Ci.nsISupportsString);
+        supportsString.data = msg.data.value;
+        Services.prefs.setComplexValue(msg.data.pref, Ci.nsISupportsString, supportsString);
+        break;
+      }
+      case "FeedConverter:ExecuteClientApp":
+        this.executeClientApp(msg.data.spec, msg.data.title,
+                              msg.data.subtitle, msg.data.feedHandler);
+        break;
     }
   },
 };
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -487,20 +487,16 @@
                         accesskey="&downloads.accesskey;"
                         key="key_openDownloads"
                         command="Tools:Downloads"/>
               <menuitem id="menu_openAddons"
                         label="&addons.label;"
                         accesskey="&addons.accesskey;"
                         key="key_openAddons"
                         command="Tools:Addons"/>
-              <menuitem id="menu_openApps"
-                        label="&webapps.label;"
-                        accesskey="&webapps.accesskey;"
-                        oncommand="BrowserOpenApps();"/>
 
               <!-- only one of sync-setup, sync-syncnowitem or sync-reauthitem will be showing at once -->
               <menuitem id="sync-setup"
                         label="&syncSignIn.label;"
                         accesskey="&syncSignIn.accesskey;"
                         observes="sync-setup-state"
                         oncommand="gSyncUI.openSetup(null, 'menubar')"/>
               <menuitem id="sync-syncnowitem"
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -734,18 +734,16 @@ HistoryMenu.prototype = {
     if (!menuitem)
       return;
 
     if (!PlacesUIUtils.shouldShowTabsFromOtherComputersMenuitem()) {
       menuitem.setAttribute("hidden", true);
       return;
     }
 
-    let enabled = PlacesUIUtils.shouldEnableTabsFromOtherComputersMenuitem();
-    menuitem.setAttribute("disabled", !enabled);
     menuitem.setAttribute("hidden", false);
   },
 
   _onPopupShowing: function HM__onPopupShowing(aEvent) {
     PlacesMenu.prototype._onPopupShowing.apply(this, arguments);
 
     // Don't handle events for submenus.
     if (aEvent.target != aEvent.currentTarget)
@@ -1812,8 +1810,49 @@ var BookmarkingUI = {
     if (aNode.getAttribute("label") != this._starButtonLabel)
       aNode.setAttribute("label", this._starButtonLabel);
   },
 
   QueryInterface: XPCOMUtils.generateQI([
     Ci.nsINavBookmarkObserver
   ])
 };
+
+var AutoShowBookmarksToolbar = {
+  init() {
+    PlacesUtils.addLazyBookmarkObserver(this, false);
+  },
+
+  uninit() {
+    PlacesUtils.removeLazyBookmarkObserver(this);
+  },
+
+  onItemAdded(aItemId, aParentId, aIndex, aItemType, aURI, aTitle, aDateAdded,
+              aGuid, aParentGuid) {
+    this._autoshow(aParentGuid);
+  },
+  onBeginUpdateBatch() {},
+  onEndUpdateBatch() {},
+  onItemRemoved() {},
+  onItemChanged() {},
+  onItemVisited() {},
+  onItemMoved(aItemId, aOldParent, aOldIndex, aNewParent, aNewIndex, aItemType,
+              aGuid, aOldParentGuid, aNewParentGuid) {
+    this._autoshow(aNewParentGuid);
+  },
+
+  _autoshow(aParentGuid) {
+    if (aParentGuid != PlacesUtils.bookmarks.toolbarGuid)
+      return;
+
+    let toolbar = document.getElementById("PersonalToolbar");
+    if (!toolbar.collapsed)
+      return;
+
+    let placement = CustomizableUI.getPlacementOfWidget("personal-bookmarks");
+    let area = placement && placement.area;
+    if (area != CustomizableUI.AREA_BOOKMARKS)
+      return;
+
+    setToolbarVisibility(toolbar, true);
+  }
+};
+
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -532,17 +532,17 @@ SocialShare = {
     let provider = Social._getProviderFromOrigin(tt.triggerNode.getAttribute("origin"));
     tt.firstChild.setAttribute("value", provider.name);
     tt.lastChild.setAttribute("value", provider.origin);
   },
 
   populateProviderMenu: function() {
     if (!this.iframe)
       return;
-    let providers = [p for (p of Social.providers) if (p.shareURL)];
+    let providers = Social.providers.filter(p => p.shareURL);
     let hbox = document.getElementById("social-share-provider-buttons");
     // remove everything before the add-share-provider button (which should also
     // be lastChild if any share providers were added)
     let addButton = document.getElementById("add-share-provider");
     while (hbox.lastChild != addButton) {
       hbox.removeChild(hbox.lastChild);
     }
     let selectedProvider = this.getSelectedProvider();
@@ -971,17 +971,17 @@ SocialSidebar = {
   _provider: null,
   ensureProvider: function() {
     if (this._provider)
       return;
     // origin for sidebar is persisted, so get the previously selected sidebar
     // first, otherwise fallback to the first provider in the list
     let sbrowser = document.getElementById("social-sidebar-browser");
     let origin = sbrowser.getAttribute("origin");
-    let providers = [p for (p of Social.providers) if (p.sidebarURL)];
+    let providers = Social.providers.filter(p => p.sidebarURL);
     let provider;
     if (origin)
       provider = Social._getProviderFromOrigin(origin);
     if (!provider && providers.length > 0)
       provider = providers[0];
     if (provider)
       this.provider = provider;
   },
@@ -1088,17 +1088,17 @@ SocialSidebar = {
   populateProviderMenu: function(providerMenuSep) {
     let menu = providerMenuSep.parentNode;
     // selectable providers are inserted before the provider-menu seperator,
     // remove any menuitems in that area
     while (providerMenuSep.previousSibling.nodeName == "menuitem") {
       menu.removeChild(providerMenuSep.previousSibling);
     }
     // only show a selection in the sidebar header menu if there is more than one
-    let providers = [p for (p of Social.providers) if (p.sidebarURL)];
+    let providers = Social.providers.filter(p => p.sidebarURL);
     if (providers.length < 2 && menu.id != "viewSidebarMenu") {
       providerMenuSep.hidden = true;
       return;
     }
     let topSep = providerMenuSep.previousSibling;
     for (let provider of providers) {
       let menuitem = document.createElement("menuitem");
       menuitem.className = "menuitem-iconic social-provider-menuitem";
@@ -1148,17 +1148,19 @@ ToolbarHelper.prototype = {
   },
 
   // should be called on disable of a provider
   removeProviderButton: function(origin) {
     CustomizableUI.destroyWidget(this.idFromOrigin(origin));
   },
 
   clearPalette: function() {
-    [this.removeProviderButton(p.origin) for (p of Social.providers)];
+    for (let p of Social.providers) {
+      this.removeProviderButton(p.origin);
+    }
   },
 
   // should be called on enable of a provider
   populatePalette: function() {
     if (!Social.enabled) {
       this.clearPalette();
       return;
     }
@@ -1315,18 +1317,17 @@ var SocialMarksWidgetListener = {
 
 /**
  * SocialMarks
  *
  * Handles updates to toolbox and signals all buttons to update when necessary.
  */
 SocialMarks = {
   get nodes() {
-    let providers = [p for (p of Social.providers) if (p.markURL)];
-    for (let p of providers) {
+    for (let p of Social.providers.filter(p => p.markURL)) {
       let widgetId = SocialMarks._toolbarHelper.idFromOrigin(p.origin);
       let widget = CustomizableUI.getWidget(widgetId);
       if (!widget)
         continue;
       let node = widget.forWindow(window).node;
       if (node)
         yield node;
     }
@@ -1343,27 +1344,29 @@ SocialMarks = {
     }
   },
 
   getProviders: function() {
     // only rely on providers that the user has placed in the UI somewhere. This
     // also means that populateToolbarPalette must be called prior to using this
     // method, otherwise you get a big fat zero. For our use case with context
     // menu's, this is ok.
-    return [p for (p of Social.providers) if (p.markURL &&
-                                              document.getElementById(this._toolbarHelper.idFromOrigin(p.origin)))];
+    return Social.providers.filter(p => p.markURL &&
+                                        document.getElementById(this._toolbarHelper.idFromOrigin(p.origin)));
   },
 
   populateContextMenu: function() {
     // only show a selection if enabled and there is more than one
     let providers = this.getProviders();
 
     // remove all previous entries by class
-    let menus = [m for (m of document.getElementsByClassName("context-socialmarks"))];
-    [m.parentNode.removeChild(m) for (m of menus)];
+    let menus = [...document.getElementsByClassName("context-socialmarks")];
+    for (let m of menus) {
+      m.parentNode.removeChild(m);
+    }
 
     let contextMenus = [
       {
         type: "link",
         id: "context-marklinkMenu",
         label: "social.marklinkMenu.label"
       },
       {
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1183,16 +1183,17 @@ var gBrowserInit = {
         !focusAndSelectUrlBar()) {
       gBrowser.selectedBrowser.focus();
     }
 
     // Enable/Disable auto-hide tabbar
     gBrowser.tabContainer.updateVisibility();
 
     BookmarkingUI.init();
+    AutoShowBookmarksToolbar.init();
 
     gPrefService.addObserver(gHomeButton.prefDomain, gHomeButton, false);
 
     var homeButton = document.getElementById("home-button");
     gHomeButton.updateTooltip(homeButton);
 
     let safeMode = document.getElementById("helpSafeMode");
     if (Services.appinfo.inSafeMode) {
@@ -1429,16 +1430,18 @@ var gBrowserInit = {
     ToolbarIconColor.uninit();
 
     TabletModeUpdater.uninit();
 
     gTabletModePageCounter.finish();
 
     BrowserOnClick.uninit();
 
+    FeedHandler.uninit();
+
     DevEdition.uninit();
 
     TrackingProtection.uninit();
 
     gMenuButtonUpdateBadge.uninit();
 
     gMenuButtonBadgeManager.uninit();
 
@@ -1479,16 +1482,17 @@ var gBrowserInit = {
         this.gmpInstallManager.uninit();
       }
 
       BrowserOffline.uninit();
       OfflineApps.uninit();
       IndexedDBPromptHelper.uninit();
       LightweightThemeListener.uninit();
       PanelUI.uninit();
+      AutoShowBookmarksToolbar.uninit();
     }
 
     // Final window teardown, do this last.
     window.XULBrowserWindow = null;
     window.QueryInterface(Ci.nsIInterfaceRequestor)
           .getInterface(Ci.nsIWebNavigation)
           .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
           .QueryInterface(Ci.nsIInterfaceRequestor)
@@ -3112,52 +3116,62 @@ function BrowserReloadWithFlags(reloadFl
 /**
  * Returns a string with detailed information about the certificate validation
  * failure from the specified URI that can be used to send a report.
  */
 function getDetailedCertErrorInfo(location, securityInfoAsString) {
   if (!securityInfoAsString)
     return "";
 
-  let details = [];
-  details.push(location);
+  let certErrorDetails = location;
 
   const serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
                        .getService(Ci.nsISerializationHelper);
   let securityInfo = serhelper.deserializeObject(securityInfoAsString);
   securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
 
   let errors = Cc["@mozilla.org/nss_errors_service;1"]
                   .getService(Ci.nsINSSErrorsService);
   let code = securityInfo.errorCode;
-  details.push(errors.getErrorMessage(errors.getXPCOMFromNSSError(code)));
+  certErrorDetails += "\r\n\r\n" + errors.getErrorMessage(errors.getXPCOMFromNSSError(code));
 
   const sss = Cc["@mozilla.org/ssservice;1"]
                  .getService(Ci.nsISiteSecurityService);
   // SiteSecurityService uses different storage if the channel is
   // private. Thus we must give isSecureHost correct flags or we
   // might get incorrect results.
   let flags = PrivateBrowsingUtils.isWindowPrivate(window) ?
               Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0;
 
   let uri = Services.io.newURI(location, null, null);
-  details.push(sss.isSecureHost(sss.HEADER_HSTS, uri.host, flags));
-  details.push(sss.isSecureHost(sss.HEADER_HPKP, uri.host, flags));
+
+  let hasHSTS = sss.isSecureHost(sss.HEADER_HSTS, uri.host, flags);
+  let hasHPKP = sss.isSecureHost(sss.HEADER_HPKP, uri.host, flags);
+  certErrorDetails += "\r\n\r\n" +
+                      gNavigatorBundle.getFormattedString("certErrorDetailsHSTS.label",
+                                                          [hasHSTS]);
+  certErrorDetails += "\r\n" +
+                      gNavigatorBundle.getFormattedString("certErrorDetailsKeyPinning.label",
+                                                          [hasHPKP]);
 
   let certChain = "";
   if (securityInfo.failedCertChain) {
     let certs = securityInfo.failedCertChain.getEnumerator();
     while (certs.hasMoreElements()) {
       let cert = certs.getNext();
       cert.QueryInterface(Ci.nsIX509Cert);
       certChain += getPEMString(cert);
     }
   }
-  details.push(certChain);
-  return gNavigatorBundle.getFormattedString("certErrorDetails.label", details, 5);
+
+  certErrorDetails += "\r\n\r\n" +
+                      gNavigatorBundle.getString("certErrorDetailsCertChain.label") +
+                      "\r\n\r\n" + certChain;
+
+  return certErrorDetails;
 }
 
 // TODO: can we pull getDERString and getPEMString in from pippki.js instead of
 // duplicating them here?
 function getDERString(cert)
 {
   var length = {};
   var derArray = cert.getRawDER(length);
@@ -6399,21 +6413,16 @@ function BrowserOpenAddonsMgr(aView) {
     // found the window above.
     Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
       Services.obs.removeObserver(observer, aTopic);
       aSubject.loadView(aView);
     }, "EM-loaded", false);
   }
 }
 
-function BrowserOpenApps() {
-  let appsURL = Services.urlFormatter.formatURLPref("browser.apps.URL");
-  switchToTabHavingURI(appsURL, true)
-}
-
 function AddKeywordForSearchField() {
   let mm = gBrowser.selectedBrowser.messageManager;
 
   let onMessage = (message) => {
     mm.removeMessageListener("ContextMenu:SearchFieldBookmarkData:Result", onMessage);
 
     let bookmarkData = message.data;
     let title = gNavigatorBundle.getFormattedString("addKeywordTitleAutoFill",
@@ -7898,17 +7907,18 @@ var AboutPrivateBrowsingListener = {
 };
 
 function TabModalPromptBox(browser) {
   this._weakBrowserRef = Cu.getWeakReference(browser);
 }
 
 TabModalPromptBox.prototype = {
   _promptCloseCallback(onCloseCallback, principalToAllowFocusFor, allowFocusCheckbox, ...args) {
-    if (principalToAllowFocusFor && allowFocusCheckbox.checked) {
+    if (principalToAllowFocusFor && allowFocusCheckbox &&
+        allowFocusCheckbox.checked) {
       Services.perms.addFromPrincipal(principalToAllowFocusFor, "focus-tab-by-prompt",
                                       Services.perms.ALLOW_ACTION);
     }
     onCloseCallback.apply(this, args);
   },
 
   appendPrompt(args, onCloseCallback) {
     const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@@ -7918,23 +7928,27 @@ TabModalPromptBox.prototype = {
     browser.setAttribute("tabmodalPromptShowing", true);
 
     newPrompt.clientTop; // style flush to assure binding is attached
 
     let principalToAllowFocusFor = this._allowTabFocusByPromptPrincipal;
     delete this._allowTabFocusByPromptPrincipal;
 
     let allowFocusCheckbox; // Define outside the if block so we can bind it into the callback.
-    if (principalToAllowFocusFor) {
+    let hostForAllowFocusCheckbox = "";
+    try {
+      hostForAllowFocusCheckbox = principalToAllowFocusFor.URI.host;
+    } catch (ex) { /* Ignore exceptions for host-less URIs */ }
+    if (hostForAllowFocusCheckbox) {
       let allowFocusRow = document.createElementNS(XUL_NS, "row");
       allowFocusCheckbox = document.createElementNS(XUL_NS, "checkbox");
       let spacer = document.createElementNS(XUL_NS, "spacer");
       allowFocusRow.appendChild(spacer);
       let label = gBrowser.mStringBundle.getFormattedString("tabs.allowTabFocusByPromptForSite",
-                                                            [principalToAllowFocusFor.URI.host]);
+                                                            [hostForAllowFocusCheckbox]);
       allowFocusCheckbox.setAttribute("label", label);
       allowFocusRow.appendChild(allowFocusCheckbox);
       newPrompt.appendChild(allowFocusRow);
     }
 
     let tab = gBrowser.getTabForBrowser(browser);
     let closeCB = this._promptCloseCallback.bind(null, onCloseCallback, principalToAllowFocusFor,
                                                  allowFocusCheckbox);
--- a/browser/base/content/newtab/grid.js
+++ b/browser/base/content/newtab/grid.js
@@ -128,17 +128,17 @@ var gGrid = {
 
     // Creates all the cells up to the maximum
     let fragment = document.createDocumentFragment();
     for (let i = 0; i < gGridPrefs.gridColumns * gGridPrefs.gridRows; i++) {
       fragment.appendChild(cell.cloneNode(true));
     }
 
     // Create cells.
-    let cells = [new Cell(this, cell) for (cell of fragment.childNodes)];
+    let cells = Array.from(fragment.childNodes, (cell) => new Cell(this, cell));
 
     // Fetch links.
     let links = gLinks.getLinks();
 
     // Create sites.
     let numLinks = Math.min(links.length, cells.length);
     for (let i = 0; i < numLinks; i++) {
       if (links[i]) {
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -331,24 +331,28 @@ nsContextMenu.prototype = {
     // there is more than MENU_LIMIT providers, we show a submenu for them,
     // otherwise we have a menuitem per provider (added in SocialMarks class).
     let markProviders = SocialMarks.getProviders();
     let enablePageMarks = markProviders.length > 0 && !(this.onLink || this.onImage
                             || this.onVideo || this.onAudio);
     this.showItem("context-markpageMenu", enablePageMarks && markProviders.length > SocialMarks.MENU_LIMIT);
     let enablePageMarkItems = enablePageMarks && markProviders.length <= SocialMarks.MENU_LIMIT;
     let linkmenus = document.getElementsByClassName("context-markpage");
-    [m.hidden = !enablePageMarkItems for (m of linkmenus)];
+    for (let m of linkmenus) {
+      m.hidden = !enablePageMarkItems;
+    }
 
     let enableLinkMarks = markProviders.length > 0 &&
                             ((this.onLink && !this.onMailtoLink) || this.onPlainTextLink);
     this.showItem("context-marklinkMenu", enableLinkMarks && markProviders.length > SocialMarks.MENU_LIMIT);
     let enableLinkMarkItems = enableLinkMarks && markProviders.length <= SocialMarks.MENU_LIMIT;
     linkmenus = document.getElementsByClassName("context-marklink");
-    [m.hidden = !enableLinkMarkItems for (m of linkmenus)];
+    for (let m of linkmenus) {
+      m.hidden = !enableLinkMarkItems;
+    }
 
     // SocialShare
     let shareButton = SocialShare.shareButton;
     let shareEnabled = shareButton && !shareButton.disabled && !this.onSocial;
     let pageShare = shareEnabled && !(this.isContentSelected ||
                             this.onTextInput || this.onLink || this.onImage ||
                             this.onVideo || this.onAudio || this.onCanvas);
     this.showItem("context-sharepage", pageShare);
--- a/browser/base/content/tab-content.js
+++ b/browser/base/content/tab-content.js
@@ -190,20 +190,16 @@ var AboutHomeListener = {
       case "bookmarks":
         sendAsyncMessage("AboutHome:Bookmarks");
         break;
 
       case "history":
         sendAsyncMessage("AboutHome:History");
         break;
 
-      case "apps":
-        sendAsyncMessage("AboutHome:Apps");
-        break;
-
       case "addons":
         sendAsyncMessage("AboutHome:Addons");
         break;
 
       case "sync":
         sendAsyncMessage("AboutHome:Sync");
         break;
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -758,17 +758,19 @@
                 if (this.mBrowser.userTypedClear > 0 ||
                     ((aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) &&
                      aLocation.spec != "about:blank") ||
                      aFlags && Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
                   this.mBrowser.userTypedValue = null;
                 }
 
                 // If the browser was playing audio, we should remove the playing state.
-                if (this.mTab.hasAttribute("soundplaying") && this.mBrowser.lastURI != aLocation) {
+                if (this.mTab.hasAttribute("soundplaying") &&
+                    (!this.mBrowser.lastURI ||
+                     this.mBrowser.lastURI.spec != aLocation.spec)) {
                   this.mTab.removeAttribute("soundplaying");
                   this.mTabBrowser._tabAttrModified(this.mTab, ["soundplaying"]);
                 }
 
                 // If the browser was previously muted, we should restore the muted state.
                 if (this.mTab.hasAttribute("muted")) {
                   this.mTab.linkedBrowser.mute();
                 }
@@ -3096,16 +3098,19 @@
 
             tabbrowser: this,  // Reference to gBrowser.
             loadTimer: null,   // TAB_SWITCH_TIMEOUT timer.
             unloadTimer: null, // UNLOAD_DELAY timer.
 
             // Map from tabs to STATE_* (below).
             tabState: new Map(),
 
+            // True if we're in the midst of switching tabs.
+            switchInProgress: false,
+
             // Keep an exact list of content processes (tabParent) in which
             // we're actively suppressing the display port. This gives a robust
             // way to make sure we don't forget to un-suppress.
             activeSuppressDisplayport: new Set(),
 
             // Set of tabs that might be visible right now. We maintain
             // this set because we can't be sure when a tab is actually
             // drawn. A tab is added to this set when we ask to make it
@@ -3405,31 +3410,31 @@
 
             // Fires when the layers become available for a tab.
             onLayersReady: function(browser) {
               this.logState("onLayersReady");
 
               let tab = this.tabbrowser.getTabForBrowser(browser);
               this.setTabState(tab, this.STATE_LOADED);
 
-              this.finishTabSwitch();
+              this.maybeFinishTabSwitch();
 
               if (this.loadingTab === tab) {
                 clearTimeout(this.loadTimer);
                 this.loadTimer = null;
                 this.loadingTab = null;
               }
             },
 
             // Fires when we paint the screen. Any tab switches we initiated
             // previously are done, so there's no need to keep the old layers
             // around.
             onPaint: function() {
               this.maybeVisibleTabs.clear();
-              this.finishTabSwitch();
+              this.maybeFinishTabSwitch();
             },
 
             // Called when we're done clearing the layers for a tab.
             onLayersCleared: function(browser) {
               this.logState("onLayersCleared");
 
               let tab = this.tabbrowser.getTabForBrowser(browser);
               if (tab) {
@@ -3518,50 +3523,59 @@
              * Telemetry and Profiler related helpers for recording tab switch
              * timing.
              */
 
             startTabSwitch: function () {
               TelemetryStopwatch.cancel("FX_TAB_SWITCH_TOTAL_E10S_MS", window);
               TelemetryStopwatch.start("FX_TAB_SWITCH_TOTAL_E10S_MS", window);
               this.addMarker("AsyncTabSwitch:Start");
+              this.switchInProgress = true;
             },
 
-            finishTabSwitch: function () {
-              if (this.requestedTab && this.getTabState(this.requestedTab) == this.STATE_LOADED) {
+            /**
+             * Something has occurred that might mean that we've completed
+             * the tab switch (layers are ready, paints are done, spinners
+             * are hidden). This checks to make sure all conditions are
+             * satisfied, and then records the tab switch as finished.
+             */
+            maybeFinishTabSwitch: function () {
+              if (this.switchInProgress && this.requestedTab &&
+                  this.getTabState(this.requestedTab) == this.STATE_LOADED) {
                 // After this point the tab has switched from the content thread's point of view.
                 // The changes will be visible after the next refresh driver tick + composite.
                 let event = new CustomEvent("TabSwitched", {
                   bubbles: true,
                   cancelable: true
                 });
                 this.tabbrowser.dispatchEvent(event);
                 let time = TelemetryStopwatch.timeElapsed("FX_TAB_SWITCH_TOTAL_E10S_MS", window);
                 if (time != -1) {
                   TelemetryStopwatch.finish("FX_TAB_SWITCH_TOTAL_E10S_MS", window);
                   this.log("DEBUG: tab switch time = " + time);
                   this.addMarker("AsyncTabSwitch:Finish");
                 }
+                this.switchInProgress = false;
               }
             },
 
             spinnerDisplayed: function () {
               this.assert(!this.spinnerTab);
               TelemetryStopwatch.start("FX_TAB_SWITCH_SPINNER_VISIBLE_MS", window);
               this.addMarker("AsyncTabSwitch:SpinnerShown");
             },
 
             spinnerHidden: function () {
               this.assert(this.spinnerTab);
               this.log("DEBUG: spinner time = " +
                        TelemetryStopwatch.timeElapsed("FX_TAB_SWITCH_SPINNER_VISIBLE_MS", window));
               TelemetryStopwatch.finish("FX_TAB_SWITCH_SPINNER_VISIBLE_MS", window);
               this.addMarker("AsyncTabSwitch:SpinnerHidden");
               // we do not get a onPaint after displaying the spinner
-              this.finishTabSwitch();
+              this.maybeFinishTabSwitch();
             },
 
             addMarker: function(marker) {
               if (Services.profiler) {
                 Services.profiler.AddMarker(marker);
               }
             },
 
@@ -4364,19 +4378,21 @@
           let tabForEvent = targetIsWindow ?
                             this._getTabForContentWindow(event.target.top) :
                             this.getTabForBrowser(event.originalTarget);
 
           // Don't need to act if the tab is already selected:
           if (tabForEvent.selected)
             return;
 
-          // If this is a tabprompt, we won't switch tabs
-          // (unless this behaviour has been disabled entirely using the pref)
+          // If this is a tabprompt, we won't switch tabs, unless:
+          // - this is a beforeunload prompt
+          // - this behaviour has been disabled entirely using the pref
           if (event.detail && event.detail.tabPrompt &&
+              !event.detail.inPermitUnload &&
               Services.prefs.getBoolPref("browser.tabs.dontfocusfordialogs")) {
             let docPrincipal = targetIsWindow ? event.target.document.nodePrincipal : null;
             // At least one of these should/will be non-null:
             let promptPrincipal = event.detail.promptPrincipal || docPrincipal ||
                                   tabForEvent.linkedBrowser.contentPrincipal;
             // For null principals, we bail immediately and don't show the checkbox:
             if (!promptPrincipal || promptPrincipal.isNullPrincipal) {
               tabForEvent.setAttribute("attention", "true");
@@ -6125,16 +6141,26 @@
           } else {
             browser.mute();
             this.setAttribute("muted", "true");
           }
           tabContainer.tabbrowser._tabAttrModified(this, ["muted"]);
         ]]>
         </body>
       </method>
+
+      <method name="setUserContextId">
+        <parameter name="aUserContextId"/>
+        <body>
+        <![CDATA[
+          this.linkedBrowser.setAttribute("usercontextid", aUserContextId);
+          this.setAttribute("usercontextid", aUserContextId);
+        ]]>
+        </body>
+      </method>
     </implementation>
 
     <handlers>
       <handler event="mouseover"><![CDATA[
         let anonid = event.originalTarget.getAttribute("anonid");
         if (anonid == "close-button")
           this.mOverCloseButton = true;
 
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/alerts/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc"
+  ]
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/chat/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc"
+  ]
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/chrome/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../../testing/mochitest/chrome.eslintrc"
+  ]
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/.eslintrc
@@ -0,0 +1,6 @@
+{
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc",
+    "../../../../../testing/mochitest/mochitest.eslintrc",
+  ]
+}
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -284,27 +284,26 @@ skip-if = e10s # Bug 1094510 - test hits
 [browser_clipboard.js]
 [browser_contentAreaClick.js]
 [browser_contextSearchTabPosition.js]
 skip-if = os == "mac" || e10s # bug 967013; e10s: bug 1094761 - test hits the network in e10s, causing next test to crash
 [browser_ctrlTab.js]
 [browser_datareporting_notification.js]
 skip-if = !datareporting
 [browser_datachoices_notification.js]
-skip-if = !datareporting || e10s # bug 1113930
+skip-if = !datareporting
 [browser_devedition.js]
 [browser_devices_get_user_media.js]
 skip-if = buildapp == 'mulet' || (os == "linux" && debug) || e10s # linux: bug 976544; e10s: bug 1071623
 [browser_devices_get_user_media_about_urls.js]
 skip-if = e10s # Bug 1071623
 [browser_devices_get_user_media_in_frame.js]
 skip-if = e10s # Bug 1071623
 [browser_discovery.js]
 [browser_double_close_tab.js]
-skip-if = e10s
 [browser_documentnavigation.js]
 [browser_duplicateIDs.js]
 [browser_drag.js]
 skip-if = true # browser_drag.js is disabled, as it needs to be updated for the new behavior from bug 320638.
 [browser_favicon_change.js]
 [browser_favicon_change_not_in_document.js]
 [browser_findbarClose.js]
 [browser_focusonkeydown.js]
@@ -467,17 +466,17 @@ skip-if = buildapp == 'mulet'
 [browser_unloaddialogs.js]
 skip-if = e10s # Bug 1100700 - test relies on unload event firing on closed tabs, which it doesn't
 [browser_urlHighlight.js]
 [browser_urlbarAutoFillTrimURLs.js]
 [browser_urlbarCopying.js]
 [browser_urlbarDelete.js]
 [browser_urlbarEnter.js]
 [browser_urlbarEnterAfterMouseOver.js]
-skip-if = os == "linux" || e10s # Bug 1073339 - Investigate autocomplete test unreliability on Linux/e10s
+skip-if = os == "linux" # Bug 1073339 - Investigate autocomplete test unreliability on Linux/e10s
 [browser_urlbarRevert.js]
 [browser_urlbarSearchSingleWordNotification.js]
 [browser_urlbarSearchSuggestions.js]
 [browser_urlbarSearchSuggestionsNotification.js]
 [browser_urlbarSearchTelemetry.js]
 [browser_urlbarStop.js]
 [browser_urlbarTrimURLs.js]
 [browser_urlbar_autoFill_backspaced.js]
--- a/browser/base/content/test/general/browser_audioTabIcon.js
+++ b/browser/base/content/test/general/browser_audioTabIcon.js
@@ -176,47 +176,81 @@ function* test_playing_icon_on_tab(tab, 
 
   // Make sure it's possible to mute using the context menu.
   yield test_muting_using_menu(tab, false);
 
   // Make sure it's possible to unmute using the context menu.
   yield test_muting_using_menu(tab, true);
 }
 
-function* test_swapped_browser(oldTab, newBrowser, isPlaying) {
+function* test_swapped_browser_while_playing(oldTab, newBrowser) {
   ok(oldTab.hasAttribute("muted"), "Expected the correct muted attribute on the old tab");
-  is(oldTab.hasAttribute("soundplaying"), isPlaying, "Expected the correct soundplaying attribute on the old tab");
+  ok(oldTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the old tab");
 
   let newTab = gBrowser.getTabForBrowser(newBrowser);
   let AttrChangePromise = BrowserTestUtils.waitForEvent(newTab, "TabAttrModified", false, event => {
-    return (event.detail.changed.indexOf("soundplaying") >= 0 || !isPlaying) &&
+    return event.detail.changed.indexOf("soundplaying") >= 0 &&
            event.detail.changed.indexOf("muted") >= 0;
   });
+
+  gBrowser.swapBrowsersAndCloseOther(newTab, oldTab);
+  yield AttrChangePromise;
+
+  ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab");
+  ok(newTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the new tab");
+
+  let receivedSoundPlaying = 0;
+  // We need to receive two TabAttrModified events with 'soundplaying'
+  // because swapBrowsersAndCloseOther involves nsDocument::OnPageHide and
+  // nsDocument::OnPageShow. Each methods lead to TabAttrModified event.
+  yield BrowserTestUtils.waitForEvent(newTab, "TabAttrModified", false, event => {
+    if (event.detail.changed.indexOf("soundplaying") >= 0) {
+      return (++receivedSoundPlaying == 2);
+    }
+  });
+
+  ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab");
+  ok(newTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the new tab");
+
+  let icon = document.getAnonymousElementByAttribute(newTab, "anonid",
+                                                     "soundplaying-icon");
+  yield test_tooltip(icon, "Unmute tab", true);
+}
+
+function* test_swapped_browser_while_not_playing(oldTab, newBrowser) {
+  ok(oldTab.hasAttribute("muted"), "Expected the correct muted attribute on the old tab");
+  ok(!oldTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the old tab");
+
+  let newTab = gBrowser.getTabForBrowser(newBrowser);
+  let AttrChangePromise = BrowserTestUtils.waitForEvent(newTab, "TabAttrModified", false, event => {
+    return event.detail.changed.indexOf("muted") >= 0;
+  });
+
   let AudioPlaybackPromise = new Promise(resolve => {
     let observer = (subject, topic, data) => {
-      ok(true, "Should see an audio-playback notification");
+      ok(false, "Should not see an audio-playback notification");
     };
-    Services.obs.addObserver(observer, "audio-playback", false);
+    Services.obs.addObserver(observer, "audiochannel-activity-normal", false);
     setTimeout(() => {
-      Services.obs.removeObserver(observer, "audio-playback");
+      Services.obs.removeObserver(observer, "audiochannel-activity-normal");
       resolve();
     }, 100);
   });
 
   gBrowser.swapBrowsersAndCloseOther(newTab, oldTab);
   yield AttrChangePromise;
 
   ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab");
-  is(newTab.hasAttribute("soundplaying"), isPlaying, "Expected the correct soundplaying attribute on the new tab");
+  ok(!newTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the new tab");
 
   // Wait to see if an audio-playback event is dispatched.
   yield AudioPlaybackPromise;
 
   ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab");
-  is(newTab.hasAttribute("soundplaying"), isPlaying, "Expected the correct soundplaying attribute on the new tab");
+  ok(!newTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the new tab");
 
   let icon = document.getAnonymousElementByAttribute(newTab, "anonid",
                                                      "soundplaying-icon");
   yield test_tooltip(icon, "Unmute tab", true);
 }
 
 function* test_browser_swapping(tab, browser) {
   // First, test swapping with a playing but muted tab.
@@ -225,27 +259,27 @@ function* test_browser_swapping(tab, bro
   let icon = document.getAnonymousElementByAttribute(tab, "anonid",
                                                      "soundplaying-icon");
   yield test_mute_tab(tab, icon, true);
 
   yield BrowserTestUtils.withNewTab({
     gBrowser,
     url: "about:blank",
   }, function*(newBrowser) {
-    yield test_swapped_browser(tab, newBrowser, true)
+    yield test_swapped_browser_while_playing(tab, newBrowser)
 
     // Now, test swapping with a muted but not playing tab.
     // Note that the tab remains muted, so we only need to pause playback.
     tab = gBrowser.getTabForBrowser(newBrowser);
     yield pause(tab);
 
     yield BrowserTestUtils.withNewTab({
       gBrowser,
       url: "about:blank",
-    }, newBrowser => test_swapped_browser(tab, newBrowser, false));
+    }, newBrowser => test_swapped_browser_while_not_playing(tab, newBrowser));
   });
 }
 
 function* test_click_on_pinned_tab_after_mute() {
   function* test_on_browser(browser) {
     let tab = gBrowser.getTabForBrowser(browser);
 
     gBrowser.selectedTab = originallySelectedTab;
--- a/browser/base/content/test/general/browser_bug575561.js
+++ b/browser/base/content/test/general/browser_bug575561.js
@@ -1,8 +1,10 @@
+requestLongerTimeout(2);
+
 const TEST_URL = "http://example.com/browser/browser/base/content/test/general/app_bug575561.html";
 
 add_task(function*() {
   SimpleTest.requestCompleteLog();
 
   // Pinned: Link to the same domain should not open a new tab
   // Tests link to http://example.com/browser/browser/base/content/test/general/dummy_page.html
   yield testLink(0, true, false);
--- a/browser/base/content/test/general/browser_bug676619.js
+++ b/browser/base/content/test/general/browser_bug676619.js
@@ -1,10 +1,10 @@
 function test () {
-  requestLongerTimeout(2);
+  requestLongerTimeout(3);
   waitForExplicitFinish();
 
   var isHTTPS = false;
 
   function loadListener() {
     function testLocation(link, url, next) {
       var tabOpenListener = new TabOpenListener(url, function () {
           gBrowser.removeTab(this.tab);
--- a/browser/base/content/test/general/browser_devices_get_user_media.js
+++ b/browser/base/content/test/general/browser_devices_get_user_media.js
@@ -1,12 +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/. */
 
+requestLongerTimeout(2);
+
 const kObservedTopics = [
   "getUserMedia:response:allow",
   "getUserMedia:revoke",
   "getUserMedia:response:deny",
   "getUserMedia:request",
   "recording-device-events",
   "recording-window-ended"
 ];
--- a/browser/base/content/test/general/browser_e10s_switchbrowser.js
+++ b/browser/base/content/test/general/browser_e10s_switchbrowser.js
@@ -1,8 +1,10 @@
+requestLongerTimeout(2);
+
 const DUMMY_PATH = "browser/browser/base/content/test/general/dummy_page.html";
 
 const gExpectedHistory = {
   index: -1,
   entries: []
 };
 
 function get_remote_history(browser) {
--- a/browser/base/content/test/general/browser_sanitize-timespans.js
+++ b/browser/base/content/test/general/browser_sanitize-timespans.js
@@ -1,11 +1,13 @@
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
+requestLongerTimeout(2);
+
 // Bug 453440 - Test the timespan-based logic of the sanitizer code
 var now_mSec = Date.now();
 var now_uSec = now_mSec * 1000;
 
 const kMsecPerMin = 60 * 1000;
 const kUsecPerMin = 60 * 1000000;
 
 var tempScope = {};
--- a/browser/base/content/test/general/browser_tab_drag_drop_perwindow.js
+++ b/browser/base/content/test/general/browser_tab_drag_drop_perwindow.js
@@ -1,12 +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/. */
 
+requestLongerTimeout(2);
+
 const CHROMEUTILS_URL = "chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js";
 var ChromeUtils = {};
 
 Services.scriptloader.loadSubScript(CHROMEUTILS_URL, ChromeUtils);
 
 /**
  * Tests that tabs from Private Browsing windows cannot be dragged
  * into non-private windows, and vice-versa.
--- a/browser/base/content/test/general/title_test.svg
+++ b/browser/base/content/test/general/title_test.svg
@@ -17,17 +17,17 @@
     This            is a title
 
     </title>
   </text>
   <text id="text2" x="10px" y="96px" font-size="24px">
     This contains only &lt;desc&gt;
     <desc>This is a desc</desc>
   </text>
-  <text id="text3" x="10px" y="128px" font-size="24px">
+  <text id="text3" x="10px" y="128px" font-size="24px" title="ignored for SVG">
     This contains nothing.
   </text>
   <a id="link1" xlink:href="#">
     This link contains &lt;title&gt;
     <title>
       This is a title
     </title>
     <text id="text4" x="10px" y="192px" font-size="24px">
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/newtab/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc"
+  ]
+}
--- a/browser/base/content/test/newtab/browser_newtab_block.js
+++ b/browser/base/content/test/newtab/browser_newtab_block.js
@@ -1,11 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+requestLongerTimeout(2);
+
 /*
  * These tests make sure that blocking/removing sites from the grid works
  * as expected. Pinned tabs should not be moved. Gaps will be re-filled
  * if more sites are available.
  */
 
 gDirectorySource = "data:application/json," + JSON.stringify({
   "suggested": [{
--- a/browser/base/content/test/newtab/browser_newtab_drag_drop_ext.js
+++ b/browser/base/content/test/newtab/browser_newtab_drag_drop_ext.js
@@ -1,11 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+requestLongerTimeout(2);
+
 const PREF_NEWTAB_COLUMNS = "browser.newtabpage.columns";
 
 /*
  * These tests make sure that dragging and dropping sites works as expected.
  * Sites contained in the grid need to shift around to indicate the result
  * of the drag-and-drop operation. If the grid is full and we're dragging
  * a new site into it another one gets pushed out.
  * This is a continuation of browser_newtab_drag_drop.js
--- a/browser/base/content/test/newtab/browser_newtab_enhanced.js
+++ b/browser/base/content/test/newtab/browser_newtab_enhanced.js
@@ -1,11 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+requestLongerTimeout(2);
+
 const PRELOAD_PREF = "browser.newtab.preload";
 
 var suggestedLink = {
   url: "http://example1.com/2",
   imageURI: "data:image/png;base64,helloWORLD3",
   title: "title2",
   type: "affiliate",
   adgroup_name: "Technology",
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugins/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc"
+  ]
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/popupNotifications/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc"
+  ]
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/referrer/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc"
+  ]
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/social/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc"
+  ]
+}
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -22,29 +22,27 @@ browser.jar:
 *       content/browser/abouthome/aboutHome.xhtml     (content/abouthome/aboutHome.xhtml)
         content/browser/abouthome/aboutHome.js        (content/abouthome/aboutHome.js)
 *       content/browser/abouthome/aboutHome.css       (content/abouthome/aboutHome.css)
         content/browser/abouthome/snippet1.png        (content/abouthome/snippet1.png)
         content/browser/abouthome/snippet2.png        (content/abouthome/snippet2.png)
         content/browser/abouthome/downloads.png       (content/abouthome/downloads.png)
         content/browser/abouthome/bookmarks.png       (content/abouthome/bookmarks.png)
         content/browser/abouthome/history.png         (content/abouthome/history.png)
-        content/browser/abouthome/apps.png            (content/abouthome/apps.png)
         content/browser/abouthome/addons.png          (content/abouthome/addons.png)
         content/browser/abouthome/sync.png            (content/abouthome/sync.png)
         content/browser/abouthome/settings.png        (content/abouthome/settings.png)
         content/browser/abouthome/restore.png         (content/abouthome/restore.png)
         content/browser/abouthome/restore-large.png   (content/abouthome/restore-large.png)
         content/browser/abouthome/mozilla.png         (content/abouthome/mozilla.png)
         content/browser/abouthome/snippet1@2x.png      (content/abouthome/snippet1@2x.png)
         content/browser/abouthome/snippet2@2x.png      (content/abouthome/snippet2@2x.png)
         content/browser/abouthome/downloads@2x.png     (content/abouthome/downloads@2x.png)
         content/browser/abouthome/bookmarks@2x.png     (content/abouthome/bookmarks@2x.png)
         content/browser/abouthome/history@2x.png       (content/abouthome/history@2x.png)
-        content/browser/abouthome/apps@2x.png          (content/abouthome/apps@2x.png)
         content/browser/abouthome/addons@2x.png        (content/abouthome/addons@2x.png)
         content/browser/abouthome/sync@2x.png          (content/abouthome/sync@2x.png)
         content/browser/abouthome/settings@2x.png      (content/abouthome/settings@2x.png)
         content/browser/abouthome/restore@2x.png       (content/abouthome/restore@2x.png)
         content/browser/abouthome/restore-large@2x.png (content/abouthome/restore-large@2x.png)
         content/browser/abouthome/mozilla@2x.png       (content/abouthome/mozilla@2x.png)
 
         content/browser/aboutNetError.xhtml            (content/aboutNetError.xhtml)
--- a/browser/components/about/AboutRedirector.cpp
+++ b/browser/components/about/AboutRedirector.cpp
@@ -100,19 +100,16 @@ static RedirEntry kRedirMap[] = {
 #ifdef MOZ_SERVICES_HEALTHREPORT
   { "healthreport", "chrome://browser/content/abouthealthreport/abouthealth.xhtml",
     nsIAboutModule::ALLOW_SCRIPT },
 #endif
   { "accounts", "chrome://browser/content/aboutaccounts/aboutaccounts.xhtml",
     nsIAboutModule::ALLOW_SCRIPT },
   { "customizing", "chrome://browser/content/customizableui/aboutCustomizing.xul",
     nsIAboutModule::ALLOW_SCRIPT },
-  {
-    "debugging", "chrome://devtools/content/aboutdebugging/aboutdebugging.xhtml",
-    nsIAboutModule::ALLOW_SCRIPT },
   { "loopconversation", "chrome://loop/content/panels/conversation.html",
     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
     nsIAboutModule::ALLOW_SCRIPT |
     nsIAboutModule::HIDE_FROM_ABOUTABOUT |
     nsIAboutModule::ENABLE_INDEXED_DB },
   { "looppanel", "chrome://loop/content/panels/panel.html",
     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
     nsIAboutModule::ALLOW_SCRIPT |
--- a/browser/components/build/nsBrowserCompsCID.h
+++ b/browser/components/build/nsBrowserCompsCID.h
@@ -5,22 +5,16 @@
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef XP_WIN
 #define NS_WINIEHISTORYENUMERATOR_CID \
 { 0x93480624, 0x806e, 0x4756, { 0xb7, 0xcb, 0x0f, 0xb7, 0xdd, 0x74, 0x6a, 0x8f } }
 
 #define NS_IEHISTORYENUMERATOR_CONTRACTID \
   "@mozilla.org/profile/migrator/iehistoryenumerator;1"
-
-#define NS_EDGEREADINGLISTEXTRACTOR_CID \
-{ 0xeeff77b1, 0xdb98, 0x4241, { 0x94, 0x36, 0x14, 0xf7, 0xa2, 0x28, 0x84, 0xc1 } }
-
-#define NS_EDGEREADINGLISTEXTRACTOR_CONTRACTID \
-  "@mozilla.org/profile/migrator/edgereadinglistextractor;1"
 #endif
 
 #define NS_SHELLSERVICE_CID \
 { 0x63c7b9f4, 0xcc8, 0x43f8, { 0xb6, 0x66, 0xa, 0x66, 0x16, 0x55, 0xcb, 0x73 } }
 
 #define NS_SHELLSERVICE_CONTRACTID \
   "@mozilla.org/browser/shell-service;1"
 
--- a/browser/components/build/nsModule.cpp
+++ b/browser/components/build/nsModule.cpp
@@ -13,17 +13,16 @@
 #elif defined(XP_MACOSX)
 #include "nsMacShellService.h"
 #elif defined(MOZ_WIDGET_GTK)
 #include "nsGNOMEShellService.h"
 #endif
 
 #if defined(XP_WIN)
 #include "nsIEHistoryEnumerator.h"
-#include "nsEdgeReadingListExtractor.h"
 #endif
 
 #include "rdf.h"
 #include "nsFeedSniffer.h"
 #include "AboutRedirector.h"
 #include "nsIAboutModule.h"
 
 #include "nsNetCID.h"
@@ -38,48 +37,45 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindows
 #elif defined(XP_MACOSX)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShellService)
 #elif defined(MOZ_WIDGET_GTK)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init)
 #endif
 
 #if defined(XP_WIN)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsIEHistoryEnumerator)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsEdgeReadingListExtractor)
 #endif
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer)
 
 NS_DEFINE_NAMED_CID(NS_BROWSERDIRECTORYPROVIDER_CID);
 #if defined(XP_WIN)
 NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
 #elif defined(MOZ_WIDGET_GTK)
 NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_FEEDSNIFFER_CID);
 NS_DEFINE_NAMED_CID(NS_BROWSER_ABOUT_REDIRECTOR_CID);
 #if defined(XP_WIN)
 NS_DEFINE_NAMED_CID(NS_WINIEHISTORYENUMERATOR_CID);
-NS_DEFINE_NAMED_CID(NS_EDGEREADINGLISTEXTRACTOR_CID);
 #elif defined(XP_MACOSX)
 NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
 #endif
 
 static const mozilla::Module::CIDEntry kBrowserCIDs[] = {
     { &kNS_BROWSERDIRECTORYPROVIDER_CID, false, nullptr, DirectoryProviderConstructor },
 #if defined(XP_WIN)
     { &kNS_SHELLSERVICE_CID, false, nullptr, nsWindowsShellServiceConstructor },
 #elif defined(MOZ_WIDGET_GTK)
     { &kNS_SHELLSERVICE_CID, false, nullptr, nsGNOMEShellServiceConstructor },
 #endif
     { &kNS_FEEDSNIFFER_CID, false, nullptr, nsFeedSnifferConstructor },
     { &kNS_BROWSER_ABOUT_REDIRECTOR_CID, false, nullptr, AboutRedirector::Create },
 #if defined(XP_WIN)
     { &kNS_WINIEHISTORYENUMERATOR_CID, false, nullptr, nsIEHistoryEnumeratorConstructor },
-    { &kNS_EDGEREADINGLISTEXTRACTOR_CID, false, nullptr, nsEdgeReadingListExtractorConstructor },
 #elif defined(XP_MACOSX)
     { &kNS_SHELLSERVICE_CID, false, nullptr, nsMacShellServiceConstructor },
 #endif
     { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
     { NS_BROWSERDIRECTORYPROVIDER_CONTRACTID, &kNS_BROWSERDIRECTORYPROVIDER_CID },
@@ -108,23 +104,21 @@ static const mozilla::Module::ContractID
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "remote-newtab", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "preferences", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "downloads", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "accounts", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
 #ifdef MOZ_SERVICES_HEALTHREPORT
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "healthreport", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
 #endif
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "customizing", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
-    { NS_ABOUT_MODULE_CONTRACTID_PREFIX "debugging", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "looppanel", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "loopconversation", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "reader", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
 #if defined(XP_WIN)
     { NS_IEHISTORYENUMERATOR_CONTRACTID, &kNS_WINIEHISTORYENUMERATOR_CID },
-    { NS_EDGEREADINGLISTEXTRACTOR_CONTRACTID, &kNS_EDGEREADINGLISTEXTRACTOR_CID },
 #elif defined(XP_MACOSX)
     { NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID },
 #endif
     { nullptr }
 };
 
 static const mozilla::Module::CategoryEntry kBrowserCategories[] = {
     { XPCOM_DIRECTORY_PROVIDER_CATEGORY, "browser-directory-provider", NS_BROWSERDIRECTORYPROVIDER_CONTRACTID },
new file mode 100644
--- /dev/null
+++ b/browser/components/contextualidentity/test/browser/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc"
+  ]
+}
--- a/browser/components/contextualidentity/test/browser/browser_usercontext.js
+++ b/browser/components/contextualidentity/test/browser/browser_usercontext.js
@@ -75,17 +75,16 @@ add_task(function* test() {
     yield BrowserTestUtils.browserLoaded(browser);
 
     // get the title
     let title = browser.contentDocument.title.trim().split("|");
 
     // check each item in the title and validate it meets expectatations
     for (let part of title) {
       let [storageMethodName, value] = part.split("=");
-      let is_f = storageMethodName == "cookie" ? is : todo_is;
-      is_f(value, expectedContext,
+      is(value, expectedContext,
             "the title reflects the expected contextual identity of " +
             expectedContext + " for method " + storageMethodName + ": " + value);
     }
 
     gBrowser.removeTab(tab);
   }
 });
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -3347,17 +3347,17 @@ this.CustomizableUI = {
     );
   },
   /**
    * Obtain an array of all the area IDs known to CustomizableUI.
    * This array is created for you, so is modifiable without CustomizableUI
    * being affected.
    */
   get areas() {
-    return [area for ([area, props] of gAreas)];
+    return [...gAreas.keys()];
   },
   /**
    * Check what kind of area (toolbar or menu panel) an area is. This is
    * useful if you have a widget that needs to behave differently depending
    * on its location. Note that widget wrappers have a convenience getter
    * property (areaType) for this purpose.
    *
    * @param aArea the ID of the area whose type you want to know
@@ -3749,17 +3749,17 @@ function WidgetGroupWrapper(aWidget) {
     if (!placement) {
       return [];
     }
     let area = placement.area;
     let buildAreas = gBuildAreas.get(area);
     if (!buildAreas) {
       return [];
     }
-    return [this.forWindow(node.ownerDocument.defaultView) for (node of buildAreas)];
+    return Array.from(buildAreas, (node) => this.forWindow(node.ownerDocument.defaultView));
   });
 
   this.__defineGetter__("areaType", function() {
     let areaProps = gAreas.get(aWidget.currentArea);
     return areaProps && areaProps.get("type");
   });
 
   Object.freeze(this);
@@ -3860,17 +3860,17 @@ function XULWidgetGroupWrapper(aWidgetId
       return null;
     }
 
     let areaProps = gAreas.get(placement.area);
     return areaProps && areaProps.get("type");
   });
 
   this.__defineGetter__("instances", function() {
-    return [this.forWindow(win) for ([win,] of gBuildWindows)];
+    return Array.from(gBuildWindows, ([win,]) => this.forWindow(win));
   });
 
   Object.freeze(this);
 }
 
 /**
  * A XULWidgetSingleWrapper is a wrapper around a single instance of a XUL
  * widget in a particular window.
--- a/browser/components/customizableui/CustomizableWidgets.jsm
+++ b/browser/components/customizableui/CustomizableWidgets.jsm
@@ -1136,28 +1136,16 @@ const CustomizableWidgets = [
     }
   }, {
     id: "email-link-button",
     tooltiptext: "email-link-button.tooltiptext3",
     onCommand: function(aEvent) {
       let win = aEvent.view;
       win.MailIntegration.sendLinkForBrowser(win.gBrowser.selectedBrowser)
     }
-  }, {
-    id: "web-apps-button",
-    label: "web-apps-button.label",
-    tooltiptext: "web-apps-button.tooltiptext",
-    onCommand: function(aEvent) {
-      let win = aEvent.target &&
-                aEvent.target.ownerDocument &&
-                aEvent.target.ownerDocument.defaultView;
-      if (win && typeof win.BrowserOpenApps == "function") {
-        win.BrowserOpenApps();
-      }
-    }
   }];
 
 if (Services.prefs.getBoolPref("privacy.panicButton.enabled")) {
   CustomizableWidgets.push({
     id: "panic-button",
     type: "view",
     viewId: "PanelUI-panicView",
     _sanitizer: null,
--- a/browser/components/customizableui/PanelWideWidgetTracker.jsm
+++ b/browser/components/customizableui/PanelWideWidgetTracker.jsm
@@ -87,17 +87,17 @@ var PanelWideWidgetTracker = {
     }
     return rv;
   },
   adjustWidgets: function(aWidgetId, aMoveForwards) {
     if (this.adjusting) {
       return;
     }
     this.adjusting = true;
-    let widgetsAffected = [w for (w of gPanelPlacements) if (gWideWidgets.has(w))];
+    let widgetsAffected = gPanelPlacements.filter((w) => gWideWidgets.has(w));
     // If we're moving the wide widgets forwards (down/to the right in the panel)
     // we want to start with the last widgets. Otherwise we move widgets over other wide
     // widgets, which might mess up their order. Likewise, if moving backwards we should start with
     // the first widget and work our way down/right from there.
     let compareFn = aMoveForwards ? ((a, b) => a < b) : ((a, b) => a > b);
     widgetsAffected.sort((a, b) => compareFn(gPanelPlacements.indexOf(a),
                                              gPanelPlacements.indexOf(b)));
     for (let widget of widgetsAffected) {
--- a/browser/components/customizableui/content/jar.mn
+++ b/browser/components/customizableui/content/jar.mn
@@ -1,11 +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/.
 
 browser.jar:
   content/browser/customizableui/aboutCustomizing.xul
   content/browser/customizableui/panelUI.css
-* content/browser/customizableui/panelUI.js
+  content/browser/customizableui/panelUI.js
   content/browser/customizableui/panelUI.xml
   content/browser/customizableui/toolbar.xml
 
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -5,16 +5,18 @@
 XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
                                   "resource:///modules/CustomizableUI.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ScrollbarSampler",
                                   "resource:///modules/ScrollbarSampler.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
                                   "resource://gre/modules/Promise.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ShortcutUtils",
                                   "resource://gre/modules/ShortcutUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
+                                  "resource://gre/modules/AppConstants.jsm");
 
 /**
  * Maintains the state and dispatches events for the main menu panel.
  */
 
 const PanelUI = {
   /** Panel events that we listen for. **/
   get kEvents() {
@@ -483,31 +485,32 @@ const PanelUI = {
       }
       button.setAttribute("class", "subviewbutton");
       fragment.appendChild(button);
     }
     items.appendChild(fragment);
   },
 
   _updateQuitTooltip: function() {
-#ifndef XP_WIN
-#ifdef XP_MACOSX
-    let tooltipId = "quit-button.tooltiptext.mac";
-#else
-    let tooltipId = "quit-button.tooltiptext.linux2";
-#endif
+    if (AppConstants.platform == "win") {
+      return;
+    }
+
+    let tooltipId = AppConstants.platform == "macosx" ?
+                    "quit-button.tooltiptext.mac" :
+                    "quit-button.tooltiptext.linux2";
+
     let brands = Services.strings.createBundle("chrome://branding/locale/brand.properties");
     let stringArgs = [brands.GetStringFromName("brandShortName")];
 
     let key = document.getElementById("key_quitApplication");
     stringArgs.push(ShortcutUtils.prettifyShortcut(key));
     let tooltipString = CustomizableUI.getLocalizedProperty({x: tooltipId}, "x", stringArgs);
     let quitButton = document.getElementById("PanelUI-quit");
     quitButton.setAttribute("tooltiptext", tooltipString);
-#endif
   },
 
   _overlayScrollListenerBoundFn: null,
   _overlayScrollListener: function(aMQL) {
     ScrollbarSampler.resetSystemScrollbarWidth();
     this._scrollWidth = null;
   },
 };
--- a/browser/components/customizableui/content/toolbar.xml
+++ b/browser/components/customizableui/content/toolbar.xml
@@ -74,18 +74,19 @@
                 toolbox.palette = node;
                 toolbox.removeChild(node);
                 break;
               }
             }
           }
 
           // pass the current set of children for comparison with placements:
-          let children = [node.id for (node of this.childNodes)
-                          if (node.getAttribute("skipintoolbarset") != "true" && node.id)];
+          let children = Array.from(this.childNodes)
+                              .filter(node => node.getAttribute("skipintoolbarset") != "true" && node.id)
+                              .map(node => node.id);
           CustomizableUI.registerToolbarNode(this, children);
         ]]></body>
       </method>
 
       <method name="handleEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
           if (aEvent.type == "overflow" && aEvent.detail > 0) {
@@ -199,17 +200,17 @@
           return orderedPlacements.filter((x) => currentWidgets.has(x)).join(',');
         ]]></getter>
         <setter><![CDATA[
           // Get list of new and old ids:
           let newVal = (val || '').split(',').filter(x => x);
           let oldIds = CustomizableUI.getWidgetIdsInArea(this.id);
 
           // Get a list of items only in the new list
-          let newIds = [id for (id of newVal) if (oldIds.indexOf(id) == -1)];
+          let newIds = newVal.filter(id => oldIds.indexOf(id) == -1);
           CustomizableUI.beginBatchUpdate();
           try {
             for (let newId of newIds) {
               oldIds = CustomizableUI.getWidgetIdsInArea(this.id);
               let nextId = newId;
               let pos;
               do {
                 // Get the next item
@@ -220,17 +221,17 @@
               } while (pos == -1 && nextId);
               if (pos == -1) {
                 pos = null; // We didn't find anything, insert at the end
               }
               CustomizableUI.addWidgetToArea(newId, this.id, pos);
             }
 
             let currentIds = this.currentSet.split(',');
-            let removedIds = [id for (id of currentIds) if (newIds.indexOf(id) == -1 && newVal.indexOf(id) == -1)];
+            let removedIds = currentIds.filter(id => newIds.indexOf(id) == -1 && newVal.indexOf(id) == -1);
             for (let removedId of removedIds) {
               CustomizableUI.removeWidgetFromArea(removedId);
             }
           } finally {
             CustomizableUI.endBatchUpdate();
           }
         ]]></setter>
       </property>
@@ -580,17 +581,17 @@
       </method>
       <property name="customizationTarget" readonly="true">
         <getter><![CDATA[
           return this;
         ]]></getter>
       </property>
       <property name="currentSet">
         <getter><![CDATA[
-          return [node.id for (node of this.children)].join(',');
+          return Array.from(this.children, node => node.id).join(",");
         ]]></getter>
         <setter><![CDATA[
           let v = val.split(',');
           let newButtons = v.filter(x => x && (!this._whiteListed.has(x) &&
                                                !CustomizableUI.isSpecialWidget(x) &&
                                                !this._currentSetMigrated.has(x)));
           for (let newButton of newButtons) {
             this._currentSetMigrated.add(newButton);
new file mode 100644
--- /dev/null
+++ b/browser/components/customizableui/test/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../testing/mochitest/browser.eslintrc"
+  ]
+}
--- a/browser/components/customizableui/test/browser_880164_customization_context_menus.js
+++ b/browser/components/customizableui/test/browser_880164_customization_context_menus.js
@@ -1,14 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
+requestLongerTimeout(2);
+
 const isOSX = (Services.appinfo.OS === "Darwin");
 
 // Right-click on the home button should
 // show a context menu with options to move it.
 add_task(function() {
   let contextMenu = document.getElementById("toolbar-context-menu");
   let shownPromise = popupShown(contextMenu);
   let homeButton = document.getElementById("home-button");
--- a/browser/components/customizableui/test/browser_938980_navbar_collapsed.js
+++ b/browser/components/customizableui/test/browser_938980_navbar_collapsed.js
@@ -1,14 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
+requestLongerTimeout(2);
+
 var bookmarksToolbar = document.getElementById("PersonalToolbar");
 var navbar = document.getElementById("nav-bar");
 var tabsToolbar = document.getElementById("TabsToolbar");
 
 // Customization reset should restore visibility to default-visible toolbars.
 add_task(function() {
   is(navbar.collapsed, false, "Test should start with navbar visible");
   setToolbarVisibility(navbar, false);
--- a/browser/components/customizableui/test/browser_942581_unregisterArea_keeps_placements.js
+++ b/browser/components/customizableui/test/browser_942581_unregisterArea_keeps_placements.js
@@ -81,17 +81,17 @@ add_task(function() {
     } else {
       CustomizableUI.destroyWidget(widget);
     }
   }
 });
 
 function checkAbstractAndRealPlacements(aNode, aExpectedPlacements) {
   assertAreaPlacements(kToolbarName, aExpectedPlacements);
-  let physicalWidgetIds = [node.id for (node of aNode.childNodes)];
+  let physicalWidgetIds = Array.from(aNode.childNodes, (node) => node.id);
   placementArraysEqual(aNode.id, physicalWidgetIds, aExpectedPlacements);
 }
 
 function checkWidgetFates(aWidgetIds) {
   for (let widget of aWidgetIds) {
     ok(!CustomizableUI.getPlacementOfWidget(widget), "Widget should be in palette");
     ok(!document.getElementById(widget), "Widget should not be in the DOM");
     let widgetInPalette = !!gNavToolbox.palette.querySelector("#" + widget);
--- a/browser/components/customizableui/test/browser_970511_undo_restore_default.js
+++ b/browser/components/customizableui/test/browser_970511_undo_restore_default.js
@@ -1,14 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
+requestLongerTimeout(2);
+
 // Restoring default should show an "undo" option which undoes the restoring operation.
 add_task(function() {
   let homeButtonId = "home-button";
   CustomizableUI.removeWidgetFromArea(homeButtonId);
   yield startCustomizing();
   ok(!CustomizableUI.inDefaultState, "Not in default state to begin with");
   is(CustomizableUI.getPlacementOfWidget(homeButtonId), null, "Home button is in palette");
   let undoResetButton = document.getElementById("customization-undo-reset-button");
--- a/browser/components/customizableui/test/browser_975719_customtoolbars_behaviour.js
+++ b/browser/components/customizableui/test/browser_975719_customtoolbars_behaviour.js
@@ -1,14 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
+requestLongerTimeout(2);
+
 const kXULWidgetId = "a-test-button"; // we'll create a button with this ID.
 
 add_task(function setup() {
   // create a XUL button and add it to the palette.
   createDummyXULButton(kXULWidgetId, "test-button");
 });
 
 add_task(function customizeToolbarAndKeepIt() {
--- a/browser/components/customizableui/test/browser_bootstrapped_custom_toolbar.js
+++ b/browser/components/customizableui/test/browser_bootstrapped_custom_toolbar.js
@@ -1,14 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
+requestLongerTimeout(2);
+
 const kTestBarID = "testBar";
 const kWidgetID = "characterencoding-button";
 
 function createTestBar(aLegacy) {
   let testBar = document.createElement("toolbar");
   testBar.id = kTestBarID;
   testBar.setAttribute("customizable", "true");
   CustomizableUI.registerArea(kTestBarID, {
new file mode 100644
--- /dev/null
+++ b/browser/components/dirprovider/tests/unit/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../../testing/xpcshell/xpcshell.eslintrc"
+  ]
+}
--- a/browser/components/downloads/content/downloads.js
+++ b/browser/components/downloads/content/downloads.js
@@ -466,21 +466,17 @@ const DownloadsPanel = {
         DownloadsView.richListBox.firstChild) {
       DownloadsView.richListBox.focus();
       DownloadsView.richListBox.selectedItem = DownloadsView.richListBox.lastChild;
       aEvent.preventDefault();
       return;
     }
 
     let pasting = aEvent.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_V &&
-#ifdef XP_MACOSX
-                  aEvent.metaKey;
-#else
-                  aEvent.ctrlKey;
-#endif
+                  aEvent.getModifierState("Accel");
 
     if (!pasting) {
       return;
     }
 
     DownloadsCommon.log("Received a paste event.");
 
     let trans = Cc["@mozilla.org/widget/transferable;1"]
--- a/browser/components/downloads/jar.mn
+++ b/browser/components/downloads/jar.mn
@@ -1,17 +1,17 @@
 # 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/.
 
 browser.jar:
 *       content/browser/downloads/download.xml           (content/download.xml)
         content/browser/downloads/download.css           (content/download.css)
         content/browser/downloads/downloads.css          (content/downloads.css)
-*       content/browser/downloads/downloads.js           (content/downloads.js)
+        content/browser/downloads/downloads.js           (content/downloads.js)
 *       content/browser/downloads/downloadsOverlay.xul   (content/downloadsOverlay.xul)
         content/browser/downloads/indicator.js           (content/indicator.js)
         content/browser/downloads/indicatorOverlay.xul   (content/indicatorOverlay.xul)
 *       content/browser/downloads/allDownloadsViewOverlay.xul (content/allDownloadsViewOverlay.xul)
         content/browser/downloads/allDownloadsViewOverlay.js  (content/allDownloadsViewOverlay.js)
         content/browser/downloads/allDownloadsViewOverlay.css (content/allDownloadsViewOverlay.css)
 *       content/browser/downloads/contentAreaDownloadsView.xul (content/contentAreaDownloadsView.xul)
         content/browser/downloads/contentAreaDownloadsView.js  (content/contentAreaDownloadsView.js)
new file mode 100644
--- /dev/null
+++ b/browser/components/downloads/test/browser/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc"
+  ]
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/downloads/test/unit/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../../testing/xpcshell/xpcshell.eslintrc"
+  ]
+}
--- a/browser/components/extensions/ext-contextMenus.js
+++ b/browser/components/extensions/ext-contextMenus.js
@@ -7,126 +7,154 @@ Cu.import("resource://gre/modules/MatchP
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 var {
   EventManager,
   runSafe,
 } = ExtensionUtils;
 
-
 // Map[Extension -> Map[ID -> MenuItem]]
 // Note: we want to enumerate all the menu items so
 // this cannot be a weak map.
 var contextMenuMap = new Map();
 
+// Map[Extension -> MenuItem]
+var rootItems = new Map();
+
 // Not really used yet, will be used for event pages.
 var onClickedCallbacksMap = new WeakMap();
 
 // If id is not specified for an item we use an integer.
 var nextID = 0;
 
+var gMaxLabelLength = 64;
+
 // When a new contextMenu is opened, this function is called and
 // we populate the |xulMenu| with all the items from extensions
 // to be displayed. We always clear all the items again when
-// popuphidden fires. Since most of the info we need is already
-// calculated in nsContextMenu.jsm we simple reuse its flags here.
-// For remote processes there is a gContextMenuContentData where all
-// the important info is stored from the child process. We get
-// this data in |contextData|.
+// popuphidden fires.
 var menuBuilder = {
   build: function(contextData) {
-    // TODO: icons should be set for items
     let xulMenu = contextData.menu;
     xulMenu.addEventListener("popuphidden", this);
-    let doc = xulMenu.ownerDocument;
-    for (let [ext, menuItemMap] of contextMenuMap) {
-      let parentMap = new Map();
-      let topLevelItems = new Set();
-      for (let entry of menuItemMap) {
-        // We need a closure over |item|, and we don't currently get a
-        // fresh binding per loop if we declare it in the loop head.
-        let [id, item] = entry;
-
-        if (item.enabledForContext(contextData)) {
-          let element;
-          if (item.isMenu) {
-            element = doc.createElement("menu");
-            // Menu elements need to have a menupopup child for
-            // its menu items.
-            let menupopup = doc.createElement("menupopup");
-            element.appendChild(menupopup);
-            // Storing the menupopup in a map, so we can find it for its
-            // menu item children later.
-            parentMap.set(id, menupopup);
-          } else {
-            element =
-             (item.type == "separator") ? doc.createElement("menuseparator")
-                                        : doc.createElement("menuitem");
-          }
-
-          // FIXME: handle %s in the title
-          element.setAttribute("label", item.title);
-
-          if (!item.enabled) {
-            element.setAttribute("disabled", true);
-          }
-
-          let parentId = item.parentId;
-          if (parentId && parentMap.has(parentId)) {
-            // If parentId is set we have to look up its parent
-            // and appened to its menupopup.
-            let parentElement = parentMap.get(parentId);
-            parentElement.appendChild(element);
-          } else {
-            topLevelItems.add(element);
-          }
-
-          element.addEventListener("command", event => { // eslint-disable-line mozilla/balanced-listeners
-            item.tabManager.addActiveTabPermission();
-            if (item.onclick) {
-              let clickData = item.getClickData(contextData, event);
-              runSafe(item.extContext, item.onclick, clickData);
-            }
-          });
-        }
+    this.xulMenu = xulMenu;
+    for (let [, root] of rootItems) {
+      let rootElement = this.buildElementWithChildren(root, contextData);
+      if (!rootElement.childNodes.length) {
+        // If the root has no visible children, there is no reason to show
+        // the root menu item itself either.
+        continue;
       }
-      if (topLevelItems.size > 1) {
-        // If more than one top level items are visible, callopse them.
-        let top = doc.createElement("menu");
-        top.setAttribute("label", ext.name);
-        top.setAttribute("ext-type", "top-level-menu");
-        let menupopup = doc.createElement("menupopup");
-        top.appendChild(menupopup);
-        for (let i of topLevelItems) {
-          menupopup.appendChild(i);
-        }
-        xulMenu.appendChild(top);
-        this._itemsToCleanUp.add(top);
-      } else if (topLevelItems.size == 1) {
-        // If there is only one visible item, we can just append it.
-        let singleItem = topLevelItems.values().next().value;
-        xulMenu.appendChild(singleItem);
-        this._itemsToCleanUp.add(singleItem);
-      }
+      rootElement.setAttribute("ext-type", "top-level-menu");
+      rootElement = this.removeTopLevelMenuIfNeeded(rootElement);
+      xulMenu.appendChild(rootElement);
+      this.itemsToCleanUp.add(rootElement);
     }
   },
 
-  handleEvent: function(event) {
-    let target = event.target;
+  buildElementWithChildren(item, contextData) {
+    let element = this.buildSingleElement(item, contextData);
+    for (let child of item.children) {
+      if (child.enabledForContext(contextData)) {
+        let childElement = this.buildElementWithChildren(child, contextData);
+        // Here element must be a menu element and its first child
+        // is a menupopup, we have to append its children to this
+        // menupopup.
+        element.firstChild.appendChild(childElement);
+      }
+    }
+
+    return element;
+  },
 
-    target.removeEventListener("popuphidden", this);
-    for (let item of this._itemsToCleanUp) {
-      target.removeChild(item);
+  removeTopLevelMenuIfNeeded(element) {
+    // If there is only one visible top level element we don't need the
+    // root menu element for the extension.
+    let menuPopup = element.firstChild;
+    if (menuPopup && menuPopup.childNodes.length == 1) {
+      let onlyChild = menuPopup.firstChild;
+      onlyChild.remove();
+      return onlyChild;
     }
-    // Let's detach the top level items.
-    this._itemsToCleanUp.clear();
+
+    return element;
+  },
+
+  buildSingleElement(item, contextData) {
+    let doc = contextData.menu.ownerDocument;
+    let element;
+    if (item.children.length > 0) {
+      element = this.createMenuElement(doc, item);
+    } else if (item.type == "separator") {
+      element = doc.createElement("menuseparator");
+    } else {
+      element = doc.createElement("menuitem");
+    }
+
+    return this.customizeElement(element, item, contextData);
   },
 
-  _itemsToCleanUp: new Set(),
+  createMenuElement(doc, item) {
+    let element = doc.createElement("menu");
+    // Menu elements need to have a menupopup child for
+    // its menu items.
+    let menupopup = doc.createElement("menupopup");
+    element.appendChild(menupopup);
+    return element;
+  },
+
+  customizeElement(element, item, contextData) {
+    let label = item.title;
+    if (label) {
+      if (contextData.isTextSelected && label.indexOf("%s") > -1) {
+        let selection = contextData.selectionText;
+        // The rendering engine will truncate the title if it's longer than 64 characters.
+        // But if it makes sense let's try truncate selection text only, to handle cases like
+        // 'look up "%s" in MyDictionary' more elegantly.
+        let maxSelectionLength = gMaxLabelLength - label.length + 2;
+        if (maxSelectionLength > 4) {
+          selection = selection.substring(0, maxSelectionLength - 3) + "...";
+        }
+        label = label.replace(/%s/g, selection);
+      }
+
+      element.setAttribute("label", label);
+    }
+
+    if (!item.enabled) {
+      element.setAttribute("disabled", true);
+    }
+
+    element.addEventListener("command", event => {  // eslint-disable-line mozilla/balanced-listeners
+      item.tabManager.addActiveTabPermission();
+      if (item.onclick) {
+        let clickData = item.getClickData(contextData, event);
+        runSafe(item.extContext, item.onclick, clickData);
+      }
+    });
+
+    return element;
+  },
+
+  handleEvent: function(event) {
+    if (this.xulMenu != event.target || event.type != "popuphidden") {
+      return;
+    }
+
+    delete this.xulMenu;
+    let target = event.target;
+    target.removeEventListener("popuphidden", this);
+    for (let item of this.itemsToCleanUp) {
+      item.remove();
+    }
+    this.itemsToCleanUp.clear();
+  },
+
+  itemsToCleanUp: new Set(),
 };
 
 function contextMenuObserver(subject, topic, data) {
   subject = subject.wrappedJSObject;
   menuBuilder.build(subject);
 }
 
 function getContexts(contextData) {
@@ -160,121 +188,154 @@ function getContexts(contextData) {
 
   if (contextData.onAudio) {
     contexts.add("audio");
   }
 
   return contexts;
 }
 
-function MenuItem(extension, extContext, createProperties) {
+function MenuItem(extension, extContext, createProperties, isRoot = false) {
   this.extension = extension;
   this.extContext = extContext;
-
+  this.children = [];
+  this.parent = null;
   this.tabManager = TabManager.for(extension);
 
-  this.init(createProperties);
+  this.setDefaults();
+  this.setProps(createProperties);
+  if (!this.hasOwnProperty("_id")) {
+    this.id = nextID++;
+  }
+  // If the item is not the root and has no parent
+  // it must be a child of the root.
+  if (!isRoot && !this.parent) {
+    this.root.addChild(this);
+  }
 }
 
 MenuItem.prototype = {
-  // init is called from the MenuItem ctor and from update. The |update|
-  // flag is for the later case.
-  init(createProperties, update = false) {
-    let item = this;
-    // return true if the prop was set on |this|
-    function parseProp(propName, defaultValue = null) {
-      if (createProperties[propName] !== null) {
-        item[propName] = createProperties[propName];
-        return true;
-      } else if (!update && defaultValue !== null) {
-        item[propName] = defaultValue;
-        return true;
+  setProps(createProperties) {
+    for (let propName in createProperties) {
+      if (createProperties[propName] === null) {
+        // Omitted optional argument.
+        continue;
       }
-      return false;
-    }
-
-    if (!update) {
-      let isIdUsed = contextMenuMap.get(this.extension).has(createProperties.id);
-      if (createProperties.id && isIdUsed) {
-        throw new Error("Id already exists");
-      }
-      this.id = createProperties.id ? createProperties.id : nextID++;
+      this[propName] = createProperties[propName];
     }
 
-    parseProp("type", "normal");
-    parseProp("title");
-    parseProp("checked", false);
-    parseProp("contexts", ["all"]);
-
-    if (createProperties.onclick !== null) {
-      this.onclick = createProperties.onclick;
-    }
-
-    if (parseProp("parentId")) {
-      let found = false;
-      let menuMap = contextMenuMap.get(this.extension);
-      if (menuMap.has(this.parentId)) {
-        found = true;
-        menuMap.get(this.parentId).isMenu = true;
-      }
-      if (!found) {
-        throw new Error("MenuItem with this parentId not found");
-      }
-    } else {
-      this.parentId = undefined;
-    }
-
-    if (parseProp("documentUrlPatterns")) {
+    if (createProperties.documentUrlPatterns != null) {
       this.documentUrlMatchPattern = new MatchPattern(this.documentUrlPatterns);
     }
 
-    if (parseProp("targetUrlPatterns")) {
-      this.targetUrlPatterns = new MatchPattern(this.targetUrlPatterns);
+    if (createProperties.targetUrlPatterns != null) {
+      this.targetUrlMatchPattern = new MatchPattern(this.targetUrlPatterns);
+    }
+  },
+
+  setDefaults() {
+    this.setProps({
+      type: "normal",
+      checked: "false",
+      contexts: ["all"],
+      enabled: "true",
+    });
+  },
+
+  set id(id) {
+    if (this.hasOwnProperty("_id")) {
+      throw new Error("Id of a MenuItem cannot be changed");
+    }
+    let isIdUsed = contextMenuMap.get(this.extension).has(id);
+    if (isIdUsed) {
+      throw new Error("Id already exists");
+    }
+    this._id = id;
+  },
+
+  get id() {
+    return this._id;
+  },
+
+  ensureValidParentId(parentId) {
+    if (parentId === undefined) {
+      return;
+    }
+    let menuMap = contextMenuMap.get(this.extension);
+    if (!menuMap.has(parentId)) {
+      throw new Error("Could not find any MenuItem with id: " + parentId);
+    }
+    for (let item = menuMap.get(parentId); item; item = item.parent) {
+      if (item === this) {
+        throw new Error("MenuItem cannot be an ancestor (or self) of its new parent.");
+      }
+    }
+  },
+
+  set parentId(parentId) {
+    this.ensureValidParentId(parentId);
+
+    if (this.parent) {
+      this.parent.detachChild(this);
     }
 
-    parseProp("enabled", true);
+    if (parentId === undefined) {
+      this.root.addChild(this);
+    } else {
+      let menuMap = contextMenuMap.get(this.extension);
+      menuMap.get(parentId).addChild(this);
+    }
+  },
+
+  get parentId() {
+    return this.parent ? this.parent.id : undefined;
+  },
+
+  addChild(child) {
+    if (child.parent) {
+      throw new Error("Child MenuItem already has a parent.");
+    }
+    this.children.push(child);
+    child.parent = this;
+  },
+
+  detachChild(child) {
+    let idx = this.children.indexOf(child);
+    if (idx < 0) {
+      throw new Error("Child MenuItem not found, it cannot be removed.");
+    }
+    this.children.splice(idx, 1);
+    child.parent = null;
+  },
+
+  get root() {
+    let extension = this.extension;
+    if (!rootItems.has(extension)) {
+      let root = new MenuItem(extension, this.context,
+                              { title: extension.name },
+                              /* isRoot = */ true);
+      rootItems.set(extension, root);
+    }
+
+    return rootItems.get(extension);
   },
 
   remove() {
-    let menuMap = contextMenuMap.get(this.extension);
-    // We want to remove all the items that has |this| in its parent chain.
-    // The |checked| map is only an optimisation to avoid checking any item
-    // twice in the algorithm.
-    let checked = new Map();
-    function hasAncestorWithId(item, id) {
-      if (checked.has(item)) {
-        return checked.get(item);
-      }
-      if (item.parentId === undefined) {
-        checked.set(item, false);
-        return false;
-      }
-      let parent = menuMap.get(item.parentId);
-      if (!parent) {
-        checked.set(item, false);
-        return false;
-      }
-      if (parent.id === id) {
-        checked.set(item, true);
-        return true;
-      }
-      let rv = hasAncestorWithId(parent, id);
-      checked.set(item, rv);
-      return rv;
+    if (this.parent) {
+      this.parent.detachChild(this);
+    }
+    let children = this.children.slice(0);
+    for (let child of children) {
+      child.remove();
     }
 
-    let toRemove = new Set();
-    toRemove.add(this.id);
-    for (let [, item] of menuMap) {
-      if (hasAncestorWithId(item, this.id)) {
-        toRemove.add(item.id);
-      }
-    }
-    for (let id of toRemove) {
-      menuMap.delete(id);
+    let menuMap = contextMenuMap.get(this.extension);
+    menuMap.delete(this.id);
+    if (this.root == this) {
+      rootItems.delete(this.extension);
     }
   },
 
   getClickData(contextData, event) {
     let mediaType;
     if (contextData.onVideo) {
       mediaType = "video";
     }
@@ -290,64 +351,59 @@ MenuItem.prototype = {
     };
 
     function setIfDefined(argName, value) {
       if (value) {
         clickData[argName] = value;
       }
     }
 
-    let tab = contextData.tab ? TabManager.convert(this.extension, contextData.tab) : undefined;
+    let tab = contextData.tab ? TabManager.convert(this.extension, contextData.tab)
+                              : undefined;
 
     setIfDefined("parentMenuItemId", this.parentId);
     setIfDefined("mediaType", mediaType);
     setIfDefined("linkUrl", contextData.linkUrl);
     setIfDefined("srcUrl", contextData.srcUrl);
     setIfDefined("pageUrl", contextData.pageUrl);
     setIfDefined("frameUrl", contextData.frameUrl);
     setIfDefined("selectionText", contextData.selectionText);
     setIfDefined("editable", contextData.onEditableArea);
     setIfDefined("tab", tab);
 
     return clickData;
   },
 
   enabledForContext(contextData) {
-    let enabled = false;
     let contexts = getContexts(contextData);
-    for (let c of this.contexts) {
-      if (contexts.has(c)) {
-        enabled = true;
-        break;
-      }
-    }
-    if (!enabled) {
+    if (!this.contexts.some(n => contexts.has(n))) {
       return false;
     }
 
-    if (this.documentUrlMatchPattern &&
-        !this.documentUrlMatchPattern.matches(contextData.documentURIObject)) {
+    let docPattern = this.documentUrlMatchPattern;
+    if (docPattern && !docPattern.matches(contextData.pageUrl)) {
       return false;
     }
 
-    if (this.targetUrlPatterns &&
-        (contextData.onImage || contextData.onAudio || contextData.onVideo) &&
-        !this.targetUrlPatterns.matches(contextData.mediaURL)) {
+    let isMedia = contextData.onImage || contextData.onAudio || contextData.onVideo;
+    let targetPattern = this.targetUrlMatchPattern;
+    if (isMedia && targetPattern && !targetPattern.matches(contextData.srcURL)) {
       // TODO: double check if mediaURL is always set when we need it
       return false;
     }
 
     return true;
   },
 };
 
 var extCount = 0;
 /* eslint-disable mozilla/balanced-listeners */
 extensions.on("startup", (type, extension) => {
   contextMenuMap.set(extension, new Map());
+  rootItems.delete(extension);
   if (++extCount == 1) {
     Services.obs.addObserver(contextMenuObserver,
                              "on-build-contextmenu",
                              false);
   }
 });
 
 extensions.on("shutdown", (type, extension) => {
@@ -369,17 +425,17 @@ extensions.registerSchemaAPI("contextMen
           runSafe(context, callback);
         }
         return menuItem.id;
       },
 
       update: function(id, updateProperties, callback) {
         let menuItem = contextMenuMap.get(extension).get(id);
         if (menuItem) {
-          menuItem.init(updateProperties, true);
+          menuItem.setProps(updateProperties);
         }
         if (callback) {
           runSafe(context, callback);
         }
       },
 
       remove: function(id, callback) {
         let menuItem = contextMenuMap.get(extension).get(id);
@@ -387,18 +443,19 @@ extensions.registerSchemaAPI("contextMen
           menuItem.remove();
         }
         if (callback) {
           runSafe(context, callback);
         }
       },
 
       removeAll: function(callback) {
-        for (let [, menuItem] of contextMenuMap.get(extension)) {
-          menuItem.remove();
+        let root = rootItems.get(extension);
+        if (root) {
+          root.remove();
         }
         if (callback) {
           runSafe(context, callback);
         }
       },
 
       // TODO: implement this once event pages are ready.
       onClicked: new EventManager(context, "contextMenus.onClicked", fire => {
--- a/browser/components/extensions/ext-tabs.js
+++ b/browser/components/extensions/ext-tabs.js
@@ -531,12 +531,89 @@ extensions.registerSchemaAPI("tabs", nul
         let mm = tab.linkedBrowser.messageManager;
 
         let recipient = {extensionId: extension.id};
         if (options && options.frameId !== null) {
           recipient.frameId = options.frameId;
         }
         return context.messenger.sendMessage(mm, message, recipient, responseCallback);
       },
+
+      move: function(tabIds, moveProperties, callback) {
+        let index = moveProperties.index;
+        let tabsMoved = [];
+        if (!Array.isArray(tabIds)) {
+          tabIds = [tabIds];
+        }
+
+        let destinationWindow = null;
+        if (moveProperties.windowId !== null) {
+          destinationWindow = WindowManager.getWindow(moveProperties.windowId);
+          // Ignore invalid window.
+          if (!destinationWindow) {
+            return;
+          }
+        }
+
+        /*
+          Indexes are maintained on a per window basis so that a call to
+            move([tabA, tabB], {index: 0})
+              -> tabA to 0, tabB to 1 if tabA and tabB are in the same window
+            move([tabA, tabB], {index: 0})
+              -> tabA to 0, tabB to 0 if tabA and tabB are in different windows
+        */
+        let indexMap = new Map();
+
+        for (let tabId of tabIds) {
+          let tab = TabManager.getTab(tabId);
+          // Ignore invalid tab ids.
+          if (!tab) {
+            continue;
+          }
+
+          // If the window is not specified, use the window from the tab.
+          let window = destinationWindow || tab.ownerDocument.defaultView;
+          let windowId = WindowManager.getId(window);
+          let gBrowser = window.gBrowser;
+
+          let getInsertionPoint = () => {
+            let point = indexMap.get(window) || index;
+            // If the index is -1 it should go to the end of the tabs.
+            if (point == -1) {
+              point = gBrowser.tabs.length;
+            }
+            indexMap.set(window, point + 1);
+            return point;
+          };
+
+          if (WindowManager.getId(tab.ownerDocument.defaultView) !== windowId) {
+            // If the window we are moving the tab in is different, then move the tab
+            // to the new window.
+            let newTab = gBrowser.addTab("about:blank");
+            let newBrowser = gBrowser.getBrowserForTab(newTab);
+            gBrowser.updateBrowserRemotenessByURL(newBrowser, tab.linkedBrowser.currentURI.spec);
+            newBrowser.stop();
+            // This is necessary for getter side-effects.
+            void newBrowser.docShell;
+
+            if (tab.pinned) {
+              gBrowser.pinTab(newTab);
+            }
+
+            gBrowser.moveTabTo(newTab, getInsertionPoint());
+
+            tab.parentNode._finishAnimateTabMove();
+            gBrowser.swapBrowsersAndCloseOther(newTab, tab);
+          } else {
+            // If the window we are moving is the same, just move the tab.
+            gBrowser.moveTabTo(tab, getInsertionPoint());
+          }
+          tabsMoved.push(tab);
+        }
+
+        if (callback) {
+          runSafe(context, callback, tabsMoved.map(tab => TabManager.convert(extension, tab)));
+        }
+      },
     },
   };
   return self;
 });
--- a/browser/components/extensions/ext-utils.js
+++ b/browser/components/extensions/ext-utils.js
@@ -39,17 +39,16 @@ global.IconDetails = {
       if (details.imageData) {
         let imageData = details.imageData;
 
         // The global might actually be from Schema.jsm, which
         // normalizes most of our arguments. In that case it won't have
         // an ImageData property. But Schema.jsm doesn't normalize
         // actual ImageData objects, so they will come from a global
         // with the right property.
-        let global = Cu.getGlobalForObject(imageData);
         if (instanceOf(imageData, "ImageData")) {
           imageData = {"19": imageData};
         }
 
         for (let size of Object.keys(imageData)) {
           if (!INTEGER.test(size)) {
             throw new Error(`Invalid icon size ${size}, must be an integer`);
           }
--- a/browser/components/extensions/test/browser/.eslintrc
+++ b/browser/components/extensions/test/browser/.eslintrc
@@ -1,44 +1,22 @@
 {
-  "extends": "../../.eslintrc",
+  "extends": "../../../../../testing/mochitest/browser.eslintrc",
+
+  "env": {
+    "webextensions": true,
+  },
 
   "globals": {
-    // DOM window globals
-    "CustomEvent": false,
-    "document": false,
-    "ImageData": false,
-    "MouseEvent": false,
-    "setTimeout": false,
-    "window": false,
-    "XMLHttpRequest": false,
-
-    "gBrowser": false,
-
-    "sendAsyncMessage": false,
-
     "NetUtil": true,
     "XPCOMUtils": true,
     "Task": true,
 
-    "browser": false,
-
     // Test harness globals
-    "add_task": false,
-    "BrowserTestUtils": false,
-    "ContentTask": false,
-    "EventUtils": false,
     "ExtensionTestUtils": false,
-    "info": false,
-    "is": false,
-    "ok": false,
-    "registerCleanupFunction": false,
-    "SimpleTest": false,
-    "SpecialPowers": false,
-    "waitForFocus": false,
 
     "clickBrowserAction": true,
     "clickPageAction": true,
     "CustomizableUI": true,
     "focusWindow": true,
     "makeWidgetId": true,
   }
 }
--- a/browser/components/extensions/test/browser/browser.ini
+++ b/browser/components/extensions/test/browser/browser.ini
@@ -22,11 +22,13 @@ support-files =
 [browser_ext_getViews.js]
 [browser_ext_tabs_executeScript_good.js]
 [browser_ext_tabs_executeScript_bad.js]
 [browser_ext_tabs_query.js]
 [browser_ext_tabs_getCurrent.js]
 [browser_ext_tabs_update.js]
 [browser_ext_tabs_onUpdated.js]
 [browser_ext_tabs_sendMessage.js]
+[browser_ext_tabs_move.js]
+[browser_ext_tabs_move_window.js]
 [browser_ext_windows_update.js]
 [browser_ext_contentscript_connect.js]
 [browser_ext_tab_runtimeConnect.js]
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus.js
+++ b/browser/components/extensions/test/browser/browser_ext_contextMenus.js
@@ -17,43 +17,54 @@ add_task(function* () {
     },
 
     background: function() {
       // A generic onclick callback function.
       function genericOnClick(info) {
         browser.test.sendMessage("menuItemClick", JSON.stringify(info));
       }
 
-      browser.contextMenus.create({ "contexts": ["all"], "type": "separator" });
+      browser.contextMenus.create({ contexts: ["all"], type: "separator" });
 
       let contexts = ["page", "selection", "image"];
       for (let i = 0; i < contexts.length; i++) {
         let context = contexts[i];
         let title = context;
-        browser.contextMenus.create({ "title": title, "contexts": [context], "id": "ext-" + context,
-                                      "onclick": genericOnClick });
+        browser.contextMenus.create({ title: title, contexts: [context], id: "ext-" + context,
+                                      onclick: genericOnClick });
         if (context == "selection") {
-          browser.contextMenus.update("ext-selection", { "title": "selection-edited" });
+          browser.contextMenus.update("ext-selection", {
+            title: "selection is: '%s'",
+            onclick: (info) => {
+              browser.contextMenus.removeAll();
+              genericOnClick(info);
+            },
+          });
         }
       }
 
-      let parent = browser.contextMenus.create({ "title": "parent" });
+      let parent = browser.contextMenus.create({ title: "parent" });
       browser.contextMenus.create(
-        { "title": "child1", "parentId": parent, "onclick": genericOnClick });
-      browser.contextMenus.create(
-        { "title": "child2", "parentId": parent, "onclick": genericOnClick });
+        { title: "child1", parentId: parent, onclick: genericOnClick });
+      let child2 = browser.contextMenus.create(
+        { title: "child2", parentId: parent, onclick: genericOnClick });
 
-      let parentToDel = browser.contextMenus.create({ "title": "parentToDel" });
+      let parentToDel = browser.contextMenus.create({ title: "parentToDel" });
       browser.contextMenus.create(
-        { "title": "child1", "parentId": parentToDel, "onclick": genericOnClick });
+        { title: "child1", parentId: parentToDel, onclick: genericOnClick });
       browser.contextMenus.create(
-        { "title": "child2", "parentId": parentToDel, "onclick": genericOnClick });
+        { title: "child2", parentId: parentToDel, onclick: genericOnClick });
       browser.contextMenus.remove(parentToDel);
 
-      browser.test.notifyPass();
+      try {
+        browser.contextMenus.update(parent, { parentId: child2 });
+        browser.test.notifyFail();
+      } catch (e) {
+        browser.test.notifyPass();
+      }
     },
   });
 
   let expectedClickInfo;
   function checkClickInfo(info) {
     info = JSON.parse(info);
     for (let i in expectedClickInfo) {
       is(info[i], expectedClickInfo[i],
@@ -110,46 +121,54 @@ add_task(function* () {
   // Select some text
   yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* (arg) {
     let doc = content.document;
     let range = doc.createRange();
     let selection = content.getSelection();
     selection.removeAllRanges();
     let textNode = doc.getElementById("img1").previousSibling;
     range.setStart(textNode, 0);
-    range.setEnd(textNode, 20);
+    range.setEnd(textNode, 100);
     selection.addRange(range);
   });
 
   // Bring up context menu again
   popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
   yield BrowserTestUtils.synthesizeMouse(null, 1, 1,
     { type: "contextmenu", button: 2 }, gBrowser.selectedBrowser);
   yield popupShownPromise;
 
   items = contentAreaContextMenu.getElementsByAttribute("ext-type", "top-level-menu");
   is(items.length, 1, "top level item was found (context=selection)");
   top = items.item(0).childNodes[0];
 
   // Check some menu items
-  items = top.getElementsByAttribute("label", "selection-edited");
+  items = top.getElementsByAttribute("label", "selection is: 'just some text 123456789012345678901234567890...'");
   is(items.length, 1, "contextMenu item for selection was found (context=selection)");
   let selectionItem = items.item(0);
 
   items = top.getElementsByAttribute("label", "selection");
   is(items.length, 0, "contextMenu item label update worked (context=selection)");
 
   popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
   expectedClickInfo = {
     menuItemId: "ext-selection",
     pageUrl: "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html",
-    selectionText: "just some text",
+    selectionText: "just some text 1234567890123456789012345678901234567890123456789012345678901234567890123456789012",
   };
   top.openPopup(topItem, "end_before", 0, 0, true, false);
   EventUtils.synthesizeMouseAtCenter(selectionItem, {});
   clickInfo = yield extension.awaitMessage("menuItemClick");
   checkClickInfo(clickInfo);
   yield popupHiddenPromise;
 
+  popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
+  yield BrowserTestUtils.synthesizeMouseAtCenter("#img1",
+    { type: "contextmenu", button: 2 }, gBrowser.selectedBrowser);
+  yield popupShownPromise;
+
+  items = contentAreaContextMenu.getElementsByAttribute("ext-type", "top-level-menu");
+  is(items.length, 0, "top level item was not found (after removeAll()");
+
   yield extension.unload();
 
   yield BrowserTestUtils.removeTab(tab1);
 });
--- a/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_good.js
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_good.js
@@ -1,12 +1,14 @@
 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set sts=2 sw=2 et tw=80: */
 "use strict";
 
+requestLongerTimeout(2);
+
 function* testHasPermission(params) {
   let contentSetup = params.contentSetup || (() => Promise.resolve());
 
   function background(contentSetup) {
     browser.runtime.onMessage.addListener((msg, sender) => {
       browser.test.assertEq(msg, "script ran", "script ran");
       browser.test.notifyPass("executeScript");
     });
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_move.js
@@ -0,0 +1,116 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+add_task(function* () {
+  let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:robots");
+  let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:config");
+
+  gBrowser.selectedTab = tab1;
+
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["tabs"],
+    },
+
+    background: function() {
+      browser.tabs.query({
+        lastFocusedWindow: true,
+      }, function(tabs) {
+        let tab = tabs[0];
+        browser.tabs.move(tab.id, {index: 0});
+        browser.tabs.query(
+          { lastFocusedWindow: true },
+          tabs => {
+            browser.test.assertEq(tabs[0].url, tab.url, "should be first tab");
+            browser.test.notifyPass("tabs.move.single");
+          });
+      });
+    },
+  });
+
+  yield extension.startup();
+  yield extension.awaitFinish("tabs.move.single");
+  yield extension.unload();
+
+  extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["tabs"],
+    },
+
+    background: function() {
+      browser.tabs.query(
+        { lastFocusedWindow: true },
+        tabs => {
+          tabs.sort(function(a, b) { return a.url > b.url; });
+          browser.tabs.move(tabs.map(tab => tab.id), {index: 0});
+          browser.tabs.query(
+            { lastFocusedWindow: true },
+            tabs => {
+              browser.test.assertEq(tabs[0].url, "about:blank", "should be first tab");
+              browser.test.assertEq(tabs[1].url, "about:config", "should be second tab");
+              browser.test.assertEq(tabs[2].url, "about:robots", "should be third tab");
+              browser.test.notifyPass("tabs.move.multiple");
+            });
+        });
+    },
+  });
+
+  yield extension.startup();
+  yield extension.awaitFinish("tabs.move.multiple");
+  yield extension.unload();
+
+  extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["tabs"],
+    },
+
+    background: function() {
+      browser.tabs.query(
+        { lastFocusedWindow: true },
+        tabs => {
+          let tab = tabs[0];
+          // Assuming that tab.id of 12345 does not exist.
+          browser.tabs.move([12345, tab.id], {index: 0});
+          browser.tabs.query(
+            { lastFocusedWindow: true },
+            tabs => {
+              browser.test.assertEq(tabs[0].url, tab.url, "should be first tab");
+              browser.test.notifyPass("tabs.move.invalid");
+            });
+        });
+    },
+  });
+
+  yield extension.startup();
+  yield extension.awaitFinish("tabs.move.invalid");
+  yield extension.unload();
+
+  extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["tabs"],
+    },
+
+    background: function() {
+      browser.tabs.query(
+        { lastFocusedWindow: true },
+        tabs => {
+          let tab = tabs[0];
+          browser.tabs.move(tab.id, {index: -1});
+          browser.tabs.query(
+            { lastFocusedWindow: true },
+            tabs => {
+              browser.test.assertEq(tabs[2].url, tab.url, "should be last tab");
+              browser.test.notifyPass("tabs.move.last");
+            });
+        });
+    },
+  });
+
+  yield extension.startup();
+  yield extension.awaitFinish("tabs.move.last");
+  yield extension.unload();
+
+  yield BrowserTestUtils.removeTab(tab1);
+  yield BrowserTestUtils.removeTab(tab2);
+});
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_move_window.js
@@ -0,0 +1,121 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+add_task(function* () {
+  yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.net/");
+  let window1 = yield BrowserTestUtils.openNewBrowserWindow();
+  yield BrowserTestUtils.openNewForegroundTab(window1.gBrowser, "http://example.com/");
+
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["tabs"],
+    },
+
+    background: function() {
+      browser.tabs.query({
+        url: "<all_urls>",
+      }, function(tabs) {
+        let destination = tabs[0];
+        let source = tabs[1]; // skip over about:blank in window1
+        browser.tabs.move(source.id, {windowId: destination.windowId, index: 0});
+
+        browser.tabs.query(
+          { url: "<all_urls>" },
+          tabs => {
+            browser.test.assertEq(tabs[0].url, "http://example.com/");
+            browser.test.assertEq(tabs[0].windowId, destination.windowId);
+            browser.test.notifyPass("tabs.move.window");
+          });
+      });
+    },
+  });
+
+  yield extension.startup();
+  yield extension.awaitFinish("tabs.move.window");
+  yield extension.unload();
+
+  for (let tab of window.gBrowser.tabs) {
+    yield BrowserTestUtils.removeTab(tab);
+  }
+  yield BrowserTestUtils.closeWindow(window1);
+});
+
+add_task(function* () {
+  yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.net/");
+  let window1 = yield BrowserTestUtils.openNewBrowserWindow();
+  let tab1 = yield BrowserTestUtils.openNewForegroundTab(window1.gBrowser, "http://example.com/");
+  window1.gBrowser.pinTab(tab1);
+
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["tabs"],
+    },
+
+    background: function() {
+      browser.tabs.query(
+        { url: "<all_urls>" },
+        tabs => {
+          let destination = tabs[0];
+          let source = tabs[1]; // remember, pinning moves it to the left.
+          browser.tabs.move(source.id, {windowId: destination.windowId, index: 0});
+
+          browser.tabs.query(
+            { url: "<all_urls>" },
+            tabs => {
+              browser.test.assertEq(true, tabs[0].pinned);
+              browser.test.notifyPass("tabs.move.pin");
+            });
+        });
+    },
+  });
+
+  yield extension.startup();
+  yield extension.awaitFinish("tabs.move.pin");
+  yield extension.unload();
+
+  for (let tab of window.gBrowser.tabs) {
+    yield BrowserTestUtils.removeTab(tab);
+  }
+  yield BrowserTestUtils.closeWindow(window1);
+});
+
+add_task(function* () {
+  let window1 = yield BrowserTestUtils.openNewBrowserWindow();
+  yield BrowserTestUtils.openNewForegroundTab(window.gBrowser, "http://example.net/");
+  yield BrowserTestUtils.openNewForegroundTab(window.gBrowser, "http://example.com/");
+  yield BrowserTestUtils.openNewForegroundTab(window1.gBrowser, "http://example.net/");
+  yield BrowserTestUtils.openNewForegroundTab(window1.gBrowser, "http://example.com/");
+
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["tabs"],
+    },
+
+    background: function() {
+      browser.tabs.query(
+        { url: "<all_urls>" },
+        tabs => {
+          let move1 = tabs[1];
+          let move3 = tabs[3];
+          browser.tabs.move([move1.id, move3.id], {index: 0});
+          browser.tabs.query(
+            { url: "<all_urls>" },
+            tabs => {
+              browser.test.assertEq(tabs[0].url, move1.url);
+              browser.test.assertEq(tabs[2].url, move3.url);
+              browser.test.notifyPass("tabs.move.multiple");
+            });
+        });
+    },
+  });
+
+  yield extension.startup();
+  yield extension.awaitFinish("tabs.move.multiple");
+  yield extension.unload();
+
+  for (let tab of window.gBrowser.tabs) {
+    yield BrowserTestUtils.removeTab(tab);
+  }
+  yield BrowserTestUtils.closeWindow(window1);
+});
--- a/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js
@@ -1,12 +1,14 @@
 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set sts=2 sw=2 et tw=80: */
 "use strict";
 
+requestLongerTimeout(2);
+
 add_task(function* () {
   let win1 = yield BrowserTestUtils.openNewBrowserWindow();
 
   yield focusWindow(win1);
 
   let extension = ExtensionTestUtils.loadExtension({
     manifest: {
       "permissions": ["tabs"],
--- a/browser/components/extensions/test/browser/browser_ext_tabs_query.js
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_query.js
@@ -1,12 +1,14 @@
 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set sts=2 sw=2 et tw=80: */
 "use strict";
 
+requestLongerTimeout(2);
+
 add_task(function* () {
   let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:robots");
   let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:config");
 
   gBrowser.selectedTab = tab1;
 
   let extension = ExtensionTestUtils.loadExtension({
     manifest: {
--- a/browser/components/extensions/test/browser/context.html
+++ b/browser/components/extensions/test/browser/context.html
@@ -1,8 +1,8 @@
 <html>
   <head>
   </head>
   <body>
-  just some text
+  just some text 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
   <img src="ctxmenu-image.png" id="img1">
   </body>
 </html>
--- a/browser/components/feeds/FeedConverter.js
+++ b/browser/components/feeds/FeedConverter.js
@@ -87,17 +87,17 @@ function getPrefReaderForType(t) {
       return PREF_AUDIO_SELECTED_READER;
 
     default:
       return PREF_SELECTED_READER;
   }
 }
 
 function safeGetCharPref(pref, defaultValue) {
-  var prefs =   
+  var prefs =
       Cc["@mozilla.org/preferences-service;1"].
       getService(Ci.nsIPrefBranch);
   try {
     return prefs.getCharPref(pref);
   }
   catch (e) {
   }
   return defaultValue;
@@ -107,106 +107,106 @@ function FeedConverter() {
 }
 FeedConverter.prototype = {
   classID: Components.ID("{229fa115-9412-4d32-baf3-2fc407f76fb1}"),
 
   /**
    * This is the downloaded text data for the feed.
    */
   _data: null,
-  
+
   /**
    * This is the object listening to the conversion, which is ultimately the
    * docshell for the load.
    */
   _listener: null,
 
   /**
    * Records if the feed was sniffed
    */
   _sniffed: false,
 
   /**
    * See nsIStreamConverter.idl
    */
-  convert: function FC_convert(sourceStream, sourceType, destinationType, 
-                               context) {
+  convert(sourceStream, sourceType, destinationType,
+          context) {
     throw Cr.NS_ERROR_NOT_IMPLEMENTED;
   },
-  
+
   /**
    * See nsIStreamConverter.idl
    */
-  asyncConvertData: function FC_asyncConvertData(sourceType, destinationType,
-                                                 listener, context) {
+  asyncConvertData(sourceType, destinationType,
+                   listener, context) {
     this._listener = listener;
   },
-  
+
   /**
    * Whether or not the preview page is being forced.
    */
   _forcePreviewPage: false,
-  
-  /** 
+
+  /**
    * Release our references to various things once we're done using them.
    */
-  _releaseHandles: function FC__releaseHandles() {
+  _releaseHandles() {
     this._listener = null;
     this._request = null;
     this._processor = null;
   },
-  
+
   /**
    * See nsIFeedResultListener.idl
    */
-  handleResult: function FC_handleResult(result) {
+  handleResult(result) {
     // Feeds come in various content types, which our feed sniffer coerces to
-    // the maybe.feed type. However, feeds are used as a transport for 
+    // the maybe.feed type. However, feeds are used as a transport for
     // different data types, e.g. news/blogs (traditional feed), video/audio
-    // (podcasts) and photos (photocasts, photostreams). Each of these is 
+    // (podcasts) and photos (photocasts, photostreams). Each of these is
     // different in that there's a different class of application suitable for
     // handling feeds of that type, but without a content-type differentiation
     // it is difficult for us to disambiguate.
-    // 
+    //
     // The other problem is that if the user specifies an auto-action handler
-    // for one feed application, the fact that the content type is shared means 
-    // that all other applications will auto-load with that handler too, 
-    // regardless of the content-type. 
+    // for one feed application, the fact that the content type is shared means
+    // that all other applications will auto-load with that handler too,
+    // regardless of the content-type.
     //
     // This means that content-type alone is not enough to determine whether
     // or not a feed should be auto-handled. This means that for feeds we need
-    // to always use this stream converter, even when an auto-action is 
-    // specified, not the basic one provided by WebContentConverter. This 
+    // to always use this stream converter, even when an auto-action is
+    // specified, not the basic one provided by WebContentConverter. This
     // converter needs to consume all of the data and parse it, and based on
-    // that determination make a judgment about type. 
+    // that determination make a judgment about type.
     //
     // Since there are no content types for this content, and I'm not going to
     // invent any, the upshot is that while a user can set an auto-handler for
     // generic feed content, the system will prevent them from setting an auto-
     // handler for other stream types. In those cases, the user will always see
-    // the preview page and have to select a handler. We can guess and show 
+    // the preview page and have to select a handler. We can guess and show
     // a client handler, but will not be able to show web handlers for those
     // types.
     //
     // If this is just a feed, not some kind of specialized application, then
     // auto-handlers can be set and we should obey them.
     try {
-      var feedService = 
+      let feedService =
           Cc["@mozilla.org/browser/feeds/result-service;1"].
           getService(Ci.nsIFeedResultService);
       if (!this._forcePreviewPage && result.doc) {
-        var feed = result.doc.QueryInterface(Ci.nsIFeed);
-        var handler = safeGetCharPref(getPrefActionForType(feed.type), "ask");
+        let feed = result.doc.QueryInterface(Ci.nsIFeed);
+        let handler = safeGetCharPref(getPrefActionForType(feed.type), "ask");
 
         if (handler != "ask") {
           if (handler == "reader")
             handler = safeGetCharPref(getPrefReaderForType(feed.type), "bookmarks");
           switch (handler) {
             case "web":
-              var wccr = 
+              let wccr =
                   Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
                   getService(Ci.nsIWebContentConverterService);
               if ((feed.type == Ci.nsIFeed.TYPE_FEED &&
                    wccr.getAutoHandler(TYPE_MAYBE_FEED)) ||
                   (feed.type == Ci.nsIFeed.TYPE_VIDEO &&
                    wccr.getAutoHandler(TYPE_MAYBE_VIDEO_FEED)) ||
                   (feed.type == Ci.nsIFeed.TYPE_AUDIO &&
                    wccr.getAutoHandler(TYPE_MAYBE_AUDIO_FEED))) {
@@ -215,365 +215,338 @@ FeedConverter.prototype = {
               }
               break;
 
             default:
               LOG("unexpected handler: " + handler);
               // fall through -- let feed service handle error
             case "bookmarks":
             case "client":
+            case "default":
               try {
-                var title = feed.title ? feed.title.plainText() : "";
-                var desc = feed.subtitle ? feed.subtitle.plainText() : "";
-                feedService.addToClientReader(result.uri.spec, title, desc, feed.type);
+                let title = feed.title ? feed.title.plainText() : "";
+                let desc = feed.subtitle ? feed.subtitle.plainText() : "";
+                let feedReader = safeGetCharPref(getPrefActionForType(feedType), "bookmarks");
+                feedService.addToClientReader(result.uri.spec, title, desc, feed.type, feedReader);
                 return;
               } catch(ex) { /* fallback to preview mode */ }
           }
         }
       }
-          
-      var ios = 
+
+      let ios =
           Cc["@mozilla.org/network/io-service;1"].
           getService(Ci.nsIIOService);
-      var chromeChannel;
+      let chromeChannel;
 
       // handling a redirect, hence forwarding the loadInfo from the old channel
       // to the newchannel.
-      var oldChannel = this._request.QueryInterface(Ci.nsIChannel);
-      var loadInfo = oldChannel.loadInfo;
+      let oldChannel = this._request.QueryInterface(Ci.nsIChannel);
+      let loadInfo = oldChannel.loadInfo;
 
       // If there was no automatic handler, or this was a podcast,
       // photostream or some other kind of application, show the preview page
       // if the parser returned a document.
       if (result.doc) {
 
         // Store the result in the result service so that the display
         // page can access it.
         feedService.addFeedResult(result);
 
         // Now load the actual XUL document.
-        var aboutFeedsURI = ios.newURI("about:feeds", null, null);
+        let aboutFeedsURI = ios.newURI("about:feeds", null, null);
         chromeChannel = ios.newChannelFromURIWithLoadInfo(aboutFeedsURI, loadInfo);
         chromeChannel.originalURI = result.uri;
         chromeChannel.owner =
           Services.scriptSecurityManager.createCodebasePrincipal(aboutFeedsURI, {});
       } else {
         chromeChannel = ios.newChannelFromURIWithLoadInfo(result.uri, loadInfo);
       }
 
       chromeChannel.loadGroup = this._request.loadGroup;
       chromeChannel.asyncOpen(this._listener, null);
     }
     finally {
       this._releaseHandles();
     }
   },
-  
+
   /**
    * See nsIStreamListener.idl
    */
-  onDataAvailable: function FC_onDataAvailable(request, context, inputStream, 
-                                               sourceOffset, count) {
+  onDataAvailable(request, context, inputStream,
+                  sourceOffset, count) {
     if (this._processor)
       this._processor.onDataAvailable(request, context, inputStream,
                                       sourceOffset, count);
   },
-  
+
   /**
    * See nsIRequestObserver.idl
    */
-  onStartRequest: function FC_onStartRequest(request, context) {
-    var channel = request.QueryInterface(Ci.nsIChannel);
+  onStartRequest(request, context) {
+    let channel = request.QueryInterface(Ci.nsIChannel);
 
     // Check for a header that tells us there was no sniffing
     // The value doesn't matter.
     try {
-      var httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
+      let httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
       // Make sure to check requestSucceeded before the potentially-throwing
       // getResponseHeader.
       if (!httpChannel.requestSucceeded) {
         // Just give up, but don't forget to cancel the channel first!
         request.cancel(Cr.NS_BINDING_ABORTED);
         return;
       }
-      var noSniff = httpChannel.getResponseHeader("X-Moz-Is-Feed");
+      let noSniff = httpChannel.getResponseHeader("X-Moz-Is-Feed");
     }
     catch (ex) {
       this._sniffed = true;
     }
 
     this._request = request;
-    
+
     // Save and reset the forced state bit early, in case there's some kind of
     // error.
-    var feedService = 
+    let feedService =
         Cc["@mozilla.org/browser/feeds/result-service;1"].
         getService(Ci.nsIFeedResultService);
     this._forcePreviewPage = feedService.forcePreviewPage;
     feedService.forcePreviewPage = false;
 
     // Parse feed data as it comes in
     this._processor =
         Cc["@mozilla.org/feed-processor;1"].
         createInstance(Ci.nsIFeedProcessor);
     this._processor.listener = this;
     this._processor.parseAsync(null, channel.URI);
-    
+
     this._processor.onStartRequest(request, context);
   },
-  
+
   /**
    * See nsIRequestObserver.idl
    */
-  onStopRequest: function FC_onStopRequest(request, context, status) {
+  onStopRequest(request, context, status) {
     if (this._processor)
       this._processor.onStopRequest(request, context, status);
   },
-  
+
   /**
    * See nsISupports.idl
    */
-  QueryInterface: function FC_QueryInterface(iid) {
+  QueryInterface(iid) {
     if (iid.equals(Ci.nsIFeedResultListener) ||
         iid.equals(Ci.nsIStreamConverter) ||
         iid.equals(Ci.nsIStreamListener) ||
         iid.equals(Ci.nsIRequestObserver)||
         iid.equals(Ci.nsISupports))
       return this;
     throw Cr.NS_ERROR_NO_INTERFACE;
   },
 };
 
 /**
  * Keeps parsed FeedResults around for use elsewhere in the UI after the stream
- * converter completes. 
+ * converter completes.
  */
 function FeedResultService() {
 }
 
 FeedResultService.prototype = {
   classID: Components.ID("{2376201c-bbc6-472f-9b62-7548040a61c6}"),
-  
+
   /**
    * A URI spec -> [nsIFeedResult] hash. We have to keep a list as the
    * value in case the same URI is requested concurrently.
    */
   _results: { },
-  
+
   /**
    * See nsIFeedResultService.idl
    */
   forcePreviewPage: false,
-  
+
   /**
    * See nsIFeedResultService.idl
    */
-  addToClientReader: function FRS_addToClientReader(spec, title, subtitle, feedType) {
-    var prefs =   
-        Cc["@mozilla.org/preferences-service;1"].
-        getService(Ci.nsIPrefBranch);
+  addToClientReader(spec, title, subtitle, feedType, feedReader) {
+    if (!feedReader) {
+      feedReader = "default";
+    }
 
-    var handler = safeGetCharPref(getPrefActionForType(feedType), "bookmarks");
+    let handler = safeGetCharPref(getPrefActionForType(feedType), "bookmarks");
     if (handler == "ask" || handler == "reader")
-      handler = safeGetCharPref(getPrefReaderForType(feedType), "bookmarks");
+      handler = feedReader;
 
     switch (handler) {
     case "client":
-      var clientApp = prefs.getComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile);
-
-      // For the benefit of applications that might know how to deal with more
-      // URLs than just feeds, send feed: URLs in the following format:
-      //
-      // http urls: replace scheme with feed, e.g.
-      // http://foo.com/index.rdf -> feed://foo.com/index.rdf
-      // other urls: prepend feed: scheme, e.g.
-      // https://foo.com/index.rdf -> feed:https://foo.com/index.rdf
-      var ios = 
-          Cc["@mozilla.org/network/io-service;1"].
-          getService(Ci.nsIIOService);
-      var feedURI = ios.newURI(spec, null, null);
-      if (feedURI.schemeIs("http")) {
-        feedURI.scheme = "feed";
-        spec = feedURI.spec;
-      }
-      else
-        spec = "feed:" + spec;
-
-      // Retrieving the shell service might fail on some systems, most
-      // notably systems where GNOME is not installed.
-      try {
-        var ss =
-            Cc["@mozilla.org/browser/shell-service;1"].
-            getService(Ci.nsIShellService);
-        ss.openApplicationWithURI(clientApp, spec);
-      } catch(e) {
-        // If we couldn't use the shell service, fallback to using a
-        // nsIProcess instance
-        var p =
-            Cc["@mozilla.org/process/util;1"].
-            createInstance(Ci.nsIProcess);
-        p.init(clientApp);
-        p.run(false, [spec], 1);
-      }
+      Services.cpmm.sendAsyncMessage("FeedConverter:ExecuteClientApp",
+                                     { spec,
+                                       title,
+                                       subtitle,
+                                       feedHandler: getPrefAppForType(feedType) });
       break;
-
+    case "default":
+      // Default system feed reader
+      Services.cpmm.sendAsyncMessage("FeedConverter:ExecuteClientApp",
+                                     { spec,
+                                       title,
+                                       subtitle,
+                                       feedHandler: "default" });
+      break;
     default:
       // "web" should have been handled elsewhere
       LOG("unexpected handler: " + handler);
       // fall through
     case "bookmarks":
-      var wm = 
-          Cc["@mozilla.org/appshell/window-mediator;1"].
-          getService(Ci.nsIWindowMediator);
-      var topWindow = wm.getMostRecentWindow("navigator:browser");
-      topWindow.PlacesCommandHook.addLiveBookmark(spec, title, subtitle)
-                                 .catch(Components.utils.reportError);
+      Services.cpmm.sendAsyncMessage("FeedConverter:addLiveBookmark",
+                                     { spec, title, subtitle });
       break;
     }
   },
-  
+
   /**
    * See nsIFeedResultService.idl
    */
-  addFeedResult: function FRS_addFeedResult(feedResult) {
+  addFeedResult(feedResult) {
     NS_ASSERT(feedResult.uri != null, "null URI!");
     NS_ASSERT(feedResult.uri != null, "null feedResult!");
-    var spec = feedResult.uri.spec;
-    if(!this._results[spec])  
+    let spec = feedResult.uri.spec;
+    if (!this._results[spec])
       this._results[spec] = [];
     this._results[spec].push(feedResult);
   },
-  
+
   /**
    * See nsIFeedResultService.idl
    */
-  getFeedResult: function RFS_getFeedResult(uri) {
+  getFeedResult(uri) {
     NS_ASSERT(uri != null, "null URI!");
-    var resultList = this._results[uri.spec];
-    for (var i in resultList) {
-      if (resultList[i].uri == uri)
-        return resultList[i];
+    let resultList = this._results[uri.spec];
+    for (let result of resultList) {
+      if (result.uri == uri)
+        return result;
     }
     return null;
   },
-  
+
   /**
    * See nsIFeedResultService.idl
    */
-  removeFeedResult: function FRS_removeFeedResult(uri) {
+  removeFeedResult(uri) {
     NS_ASSERT(uri != null, "null URI!");
-    var resultList = this._results[uri.spec];
+    let resultList = this._results[uri.spec];
     if (!resultList)
       return;
-    var deletions = 0;
-    for (var i = 0; i < resultList.length; ++i) {
+    let deletions = 0;
+    for (let i = 0; i < resultList.length; ++i) {
       if (resultList[i].uri == uri) {
         delete resultList[i];
         ++deletions;
       }
     }
-    
+
     // send the holes to the end
     resultList.sort();
     // and trim the list
     resultList.splice(resultList.length - deletions, deletions);
     if (resultList.length == 0)
       delete this._results[uri.spec];
   },
 
-  createInstance: function FRS_createInstance(outer, iid) {
+  createInstance(outer, iid) {
     if (outer != null)
       throw Cr.NS_ERROR_NO_AGGREGATION;
     return this.QueryInterface(iid);
   },
-  
-  QueryInterface: function FRS_QueryInterface(iid) {
+
+  QueryInterface(iid) {
     if (iid.equals(Ci.nsIFeedResultService) ||
         iid.equals(Ci.nsIFactory) ||
         iid.equals(Ci.nsISupports))
       return this;
     throw Cr.NS_ERROR_NOT_IMPLEMENTED;
   },
 };
 
 /**
  * A protocol handler that attempts to deal with the variant forms of feed:
  * URIs that are actually either http or https.
  */
 function GenericProtocolHandler() {
 }
 GenericProtocolHandler.prototype = {
-  _init: function GPH_init(scheme) {
-    var ios = 
+  _init(scheme) {
+    let ios =
       Cc["@mozilla.org/network/io-service;1"].
       getService(Ci.nsIIOService);
     this._http = ios.getProtocolHandler("http");
     this._scheme = scheme;
   },
 
   get scheme() {
     return this._scheme;
   },
-  
+
   get protocolFlags() {
     return this._http.protocolFlags;
   },
-  
+
   get defaultPort() {
     return this._http.defaultPort;
   },
-  
-  allowPort: function GPH_allowPort(port, scheme) {
+
+  allowPort(port, scheme) {
     return this._http.allowPort(port, scheme);
   },
-  
-  newURI: function GPH_newURI(spec, originalCharset, baseURI) {
+
+  newURI(spec, originalCharset, baseURI) {
     // Feed URIs can be either nested URIs of the form feed:realURI (in which
     // case we create a nested URI for the realURI) or feed://example.com, in
     // which case we create a nested URI for the real protocol which is http.
 
-    var scheme = this._scheme + ":";
+    let scheme = this._scheme + ":";
     if (spec.substr(0, scheme.length) != scheme)
       throw Cr.NS_ERROR_MALFORMED_URI;
 
-    var prefix = spec.substr(scheme.length, 2) == "//" ? "http:" : "";
-    var inner = Cc["@mozilla.org/network/io-service;1"].
+    let prefix = spec.substr(scheme.length, 2) == "//" ? "http:" : "";
+    let inner = Cc["@mozilla.org/network/io-service;1"].
                 getService(Ci.nsIIOService).newURI(spec.replace(scheme, prefix),
                                                    originalCharset, baseURI);
-    var netutil = Cc["@mozilla.org/network/util;1"].getService(Ci.nsINetUtil);
+    let netutil = Cc["@mozilla.org/network/util;1"].getService(Ci.nsINetUtil);
     const URI_INHERITS_SECURITY_CONTEXT = Ci.nsIProtocolHandler
                                             .URI_INHERITS_SECURITY_CONTEXT;
     if (netutil.URIChainHasFlags(inner, URI_INHERITS_SECURITY_CONTEXT))
       throw Cr.NS_ERROR_MALFORMED_URI;
 
-    var uri = netutil.newSimpleNestedURI(inner);
+    let uri = netutil.newSimpleNestedURI(inner);
     uri.spec = inner.spec.replace(prefix, scheme);
     return uri;
   },
-  
-  newChannel2: function GPH_newChannel(aUri, aLoadInfo) {
-    var inner = aUri.QueryInterface(Ci.nsINestedURI).innerURI;
-    var channel = Cc["@mozilla.org/network/io-service;1"].
+
+  newChannel2(aUri, aLoadInfo) {
+    let inner = aUri.QueryInterface(Ci.nsINestedURI).innerURI;
+    let channel = Cc["@mozilla.org/network/io-service;1"].
                   getService(Ci.nsIIOService).
                   newChannelFromURIWithLoadInfo(inner, aLoadInfo);
 
     if (channel instanceof Components.interfaces.nsIHttpChannel)
       // Set this so we know this is supposed to be a feed
       channel.setRequestHeader("X-Moz-Is-Feed", "1", false);
     channel.originalURI = aUri;
     return channel;
   },
-  
 
-  QueryInterface: function GPH_QueryInterface(iid) {
+  QueryInterface(iid) {
     if (iid.equals(Ci.nsIProtocolHandler) ||
         iid.equals(Ci.nsISupports))
       return this;
     throw Cr.NS_ERROR_NO_INTERFACE;
-  }  
+  }
 };
 
 function FeedProtocolHandler() {
   this._init('feed');
 }
 FeedProtocolHandler.prototype = new GenericProtocolHandler();
 FeedProtocolHandler.prototype.classID = Components.ID("{4f91ef2e-57ba-472e-ab7a-b4999e42d6c0}");
 
--- a/browser/components/feeds/FeedWriter.js
+++ b/browser/components/feeds/FeedWriter.js
@@ -1,47 +1,47 @@
-# -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-# 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/.
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 const FEEDWRITER_CID = Components.ID("{49bb6593-3aff-4eb3-a068-2712c28bd58e}");
 const FEEDWRITER_CONTRACTID = "@mozilla.org/browser/feeds/result-writer;1";
 
 function LOG(str) {
-  var prefB = Cc["@mozilla.org/preferences-service;1"].
+  let prefB = Cc["@mozilla.org/preferences-service;1"].
               getService(Ci.nsIPrefBranch);
 
-  var shouldLog = false;
+  let shouldLog = false;
   try {
     shouldLog = prefB.getBoolPref("feeds.log");
-  } 
+  }
   catch (ex) {
   }
 
   if (shouldLog)
     dump("*** Feeds: " + str + "\n");
 }
 
 /**
  * Wrapper function for nsIIOService::newURI.
  * @param aURLSpec
  *        The URL string from which to create an nsIURI.
  * @returns an nsIURI object, or null if the creation of the URI failed.
  */
 function makeURI(aURLSpec, aCharset) {
-  var ios = Cc["@mozilla.org/network/io-service;1"].
+  let ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
   try {
     return ios.newURI(aURLSpec, aCharset, null);
   } catch (ex) { }
 
   return null;
 }
 
@@ -127,17 +127,17 @@ function getPrefReaderForType(t) {
 
 /**
  * Converts a number of bytes to the appropriate unit that results in a
  * number that needs fewer than 4 digits
  *
  * @return a pair: [new value with 3 sig. figs., its unit]
   */
 function convertByteUnits(aBytes) {
-  var units = ["bytes", "kilobyte", "megabyte", "gigabyte"];
+  let units = ["bytes", "kilobyte", "megabyte", "gigabyte"];
   let unitIndex = 0;
 
   // convert to next unit if it needs 4 digits (after rounding), but only if
   // we know the name of the next unit
   while ((aBytes >= 999.5) && (unitIndex < units.length - 1)) {
     aBytes /= 1024;
     unitIndex++;
   }
@@ -147,61 +147,61 @@ function convertByteUnits(aBytes) {
   aBytes = aBytes.toFixed((aBytes > 0) && (aBytes < 100) ? 1 : 0);
 
   return [aBytes, units[unitIndex]];
 }
 
 function FeedWriter() {
   this._selectedApp = undefined;
   this._selectedAppMenuItem = null;
+  this._subscribeCallback = null;
   this._defaultHandlerMenuItem = null;
 }
 
 FeedWriter.prototype = {
   _mimeSvc      : Cc["@mozilla.org/mime;1"].
                   getService(Ci.nsIMIMEService),
 
-  _getPropertyAsBag: function FW__getPropertyAsBag(container, property) {
+  _getPropertyAsBag(container, property) {
     return container.fields.getProperty(property).
                      QueryInterface(Ci.nsIPropertyBag2);
   },
 
-  _getPropertyAsString: function FW__getPropertyAsString(container, property) {
+  _getPropertyAsString(container, property) {
     try {
       return container.fields.getPropertyAsAString(property);
     }
     catch (e) {
     }
     return "";
   },
 
-  _setContentText: function FW__setContentText(id, text) {
-    var element = this._document.getElementById(id);
-    var textNode = text.createDocumentFragment(element);
+  _setContentText(id, text) {
+    let element = this._document.getElementById(id);
+    let textNode = text.createDocumentFragment(element);
     while (element.hasChildNodes())
       element.removeChild(element.firstChild);
     element.appendChild(textNode);
     if (text.base) {
       element.setAttributeNS(XML_NS, 'base', text.base.spec);
     }
   },
 
   /**
-   * Safely sets the href attribute on an anchor tag, providing the URI 
-   * specified can be loaded according to rules. 
+   * Safely sets the href attribute on an anchor tag, providing the URI
+   * specified can be loaded according to rules.
    * @param   element
    *          The element to set a URI attribute on
    * @param   attribute
    *          The attribute of the element to set the URI to, e.g. href or src
    * @param   uri
    *          The URI spec to set as the href
    */
-  _safeSetURIAttribute:
-  function FW__safeSetURIAttribute(element, attribute, uri) {
-    var secman = Cc["@mozilla.org/scriptsecuritymanager;1"].
+  _safeSetURIAttribute(element, attribute, uri) {
+    let secman = Cc["@mozilla.org/scriptsecuritymanager;1"].
                  getService(Ci.nsIScriptSecurityManager);
     const flags = Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL;
     try {
       // TODO Is this necessary?
       secman.checkLoadURIStrWithPrincipal(this._feedPrincipal, uri, flags);
       // checkLoadURIStrWithPrincipal will throw if the link URI should not be
       // loaded, either because our feedURI isn't allowed to load it or per
       // the rules specified in |flags|, so we'll never "linkify" the link...
@@ -228,96 +228,83 @@ FeedWriter.prototype = {
     if (!this.__bundle) {
       this.__bundle = Cc["@mozilla.org/intl/stringbundle;1"].
                       getService(Ci.nsIStringBundleService).
                       createBundle(URI_BUNDLE);
     }
     return this.__bundle;
   },
 
-  _getFormattedString: function FW__getFormattedString(key, params) {
+  _getFormattedString(key, params) {
     return this._bundle.formatStringFromName(key, params, params.length);
   },
-  
-  _getString: function FW__getString(key) {
+
+  _getString(key) {
     return this._bundle.GetStringFromName(key);
   },
 
-  /* Magic helper methods to be used instead of xbl properties */
-  _getSelectedItemFromMenulist: function FW__getSelectedItemFromList(aList) {
-    var node = aList.firstChild.firstChild;
-    while (node) {
-      if (node.localName == "menuitem" && node.getAttribute("selected") == "true")
-        return node;
-
-      node = node.nextSibling;
-    }
-
-    return null;
-  },
-
-  _setCheckboxCheckedState: function FW__setCheckboxCheckedState(aCheckbox, aValue) {
+  _setCheckboxCheckedState(aCheckbox, aValue) {
     // see checkbox.xml, xbl bindings are not applied within the sandbox! TODO
-    var change = (aValue != (aCheckbox.getAttribute('checked') == 'true'));
+    let change = (aValue != (aCheckbox.getAttribute('checked') == 'true'));
     if (aValue)
       aCheckbox.setAttribute('checked', 'true');
     else
       aCheckbox.removeAttribute('checked');
 
     if (change) {
-      var event = this._document.createEvent('Events');
+      let event = this._document.createEvent('Events');
       event.initEvent('CheckboxStateChange', true, true);
       aCheckbox.dispatchEvent(event);
     }
   },
 
    /**
-   * Returns a date suitable for displaying in the feed preview. 
+   * Returns a date suitable for displaying in the feed preview.
    * If the date cannot be parsed, the return value is "false".
    * @param   dateString
    *          A date as extracted from a feed entry. (entry.updated)
    */
-  _parseDate: function FW__parseDate(dateString) {
+  _parseDate(dateString) {
     // Convert the date into the user's local time zone
-    var dateObj = new Date(dateString);
+    let dateObj = new Date(dateString);
 
     // Make sure the date we're given is valid.
     if (!dateObj.getTime())
       return false;
 
-    var dateService = Cc["@mozilla.org/intl/scriptabledateformat;1"].
+    let dateService = Cc["@mozilla.org/intl/scriptabledateformat;1"].
                       getService(Ci.nsIScriptableDateFormat);
     return dateService.FormatDateTime("", dateService.dateFormatLong, dateService.timeFormatNoSeconds,
                                       dateObj.getFullYear(), dateObj.getMonth()+1, dateObj.getDate(),
                                       dateObj.getHours(), dateObj.getMinutes(), dateObj.getSeconds());
   },
 
   /**
    * Returns the feed type.
    */
   __feedType: null,
-  _getFeedType: function FW__getFeedType() {
+  _getFeedType() {
     if (this.__feedType != null)
       return this.__feedType;
 
     try {
       // grab the feed because it's got the feed.type in it.
-      var container = this._getContainer();
-      var feed = container.QueryInterface(Ci.nsIFeed);
+      let container = this._getContainer();
+      let feed = container.QueryInterface(Ci.nsIFeed);
       this.__feedType = feed.type;
       return feed.type;
     } catch (ex) { }
 
     return Ci.nsIFeed.TYPE_FEED;
   },
 
   /**
    * Maps a feed type to a maybe-feed mimetype.
    */
-  _getMimeTypeForFeedType: function FW__getMimeTypeForFeedType() {
+  _getMimeTypeForFeedType() {
     switch (this._getFeedType()) {
       case Ci.nsIFeed.TYPE_VIDEO:
         return TYPE_MAYBE_VIDEO_FEED;
 
       case Ci.nsIFeed.TYPE_AUDIO:
         return TYPE_MAYBE_AUDIO_FEED;
 
       default:
@@ -325,49 +312,49 @@ FeedWriter.prototype = {
     }
   },
 
   /**
    * Writes the feed title into the preview document.
    * @param   container
    *          The feed container
    */
-  _setTitleText: function FW__setTitleText(container) {
+  _setTitleText(container) {
     if (container.title) {
-      var title = container.title.plainText();
+      let title = container.title.plainText();
       this._setContentText(TITLE_ID, container.title);
       this._document.title = title;
     }
 
-    var feed = container.QueryInterface(Ci.nsIFeed);
+    let feed = container.QueryInterface(Ci.nsIFeed);
     if (feed && feed.subtitle)
       this._setContentText(SUBTITLE_ID, container.subtitle);
   },
 
   /**
    * Writes the title image into the preview document if one is present.
    * @param   container
    *          The feed container
    */
-  _setTitleImage: function FW__setTitleImage(container) {
+  _setTitleImage(container) {
     try {
-      var parts = container.image;
+      let parts = container.image;
 
       // Set up the title image (supplied by the feed)
-      var feedTitleImage = this._document.getElementById("feedTitleImage");
-      this._safeSetURIAttribute(feedTitleImage, "src", 
+      let feedTitleImage = this._document.getElementById("feedTitleImage");
+      this._safeSetURIAttribute(feedTitleImage, "src",
                                 parts.getPropertyAsAString("url"));
 
       // Set up the title image link
-      var feedTitleLink = this._document.getElementById("feedTitleLink");
+      let feedTitleLink = this._document.getElementById("feedTitleLink");
 
-      var titleText = this._getFormattedString("linkTitleTextFormat", 
+      let titleText = this._getFormattedString("linkTitleTextFormat",
                                                [parts.getPropertyAsAString("title")]);
-      var feedTitleText = this._document.getElementById("feedTitleText");
-      var titleImageWidth = parseInt(parts.getPropertyAsAString("width")) + 15;
+      let feedTitleText = this._document.getElementById("feedTitleText");
+      let titleImageWidth = parseInt(parts.getPropertyAsAString("width")) + 15;
 
       // Fix the margin on the main title, so that the image doesn't run over
       // the underline
       feedTitleLink.setAttribute('title', titleText);
       feedTitleText.style.marginRight = titleImageWidth + 'px';
 
       this._safeSetURIAttribute(feedTitleLink, "href",
                                 parts.getPropertyAsAString("link"));
@@ -377,680 +364,542 @@ FeedWriter.prototype = {
     }
   },
 
   /**
    * Writes all entries contained in the feed.
    * @param   container
    *          The container of entries in the feed
    */
-  _writeFeedContent: function FW__writeFeedContent(container) {
+  _writeFeedContent(container) {
     // Build the actual feed content
-    var feed = container.QueryInterface(Ci.nsIFeed);
+    let feed = container.QueryInterface(Ci.nsIFeed);
     if (feed.items.length == 0)
       return;
 
-    var feedContent = this._document.getElementById("feedContent");
+    let feedContent = this._document.getElementById("feedContent");
 
-    for (var i = 0; i < feed.items.length; ++i) {
-      var entry = feed.items.queryElementAt(i, Ci.nsIFeedEntry);
+    for (let i = 0; i < feed.items.length; ++i) {
+      let entry = feed.items.queryElementAt(i, Ci.nsIFeedEntry);
       entry.QueryInterface(Ci.nsIFeedContainer);
 
-      var entryContainer = this._document.createElementNS(HTML_NS, "div");
+      let entryContainer = this._document.createElementNS(HTML_NS, "div");
       entryContainer.className = "entry";
 
       // If the entry has a title, make it a link
       if (entry.title) {
-        var a = this._document.createElementNS(HTML_NS, "a");
-        var span = this._document.createElementNS(HTML_NS, "span");
+        let a = this._document.createElementNS(HTML_NS, "a");
+        let span = this._document.createElementNS(HTML_NS, "span");
         a.appendChild(span);
         if (entry.title.base)
           span.setAttributeNS(XML_NS, "base", entry.title.base.spec);
         span.appendChild(entry.title.createDocumentFragment(a));
 
         // Entries are not required to have links, so entry.link can be null.
         if (entry.link)
           this._safeSetURIAttribute(a, "href", entry.link.spec);
 
-        var title = this._document.createElementNS(HTML_NS, "h3");
+        let title = this._document.createElementNS(HTML_NS, "h3");
         title.appendChild(a);
 
-        var lastUpdated = this._parseDate(entry.updated);
+        let lastUpdated = this._parseDate(entry.updated);
         if (lastUpdated) {
-          var dateDiv = this._document.createElementNS(HTML_NS, "div");
+          let dateDiv = this._document.createElementNS(HTML_NS, "div");
           dateDiv.className = "lastUpdated";
           dateDiv.textContent = lastUpdated;
           title.appendChild(dateDiv);
         }
 
         entryContainer.appendChild(title);
       }
 
-      var body = this._document.createElementNS(HTML_NS, "div");
-      var summary = entry.summary || entry.content;
-      var docFragment = null;
+      let body = this._document.createElementNS(HTML_NS, "div");
+      let summary = entry.summary || entry.content;
+      let docFragment = null;
       if (summary) {
         if (summary.base)
           body.setAttributeNS(XML_NS, "base", summary.base.spec);
         else
           LOG("no base?");
         docFragment = summary.createDocumentFragment(body);
         if (docFragment)
           body.appendChild(docFragment);
 
         // If the entry doesn't have a title, append a # permalink
         // See http://scripting.com/rss.xml for an example
         if (!entry.title && entry.link) {
-          var a = this._document.createElementNS(HTML_NS, "a");
+          let a = this._document.createElementNS(HTML_NS, "a");
           a.appendChild(this._document.createTextNode("#"));
           this._safeSetURIAttribute(a, "href", entry.link.spec);
           body.appendChild(this._document.createTextNode(" "));
           body.appendChild(a);
         }
 
       }
       body.className = "feedEntryContent";
       entryContainer.appendChild(body);
 
       if (entry.enclosures && entry.enclosures.length > 0) {
-        var enclosuresDiv = this._buildEnclosureDiv(entry);
+        let enclosuresDiv = this._buildEnclosureDiv(entry);
         entryContainer.appendChild(enclosuresDiv);
       }
 
-      var clearDiv = this._document.createElementNS(HTML_NS, "div");
+      let clearDiv = this._document.createElementNS(HTML_NS, "div");
       clearDiv.style.clear = "both";
 
       feedContent.appendChild(entryContainer);
       feedContent.appendChild(clearDiv);
     }
   },
 
   /**
    * Takes a url to a media item and returns the best name it can come up with.
-   * Frequently this is the filename portion (e.g. passing in 
+   * Frequently this is the filename portion (e.g. passing in
    * http://example.com/foo.mpeg would return "foo.mpeg"), but in more complex
    * cases, this will return the entire url (e.g. passing in
-   * http://example.com/somedirectory/ would return 
+   * http://example.com/somedirectory/ would return
    * http://example.com/somedirectory/).
    * @param aURL
    *        The URL string from which to create a display name
    * @returns a string
    */
-  _getURLDisplayName: function FW__getURLDisplayName(aURL) {
-    var url = makeURI(aURL);
+  _getURLDisplayName(aURL) {
+    let url = makeURI(aURL);
     url.QueryInterface(Ci.nsIURL);
     if (url == null || url.fileName.length == 0)
       return decodeURIComponent(aURL);
 
     return decodeURIComponent(url.fileName);
   },
 
   /**
    * Takes a FeedEntry with enclosures, generates the HTML code to represent
    * them, and returns that.
    * @param   entry
    *          FeedEntry with enclosures
    * @returns element
    */
-  _buildEnclosureDiv: function FW__buildEnclosureDiv(entry) {
-    var enclosuresDiv = this._document.createElementNS(HTML_NS, "div");
+  _buildEnclosureDiv(entry) {
+    let enclosuresDiv = this._document.createElementNS(HTML_NS, "div");
     enclosuresDiv.className = "enclosures";
 
     enclosuresDiv.appendChild(this._document.createTextNode(this._getString("mediaLabel")));
 
-    var roundme = function(n) {
+    let roundme = function(n) {
       return (Math.round(n * 100) / 100).toLocaleString();
     }
 
-    for (var i_enc = 0; i_enc < entry.enclosures.length; ++i_enc) {
-      var enc = entry.enclosures.queryElementAt(i_enc, Ci.nsIWritablePropertyBag2);
+    for (let i_enc = 0; i_enc < entry.enclosures.length; ++i_enc) {
+      let enc = entry.enclosures.queryElementAt(i_enc, Ci.nsIWritablePropertyBag2);
 
-      if (!(enc.hasKey("url"))) 
+      if (!(enc.has