Merge m-c to b-i
authorPhil Ringnalda <philringnalda@gmail.com>
Sat, 17 Oct 2015 20:00:32 -0700
changeset 301611 de1fd96512f72d4e287a429dd3785c6ae108e466
parent 301610 312f559139dc4d1762f7316d9770bec0abc0afc0 (current diff)
parent 301570 e8c7dfe727cd970e2c3294934e2927b14143c205 (diff)
child 301612 e837513663a4773914afe4335279c203c0db2dc2
push id5392
push userraliiev@mozilla.com
push dateMon, 14 Dec 2015 20:08:23 +0000
treeherdermozilla-beta@16ce8562a975 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to b-i CLOSED TREE
browser/components/loop/content/css/contacts.css
browser/components/loop/content/js/contacts.js
browser/components/loop/content/js/contacts.jsx
browser/components/loop/content/shared/img/empty_contacts.svg
browser/components/loop/test/desktop-local/contacts_test.js
browser/components/loop/test/mochitest/browser_mozLoop_pluralStrings.js
devtools/client/memory/reducers/snapshot.js
dom/workers/test/WorkerDebugger.isFrozen_iframe1.html
dom/workers/test/WorkerDebugger.isFrozen_iframe2.html
dom/workers/test/WorkerDebugger.isFrozen_worker1.js
dom/workers/test/WorkerDebugger.isFrozen_worker2.js
dom/workers/test/test_WorkerDebugger.isFrozen.xul
js/src/jit-test/tests/basic/bug821470.js
mfbt/RefPtr.h
mfbt/nsRefPtr.h
mobile/android/base/overlays/ui/OverlayToastHelper.java
testing/docker/desktop-test/bin/entrypoint
testing/docker/desktop-test/bin/pull_gaia.sh
testing/docker/desktop-test/mozharness_configs/emulator_override.py
testing/docker/desktop-test/mozharness_configs/gaia_integration_override.py
testing/docker/desktop-test/mozharness_configs/remove_executables.py
testing/web-platform/meta/XMLHttpRequest/XMLHttpRequest-withCredentials.html.ini
testing/web-platform/meta/XMLHttpRequest/XMLHttpRequest-withCredentials.worker.js.ini
testing/web-platform/meta/XMLHttpRequest/send-content-type-charset.htm.ini
testing/web-platform/meta/dom/ranges/Range-deleteContents.html.ini
testing/web-platform/meta/dom/ranges/Range-extractContents.html.ini
testing/web-platform/meta/html/editing/dnd/the-draggable-attribute/draggable_attribute.html.ini
testing/web-platform/meta/microdata/microdata-dom-api/001.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/resources/fetch-response-xhr-iframe.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/resources/invalid-blobtype-iframe.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/resources/invalid-header-iframe.https.html.ini
testing/web-platform/tests/microdata/microdata-dom-api/.gitkeep
testing/web-platform/tests/microdata/microdata-dom-api/001.html
testing/web-platform/tests/microdata/microdata-dom-api/htmlpropertiescollection/.gitkeep
widget/android/nsWindow.cpp
--- 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.
 
-No bug - unknown something produced intermittent OS X build failures in libstagefright and jemalloc and malloc
+Bug 1210154 - Update the clang toolchain
--- a/accessible/atk/AccessibleWrap.cpp
+++ b/accessible/atk/AccessibleWrap.cpp
@@ -1466,16 +1466,20 @@ a11y::ProxyEvent(ProxyAccessible* aTarge
     atk_focus_tracker_notify(wrapper); // fire extra focus event
     atk_object_notify_state_change(wrapper, ATK_STATE_VISIBLE, true);
     atk_object_notify_state_change(wrapper, ATK_STATE_SHOWING, true);
     break;
   case nsIAccessibleEvent::EVENT_MENUPOPUP_END:
     atk_object_notify_state_change(wrapper, ATK_STATE_VISIBLE, false);
     atk_object_notify_state_change(wrapper, ATK_STATE_SHOWING, false);
     break;
+  case nsIAccessibleEvent::EVENT_ALERT:
+    // A hack using state change showing events as alert events.
+    atk_object_notify_state_change(wrapper, ATK_STATE_SHOWING, true);
+    break;
   }
 }
 
 void
 a11y::ProxyStateChangeEvent(ProxyAccessible* aTarget, uint64_t aState,
                             bool aEnabled)
 {
   MaiAtkObject* atkObj = MAI_ATK_OBJECT(GetWrapperFor(aTarget));
--- a/accessible/base/AccCollector.cpp
+++ b/accessible/base/AccCollector.cpp
@@ -97,21 +97,23 @@ AccCollector::AppendObject(Accessible* a
 ////////////////////////////////////////////////////////////////////////////////
 
 int32_t
 EmbeddedObjCollector::GetIndexAt(Accessible* aAccessible)
 {
   if (aAccessible->mParent != mRoot)
     return -1;
 
-  if (aAccessible->mIndexOfEmbeddedChild != -1)
-    return aAccessible->mIndexOfEmbeddedChild;
+  MOZ_ASSERT(!aAccessible->IsProxy());
+  if (aAccessible->mInt.mIndexOfEmbeddedChild != -1)
+    return aAccessible->mInt.mIndexOfEmbeddedChild;
 
   return mFilterFunc(aAccessible) & filters::eMatch ?
     EnsureNGetIndex(aAccessible) : -1;
 }
 
 void
 EmbeddedObjCollector::AppendObject(Accessible* aAccessible)
 {
-  aAccessible->mIndexOfEmbeddedChild = mObjects.Length();
+  MOZ_ASSERT(!aAccessible->IsProxy());
+  aAccessible->mInt.mIndexOfEmbeddedChild = mObjects.Length();
   mObjects.AppendElement(aAccessible);
 }
--- a/accessible/base/AccEvent.h
+++ b/accessible/base/AccEvent.h
@@ -122,17 +122,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent)
 
 protected:
   virtual ~AccEvent() {}
 
   bool mIsFromUserInput;
   uint32_t mEventType;
   EEventRule mEventRule;
-  nsRefPtr<Accessible> mAccessible;
+  RefPtr<Accessible> mAccessible;
 
   friend class EventQueue;
   friend class AccReorderEvent;
 };
 
 
 /**
  * Accessible state change event.
@@ -232,18 +232,18 @@ public:
   // MutationEvent
   bool IsShow() const { return mEventType == nsIAccessibleEvent::EVENT_SHOW; }
   bool IsHide() const { return mEventType == nsIAccessibleEvent::EVENT_HIDE; }
 
   Accessible* Parent() const { return mParent; }
 
 protected:
   nsCOMPtr<nsINode> mNode;
-  nsRefPtr<Accessible> mParent;
-  nsRefPtr<AccTextChangeEvent> mTextChangeEvent;
+  RefPtr<Accessible> mParent;
+  RefPtr<AccTextChangeEvent> mTextChangeEvent;
 
   friend class EventQueue;
 };
 
 
 /**
  * Accessible hide event.
  */
@@ -263,18 +263,18 @@ public:
   // AccHideEvent
   Accessible* TargetParent() const { return mParent; }
   Accessible* TargetNextSibling() const { return mNextSibling; }
   Accessible* TargetPrevSibling() const { return mPrevSibling; }
   bool NeedsShutdown() const { return mNeedsShutdown; }
 
 protected:
   bool mNeedsShutdown;
-  nsRefPtr<Accessible> mNextSibling;
-  nsRefPtr<Accessible> mPrevSibling;
+  RefPtr<Accessible> mNextSibling;
+  RefPtr<Accessible> mPrevSibling;
 
   friend class EventQueue;
 };
 
 
 /**
  * Accessible show event.
  */
@@ -392,17 +392,17 @@ public:
   // AccTextSelChangeEvent
 
   /**
    * Return true if the text selection change wasn't caused by pure caret move.
    */
   bool IsCaretMoveOnly() const;
 
 private:
-  nsRefPtr<dom::Selection> mSel;
+  RefPtr<dom::Selection> mSel;
   int32_t mReason;
 
   friend class EventQueue;
   friend class SelectionManager;
 };
 
 
 /**
@@ -427,18 +427,18 @@ public:
   {
     return AccEvent::GetEventGroups() | (1U << eSelectionChangeEvent);
   }
 
   // AccSelChangeEvent
   Accessible* Widget() const { return mWidget; }
 
 private:
-  nsRefPtr<Accessible> mWidget;
-  nsRefPtr<Accessible> mItem;
+  RefPtr<Accessible> mWidget;
+  RefPtr<Accessible> mItem;
   SelChangeType mSelChangeType;
   uint32_t mPreceedingCount;
   AccSelChangeEvent* mPackedEvent;
 
   friend class EventQueue;
 };
 
 
@@ -490,17 +490,17 @@ public:
 
   // AccTableChangeEvent
   Accessible* OldAccessible() const { return mOldAccessible; }
   int32_t OldStartOffset() const { return mOldStart; }
   int32_t OldEndOffset() const { return mOldEnd; }
   int32_t Reason() const { return mReason; }
 
 private:
-  nsRefPtr<Accessible> mOldAccessible;
+  RefPtr<Accessible> mOldAccessible;
   int32_t mOldStart;
   int32_t mOldEnd;
   int16_t mReason;
 };
 
 /**
  * Accessible object attribute changed event.
  */
--- a/accessible/base/AccIterator.cpp
+++ b/accessible/base/AccIterator.cpp
@@ -389,17 +389,17 @@ ARIAOwnsIterator::Next()
 
 ////////////////////////////////////////////////////////////////////////////////
 // SingleAccIterator
 ////////////////////////////////////////////////////////////////////////////////
 
 Accessible*
 SingleAccIterator::Next()
 {
-  nsRefPtr<Accessible> nextAcc;
+  RefPtr<Accessible> nextAcc;
   mAcc.swap(nextAcc);
   if (!nextAcc || nextAcc->IsDefunct()) {
     return nullptr;
   }
   return nextAcc;
 }
 
 
--- a/accessible/base/AccIterator.h
+++ b/accessible/base/AccIterator.h
@@ -301,17 +301,17 @@ public:
 
   virtual Accessible* Next() override;
 
 private:
   SingleAccIterator();
   SingleAccIterator(const SingleAccIterator&);
   SingleAccIterator& operator = (const SingleAccIterator&);
 
-  nsRefPtr<Accessible> mAcc;
+  RefPtr<Accessible> mAcc;
 };
 
 
 /**
  * Used to iterate items of the given item container.
  */
 class ItemIterator : public AccIterable
 {
--- a/accessible/base/DocManager.cpp
+++ b/accessible/base/DocManager.cpp
@@ -422,17 +422,17 @@ DocManager::CreateDocOrRootAccessible(ns
                  "Can't create an accessible for the document!");
     if (!parentDocAcc)
       return nullptr;
   }
 
   // We only create root accessibles for the true root, otherwise create a
   // doc accessible.
   nsIContent *rootElm = nsCoreUtils::GetRoleContent(aDocument);
-  nsRefPtr<DocAccessible> docAcc = isRootDoc ?
+  RefPtr<DocAccessible> docAcc = isRootDoc ?
     new RootAccessibleWrap(aDocument, rootElm, presShell) :
     new DocAccessibleWrap(aDocument, rootElm, presShell);
 
   // Cache the document accessible into document cache.
   mDocAccessibleCache.Put(aDocument, docAcc);
 
   // Initialize the document accessible.
   docAcc->Init();
--- a/accessible/base/EventQueue.cpp
+++ b/accessible/base/EventQueue.cpp
@@ -56,17 +56,17 @@ EventQueue::PushEvent(AccEvent* aEvent)
     while (parent &&
            nsTextEquivUtils::HasNameRule(parent, eNameFromSubtreeIfReqRule)) {
       // Test possible name dependent parent.
       if (nsTextEquivUtils::HasNameRule(parent, eNameFromSubtreeRule)) {
         nsAutoString name;
         ENameValueFlag nameFlag = parent->Name(name);
         // If name is obtained from subtree, fire name change event.
         if (nameFlag == eNameFromSubtree) {
-          nsRefPtr<AccEvent> nameChangeEvent =
+          RefPtr<AccEvent> nameChangeEvent =
             new AccEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, parent);
           PushEvent(nameChangeEvent);
         }
         break;
       }
       parent = parent->Parent();
     }
   }
@@ -477,17 +477,17 @@ EventQueue::CreateTextChangeEventFor(Acc
 
 ////////////////////////////////////////////////////////////////////////////////
 // EventQueue: event queue
 
 void
 EventQueue::ProcessEventQueue()
 {
   // Process only currently queued events.
-  nsTArray<nsRefPtr<AccEvent> > events;
+  nsTArray<RefPtr<AccEvent> > events;
   events.SwapElements(mEvents);
 
   uint32_t eventCount = events.Length();
 #ifdef A11Y_LOG
   if (eventCount > 0 && logging::IsEnabled(logging::eEvents)) {
     logging::MsgBegin("EVENTS", "events processing");
     logging::Address("document", mDocument);
     logging::MsgEnd();
--- a/accessible/base/EventQueue.h
+++ b/accessible/base/EventQueue.h
@@ -74,15 +74,15 @@ protected:
    * The document accessible reference owning this queue.
    */
   DocAccessible* mDocument;
 
   /**
    * Pending events array. Don't make this an nsAutoTArray; we use
    * SwapElements() on it.
    */
-  nsTArray<nsRefPtr<AccEvent> > mEvents;
+  nsTArray<RefPtr<AccEvent> > mEvents;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif // mozilla_a11y_EventQueue_h_
--- a/accessible/base/FocusManager.cpp
+++ b/accessible/base/FocusManager.cpp
@@ -213,17 +213,17 @@ FocusManager::ForceFocusEvent()
 }
 
 void
 FocusManager::DispatchFocusEvent(DocAccessible* aDocument,
                                  Accessible* aTarget)
 {
   NS_PRECONDITION(aDocument, "No document for focused accessible!");
   if (aDocument) {
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccEvent(nsIAccessibleEvent::EVENT_FOCUS, aTarget,
                    eAutoDetect, AccEvent::eCoalesceOfSameType);
     aDocument->FireDelayedEvent(event);
 
 #ifdef A11Y_LOG
     if (logging::IsEnabled(logging::eFocus))
       logging::FocusDispatched(aTarget);
 #endif
@@ -326,35 +326,35 @@ FocusManager::ProcessFocusEvent(AccEvent
 
       parent = ARIAOwnedByIterator(child).Next();
       tryOwnsParent = false;
     }
 
     if (ARIAMenubar != mActiveARIAMenubar) {
       // Leaving ARIA menu. Fire menu_end event on current menubar.
       if (mActiveARIAMenubar) {
-        nsRefPtr<AccEvent> menuEndEvent =
+        RefPtr<AccEvent> menuEndEvent =
           new AccEvent(nsIAccessibleEvent::EVENT_MENU_END, mActiveARIAMenubar,
                        aEvent->FromUserInput());
         nsEventShell::FireEvent(menuEndEvent);
       }
 
       mActiveARIAMenubar = ARIAMenubar;
 
       // Entering ARIA menu. Fire menu_start event.
       if (mActiveARIAMenubar) {
-        nsRefPtr<AccEvent> menuStartEvent =
+        RefPtr<AccEvent> menuStartEvent =
           new AccEvent(nsIAccessibleEvent::EVENT_MENU_START,
                        mActiveARIAMenubar, aEvent->FromUserInput());
         nsEventShell::FireEvent(menuStartEvent);
       }
     }
   } else if (mActiveARIAMenubar) {
     // Focus left a menu. Fire menu_end event.
-    nsRefPtr<AccEvent> menuEndEvent =
+    RefPtr<AccEvent> menuEndEvent =
       new AccEvent(nsIAccessibleEvent::EVENT_MENU_END, mActiveARIAMenubar,
                    aEvent->FromUserInput());
     nsEventShell::FireEvent(menuEndEvent);
 
     mActiveARIAMenubar = nullptr;
   }
 
 #ifdef A11Y_LOG
@@ -362,17 +362,17 @@ FocusManager::ProcessFocusEvent(AccEvent
     logging::FocusNotificationTarget("fire focus event", "Target", target);
 #endif
 
   // Reset cached caret value. The cache will be updated upon processing the
   // next caret move event. This ensures that we will return the correct caret
   // offset before the caret move event is handled.
   SelectionMgr()->ResetCaretOffset();
 
-  nsRefPtr<AccEvent> focusEvent =
+  RefPtr<AccEvent> focusEvent =
     new AccEvent(nsIAccessibleEvent::EVENT_FOCUS, target, aEvent->FromUserInput());
   nsEventShell::FireEvent(focusEvent);
 
   // Fire scrolling_start event when the document receives the focus if it has
   // an anchor jump. If an accessible within the document receive the focus
   // then null out the anchor jump because it no longer applies.
   DocAccessible* targetDocument = target->Document();
   Accessible* anchorJump = targetDocument->AnchorJump();
--- a/accessible/base/FocusManager.h
+++ b/accessible/base/FocusManager.h
@@ -119,16 +119,16 @@ private:
   nsINode* FocusedDOMNode() const;
 
   /**
    * Return DOM document having DOM focus.
    */
   nsIDocument* FocusedDOMDocument() const;
 
 private:
-  nsRefPtr<Accessible> mActiveItem;
-  nsRefPtr<Accessible> mActiveARIAMenubar;
+  RefPtr<Accessible> mActiveItem;
+  RefPtr<Accessible> mActiveARIAMenubar;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/base/NotificationController.cpp
+++ b/accessible/base/NotificationController.cpp
@@ -96,17 +96,17 @@ NotificationController::ScheduleChildDoc
   ScheduleProcessing();
 }
 
 void
 NotificationController::ScheduleContentInsertion(Accessible* aContainer,
                                                  nsIContent* aStartChildNode,
                                                  nsIContent* aEndChildNode)
 {
-  nsRefPtr<ContentInsertion> insertion = new ContentInsertion(mDocument,
+  RefPtr<ContentInsertion> insertion = new ContentInsertion(mDocument,
                                                               aContainer);
   if (insertion && insertion->InitChildList(aStartChildNode, aEndChildNode) &&
       mContentInsertions.AppendElement(insertion)) {
     ScheduleProcessing();
   }
 }
 
 void
@@ -188,17 +188,17 @@ NotificationController::WillRefresh(mozi
   // notifications are queued during this processing then they will be processed
   // on next refresh. If notification processing queues up new events then they
   // are processed in this refresh. If events processing queues up new events
   // then new events are processed on next refresh.
   // Note: notification processing or event handling may shut down the owning
   // document accessible.
 
   // Process only currently queued content inserted notifications.
-  nsTArray<nsRefPtr<ContentInsertion> > contentInsertions;
+  nsTArray<RefPtr<ContentInsertion> > contentInsertions;
   contentInsertions.SwapElements(mContentInsertions);
 
   uint32_t insertionCount = contentInsertions.Length();
   for (uint32_t idx = 0; idx < insertionCount; idx++) {
     contentInsertions[idx]->Process();
     if (!mDocument)
       return;
   }
@@ -286,17 +286,17 @@ NotificationController::WillRefresh(mozi
         mDocument->ProcessContentInserted(container, &insertedContents);
       }
     }
   }
   mTextHash.Clear();
 
   // Bind hanging child documents.
   uint32_t hangingDocCnt = mHangingChildDocuments.Length();
-  nsTArray<nsRefPtr<DocAccessible>> newChildDocs;
+  nsTArray<RefPtr<DocAccessible>> newChildDocs;
   for (uint32_t idx = 0; idx < hangingDocCnt; idx++) {
     DocAccessible* childDoc = mHangingChildDocuments[idx];
     if (childDoc->IsDefunct())
       continue;
 
     nsIContent* ownerContent = mDocument->DocumentNode()->
       FindContentForSubDocument(childDoc->DocumentNode());
     if (ownerContent) {
@@ -332,17 +332,17 @@ NotificationController::WillRefresh(mozi
     if (childDocIdx == childDocCnt) {
       mDocument->ProcessLoad();
       if (!mDocument)
         return;
     }
   }
 
   // Process only currently queued generic notifications.
-  nsTArray < nsRefPtr<Notification> > notifications;
+  nsTArray < RefPtr<Notification> > notifications;
   notifications.SwapElements(mNotifications);
 
   uint32_t notificationCount = notifications.Length();
   for (uint32_t idx = 0; idx < notificationCount; idx++) {
     notifications[idx]->Process();
     if (!mDocument)
       return;
   }
--- a/accessible/base/NotificationController.h
+++ b/accessible/base/NotificationController.h
@@ -76,17 +76,17 @@ private:
   template <size_t... Indices>
     void ProcessHelper(IndexSequence<Indices...>)
   {
      (mInstance->*mCallback)(Get<Indices>(mArgs)...);
   }
 
   Class* mInstance;
   Callback mCallback;
-  Tuple<nsRefPtr<Args> ...> mArgs;
+  Tuple<RefPtr<Args> ...> mArgs;
 };
 
 /**
  * Used to process notifications from core for the document accessible.
  */
 class NotificationController final : public EventQueue,
                                      public nsARefreshObserver
 {
@@ -156,33 +156,33 @@ public:
 #ifdef A11Y_LOG
       if (mozilla::a11y::logging::IsEnabled(mozilla::a11y::logging::eNotifications))
         mozilla::a11y::logging::Text("sync notification processing");
 #endif
       (aInstance->*aMethod)(aArg);
       return;
     }
 
-    nsRefPtr<Notification> notification =
+    RefPtr<Notification> notification =
       new TNotification<Class, Arg>(aInstance, aMethod, aArg);
     if (notification && mNotifications.AppendElement(notification))
       ScheduleProcessing();
   }
 
   /**
    * Schedule the generic notification to process asynchronously.
    *
    * @note  The caller must guarantee that the given instance still exists when
    *        the notification is processed.
    */
   template<class Class>
   inline void ScheduleNotification(Class* aInstance,
                                    typename TNotification<Class>::Callback aMethod)
   {
-    nsRefPtr<Notification> notification =
+    RefPtr<Notification> notification =
       new TNotification<Class>(aInstance, aMethod);
     if (notification && mNotifications.AppendElement(notification))
       ScheduleProcessing();
   }
 
 #ifdef DEBUG
   bool IsUpdating() const
     { return mObservingState == eRefreshProcessingForUpdate; }
@@ -222,17 +222,17 @@ private:
   /**
    * The presshell of the document accessible.
    */
   nsIPresShell* mPresShell;
 
   /**
    * Child documents that needs to be bound to the tree.
    */
-  nsTArray<nsRefPtr<DocAccessible> > mHangingChildDocuments;
+  nsTArray<RefPtr<DocAccessible> > mHangingChildDocuments;
 
   /**
    * Storage for content inserted notification information.
    */
   class ContentInsertion
   {
   public:
     ContentInsertion(DocAccessible* aDocument, Accessible* aContainer);
@@ -252,27 +252,27 @@ private:
     ContentInsertion& operator = (const ContentInsertion&);
 
     // The document used to process content insertion, matched to document of
     // the notification controller that this notification belongs to, therefore
     // it's ok to keep it as weak ref.
     DocAccessible* mDocument;
 
     // The container accessible that content insertion occurs within.
-    nsRefPtr<Accessible> mContainer;
+    RefPtr<Accessible> mContainer;
 
     // Array of inserted contents.
     nsTArray<nsCOMPtr<nsIContent> > mInsertedContent;
   };
 
   /**
    * A pending accessible tree update notifications for content insertions.
    * Don't make this an nsAutoTArray; we use SwapElements() on it.
    */
-  nsTArray<nsRefPtr<ContentInsertion> > mContentInsertions;
+  nsTArray<RefPtr<ContentInsertion> > mContentInsertions;
 
   template<class T>
   class nsCOMPtrHashKey : public PLDHashEntryHdr
   {
   public:
     typedef T* KeyType;
     typedef const T* KeyTypePointer;
 
@@ -297,15 +297,15 @@ private:
    * A pending accessible tree update notifications for rendered text changes.
    */
   nsTHashtable<nsCOMPtrHashKey<nsIContent> > mTextHash;
 
   /**
    * Other notifications like DOM events. Don't make this an nsAutoTArray; we
    * use SwapElements() on it.
    */
-  nsTArray<nsRefPtr<Notification> > mNotifications;
+  nsTArray<RefPtr<Notification> > mNotifications;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif // mozilla_a11y_NotificationController_h_
--- a/accessible/base/SelectionManager.cpp
+++ b/accessible/base/SelectionManager.cpp
@@ -24,17 +24,17 @@ using namespace mozilla;
 using namespace mozilla::a11y;
 using mozilla::dom::Selection;
 
 struct mozilla::a11y::SelData final
 {
   SelData(Selection* aSel, int32_t aReason) :
     mSel(aSel), mReason(aReason) {}
 
-  nsRefPtr<Selection> mSel;
+  RefPtr<Selection> mSel;
   int16_t mReason;
 
   NS_INLINE_DECL_REFCOUNTING(SelData)
 
 private:
   // Private destructor, to discourage deletion outside of Release():
   ~SelData() {}
 };
@@ -159,17 +159,17 @@ SelectionManager::ProcessTextSelChangeEv
   // event->mSel is correct.
   if (!selection)
     selection = event->mSel;
 
   mCaretOffset = caretCntr->DOMPointToOffset(selection->GetFocusNode(),
                                              selection->FocusOffset());
   mAccWithCaret = caretCntr;
   if (mCaretOffset != -1) {
-    nsRefPtr<AccCaretMoveEvent> caretMoveEvent =
+    RefPtr<AccCaretMoveEvent> caretMoveEvent =
       new AccCaretMoveEvent(caretCntr, mCaretOffset, aEvent->FromUserInput());
     nsEventShell::FireEvent(caretMoveEvent);
   }
 }
 
 NS_IMETHODIMP
 SelectionManager::NotifySelectionChanged(nsIDOMDocument* aDOMDocument,
                                          nsISelection* aSelection,
@@ -184,17 +184,17 @@ SelectionManager::NotifySelectionChanged
   if (logging::IsEnabled(logging::eSelection))
     logging::SelChange(aSelection, document, aReason);
 #endif
 
   if (document) {
     // Selection manager has longer lifetime than any document accessible,
     // so that we are guaranteed that the notification is processed before
     // the selection manager is destroyed.
-    nsRefPtr<SelData> selData =
+    RefPtr<SelData> selData =
       new SelData(static_cast<Selection*>(aSelection), aReason);
     document->HandleNotification<SelectionManager, SelData>
       (this, &SelectionManager::ProcessSelectionChanged, selData);
   }
 
   return NS_OK;
 }
 
@@ -221,17 +221,17 @@ SelectionManager::ProcessSelectionChange
 
   HyperTextAccessible* text = nsAccUtils::GetTextContainer(cntrNode);
   if (!text) {
     NS_NOTREACHED("We must reach document accessible implementing text interface!");
     return;
   }
 
   if (selection->GetType() == nsISelectionController::SELECTION_NORMAL) {
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccTextSelChangeEvent(text, selection, aSelData->mReason);
     text->Document()->FireDelayedEvent(event);
 
   } else if (selection->GetType() == nsISelectionController::SELECTION_SPELLCHECK) {
     // XXX: fire an event for container accessible of the focus/anchor range
     // of the spelcheck selection.
     text->Document()->FireDelayedEvent(nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED,
                                        text);
--- a/accessible/base/StyleInfo.h
+++ b/accessible/base/StyleInfo.h
@@ -34,15 +34,15 @@ public:
 private:
   StyleInfo() = delete;
   StyleInfo(const StyleInfo&) = delete;
   StyleInfo& operator = (const StyleInfo&) = delete;
 
   void Margin(Side aSide, nsAString& aValue);
 
   dom::Element* mElement;
-  nsRefPtr<nsStyleContext> mStyleContext;
+  RefPtr<nsStyleContext> mStyleContext;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/base/TextAttrs.cpp
+++ b/accessible/base/TextAttrs.cpp
@@ -455,17 +455,17 @@ TextAttrsMgr::FontFamilyTextAttr::
 {
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_family, aValue);
 }
 
 bool
 TextAttrsMgr::FontFamilyTextAttr::
   GetFontFamily(nsIFrame* aFrame, nsString& aFamily)
 {
-  nsRefPtr<nsFontMetrics> fm;
+  RefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
 
   gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
   gfxFont* font = fontGroup->GetFirstValidFont();
   gfxFontEntry* fontEntry = font->GetFontEntry();
   aFamily = fontEntry->FamilyName();
   return true;
 }
@@ -613,17 +613,17 @@ TextAttrsMgr::FontWeightTextAttr::
 }
 
 int32_t
 TextAttrsMgr::FontWeightTextAttr::
   GetFontWeight(nsIFrame* aFrame)
 {
   // nsFont::width isn't suitable here because it's necessary to expose real
   // value of font weight (used font might not have some font weight values).
-  nsRefPtr<nsFontMetrics> fm;
+  RefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
 
   gfxFontGroup *fontGroup = fm->GetThebesFontGroup();
   gfxFont *font = fontGroup->GetFirstValidFont();
 
   // When there doesn't exist a bold font in the family and so the rendering of
   // a non-bold font face is changed so that the user sees what looks like a
   // bold font, i.e. synthetic bolding is used. IsSyntheticBold method is only
--- a/accessible/base/TextRange.h
+++ b/accessible/base/TextRange.h
@@ -238,19 +238,19 @@ private:
   bool TextInternal(nsAString& aText, Accessible* aCurrent,
                     uint32_t aStartIntlOffset) const;
 
   void MoveInternal(ETextUnit aUnit, int32_t aCount,
                     HyperTextAccessible& aContainer, int32_t aOffset,
                     HyperTextAccessible* aStopContainer = nullptr,
                     int32_t aStopOffset = 0);
 
-  nsRefPtr<HyperTextAccessible> mRoot;
-  nsRefPtr<HyperTextAccessible> mStartContainer;
-  nsRefPtr<HyperTextAccessible> mEndContainer;
+  RefPtr<HyperTextAccessible> mRoot;
+  RefPtr<HyperTextAccessible> mStartContainer;
+  RefPtr<HyperTextAccessible> mEndContainer;
   int32_t mStartOffset;
   int32_t mEndOffset;
 };
 
 
 } // namespace a11y
 } // namespace mozilla
 
--- a/accessible/base/TextUpdater.cpp
+++ b/accessible/base/TextUpdater.cpp
@@ -76,24 +76,24 @@ TextUpdater::DoUpdate(const nsAString& a
 
   // It could be single insertion or removal or the case of long strings. Do not
   // calculate the difference between long strings and prefer to fire pair of
   // insert/remove events as the old string was replaced on the new one.
   if (strLen1 == 0 || strLen2 == 0 ||
       strLen1 > kMaxStrLen || strLen2 > kMaxStrLen) {
     if (strLen1 > 0) {
       // Fire text change event for removal.
-      nsRefPtr<AccEvent> textRemoveEvent =
+      RefPtr<AccEvent> textRemoveEvent =
         new AccTextChangeEvent(mHyperText, mTextOffset, str1, false);
       mDocument->FireDelayedEvent(textRemoveEvent);
     }
 
     if (strLen2 > 0) {
       // Fire text change event for insertion.
-      nsRefPtr<AccEvent> textInsertEvent =
+      RefPtr<AccEvent> textInsertEvent =
         new AccTextChangeEvent(mHyperText, mTextOffset, str2, true);
       mDocument->FireDelayedEvent(textInsertEvent);
     }
 
     mDocument->MaybeNotifyOfValueChange(mHyperText);
 
     // Update the text.
     mTextLeaf->SetText(aNewText);
@@ -124,17 +124,17 @@ TextUpdater::DoUpdate(const nsAString& a
         row[colIdx] = std::min(upleft, std::min(left, up)) + 1;
       } else {
         row[colIdx] = prevRow[colIdx - 1];
       }
     }
   }
 
   // Compute events based on the difference.
-  nsTArray<nsRefPtr<AccEvent> > events;
+  nsTArray<RefPtr<AccEvent> > events;
   ComputeTextChangeEvents(str1, str2, entries, events);
 
   delete [] entries;
 
   // Fire events.
   for (int32_t idx = events.Length() - 1; idx >= 0; idx--)
     mDocument->FireDelayedEvent(events[idx]);
 
@@ -143,17 +143,17 @@ TextUpdater::DoUpdate(const nsAString& a
   // Update the text.
   mTextLeaf->SetText(aNewText);
 }
 
 void
 TextUpdater::ComputeTextChangeEvents(const nsAString& aStr1,
                                      const nsAString& aStr2,
                                      uint32_t* aEntries,
-                                     nsTArray<nsRefPtr<AccEvent> >& aEvents)
+                                     nsTArray<RefPtr<AccEvent> >& aEvents)
 {
   int32_t colIdx = aStr1.Length(), rowIdx = aStr2.Length();
 
   // Point at which strings last matched.
   int32_t colEnd = colIdx;
   int32_t rowEnd = rowIdx;
 
   int32_t colLen = colEnd + 1;
--- a/accessible/base/TextUpdater.h
+++ b/accessible/base/TextUpdater.h
@@ -46,37 +46,37 @@ private:
   TextUpdater& operator=(const TextUpdater&);
 
   /**
    * Fire text change events based on difference between strings.
    */
   void ComputeTextChangeEvents(const nsAString& aStr1,
                                const nsAString& aStr2,
                                uint32_t* aEntries,
-                               nsTArray<nsRefPtr<AccEvent> >& aEvents);
+                               nsTArray<RefPtr<AccEvent> >& aEvents);
 
   /**
    * Helper to create text change events for inserted text.
    */
   inline void FireInsertEvent(const nsAString& aText, uint32_t aAddlOffset,
-                              nsTArray<nsRefPtr<AccEvent> >& aEvents)
+                              nsTArray<RefPtr<AccEvent> >& aEvents)
   {
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccTextChangeEvent(mHyperText, mTextOffset + aAddlOffset,
                              aText, true);
     aEvents.AppendElement(event);
   }
 
   /**
    * Helper to create text change events for removed text.
    */
   inline void FireDeleteEvent(const nsAString& aText, uint32_t aAddlOffset,
-                              nsTArray<nsRefPtr<AccEvent> >& aEvents)
+                              nsTArray<RefPtr<AccEvent> >& aEvents)
   {
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccTextChangeEvent(mHyperText, mTextOffset + aAddlOffset,
                              aText, false);
     aEvents.AppendElement(event);
   }
 
   /**
    * The constant used to skip string difference calculation in case of long
    * strings.
--- a/accessible/base/nsAccCache.h
+++ b/accessible/base/nsAccCache.h
@@ -12,28 +12,28 @@
 // Accessible cache utils
 ////////////////////////////////////////////////////////////////////////////////
 
 /**
  * Shutdown and removes the accessible from cache.
  */
 template <class T>
 static PLDHashOperator
-ClearCacheEntry(const void* aKey, nsRefPtr<T>& aAccessible, void* aUserArg)
+ClearCacheEntry(const void* aKey, RefPtr<T>& aAccessible, void* aUserArg)
 {
   NS_ASSERTION(aAccessible, "Calling ClearCacheEntry with a nullptr pointer!");
   if (aAccessible && !aAccessible->IsDefunct())
     aAccessible->Shutdown();
 
   return PL_DHASH_REMOVE;
 }
 
 template <class T>
 static PLDHashOperator
-UnbindCacheEntryFromDocument(const void* aKey, nsRefPtr<T>& aAccessible,
+UnbindCacheEntryFromDocument(const void* aKey, RefPtr<T>& aAccessible,
                              void* aUserArg)
 {
   MOZ_ASSERT(aAccessible && !aAccessible->IsDefunct());
   aAccessible->Document()->UnbindFromDocument(aAccessible);
 
   return PL_DHASH_REMOVE;
 }
 
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -451,57 +451,57 @@ nsAccessibilityService::CreatePluginAcce
                                                Accessible* aContext)
 {
   // nsPluginFrame means a plugin, so we need to use the accessibility support
   // of the plugin.
   if (aFrame->GetRect().IsEmpty())
     return nullptr;
 
 #if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK)
-  nsRefPtr<nsNPAPIPluginInstance> pluginInstance;
+  RefPtr<nsNPAPIPluginInstance> pluginInstance;
   if (NS_SUCCEEDED(aFrame->GetPluginInstance(getter_AddRefs(pluginInstance))) &&
       pluginInstance) {
 #ifdef XP_WIN
     if (!sPendingPlugins->Contains(aContent) &&
         (Preferences::GetBool("accessibility.delay_plugins") ||
          Compatibility::IsJAWS() || Compatibility::IsWE())) {
       nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
-      nsRefPtr<PluginTimerCallBack> cb = new PluginTimerCallBack(aContent);
+      RefPtr<PluginTimerCallBack> cb = new PluginTimerCallBack(aContent);
       timer->InitWithCallback(cb, Preferences::GetUint("accessibility.delay_plugin_time"),
                               nsITimer::TYPE_ONE_SHOT);
       sPluginTimers->AppendElement(timer);
       sPendingPlugins->AppendElement(aContent);
       return nullptr;
     }
 
     // We need to remove aContent from the pending plugins here to avoid
     // reentrancy.  When the timer fires it calls
     // DocAccessible::ContentInserted() which does the work async.
     sPendingPlugins->RemoveElement(aContent);
 
     // Note: pluginPort will be null if windowless.
     HWND pluginPort = nullptr;
     aFrame->GetPluginPort(&pluginPort);
 
-    nsRefPtr<Accessible> accessible =
+    RefPtr<Accessible> accessible =
       new HTMLWin32ObjectOwnerAccessible(aContent, aContext->Document(),
                                          pluginPort);
     return accessible.forget();
 
 #elif MOZ_ACCESSIBILITY_ATK
     if (!AtkSocketAccessible::gCanEmbed)
       return nullptr;
 
     // Note this calls into the plugin, so crazy things may happen and aFrame
     // may go away.
     nsCString plugId;
     nsresult rv = pluginInstance->GetValueFromPlugin(
       NPPVpluginNativeAccessibleAtkPlugId, &plugId);
     if (NS_SUCCEEDED(rv) && !plugId.IsEmpty()) {
-      nsRefPtr<AtkSocketAccessible> socketAccessible =
+      RefPtr<AtkSocketAccessible> socketAccessible =
         new AtkSocketAccessible(aContent, aContext->Document(), plugId);
 
       return socketAccessible.forget();
     }
 #endif
   }
 #endif
 
@@ -782,17 +782,17 @@ nsAccessibilityService::GetStringRole(ui
 
 #undef ROLE
 }
 
 NS_IMETHODIMP
 nsAccessibilityService::GetStringStates(uint32_t aState, uint32_t aExtraState,
                                         nsISupports **aStringStates)
 {
-  nsRefPtr<DOMStringList> stringStates = new DOMStringList();
+  RefPtr<DOMStringList> stringStates = new DOMStringList();
 
   uint64_t state = nsAccUtils::To64State(aState, aExtraState);
 
   // states
   if (state & states::UNAVAILABLE)
     stringStates->Add(NS_LITERAL_STRING("unavailable"));
   if (state & states::SELECTED)
     stringStates->Add(NS_LITERAL_STRING("selected"));
@@ -1082,17 +1082,17 @@ nsAccessibilityService::GetOrCreateAcces
 
 #ifdef DEBUG
   nsImageFrame* imageFrame = do_QueryFrame(frame);
   NS_ASSERTION(!imageFrame || !content->IsHTMLElement(nsGkAtoms::area),
                "Image map manages the area accessible creation!");
 #endif
 
   // Attempt to create an accessible based on what we know.
-  nsRefPtr<Accessible> newAcc;
+  RefPtr<Accessible> newAcc;
 
   // Create accessible for visible text frames.
   if (content->IsNodeOfType(nsINode::eTEXT)) {
     nsAutoString text;
     frame->GetRenderedText(&text, nullptr, nullptr, 0, UINT32_MAX);
     // Ignore not rendered text nodes and whitespace text nodes between table
     // cells.
     if (text.IsEmpty() ||
@@ -1419,21 +1419,21 @@ nsAccessibilityService::CreateAccessible
     if (!role.IsEmpty())
       break;
   }
 
   if (role.IsEmpty() || role.EqualsLiteral("none"))
     return nullptr;
 
   if (role.EqualsLiteral("outerdoc")) {
-    nsRefPtr<Accessible> accessible = new OuterDocAccessible(aContent, aDoc);
+    RefPtr<Accessible> accessible = new OuterDocAccessible(aContent, aDoc);
     return accessible.forget();
   }
 
-  nsRefPtr<Accessible> accessible;
+  RefPtr<Accessible> accessible;
 #ifdef MOZ_XUL
   // XUL controls
   if (role.EqualsLiteral("xul:alert")) {
     accessible = new XULAlertAccessible(aContent, aDoc);
 
   } else if (role.EqualsLiteral("xul:button")) {
     accessible = new XULButtonAccessible(aContent, aDoc);
 
@@ -1595,17 +1595,17 @@ nsAccessibilityService::CreateAccessible
 
 already_AddRefed<Accessible>
 nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
                                                     nsIContent* aContent,
                                                     Accessible* aContext)
 {
   DocAccessible* document = aContext->Document();
 
-  nsRefPtr<Accessible> newAcc;
+  RefPtr<Accessible> newAcc;
   switch (aFrame->AccessibleType()) {
     case eNoType:
       return nullptr;
     case eHTMLBRType:
       newAcc = new HTMLBRAccessible(aContent, document);
       break;
     case eHTMLButtonType:
       newAcc = new HTMLButtonAccessible(aContent, document);
@@ -1822,17 +1822,17 @@ NS_GetAccessibilityService(nsIAccessibil
   NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
   *aResult = nullptr;
 
   if (nsAccessibilityService::gAccessibilityService) {
     NS_ADDREF(*aResult = nsAccessibilityService::gAccessibilityService);
     return NS_OK;
   }
 
-  nsRefPtr<nsAccessibilityService> service = new nsAccessibilityService();
+  RefPtr<nsAccessibilityService> service = new nsAccessibilityService();
   NS_ENSURE_TRUE(service, NS_ERROR_OUT_OF_MEMORY);
 
   if (!service->Init()) {
     service->Shutdown();
     return NS_ERROR_FAILURE;
   }
 
   statistics::A11yInitialized();
@@ -1855,29 +1855,29 @@ nsAccessibilityService::CreateAccessible
                                                       nsGkAtoms::treechildren);
   if (!child)
     return nullptr;
 
   nsTreeBodyFrame* treeFrame = do_QueryFrame(child->GetPrimaryFrame());
   if (!treeFrame)
     return nullptr;
 
-  nsRefPtr<nsTreeColumns> treeCols = treeFrame->Columns();
+  RefPtr<nsTreeColumns> treeCols = treeFrame->Columns();
   int32_t count = 0;
   treeCols->GetCount(&count);
 
   // Outline of list accessible.
   if (count == 1) {
-    nsRefPtr<Accessible> accessible =
+    RefPtr<Accessible> accessible =
       new XULTreeAccessible(aContent, aDoc, treeFrame);
     return accessible.forget();
   }
 
   // Table or tree table accessible.
-  nsRefPtr<Accessible> accessible =
+  RefPtr<Accessible> accessible =
     new XULTreeGridAccessibleWrap(aContent, aDoc, treeFrame);
   return accessible.forget();
 }
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
 // Services
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/base/nsAccessiblePivot.cpp
+++ b/accessible/base/nsAccessiblePivot.cpp
@@ -84,17 +84,17 @@ nsAccessiblePivot::GetPosition(nsIAccess
   NS_IF_ADDREF(*aPosition = ToXPC(mPosition));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessiblePivot::SetPosition(nsIAccessible* aPosition)
 {
-  nsRefPtr<Accessible> position = nullptr;
+  RefPtr<Accessible> position = nullptr;
 
   if (aPosition) {
     position = aPosition->ToInternalAccessible();
     if (!position || !IsDescendantOf(position, GetActiveRoot()))
       return NS_ERROR_INVALID_ARG;
   }
 
   // Swap old position with new position, saves us an AddRef/Release.
@@ -163,17 +163,17 @@ nsAccessiblePivot::SetTextRange(nsIAcces
   // smaller than 0, both should be -1.
   NS_ENSURE_TRUE(aStartOffset <= aEndOffset &&
                  (aStartOffset >= 0 || (aStartOffset != -1 && aEndOffset != -1)),
                  NS_ERROR_INVALID_ARG);
 
   nsCOMPtr<nsIAccessible> xpcAcc = do_QueryInterface(aTextAccessible);
   NS_ENSURE_ARG(xpcAcc);
 
-  nsRefPtr<Accessible> acc = xpcAcc->ToInternalAccessible();
+  RefPtr<Accessible> acc = xpcAcc->ToInternalAccessible();
   NS_ENSURE_ARG(acc);
 
   HyperTextAccessible* position = acc->AsHyperText();
   if (!position || !IsDescendantOf(position, GetActiveRoot()))
     return NS_ERROR_INVALID_ARG;
 
   // Make sure the given offsets don't exceed the character count.
   if (aEndOffset > static_cast<int32_t>(position->CharacterCount()))
@@ -638,17 +638,17 @@ nsAccessiblePivot::IsDescendantOf(Access
   return false;
 }
 
 bool
 nsAccessiblePivot::MovePivotInternal(Accessible* aPosition,
                                      PivotMoveReason aReason,
                                      bool aIsFromUserInput)
 {
-  nsRefPtr<Accessible> oldPosition = mPosition.forget();
+  RefPtr<Accessible> oldPosition = mPosition.forget();
   mPosition = aPosition;
   int32_t oldStart = mStartOffset, oldEnd = mEndOffset;
   mStartOffset = mEndOffset = -1;
 
   return NotifyOfPivotChange(oldPosition, oldStart, oldEnd, aReason,
                              aIsFromUserInput);
 }
 
--- a/accessible/base/nsAccessiblePivot.h
+++ b/accessible/base/nsAccessiblePivot.h
@@ -109,27 +109,27 @@ private:
    *
    */
   Accessible* AdjustStartPosition(Accessible* aAccessible, RuleCache& aCache,
                                   uint16_t* aFilterResult, nsresult* aResult);
 
   /*
    * The root accessible.
    */
-  nsRefPtr<Accessible> mRoot;
+  RefPtr<Accessible> mRoot;
 
   /*
    * The temporary modal root accessible.
    */
-  nsRefPtr<Accessible> mModalRoot;
+  RefPtr<Accessible> mModalRoot;
 
   /*
    * The current pivot position.
    */
-  nsRefPtr<Accessible> mPosition;
+  RefPtr<Accessible> mPosition;
 
   /*
    * The text start offset ofthe pivot.
    */
   int32_t mStartOffset;
 
   /*
    * The text end offset ofthe pivot.
--- a/accessible/base/nsCoreUtils.cpp
+++ b/accessible/base/nsCoreUtils.cpp
@@ -97,17 +97,17 @@ nsCoreUtils::DispatchClickEvent(nsITreeB
   // Dispatch mouse events.
   nsWeakFrame tcFrame = tcContent->GetPrimaryFrame();
   nsIFrame* rootFrame = presShell->GetRootFrame();
 
   nsPoint offset;
   nsIWidget *rootWidget =
     rootFrame->GetViewExternal()->GetNearestWidget(&offset);
 
-  nsRefPtr<nsPresContext> presContext = presShell->GetPresContext();
+  RefPtr<nsPresContext> presContext = presShell->GetPresContext();
 
   int32_t cnvdX = presContext->CSSPixelsToDevPixels(tcX + x + 1) +
     presContext->AppUnitsToDevPixels(offset.x);
   int32_t cnvdY = presContext->CSSPixelsToDevPixels(tcY + y + 1) +
     presContext->AppUnitsToDevPixels(offset.y);
 
   // XUL is just desktop, so there is no real reason for senfing touch events.
   DispatchMouseEvent(eMouseDown, cnvdX, cnvdY,
@@ -144,17 +144,17 @@ nsCoreUtils::DispatchTouchEvent(EventMes
   if (!dom::TouchEvent::PrefEnabled())
     return;
 
   WidgetTouchEvent event(true, aMessage, aRootWidget);
 
   event.time = PR_IntervalNow();
 
   // XXX: Touch has an identifier of -1 to hint that it is synthesized.
-  nsRefPtr<dom::Touch> t = new dom::Touch(-1, LayoutDeviceIntPoint(aX, aY),
+  RefPtr<dom::Touch> t = new dom::Touch(-1, LayoutDeviceIntPoint(aX, aY),
                                           nsIntPoint(1, 1), 0.0f, 1.0f);
   t->SetTarget(aContent);
   event.touches.AppendElement(t);
   nsEventStatus status = nsEventStatus_eIgnore;
   aPresShell->HandleEventWithTarget(&event, aFrame, aContent, &status);
 }
 
 uint32_t
--- a/accessible/base/nsEventShell.cpp
+++ b/accessible/base/nsEventShell.cpp
@@ -37,17 +37,17 @@ nsEventShell::FireEvent(AccEvent* aEvent
 }
 
 void
 nsEventShell::FireEvent(uint32_t aEventType, Accessible* aAccessible,
                         EIsFromUserInput aIsFromUserInput)
 {
   NS_ENSURE_TRUE_VOID(aAccessible);
 
-  nsRefPtr<AccEvent> event = new AccEvent(aEventType, aAccessible,
+  RefPtr<AccEvent> event = new AccEvent(aEventType, aAccessible,
                                           aIsFromUserInput);
 
   FireEvent(event);
 }
 
 void 
 nsEventShell::GetEventAttributes(nsINode *aNode,
                                  nsIPersistentProperties *aAttributes)
--- a/accessible/base/nsEventShell.h
+++ b/accessible/base/nsEventShell.h
@@ -36,17 +36,17 @@ public:
                         mozilla::a11y::EIsFromUserInput aIsFromUserInput = mozilla::a11y::eAutoDetect);
 
   /**
    * Fire state change event.
    */
   static void FireEvent(mozilla::a11y::Accessible* aTarget, uint64_t aState,
                         bool aIsEnabled, bool aIsFromUserInput)
   {
-    nsRefPtr<mozilla::a11y::AccStateChangeEvent> stateChangeEvent =
+    RefPtr<mozilla::a11y::AccStateChangeEvent> stateChangeEvent =
       new mozilla::a11y::AccStateChangeEvent(aTarget, aState, aIsEnabled,
                                              (aIsFromUserInput ?
                                                mozilla::a11y::eFromUserInput :
                                                mozilla::a11y::eNoUserInput));
     FireEvent(stateChangeEvent);
   }
 
   /**
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -102,19 +102,20 @@ NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Accessible)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(Accessible, LastRelease())
 
 Accessible::Accessible(nsIContent* aContent, DocAccessible* aDoc) :
   mContent(aContent), mDoc(aDoc),
   mParent(nullptr), mIndexInParent(-1), mChildrenFlags(eChildrenUninitialized),
   mStateFlags(0), mContextFlags(0), mType(0), mGenericTypes(0),
-  mIndexOfEmbeddedChild(-1), mRoleMapEntry(nullptr)
+  mRoleMapEntry(nullptr)
 {
   mBits.groupInfo = nullptr;
+  mInt.mIndexOfEmbeddedChild = -1;
 }
 
 Accessible::~Accessible()
 {
   NS_ASSERTION(!mDoc, "LastRelease was never called!?!");
 }
 
 ENameValueFlag
@@ -1781,17 +1782,17 @@ Accessible::DoCommand(nsIContent *aConte
 
     void Revoke()
     {
       mAcc = nullptr;
       mContent = nullptr;
     }
 
   private:
-    nsRefPtr<Accessible> mAcc;
+    RefPtr<Accessible> mAcc;
     nsCOMPtr<nsIContent> mContent;
     uint32_t mIdx;
   };
 
   nsIContent* content = aContent ? aContent : mContent.get();
   nsCOMPtr<nsIRunnable> runnable = new Runnable(this, content, aActionIndex);
   NS_DispatchToMainThread(runnable);
 }
@@ -1817,17 +1818,17 @@ Accessible::DispatchClickEvent(nsIConten
   // Compute x and y coordinates.
   nsPoint point;
   nsCOMPtr<nsIWidget> widget = frame->GetNearestWidget(point);
   if (!widget)
     return;
 
   nsSize size = frame->GetSize();
 
-  nsRefPtr<nsPresContext> presContext = presShell->GetPresContext();
+  RefPtr<nsPresContext> presContext = presShell->GetPresContext();
   int32_t x = presContext->AppUnitsToDevPixels(point.x + size.width / 2);
   int32_t y = presContext->AppUnitsToDevPixels(point.y + size.height / 2);
 
   // Simulate a touch interaction by dispatching touch events with mouse events.
   nsCoreUtils::DispatchTouchEvent(eTouchStart, x, y, aContent, frame,
                                   presShell, widget);
   nsCoreUtils::DispatchMouseEvent(eMouseDown, x, y, aContent, frame,
                                   presShell, widget);
@@ -1996,17 +1997,17 @@ Accessible::BindToParent(Accessible* aPa
 void
 Accessible::UnbindFromParent()
 {
 #ifdef DEBUG
   AssertInMutatingSubtree();
 #endif
   mParent = nullptr;
   mIndexInParent = -1;
-  mIndexOfEmbeddedChild = -1;
+  mInt.mIndexOfEmbeddedChild = -1;
   if (IsProxy())
     MOZ_CRASH("this should never be called on proxy wrappers");
 
   delete mBits.groupInfo;
   mBits.groupInfo = nullptr;
   mContextFlags &= ~eHasNameDependentParent;
 }
 
--- a/accessible/generic/Accessible.h
+++ b/accessible/generic/Accessible.h
@@ -613,16 +613,26 @@ public:
   bool IsMenuPopup() const { return mType == eMenuPopupType; }
 
   bool IsProxy() const { return mType == eProxyType; }
   ProxyAccessible* Proxy() const
   {
     MOZ_ASSERT(IsProxy());
     return mBits.proxy;
   }
+  uint32_t ProxyInterfaces() const
+  {
+    MOZ_ASSERT(IsProxy());
+    return mInt.mProxyInterfaces;
+  }
+  void SetProxyInterfaces(uint32_t aInterfaces)
+  {
+    MOZ_ASSERT(IsProxy());
+    mInt.mProxyInterfaces = aInterfaces;
+  }
 
   bool IsOuterDoc() const { return mType == eOuterDocType; }
   OuterDocAccessible* AsOuterDoc();
 
   bool IsProgress() const { return mType == eProgressType; }
 
   bool IsRoot() const { return mType == eRootType; }
   a11y::RootAccessible* AsRoot();
@@ -1106,18 +1116,18 @@ protected:
    * Flag all children group info as needing to be updated.
    */
   void InvalidateChildrenGroupInfo();
 
   // Data Members
   nsCOMPtr<nsIContent> mContent;
   DocAccessible* mDoc;
 
-  nsRefPtr<Accessible> mParent;
-  nsTArray<nsRefPtr<Accessible> > mChildren;
+  RefPtr<Accessible> mParent;
+  nsTArray<RefPtr<Accessible> > mChildren;
   int32_t mIndexInParent;
 
   static const uint8_t kChildrenFlagsBits = 2;
   static const uint8_t kStateFlagsBits = 10;
   static const uint8_t kContextFlagsBits = 2;
   static const uint8_t kTypeBits = 6;
   static const uint8_t kGenericTypesBits = 14;
 
@@ -1133,17 +1143,21 @@ protected:
   void StaticAsserts() const;
   void AssertInMutatingSubtree() const;
 
   friend class DocAccessible;
   friend class xpcAccessible;
   friend class AutoTreeMutation;
 
   nsAutoPtr<mozilla::a11y::EmbeddedObjCollector> mEmbeddedObjCollector;
-  int32_t mIndexOfEmbeddedChild;
+  union {
+    int32_t mIndexOfEmbeddedChild;
+    uint32_t mProxyInterfaces;
+  } mInt;
+
   friend class EmbeddedObjCollector;
 
   union
   {
     AccGroupInfo* groupInfo;
     ProxyAccessible* proxy;
   } mBits;
   friend class AccGroupInfo;
--- a/accessible/generic/DocAccessible-inl.h
+++ b/accessible/generic/DocAccessible-inl.h
@@ -40,17 +40,17 @@ DocAccessible::FireDelayedEvent(AccEvent
 #endif
 
   mNotificationController->QueueEvent(aEvent);
 }
 
 inline void
 DocAccessible::FireDelayedEvent(uint32_t aEventType, Accessible* aTarget)
 {
-  nsRefPtr<AccEvent> event = new AccEvent(aEventType, aTarget);
+  RefPtr<AccEvent> event = new AccEvent(aEventType, aTarget);
   FireDelayedEvent(event);
 }
 
 inline void
 DocAccessible::BindChildDocument(DocAccessible* aDocument)
 {
   mNotificationController->ScheduleChildDocBinding(aDocument);
 }
@@ -108,17 +108,17 @@ inline void
 DocAccessible::NotifyOfLoad(uint32_t aLoadEventType)
 {
   mLoadState |= eDOMLoaded;
   mLoadEventType = aLoadEventType;
 
   // If the document is loaded completely then network activity was presumingly
   // caused by file loading. Fire busy state change event.
   if (HasLoadState(eCompletelyLoaded) && IsLoadEventTarget()) {
-    nsRefPtr<AccEvent> stateEvent =
+    RefPtr<AccEvent> stateEvent =
       new AccStateChangeEvent(this, states::BUSY, false);
     FireDelayedEvent(stateEvent);
   }
 }
 
 inline void
 DocAccessible::MaybeNotifyOfValueChange(Accessible* aAccessible)
 {
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -656,17 +656,17 @@ NS_IMETHODIMP
 DocAccessible::Observe(nsISupports* aSubject, const char* aTopic,
                        const char16_t* aData)
 {
   if (!nsCRT::strcmp(aTopic,"obs_documentCreated")) {    
     // State editable will now be set, readonly is now clear
     // Normally we only fire delayed events created from the node, not an
     // accessible object. See the AccStateChangeEvent constructor for details
     // about this exceptional case.
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccStateChangeEvent(this, states::EDITABLE, true);
     FireDelayedEvent(event);
   }
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -674,17 +674,17 @@ DocAccessible::Observe(nsISupports* aSub
 
 NS_IMETHODIMP
 DocAccessible::OnPivotChanged(nsIAccessiblePivot* aPivot,
                               nsIAccessible* aOldAccessible,
                               int32_t aOldStart, int32_t aOldEnd,
                               PivotMoveReason aReason,
                               bool aIsFromUserInput)
 {
-  nsRefPtr<AccEvent> event =
+  RefPtr<AccEvent> event =
     new AccVCChangeEvent(
       this, (aOldAccessible ? aOldAccessible->ToInternalAccessible() : nullptr),
       aOldStart, aOldEnd, aReason,
       aIsFromUserInput ? eFromUserInput : eNoUserInput);
   nsEventShell::FireEvent(event);
 
   return NS_OK;
 }
@@ -818,21 +818,21 @@ DocAccessible::AttributeChangedImpl(Acce
   // ARIA's aria-disabled does not affect the disabled state bit.
   if (aAttribute == nsGkAtoms::disabled ||
       aAttribute == nsGkAtoms::aria_disabled) {
     // Do nothing if state wasn't changed (like @aria-disabled was removed but
     // @disabled is still presented).
     if (aAccessible->Unavailable() == mStateBitWasOn)
       return;
 
-    nsRefPtr<AccEvent> enabledChangeEvent =
+    RefPtr<AccEvent> enabledChangeEvent =
       new AccStateChangeEvent(aAccessible, states::ENABLED, mStateBitWasOn);
     FireDelayedEvent(enabledChangeEvent);
 
-    nsRefPtr<AccEvent> sensitiveChangeEvent =
+    RefPtr<AccEvent> sensitiveChangeEvent =
       new AccStateChangeEvent(aAccessible, states::SENSITIVE, mStateBitWasOn);
     FireDelayedEvent(sensitiveChangeEvent);
     return;
   }
 
   // Check for namespaced ARIA attribute
   if (aNameSpaceID == kNameSpaceID_None) {
     // Check for hyphenated aria-foo property?
@@ -881,43 +881,43 @@ DocAccessible::AttributeChangedImpl(Acce
       FireDelayedEvent(nsIAccessibleEvent::EVENT_DESCRIPTION_CHANGE, aAccessible);
 
     return;
   }
 
   if (aAttribute == nsGkAtoms::aria_busy) {
     bool isOn = elm->AttrValueIs(aNameSpaceID, aAttribute, nsGkAtoms::_true,
                                  eCaseMatters);
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccStateChangeEvent(aAccessible, states::BUSY, isOn);
     FireDelayedEvent(event);
     return;
   }
 
   // ARIA or XUL selection
   if ((aAccessible->GetContent()->IsXULElement() &&
        aAttribute == nsGkAtoms::selected) ||
       aAttribute == nsGkAtoms::aria_selected) {
     Accessible* widget =
       nsAccUtils::GetSelectableContainer(aAccessible, aAccessible->State());
     if (widget) {
       AccSelChangeEvent::SelChangeType selChangeType =
         elm->AttrValueIs(aNameSpaceID, aAttribute, nsGkAtoms::_true, eCaseMatters) ?
           AccSelChangeEvent::eSelectionAdd : AccSelChangeEvent::eSelectionRemove;
 
-      nsRefPtr<AccEvent> event =
+      RefPtr<AccEvent> event =
         new AccSelChangeEvent(widget, aAccessible, selChangeType);
       FireDelayedEvent(event);
     }
 
     return;
   }
 
   if (aAttribute == nsGkAtoms::contenteditable) {
-    nsRefPtr<AccEvent> editableChangeEvent =
+    RefPtr<AccEvent> editableChangeEvent =
       new AccStateChangeEvent(aAccessible, states::EDITABLE);
     FireDelayedEvent(editableChangeEvent);
     return;
   }
 
   if (aAttribute == nsGkAtoms::value) {
     if (aAccessible->IsProgress())
       FireDelayedEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aAccessible);
@@ -927,24 +927,24 @@ DocAccessible::AttributeChangedImpl(Acce
 // DocAccessible protected member
 void
 DocAccessible::ARIAAttributeChanged(Accessible* aAccessible, nsIAtom* aAttribute)
 {
   // Note: For universal/global ARIA states and properties we don't care if
   // there is an ARIA role present or not.
 
   if (aAttribute == nsGkAtoms::aria_required) {
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccStateChangeEvent(aAccessible, states::REQUIRED);
     FireDelayedEvent(event);
     return;
   }
 
   if (aAttribute == nsGkAtoms::aria_invalid) {
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccStateChangeEvent(aAccessible, states::INVALID);
     FireDelayedEvent(event);
     return;
   }
 
   // The activedescendant universal property redirects accessible focus events
   // to the element with the id that activedescendant points to. Make sure
   // the tree up to date before processing.
@@ -952,70 +952,70 @@ DocAccessible::ARIAAttributeChanged(Acce
     mNotificationController->HandleNotification<DocAccessible, Accessible>
       (this, &DocAccessible::ARIAActiveDescendantChanged, aAccessible);
 
     return;
   }
 
   // We treat aria-expanded as a global ARIA state for historical reasons
   if (aAttribute == nsGkAtoms::aria_expanded) {
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccStateChangeEvent(aAccessible, states::EXPANDED);
     FireDelayedEvent(event);
     return;
   }
 
   // For aria attributes like drag and drop changes we fire a generic attribute
   // change event; at least until native API comes up with a more meaningful event.
   uint8_t attrFlags = aria::AttrCharacteristicsFor(aAttribute);
   if (!(attrFlags & ATTR_BYPASSOBJ)) {
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccObjectAttrChangedEvent(aAccessible, aAttribute);
     FireDelayedEvent(event);
   }
 
   nsIContent* elm = aAccessible->GetContent();
 
   // Update aria-hidden flag for the whole subtree iff aria-hidden is changed
   // on the root, i.e. ignore any affiliated aria-hidden changes in the subtree
   // of top aria-hidden.
   if (aAttribute == nsGkAtoms::aria_hidden) {
     bool isDefined = aria::HasDefinedARIAHidden(elm);
     if (isDefined != aAccessible->IsARIAHidden() &&
         !aAccessible->Parent()->IsARIAHidden()) {
       aAccessible->SetARIAHidden(isDefined);
 
-      nsRefPtr<AccEvent> event =
+      RefPtr<AccEvent> event =
         new AccObjectAttrChangedEvent(aAccessible, aAttribute);
       FireDelayedEvent(event);
     }
     return;
   }
 
   if (aAttribute == nsGkAtoms::aria_checked ||
       (aAccessible->IsButton() &&
        aAttribute == nsGkAtoms::aria_pressed)) {
     const uint64_t kState = (aAttribute == nsGkAtoms::aria_checked) ?
                             states::CHECKED : states::PRESSED;
-    nsRefPtr<AccEvent> event = new AccStateChangeEvent(aAccessible, kState);
+    RefPtr<AccEvent> event = new AccStateChangeEvent(aAccessible, kState);
     FireDelayedEvent(event);
 
     bool wasMixed = (mARIAAttrOldValue == nsGkAtoms::mixed);
     bool isMixed = elm->AttrValueIs(kNameSpaceID_None, aAttribute,
                                     nsGkAtoms::mixed, eCaseMatters);
     if (isMixed != wasMixed) {
-      nsRefPtr<AccEvent> event =
+      RefPtr<AccEvent> event =
         new AccStateChangeEvent(aAccessible, states::MIXED, isMixed);
       FireDelayedEvent(event);
     }
     return;
   }
 
   if (aAttribute == nsGkAtoms::aria_readonly) {
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccStateChangeEvent(aAccessible, states::READONLY);
     FireDelayedEvent(event);
     return;
   }
 
   // Fire value change event whenever aria-valuetext is changed, or
   // when aria-valuenow is changed and aria-valuetext is empty
   if (aAttribute == nsGkAtoms::aria_valuetext ||
@@ -1069,36 +1069,36 @@ DocAccessible::ContentStateChanged(nsIDo
     return;
 
   if (aStateMask.HasState(NS_EVENT_STATE_CHECKED)) {
     Accessible* widget = accessible->ContainerWidget();
     if (widget && widget->IsSelect()) {
       AccSelChangeEvent::SelChangeType selChangeType =
         aContent->AsElement()->State().HasState(NS_EVENT_STATE_CHECKED) ?
           AccSelChangeEvent::eSelectionAdd : AccSelChangeEvent::eSelectionRemove;
-      nsRefPtr<AccEvent> event =
+      RefPtr<AccEvent> event =
         new AccSelChangeEvent(widget, accessible, selChangeType);
       FireDelayedEvent(event);
       return;
     }
 
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccStateChangeEvent(accessible, states::CHECKED,
                               aContent->AsElement()->State().HasState(NS_EVENT_STATE_CHECKED));
     FireDelayedEvent(event);
   }
 
   if (aStateMask.HasState(NS_EVENT_STATE_INVALID)) {
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccStateChangeEvent(accessible, states::INVALID, true);
     FireDelayedEvent(event);
   }
 
   if (aStateMask.HasState(NS_EVENT_STATE_VISITED)) {
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccStateChangeEvent(accessible, states::TRAVERSED, true);
     FireDelayedEvent(event);
   }
 }
 
 void
 DocAccessible::DocumentStatesChanged(nsIDocument* aDocument,
                                      EventStates aStateMask)
@@ -1368,18 +1368,18 @@ DocAccessible::ProcessInvalidationList()
     if (!oldParent) {
       NS_ERROR("The accessible is in document but doesn't have a parent");
       continue;
     }
     int32_t idxInParent = child->IndexInParent();
 
     // XXX: update context flags
     {
-      nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(oldParent);
-      nsRefPtr<AccMutationEvent> hideEvent =
+      RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(oldParent);
+      RefPtr<AccMutationEvent> hideEvent =
         new AccHideEvent(child, child->GetContent(), false);
       FireDelayedEvent(hideEvent);
       reorderEvent->AddSubMutationEvent(hideEvent);
 
       AutoTreeMutation mut(oldParent);
       oldParent->RemoveChild(child);
 
       MaybeNotifyOfValueChange(oldParent);
@@ -1394,18 +1394,18 @@ DocAccessible::ProcessInvalidationList()
 
     Accessible* newParent = owner;
     if (!isReinserted) {
       AutoTreeMutation mut(oldParent);
       oldParent->InsertChildAt(idxInParent, child);
       newParent = oldParent;
     }
 
-    nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(newParent);
-    nsRefPtr<AccMutationEvent> showEvent =
+    RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(newParent);
+    RefPtr<AccMutationEvent> showEvent =
       new AccShowEvent(child, child->GetContent());
     FireDelayedEvent(showEvent);
     reorderEvent->AddSubMutationEvent(showEvent);
 
     MaybeNotifyOfValueChange(newParent);
     FireDelayedEvent(reorderEvent);
 
     child->SetRepositioned(isReinserted);
@@ -1480,24 +1480,24 @@ DocAccessible::NotifyOfLoading(bool aIsR
 
   if (!IsLoadEventTarget())
     return;
 
   if (aIsReloading) {
     // Fire reload and state busy events on existing document accessible while
     // event from user input flag can be calculated properly and accessible
     // is alive. When new document gets loaded then this one is destroyed.
-    nsRefPtr<AccEvent> reloadEvent =
+    RefPtr<AccEvent> reloadEvent =
       new AccEvent(nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD, this);
     nsEventShell::FireEvent(reloadEvent);
   }
 
   // Fire state busy change event. Use delayed event since we don't care
   // actually if event isn't delivered when the document goes away like a shot.
-  nsRefPtr<AccEvent> stateEvent =
+  RefPtr<AccEvent> stateEvent =
     new AccStateChangeEvent(this, states::BUSY, true);
   FireDelayedEvent(stateEvent);
 }
 
 void
 DocAccessible::DoInitialUpdate()
 {
   if (nsCoreUtils::IsTabDocument(mDocumentNode))
@@ -1519,24 +1519,24 @@ DocAccessible::DoInitialUpdate()
   AutoTreeMutation mut(this, false);
   CacheChildrenInSubtree(this);
 
   // Fire reorder event after the document tree is constructed. Note, since
   // this reorder event is processed by parent document then events targeted to
   // this document may be fired prior to this reorder event. If this is
   // a problem then consider to keep event processing per tab document.
   if (!IsRoot()) {
-    nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(Parent());
+    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);
-    nsRefPtr<AccShowEvent> event = new AccShowEvent(child, child->GetContent());
+    RefPtr<AccShowEvent> event = new AccShowEvent(child, child->GetContent());
   FireDelayedEvent(event);
   }
 }
 
 void
 DocAccessible::ProcessLoad()
 {
   mLoadState |= eCompletelyLoaded;
@@ -1552,24 +1552,24 @@ DocAccessible::ProcessLoad()
   // documents
   // b) document load event on sub documents causes screen readers to act is if
   // entire page is reloaded.
   if (!IsLoadEventTarget())
     return;
 
   // Fire complete/load stopped if the load event type is given.
   if (mLoadEventType) {
-    nsRefPtr<AccEvent> loadEvent = new AccEvent(mLoadEventType, this);
+    RefPtr<AccEvent> loadEvent = new AccEvent(mLoadEventType, this);
     FireDelayedEvent(loadEvent);
 
     mLoadEventType = 0;
   }
 
   // Fire busy state change event.
-  nsRefPtr<AccEvent> stateEvent =
+  RefPtr<AccEvent> stateEvent =
     new AccStateChangeEvent(this, states::BUSY, false);
   FireDelayedEvent(stateEvent);
 }
 
 void
 DocAccessible::AddDependentIDsFor(Accessible* aRelProvider, nsIAtom* aRelAttr)
 {
   dom::Element* relProviderEl = aRelProvider->Elm();
@@ -1697,25 +1697,25 @@ DocAccessible::RemoveDependentIDsFor(Acc
 
     // aria-owns has gone, put the children back.
     if (relAttr == nsGkAtoms::aria_owns) {
       nsTArray<nsIContent*>* children = mARIAOwnsHash.Get(aRelProvider);
       if (children) {
         nsTArray<Accessible*> containers;
 
         // Remove ARIA owned elements from where they belonged.
-        nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(aRelProvider);
+        RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(aRelProvider);
         {
           AutoTreeMutation mut(aRelProvider);
           for (uint32_t idx = 0; idx < children->Length(); idx++) {
             nsIContent* childEl = children->ElementAt(idx);
             Accessible* child = GetAccessible(childEl);
             if (child && child->IsRepositioned()) {
               {
-                nsRefPtr<AccMutationEvent> hideEvent =
+                RefPtr<AccMutationEvent> hideEvent =
                   new AccHideEvent(child, childEl, false);
                 FireDelayedEvent(hideEvent);
                 reorderEvent->AddSubMutationEvent(hideEvent);
 
                 aRelProvider->RemoveChild(child);
               }
 
               // Collect DOM-order containers to update their trees.
@@ -1895,17 +1895,17 @@ DocAccessible::UpdateTreeOnInsertion(Acc
     Accessible* child = aContainer->ContentChildAt(idx);
     child->SetSurvivingInUpdate(true);
    }
 
   AutoTreeMutation mut(aContainer);
   aContainer->InvalidateChildren();
   aContainer->EnsureChildren();
 
-  nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(aContainer);
+  RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(aContainer);
 
   uint32_t updateFlags = eNoAccessible;
   for (uint32_t idx = 0; idx < aContainer->ContentChildCount(); idx++) {
     Accessible* child = aContainer->ContentChildAt(idx);
     if (child->IsSurvivingInUpdate()) {
       child->SetSurvivingInUpdate(false);
       continue;
     }
@@ -1967,17 +1967,17 @@ DocAccessible::UpdateTreeOnRemoval(Acces
     else
       logging::MsgEntry("child accessible: null");
 
     logging::MsgEnd();
   }
 #endif
 
   uint32_t updateFlags = eNoAccessible;
-  nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(aContainer);
+  RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(aContainer);
   AutoTreeMutation mut(aContainer);
 
   if (child) {
     updateFlags |= UpdateTreeInternal(child, false, reorderEvent);
   } else {
     // aChildNode may not coorespond to a particular accessible, to handle
     // this we go through all the children of aContainer.  Then if a child
     // has aChildNode as an ancestor, or does not have the node for
@@ -2049,17 +2049,17 @@ DocAccessible::UpdateTreeInternal(Access
     // the changes before our processing and we may miss some menupopup
     // events. Now we just want to be consistent in content insertion/removal
     // handling.
     if (aChild->ARIARole() == roles::MENUPOPUP)
       FireDelayedEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END, aChild);
   }
 
   // Fire show/hide event.
-  nsRefPtr<AccMutationEvent> event;
+  RefPtr<AccMutationEvent> event;
   if (aIsInsert)
     event = new AccShowEvent(aChild, node);
   else
     event = new AccHideEvent(aChild, node);
 
   FireDelayedEvent(event);
   aReorderEvent->AddSubMutationEvent(event);
 
--- a/accessible/generic/DocAccessible.h
+++ b/accessible/generic/DocAccessible.h
@@ -619,22 +619,22 @@ protected:
   union {
     // ARIA attribute value
     nsIAtom* mARIAAttrOldValue;
 
     // True if the accessible state bit was on
     bool mStateBitWasOn;
   };
 
-  nsTArray<nsRefPtr<DocAccessible> > mChildDocuments;
+  nsTArray<RefPtr<DocAccessible> > mChildDocuments;
 
   /**
    * The virtual cursor of the document.
    */
-  nsRefPtr<nsAccessiblePivot> mVirtualCursor;
+  RefPtr<nsAccessiblePivot> mVirtualCursor;
 
   /**
    * A storage class for pairing content with one of its relation attributes.
    */
   class AttrRelProvider
   {
   public:
     AttrRelProvider(nsIAtom* aRelAttr, nsIContent* aContent) :
@@ -682,25 +682,25 @@ protected:
   struct ARIAOwnsPair {
     ARIAOwnsPair(Accessible* aOwner, nsIContent* aChild) :
       mOwner(aOwner), mChild(aChild) { }
     ARIAOwnsPair(const ARIAOwnsPair& aPair) :
       mOwner(aPair.mOwner), mChild(aPair.mChild) { }
     ARIAOwnsPair& operator =(const ARIAOwnsPair& aPair)
       { mOwner = aPair.mOwner; mChild = aPair.mChild; return *this; }
 
-    nsRefPtr<Accessible> mOwner;
+    RefPtr<Accessible> mOwner;
     nsCOMPtr<nsIContent> mChild;
   };
   nsTArray<ARIAOwnsPair> mARIAOwnsInvalidationList;
 
   /**
    * Used to process notification from core and accessible events.
    */
-  nsRefPtr<NotificationController> mNotificationController;
+  RefPtr<NotificationController> mNotificationController;
   friend class EventQueue;
   friend class NotificationController;
 
 private:
 
   nsIPresShell* mPresShell;
 
   // Exclusively owned by IPDL so don't manually delete it!
--- a/accessible/generic/HyperTextAccessible-inl.h
+++ b/accessible/generic/HyperTextAccessible-inl.h
@@ -148,32 +148,32 @@ HyperTextAccessible::AdjustCaretOffset(u
     return aOffset - 1;
 
   return aOffset;
 }
 
 inline bool
 HyperTextAccessible::IsCaretAtEndOfLine() const
 {
-  nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
+  RefPtr<nsFrameSelection> frameSelection = FrameSelection();
   return frameSelection &&
     frameSelection->GetHint() == CARET_ASSOCIATE_BEFORE;
 }
 
 inline already_AddRefed<nsFrameSelection>
 HyperTextAccessible::FrameSelection() const
 {
   nsIFrame* frame = GetFrame();
   return frame ? frame->GetFrameSelection() : nullptr;
 }
 
 inline dom::Selection*
 HyperTextAccessible::DOMSelection() const
 {
-  nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
+  RefPtr<nsFrameSelection> frameSelection = FrameSelection();
   return frameSelection ?
     frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL) :
     nullptr;
 }
 
 } // namespace a11y
 } // namespace mozilla
 
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -1425,17 +1425,17 @@ HyperTextAccessible::CaretOffset() const
   return DOMPointToOffset(focusNode, focusOffset);
 }
 
 int32_t
 HyperTextAccessible::CaretLineNumber()
 {
   // Provide the line number for the caret, relative to the
   // currently focused node. Use a 1-based index
-  nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
+  RefPtr<nsFrameSelection> frameSelection = FrameSelection();
   if (!frameSelection)
     return -1;
 
   dom::Selection* domSel =
     frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL);
   if (!domSel)
     return - 1;
 
@@ -1494,17 +1494,17 @@ HyperTextAccessible::CaretLineNumber()
   return lineNumber;
 }
 
 nsIntRect
 HyperTextAccessible::GetCaretRect(nsIWidget** aWidget)
 {
   *aWidget = nullptr;
 
-  nsRefPtr<nsCaret> caret = mDoc->PresShell()->GetCaret();
+  RefPtr<nsCaret> caret = mDoc->PresShell()->GetCaret();
   NS_ENSURE_TRUE(caret, nsIntRect());
 
   bool isVisible = caret->IsVisible();
   if (!isVisible)
     return nsIntRect();
 
   nsRect rect;
   nsIFrame* frame = caret->GetGeometry(&rect);
@@ -1536,17 +1536,17 @@ HyperTextAccessible::GetCaretRect(nsIWid
   return caretRect;
 }
 
 void
 HyperTextAccessible::GetSelectionDOMRanges(int16_t aType,
                                            nsTArray<nsRange*>* aRanges)
 {
   // Ignore selection if it is not visible.
-  nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
+  RefPtr<nsFrameSelection> frameSelection = FrameSelection();
   if (!frameSelection ||
       frameSelection->GetDisplaySelection() <= nsISelectionController::SELECTION_HIDDEN)
     return;
 
   dom::Selection* domSel = frameSelection->GetSelection(aType);
   if (!domSel)
     return;
 
@@ -1644,17 +1644,17 @@ HyperTextAccessible::SetSelectionBoundsA
     NS_ERROR("Wrong in offset");
     return false;
   }
 
   dom::Selection* domSel = DOMSelection();
   if (!domSel)
     return false;
 
-  nsRefPtr<nsRange> range;
+  RefPtr<nsRange> range;
   uint32_t rangeCount = domSel->RangeCount();
   if (aSelectionNum == static_cast<int32_t>(rangeCount))
     range = new nsRange(mContent);
   else
     range = domSel->GetRangeAt(aSelectionNum);
 
   if (!range)
     return false;
@@ -1684,17 +1684,17 @@ HyperTextAccessible::RemoveFromSelection
   domSel->RemoveRange(domSel->GetRangeAt(aSelectionNum));
   return true;
 }
 
 void
 HyperTextAccessible::ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
                                        uint32_t aScrollType)
 {
-  nsRefPtr<nsRange> range = new nsRange(mContent);
+  RefPtr<nsRange> range = new nsRange(mContent);
   if (OffsetsToDOMRange(aStartOffset, aEndOffset, range))
     nsCoreUtils::ScrollSubstringTo(GetFrame(), range, aScrollType);
 }
 
 void
 HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartOffset,
                                             int32_t aEndOffset,
                                             uint32_t aCoordinateType,
@@ -1702,17 +1702,17 @@ HyperTextAccessible::ScrollSubstringToPo
 {
   nsIFrame *frame = GetFrame();
   if (!frame)
     return;
 
   nsIntPoint coords = nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordinateType,
                                                         this);
 
-  nsRefPtr<nsRange> range = new nsRange(mContent);
+  RefPtr<nsRange> range = new nsRange(mContent);
   if (!OffsetsToDOMRange(aStartOffset, aEndOffset, range))
     return;
 
   nsPresContext* presContext = frame->PresContext();
   nsPoint coordsInAppUnits =
     ToAppUnits(coords, presContext->AppUnitsPerDevPixel());
 
   bool initialScrolled = false;
@@ -2148,17 +2148,17 @@ HyperTextAccessible::GetDOMPointByFrameO
 // HyperTextAccessible
 void
 HyperTextAccessible::GetSpellTextAttr(nsINode* aNode,
                                       int32_t aNodeOffset,
                                       uint32_t* aStartOffset,
                                       uint32_t* aEndOffset,
                                       nsIPersistentProperties* aAttributes)
 {
-  nsRefPtr<nsFrameSelection> fs = FrameSelection();
+  RefPtr<nsFrameSelection> fs = FrameSelection();
   if (!fs)
     return;
 
   dom::Selection* domSel = fs->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
   if (!domSel)
     return;
 
   int32_t rangeCount = domSel->RangeCount();
--- a/accessible/generic/RootAccessible.cpp
+++ b/accessible/generic/RootAccessible.cpp
@@ -306,17 +306,17 @@ RootAccessible::ProcessDOMEvent(nsIDOMEv
   }
 #endif
 
   if (eventType.EqualsLiteral("RadioStateChange")) {
     uint64_t state = accessible->State();
     bool isEnabled = (state & (states::CHECKED | states::SELECTED)) != 0;
 
     if (accessible->NeedsDOMUIEvent()) {
-      nsRefPtr<AccEvent> accEvent =
+      RefPtr<AccEvent> accEvent =
         new AccStateChangeEvent(accessible, states::CHECKED, isEnabled);
       nsEventShell::FireEvent(accEvent);
     }
 
     if (isEnabled) {
       FocusMgr()->ActiveItemChanged(accessible);
 #ifdef A11Y_LOG
       if (logging::IsEnabled(logging::eFocus))
@@ -327,17 +327,17 @@ RootAccessible::ProcessDOMEvent(nsIDOMEv
     return;
   }
 
   if (eventType.EqualsLiteral("CheckboxStateChange")) {
     if (accessible->NeedsDOMUIEvent()) {
       uint64_t state = accessible->State();
       bool isEnabled = !!(state & states::CHECKED);
 
-      nsRefPtr<AccEvent> accEvent =
+      RefPtr<AccEvent> accEvent =
         new AccStateChangeEvent(accessible, states::CHECKED, isEnabled);
       nsEventShell::FireEvent(accEvent);
     }
     return;
   }
 
   Accessible* treeItemAcc = nullptr;
 #ifdef MOZ_XUL
@@ -347,17 +347,17 @@ RootAccessible::ProcessDOMEvent(nsIDOMEv
     if (treeItemAcc)
       accessible = treeItemAcc;
   }
 
   if (treeItemAcc && eventType.EqualsLiteral("OpenStateChange")) {
     uint64_t state = accessible->State();
     bool isEnabled = (state & states::EXPANDED) != 0;
 
-    nsRefPtr<AccEvent> accEvent =
+    RefPtr<AccEvent> accEvent =
       new AccStateChangeEvent(accessible, states::EXPANDED, isEnabled);
     nsEventShell::FireEvent(accEvent);
     return;
   }
 
   nsINode* targetNode = accessible->GetNode();
   if (treeItemAcc && eventType.EqualsLiteral("select")) {
     // XXX: We shouldn't be based on DOM select event which doesn't provide us
@@ -373,17 +373,17 @@ RootAccessible::ProcessDOMEvent(nsIDOMEv
         // for each tree item. Perhaps each tree item will need to cache its
         // selection state and fire an event after a DOM "select" event when
         // that state changes. XULTreeAccessible::UpdateTreeSelection();
         nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
                                 accessible);
         return;
       }
 
-      nsRefPtr<AccSelChangeEvent> selChangeEvent =
+      RefPtr<AccSelChangeEvent> selChangeEvent =
         new AccSelChangeEvent(treeAcc, treeItemAcc,
                               AccSelChangeEvent::eSelectionAdd);
       nsEventShell::FireEvent(selChangeEvent);
       return;
     }
   }
   else
 #endif
@@ -531,17 +531,17 @@ RootAccessible::HandlePopupShownEvent(Ac
     // Fire expanded state change event for comboboxes and autocompeletes.
     Accessible* combobox = aAccessible->Parent();
     if (!combobox)
       return;
 
     roles::Role comboboxRole = combobox->Role();
     if (comboboxRole == roles::COMBOBOX || 
 	comboboxRole == roles::AUTOCOMPLETE) {
-      nsRefPtr<AccEvent> event =
+      RefPtr<AccEvent> event =
         new AccStateChangeEvent(combobox, states::EXPANDED, true);
       if (event)
         nsEventShell::FireEvent(event);
     }
   }
 }
 
 void
@@ -640,17 +640,17 @@ RootAccessible::HandlePopupHidingEvent(n
 #ifdef A11Y_LOG
     if (logging::IsEnabled(logging::eFocus))
       logging::ActiveItemChangeCausedBy("popuphiding", popup);
 #endif
   }
 
   // Fire expanded state change event.
   if (notifyOf & kNotifyOfState) {
-    nsRefPtr<AccEvent> event =
+    RefPtr<AccEvent> event =
       new AccStateChangeEvent(widget, states::EXPANDED, false);
     document->FireDelayedEvent(event);
   }
 }
 
 #ifdef MOZ_XUL
 void
 RootAccessible::HandleTreeRowCountChangedEvent(nsIDOMEvent* aEvent,
--- a/accessible/html/HTMLElementAccessibles.cpp
+++ b/accessible/html/HTMLElementAccessibles.cpp
@@ -63,17 +63,17 @@ HTMLLabelAccessible::NativeName(nsString
   return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
 }
 
 Relation
 HTMLLabelAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
   if (aType == RelationType::LABEL_FOR) {
-    nsRefPtr<dom::HTMLLabelElement> label = dom::HTMLLabelElement::FromContent(mContent);
+    RefPtr<dom::HTMLLabelElement> label = dom::HTMLLabelElement::FromContent(mContent);
     rel.AppendTarget(mDoc, label->GetControl());
   }
 
   return rel;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLOuputAccessible
--- a/accessible/html/HTMLFormControlAccessible.cpp
+++ b/accessible/html/HTMLFormControlAccessible.cpp
@@ -129,17 +129,17 @@ HTMLRadioButtonAccessible::GetPositionAn
   nsAutoString tagName;
   mContent->NodeInfo()->GetName(tagName);
 
   nsAutoString type;
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
   nsAutoString name;
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
 
-  nsRefPtr<nsContentList> inputElms;
+  RefPtr<nsContentList> inputElms;
 
   nsCOMPtr<nsIFormControl> formControlNode(do_QueryInterface(mContent));
   dom::Element* formElm = formControlNode->GetFormElement();
   if (formElm)
     inputElms = NS_GetContentList(formElm, namespaceId, tagName);
   else
     inputElms = NS_GetContentList(mContent->OwnerDoc(), namespaceId, tagName);
   NS_ENSURE_TRUE_VOID(inputElms);
@@ -524,17 +524,17 @@ HTMLFileInputAccessible::HandleAccEvent(
   AccStateChangeEvent* event = downcast_accEvent(aEvent);
   if (event &&
       (event->GetState() == states::BUSY ||
        event->GetState() == states::REQUIRED ||
        event->GetState() == states::HASPOPUP ||
        event->GetState() == states::INVALID)) {
     Accessible* button = GetChildAt(0);
     if (button && button->Role() == roles::PUSHBUTTON) {
-      nsRefPtr<AccStateChangeEvent> childEvent =
+      RefPtr<AccStateChangeEvent> childEvent =
         new AccStateChangeEvent(button, event->GetState(),
                                 event->IsStateEnabled(), event->FromUserInput());
       nsEventShell::FireEvent(childEvent);
     }
   }
 
   return NS_OK;
 }
--- a/accessible/html/HTMLImageMapAccessible.cpp
+++ b/accessible/html/HTMLImageMapAccessible.cpp
@@ -82,51 +82,51 @@ HTMLImageMapAccessible::UpdateChildAreas
 
   // If image map is not initialized yet then we trigger one time more later.
   nsImageMap* imageMapObj = imageFrame->GetExistingImageMap();
   if (!imageMapObj)
     return;
 
   bool treeChanged = false;
   AutoTreeMutation mut(this);
-  nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
+  RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
 
   // Remove areas that are not a valid part of the image map anymore.
   for (int32_t childIdx = mChildren.Length() - 1; childIdx >= 0; childIdx--) {
     Accessible* area = mChildren.ElementAt(childIdx);
     if (area->GetContent()->GetPrimaryFrame())
       continue;
 
     if (aDoFireEvents) {
-      nsRefPtr<AccHideEvent> event = new AccHideEvent(area, area->GetContent());
+      RefPtr<AccHideEvent> event = new AccHideEvent(area, area->GetContent());
       mDoc->FireDelayedEvent(event);
       reorderEvent->AddSubMutationEvent(event);
     }
 
     RemoveChild(area);
     treeChanged = true;
   }
 
   // Insert new areas into the tree.
   uint32_t areaElmCount = imageMapObj->AreaCount();
   for (uint32_t idx = 0; idx < areaElmCount; idx++) {
     nsIContent* areaContent = imageMapObj->GetAreaAt(idx);
 
     Accessible* area = mChildren.SafeElementAt(idx);
     if (!area || area->GetContent() != areaContent) {
-      nsRefPtr<Accessible> area = new HTMLAreaAccessible(areaContent, mDoc);
+      RefPtr<Accessible> area = new HTMLAreaAccessible(areaContent, mDoc);
       mDoc->BindToDocument(area, aria::GetRoleMap(areaContent));
 
       if (!InsertChildAt(idx, area)) {
         mDoc->UnbindFromDocument(area);
         break;
       }
 
       if (aDoFireEvents) {
-        nsRefPtr<AccShowEvent> event = new AccShowEvent(area, areaContent);
+        RefPtr<AccShowEvent> event = new AccShowEvent(area, areaContent);
         mDoc->FireDelayedEvent(event);
         reorderEvent->AddSubMutationEvent(event);
       }
 
       treeChanged = true;
     }
   }
 
--- a/accessible/html/HTMLListAccessible.cpp
+++ b/accessible/html/HTMLListAccessible.cpp
@@ -97,30 +97,30 @@ HTMLLIAccessible::Bounds() const
 void
 HTMLLIAccessible::UpdateBullet(bool aHasBullet)
 {
   if (aHasBullet == !!mBullet) {
     NS_NOTREACHED("Bullet and accessible are in sync already!");
     return;
   }
 
-  nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
+  RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
   AutoTreeMutation mut(this);
 
   DocAccessible* document = Document();
   if (aHasBullet) {
     mBullet = new HTMLListBulletAccessible(mContent, mDoc);
     document->BindToDocument(mBullet, nullptr);
     InsertChildAt(0, mBullet);
 
-    nsRefPtr<AccShowEvent> event = new AccShowEvent(mBullet, mBullet->GetContent());
+    RefPtr<AccShowEvent> event = new AccShowEvent(mBullet, mBullet->GetContent());
     mDoc->FireDelayedEvent(event);
     reorderEvent->AddSubMutationEvent(event);
   } else {
-    nsRefPtr<AccHideEvent> event = new AccHideEvent(mBullet, mBullet->GetContent());
+    RefPtr<AccHideEvent> event = new AccHideEvent(mBullet, mBullet->GetContent());
     mDoc->FireDelayedEvent(event);
     reorderEvent->AddSubMutationEvent(event);
 
     RemoveChild(mBullet);
     mBullet = nullptr;
   }
 
   mDoc->FireDelayedEvent(reorderEvent);
--- a/accessible/html/HTMLListAccessible.h
+++ b/accessible/html/HTMLListAccessible.h
@@ -59,17 +59,17 @@ public:
 
 protected:
   virtual ~HTMLLIAccessible() { }
 
   // Accessible
   virtual void CacheChildren() override;
 
 private:
-  nsRefPtr<HTMLListBulletAccessible> mBullet;
+  RefPtr<HTMLListBulletAccessible> mBullet;
 };
 
 
 /**
  * Used for bullet of HTML list item element (for example, HTML li).
  */
 class HTMLListBulletAccessible : public LeafAccessible
 {
--- a/accessible/html/HTMLSelectAccessible.cpp
+++ b/accessible/html/HTMLSelectAccessible.cpp
@@ -129,17 +129,17 @@ HTMLSelectListAccessible::CacheChildren(
     if (!childContent->IsHTMLElement()) {
       continue;
     }
 
     if (childContent->IsAnyOfHTMLElements(nsGkAtoms::option,
                                           nsGkAtoms::optgroup)) {
 
       // Get an accessible for option or optgroup and cache it.
-      nsRefPtr<Accessible> accessible =
+      RefPtr<Accessible> accessible =
         GetAccService()->GetOrCreateAccessible(childContent, this);
       if (accessible)
         AppendChild(accessible);
     }
   }
 }
 
 
--- a/accessible/html/HTMLSelectAccessible.h
+++ b/accessible/html/HTMLSelectAccessible.h
@@ -191,17 +191,17 @@ protected:
   virtual void CacheChildren() override;
 
   /**
    * Return selected option.
    */
   Accessible* SelectedOption() const;
 
 private:
-  nsRefPtr<HTMLComboboxListAccessible> mListAccessible;
+  RefPtr<HTMLComboboxListAccessible> mListAccessible;
 };
 
 /*
  * A class that represents the window that lives to the right
  * of the drop down button inside the Select. This is the window
  * that is made visible when the button is pressed.
  */
 class HTMLComboboxListAccessible : public HTMLSelectListAccessible
--- a/accessible/html/HTMLTableAccessible.cpp
+++ b/accessible/html/HTMLTableAccessible.cpp
@@ -807,17 +807,17 @@ HTMLTableAccessible::AddRowOrColumnToSel
 
   uint32_t count = 0;
   if (doSelectRow)
     count = ColCount();
   else
     count = RowCount();
 
   nsIPresShell* presShell(mDoc->PresShell());
-  nsRefPtr<nsFrameSelection> tableSelection =
+  RefPtr<nsFrameSelection> tableSelection =
     const_cast<nsFrameSelection*>(presShell->ConstFrameSelection());
 
   for (uint32_t idx = 0; idx < count; idx++) {
     int32_t rowIdx = doSelectRow ? aIndex : idx;
     int32_t colIdx = doSelectRow ? idx : aIndex;
     nsTableCellFrame* cellFrame = tableFrame->GetCellFrameAt(rowIdx, colIdx);
     if (cellFrame && !cellFrame->IsSelected()) {
       nsresult rv = tableSelection->SelectCellElement(cellFrame->GetContent());
@@ -833,17 +833,17 @@ HTMLTableAccessible::RemoveRowsOrColumns
                                                       uint32_t aTarget,
                                                       bool aIsOuter)
 {
   nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
   if (!tableFrame)
     return NS_OK;
 
   nsIPresShell* presShell(mDoc->PresShell());
-  nsRefPtr<nsFrameSelection> tableSelection =
+  RefPtr<nsFrameSelection> tableSelection =
     const_cast<nsFrameSelection*>(presShell->ConstFrameSelection());
 
   bool doUnselectRow = (aTarget == nsISelectionPrivate::TABLESELECTION_ROW);
   uint32_t count = doUnselectRow ? ColCount() : RowCount();
 
   int32_t startRowIdx = doUnselectRow ? aIndex : 0;
   int32_t endRowIdx = doUnselectRow ? aIndex : count - 1;
   int32_t startColIdx = doUnselectRow ? 0 : aIndex;
--- a/accessible/windows/ia2/ia2Accessible.cpp
+++ b/accessible/windows/ia2/ia2Accessible.cpp
@@ -113,39 +113,39 @@ ia2Accessible::get_relation(long aRelati
     size_t targetSetCount = targetSets.Length();
     for (size_t i = 0; i < targetSetCount; i++) {
       uint32_t relTypeIdx = static_cast<uint32_t>(types[i]);
       MOZ_ASSERT(sRelationTypePairs[relTypeIdx].first == types[i]);
       if (sRelationTypePairs[relTypeIdx].second == IA2_RELATION_NULL)
         continue;
 
       if (static_cast<size_t>(aRelationIndex) == i) {
-        nsTArray<nsRefPtr<Accessible>> targets;
+        nsTArray<RefPtr<Accessible>> targets;
         size_t targetCount = targetSets[i].Length();
         for (size_t j = 0; j < targetCount; j++)
           targets.AppendElement(WrapperFor(targetSets[i][j]));
 
-        nsRefPtr<ia2AccessibleRelation> rel =
+        RefPtr<ia2AccessibleRelation> rel =
           new ia2AccessibleRelation(types[i], Move(targets));
         rel.forget(aRelation);
         return S_OK;
       }
     }
 
     return E_INVALIDARG;
   }
 
   long relIdx = 0;
   for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs); idx++) {
     if (sRelationTypePairs[idx].second == IA2_RELATION_NULL)
       continue;
 
     RelationType relationType = sRelationTypePairs[idx].first;
     Relation rel = acc->RelationByType(relationType);
-    nsRefPtr<ia2AccessibleRelation> ia2Relation =
+    RefPtr<ia2AccessibleRelation> ia2Relation =
       new ia2AccessibleRelation(relationType, &rel);
     if (ia2Relation->HasTargets()) {
       if (relIdx == aRelationIndex) {
         ia2Relation.forget(aRelation);
         return S_OK;
       }
 
       relIdx++;
@@ -181,38 +181,38 @@ ia2Accessible::get_relations(long aMaxRe
                             static_cast<size_t>(aMaxRelations));
     size_t i = 0;
     while (i < count) {
       uint32_t relTypeIdx = static_cast<uint32_t>(types[i]);
       if (sRelationTypePairs[relTypeIdx].second == IA2_RELATION_NULL)
         continue;
 
       size_t targetCount = targetSets[i].Length();
-      nsTArray<nsRefPtr<Accessible>> targets(targetCount);
+      nsTArray<RefPtr<Accessible>> targets(targetCount);
       for (size_t j = 0; j < targetCount; j++)
         targets.AppendElement(WrapperFor(targetSets[i][j]));
 
-      nsRefPtr<ia2AccessibleRelation> rel =
+      RefPtr<ia2AccessibleRelation> rel =
         new ia2AccessibleRelation(types[i], Move(targets));
       rel.forget(aRelation + i);
       i++;
     }
 
     *aNRelations = i;
     return S_OK;
   }
 
   for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs) &&
        *aNRelations < aMaxRelations; idx++) {
     if (sRelationTypePairs[idx].second == IA2_RELATION_NULL)
       continue;
 
     RelationType relationType = sRelationTypePairs[idx].first;
     Relation rel = acc->RelationByType(relationType);
-    nsRefPtr<ia2AccessibleRelation> ia2Rel =
+    RefPtr<ia2AccessibleRelation> ia2Rel =
       new ia2AccessibleRelation(relationType, &rel);
     if (ia2Rel->HasTargets()) {
       ia2Rel.forget(aRelation + (*aNRelations));
       (*aNRelations)++;
     }
   }
   return S_OK;
 
--- a/accessible/windows/ia2/ia2AccessibleHyperlink.cpp
+++ b/accessible/windows/ia2/ia2AccessibleHyperlink.cpp
@@ -21,17 +21,20 @@ STDMETHODIMP
 ia2AccessibleHyperlink::QueryInterface(REFIID iid, void** ppv)
 {
   if (!ppv)
     return E_INVALIDARG;
 
   *ppv = nullptr;
 
   if (IID_IAccessibleHyperlink == iid) {
-    if (!static_cast<AccessibleWrap*>(this)->IsLink())
+    auto accWrap = static_cast<AccessibleWrap*>(this);
+    if (accWrap->IsProxy() ?
+        !(accWrap->ProxyInterfaces() & Interfaces::HYPERLINK) :
+        !accWrap->IsLink())
       return E_NOINTERFACE;
 
     *ppv = static_cast<IAccessibleHyperlink*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   return ia2AccessibleAction::QueryInterface(iid, ppv);
--- a/accessible/windows/ia2/ia2AccessibleRelation.h
+++ b/accessible/windows/ia2/ia2AccessibleRelation.h
@@ -20,17 +20,17 @@ namespace mozilla {
 namespace a11y {
 
 class ia2AccessibleRelation final : public IAccessibleRelation
 {
 public:
   ia2AccessibleRelation(RelationType aType, Relation* aRel);
 
   ia2AccessibleRelation(RelationType aType,
-                        nsTArray<nsRefPtr<Accessible>>&& aTargets) :
+                        nsTArray<RefPtr<Accessible>>&& aTargets) :
     mType(aType), mTargets(Move(aTargets)) {}
 
   // IUnknown
   DECL_IUNKNOWN
 
   // IAccessibleRelation
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_relationType(
       /* [retval][out] */ BSTR *relationType);
@@ -54,17 +54,17 @@ public:
     { return mTargets.Length(); }
 
 private:
   ia2AccessibleRelation();
   ia2AccessibleRelation(const ia2AccessibleRelation&);
   ia2AccessibleRelation& operator = (const ia2AccessibleRelation&);
 
   RelationType mType;
-  nsTArray<nsRefPtr<Accessible> > mTargets;
+  nsTArray<RefPtr<Accessible> > mTargets;
 };
 
 
 /**
  * Gecko to IAccessible2 relation types map.
  */
 
 const WCHAR *const IA2_RELATION_NULL = L"";
--- a/accessible/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/windows/msaa/AccessibleWrap.cpp
@@ -828,17 +828,17 @@ AccessibleWrap::get_accSelection(VARIANT
   if (IsProxy())
     return E_NOTIMPL;
 
   if (IsSelect()) {
     nsAutoTArray<Accessible*, 10> selectedItems;
     SelectedItems(&selectedItems);
 
     // 1) Create and initialize the enumeration
-    nsRefPtr<AccessibleEnumerator> pEnum = new AccessibleEnumerator(selectedItems);
+    RefPtr<AccessibleEnumerator> pEnum = new AccessibleEnumerator(selectedItems);
     pvarChildren->vt = VT_UNKNOWN;    // this must be VT_UNKNOWN for an IEnumVARIANT
     NS_ADDREF(pvarChildren->punkVal = pEnum);
   }
   return S_OK;
 
   A11Y_TRYBLOCK_END
 }
 
--- a/accessible/windows/msaa/EnumVariant.h
+++ b/accessible/windows/msaa/EnumVariant.h
@@ -44,17 +44,17 @@ private:
   ChildrenEnumVariant& operator =(const ChildrenEnumVariant&) = delete;
 
   ChildrenEnumVariant(const ChildrenEnumVariant& aEnumVariant) :
     mAnchorAcc(aEnumVariant.mAnchorAcc), mCurAcc(aEnumVariant.mCurAcc),
     mCurIndex(aEnumVariant.mCurIndex) { }
   virtual ~ChildrenEnumVariant() { }
 
 protected:
-  nsRefPtr<AccessibleWrap> mAnchorAcc;
+  RefPtr<AccessibleWrap> mAnchorAcc;
   Accessible* mCurAcc;
   uint32_t mCurIndex;
 };
 
 } // a11y namespace
 } // mozilla namespace
 
 #endif
--- a/accessible/windows/msaa/HTMLWin32ObjectAccessible.h
+++ b/accessible/windows/msaa/HTMLWin32ObjectAccessible.h
@@ -32,17 +32,17 @@ public:
   virtual bool NativelyUnavailable() const;
 
 protected:
 
   // Accessible
   virtual void CacheChildren();
 
   void* mHwnd;
-  nsRefPtr<Accessible> mNativeAccessible;
+  RefPtr<Accessible> mNativeAccessible;
 };
 
 /**
   * This class is used only internally, we never! send out an IAccessible linked
   *   back to this object. This class is used to represent a plugin object when
   *   referenced as a child or sibling of another Accessible node. We need only
   *   a limited portion of the Accessible interface implemented here. The
   *   in depth accessible information will be returned by the actual IAccessible
--- a/accessible/windows/msaa/Platform.cpp
+++ b/accessible/windows/msaa/Platform.cpp
@@ -41,16 +41,17 @@ a11y::ProxyCreated(ProxyAccessible* aPro
   if (aInterfaces & Interfaces::DOCUMENT) {
     wrapper = new DocProxyAccessibleWrap(aProxy);
   } else if (aInterfaces & Interfaces::HYPERTEXT) {
     wrapper = new HyperTextProxyAccessibleWrap(aProxy);
   } else {
     wrapper = new ProxyAccessibleWrap(aProxy);
   }
 
+  wrapper->SetProxyInterfaces(aInterfaces);
   wrapper->AddRef();
   aProxy->SetWrapper(reinterpret_cast<uintptr_t>(wrapper));
 }
 
 void
 a11y::ProxyDestroyed(ProxyAccessible* aProxy)
 {
   AccessibleWrap* wrapper =
--- a/accessible/windows/msaa/ServiceProvider.h
+++ b/accessible/windows/msaa/ServiceProvider.h
@@ -24,15 +24,15 @@ public:
   DECL_IUNKNOWN
 
   // IServiceProvider
   virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID aGuidService,
                                                  REFIID aIID,
                                                  void** aInstancePtr);
 
 private:
-  nsRefPtr<AccessibleWrap> mAccessible;
+  RefPtr<AccessibleWrap> mAccessible;
 };
 
 }
 }
 
 #endif
--- a/accessible/windows/sdn/sdnDocAccessible.h
+++ b/accessible/windows/sdn/sdnDocAccessible.h
@@ -39,15 +39,15 @@ public:
   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_nameSpaceURIForID(
     /* [in] */ short nameSpaceID,
     /* [out] */ BSTR __RPC_FAR *nameSpaceURI);
 
   virtual /* [id] */ HRESULT STDMETHODCALLTYPE put_alternateViewMediaTypes(
     /* [in] */ BSTR __RPC_FAR *commaSeparatedMediaTypes);
 
 protected:
-  nsRefPtr<DocAccessibleWrap> mAccessible;
+  RefPtr<DocAccessibleWrap> mAccessible;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/windows/sdn/sdnTextAccessible.cpp
+++ b/accessible/windows/sdn/sdnTextAccessible.cpp
@@ -143,17 +143,17 @@ STDMETHODIMP
 sdnTextAccessible::scrollToSubstring(unsigned int aStartIndex,
                                      unsigned int aEndIndex)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (mAccessible->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
-  nsRefPtr<nsRange> range = new nsRange(mAccessible->GetContent());
+  RefPtr<nsRange> range = new nsRange(mAccessible->GetContent());
   if (NS_FAILED(range->SetStart(mAccessible->GetContent(), aStartIndex)))
     return E_FAIL;
 
   if (NS_FAILED(range->SetEnd(mAccessible->GetContent(), aEndIndex)))
     return E_FAIL;
 
   nsresult rv =
     nsCoreUtils::ScrollSubstringTo(mAccessible->GetFrame(), range,
@@ -174,17 +174,17 @@ sdnTextAccessible::get_fontFamily(BSTR _
 
   if (mAccessible->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsIFrame* frame = mAccessible->GetFrame();
   if (!frame)
     return E_FAIL;
 
-  nsRefPtr<nsFontMetrics> fm;
+  RefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(frame, getter_AddRefs(fm));
 
   const nsString& name =
     fm->GetThebesFontGroup()->GetFirstValidFont()->GetName();
   if (name.IsEmpty())
     return S_FALSE;
 
   *aFontFamily = ::SysAllocStringLen(name.get(), name.Length());
--- a/accessible/windows/sdn/sdnTextAccessible.h
+++ b/accessible/windows/sdn/sdnTextAccessible.h
@@ -57,15 +57,15 @@ public:
 private:
   /**
    *  Return child frame containing offset on success.
    */
   nsIFrame* GetPointFromOffset(nsIFrame* aContainingFrame,
                                int32_t aOffset, bool aPreferNext,
                                nsPoint& aOutPoint);
 
-  nsRefPtr<AccessibleWrap> mAccessible;
+  RefPtr<AccessibleWrap> mAccessible;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/windows/uia/uiaRawElmProvider.h
+++ b/accessible/windows/uia/uiaRawElmProvider.h
@@ -61,15 +61,15 @@ public:
     /* [retval][out] */ __RPC__deref_out_opt IRawElementProviderSimple** aRawElmProvider);
 
 private:
   uiaRawElmProvider() = delete;
   uiaRawElmProvider& operator =(const uiaRawElmProvider&) = delete;
   uiaRawElmProvider(const uiaRawElmProvider&) = delete;
 
 protected:
-  nsRefPtr<AccessibleWrap> mAcc;
+  RefPtr<AccessibleWrap> mAcc;
 };
 
 } // a11y namespace
 } // mozilla namespace
 
 #endif
--- a/accessible/xpcom/xpcAccessibleDocument.cpp
+++ b/accessible/xpcom/xpcAccessibleDocument.cpp
@@ -191,17 +191,17 @@ xpcAccessibleDocument::GetAccessible(Acc
   else
     xpcAcc = new xpcAccessibleGeneric(aAccessible);
 
   mCache.Put(aAccessible, xpcAcc);
   return xpcAcc;
 }
 
 static PLDHashOperator
-ShutdownAndRemove(const Accessible* aKey, nsRefPtr<xpcAccessibleGeneric>& aValue,
+ShutdownAndRemove(const Accessible* aKey, RefPtr<xpcAccessibleGeneric>& aValue,
                   void* aUnused)
 {
   aValue->Shutdown();
   return PL_DHASH_REMOVE;
 }
 
 void
 xpcAccessibleDocument::Shutdown()
--- a/accessible/xpcom/xpcAccessibleHyperLink.cpp
+++ b/accessible/xpcom/xpcAccessibleHyperLink.cpp
@@ -54,17 +54,17 @@ xpcAccessibleHyperLink::GetURI(int32_t a
   NS_ENSURE_ARG_POINTER(aURI);
 
   if (!Intl())
     return NS_ERROR_FAILURE;
 
   if (aIndex < 0 || aIndex >= static_cast<int32_t>(Intl()->AnchorCount()))
     return NS_ERROR_INVALID_ARG;
 
-  nsRefPtr<nsIURI>(Intl()->AnchorURIAt(aIndex)).forget(aURI);
+  RefPtr<nsIURI>(Intl()->AnchorURIAt(aIndex)).forget(aURI);
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 xpcAccessibleHyperLink::GetAnchor(int32_t aIndex, nsIAccessible** aAccessible)
 {
   NS_ENSURE_ARG_POINTER(aAccessible);
--- a/accessible/xpcom/xpcAccessibleHyperText.cpp
+++ b/accessible/xpcom/xpcAccessibleHyperText.cpp
@@ -342,17 +342,17 @@ NS_IMETHODIMP
 xpcAccessibleHyperText::GetEnclosingRange(nsIAccessibleTextRange** aRange)
 {
   NS_ENSURE_ARG_POINTER(aRange);
   *aRange = nullptr;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
 
-  nsRefPtr<xpcAccessibleTextRange> range = new xpcAccessibleTextRange;
+  RefPtr<xpcAccessibleTextRange> range = new xpcAccessibleTextRange;
   Intl()->EnclosingRange(range->mRange);
   NS_ASSERTION(range->mRange.IsValid(),
                "Should always have an enclosing range!");
 
   range.forget(aRange);
 
   return NS_OK;
 }
@@ -414,17 +414,17 @@ xpcAccessibleHyperText::GetRangeByChild(
   NS_ENSURE_ARG_POINTER(aRange);
   *aRange = nullptr;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
 
   Accessible* child = aChild->ToInternalAccessible();
   if (child) {
-    nsRefPtr<xpcAccessibleTextRange> range = new xpcAccessibleTextRange;
+    RefPtr<xpcAccessibleTextRange> range = new xpcAccessibleTextRange;
     Intl()->RangeByChild(child, range->mRange);
     if (range->mRange.IsValid())
       range.forget(aRange);
   }
 
   return NS_OK;
 }
 
@@ -433,17 +433,17 @@ xpcAccessibleHyperText::GetRangeAtPoint(
                                         nsIAccessibleTextRange** aRange)
 {
   NS_ENSURE_ARG_POINTER(aRange);
   *aRange = nullptr;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
 
-  nsRefPtr<xpcAccessibleTextRange> range = new xpcAccessibleTextRange;
+  RefPtr<xpcAccessibleTextRange> range = new xpcAccessibleTextRange;
   Intl()->RangeAtPoint(aX, aY, range->mRange);
   if (range->mRange.IsValid())
     range.forget(aRange);
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/xpcom/xpcAccessibleTextRange.cpp
+++ b/accessible/xpcom/xpcAccessibleTextRange.cpp
@@ -94,31 +94,31 @@ xpcAccessibleTextRange::GetEmbeddedChild
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleTextRange::Compare(nsIAccessibleTextRange* aOtherRange,
                                 bool* aResult)
 {
 
-  nsRefPtr<xpcAccessibleTextRange> xpcRange(do_QueryObject(aOtherRange));
+  RefPtr<xpcAccessibleTextRange> xpcRange(do_QueryObject(aOtherRange));
   if (!xpcRange || !aResult)
     return NS_ERROR_INVALID_ARG;
 
   *aResult = (mRange == xpcRange->mRange);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleTextRange::CompareEndPoints(uint32_t aEndPoint,
                                          nsIAccessibleTextRange* aOtherRange,
                                          uint32_t aOtherRangeEndPoint,
                                          int32_t* aResult)
 {
-  nsRefPtr<xpcAccessibleTextRange> xpcRange(do_QueryObject(aOtherRange));
+  RefPtr<xpcAccessibleTextRange> xpcRange(do_QueryObject(aOtherRange));
   if (!xpcRange || !aResult)
     return NS_ERROR_INVALID_ARG;
 
   TextPoint p = (aEndPoint == EndPoint_Start) ?
     mRange.StartPoint() : mRange.EndPoint();
   TextPoint otherPoint = (aOtherRangeEndPoint == EndPoint_Start) ?
     xpcRange->mRange.StartPoint() : xpcRange->mRange.EndPoint();
 
--- a/accessible/xul/XULElementAccessibles.h
+++ b/accessible/xul/XULElementAccessibles.h
@@ -31,17 +31,17 @@ public:
   void UpdateLabelValue(const nsString& aValue);
 
 protected:
   // Accessible
   virtual ENameValueFlag NativeName(nsString& aName) override;
   virtual void CacheChildren() override;
 
 private:
-  nsRefPtr<XULLabelTextLeafAccessible> mValueTextLeaf;
+  RefPtr<XULLabelTextLeafAccessible> mValueTextLeaf;
 };
 
 inline XULLabelAccessible*
 Accessible::AsXULLabel()
 {
   return IsXULLabel() ? static_cast<XULLabelAccessible*>(this) : nullptr;
 }
 
--- a/accessible/xul/XULTreeAccessible.cpp
+++ b/accessible/xul/XULTreeAccessible.cpp
@@ -162,17 +162,17 @@ XULTreeAccessible::NativeRole()
 
   nsIContent* child = nsTreeUtils::GetDescendantChild(mContent, nsGkAtoms::treechildren);
   NS_ASSERTION(child, "tree without treechildren!");
   nsTreeBodyFrame* treeFrame = do_QueryFrame(child->GetPrimaryFrame());
   NS_ASSERTION(treeFrame, "xul tree accessible for tree without a frame!");
   if (!treeFrame)
     return roles::LIST;
 
-  nsRefPtr<nsTreeColumns> cols = treeFrame->Columns();
+  RefPtr<nsTreeColumns> cols = treeFrame->Columns();
   nsCOMPtr<nsITreeColumn> primaryCol;
   cols->GetPrimaryColumn(getter_AddRefs(primaryCol));
 
   return primaryCol ? roles::OUTLINE : roles::LIST;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeAccessible: Accessible implementation (DON'T put methods here)
@@ -205,17 +205,17 @@ XULTreeAccessible::ChildAtPoint(int32_t 
   // If we failed to find tree cell for the given point then it might be
   // tree columns.
   if (row == -1 || !column)
     return AccessibleWrap::ChildAtPoint(aX, aY, aWhichChild);
 
   Accessible* child = GetTreeItemAccessible(row);
   if (aWhichChild == eDeepestChild && child) {
     // Look for accessible cell for the found item accessible.
-    nsRefPtr<XULTreeItemAccessibleBase> treeitem = do_QueryObject(child);
+    RefPtr<XULTreeItemAccessibleBase> treeitem = do_QueryObject(child);
 
     Accessible* cell = treeitem->GetCellAccessible(column);
     if (cell)
       child = cell;
   }
 
   return child;
 }
@@ -528,17 +528,17 @@ XULTreeAccessible::GetTreeItemAccessible
   if (NS_FAILED(rv) || aRow >= rowCount)
     return nullptr;
 
   void *key = reinterpret_cast<void*>(aRow);
   Accessible* cachedTreeItem = mAccessibleCache.GetWeak(key);
   if (cachedTreeItem)
     return cachedTreeItem;
 
-  nsRefPtr<Accessible> treeItem = CreateTreeItemAccessible(aRow);
+  RefPtr<Accessible> treeItem = CreateTreeItemAccessible(aRow);
   if (treeItem) {
     mAccessibleCache.Put(key, treeItem);
     Document()->BindToDocument(treeItem, nullptr);
     return treeItem;
   }
 
   return nullptr;
 }
@@ -563,17 +563,17 @@ XULTreeAccessible::InvalidateCache(int32
 
   // Fire destroy event for removed tree items and delete them from caches.
   for (int32_t rowIdx = aRow; rowIdx < aRow - aCount; rowIdx++) {
 
     void* key = reinterpret_cast<void*>(rowIdx);
     Accessible* treeItem = mAccessibleCache.GetWeak(key);
 
     if (treeItem) {
-      nsRefPtr<AccEvent> event =
+      RefPtr<AccEvent> event =
         new AccEvent(nsIAccessibleEvent::EVENT_HIDE, treeItem);
       nsEventShell::FireEvent(event);
 
       // Unbind from document, shutdown and remove from tree cache.
       document->UnbindFromDocument(treeItem);
       mAccessibleCache.Remove(key);
     }
   }
@@ -643,50 +643,50 @@ XULTreeAccessible::TreeViewInvalidated(i
   }
 
   for (int32_t rowIdx = aStartRow; rowIdx <= endRow; ++rowIdx) {
 
     void *key = reinterpret_cast<void*>(rowIdx);
     Accessible* accessible = mAccessibleCache.GetWeak(key);
 
     if (accessible) {
-      nsRefPtr<XULTreeItemAccessibleBase> treeitemAcc = do_QueryObject(accessible);
+      RefPtr<XULTreeItemAccessibleBase> treeitemAcc = do_QueryObject(accessible);
       NS_ASSERTION(treeitemAcc, "Wrong accessible at the given key!");
 
       treeitemAcc->RowInvalidated(aStartCol, endCol);
     }
   }
 }
 
 void
 XULTreeAccessible::TreeViewChanged(nsITreeView* aView)
 {
   if (IsDefunct())
     return;
 
   // Fire reorder event on tree accessible on accessible tree (do not fire
   // show/hide events on tree items because it can be expensive to fire them for
   // each tree item.
-  nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
+  RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
   Document()->FireDelayedEvent(reorderEvent);
 
   // Clear cache.
   mAccessibleCache.Enumerate(UnbindCacheEntryFromDocument<Accessible>,
                              nullptr);
 
   mTreeView = aView;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeAccessible: protected implementation
 
 already_AddRefed<Accessible>
 XULTreeAccessible::CreateTreeItemAccessible(int32_t aRow) const
 {
-  nsRefPtr<Accessible> accessible =
+  RefPtr<Accessible> accessible =
     new XULTreeItemAccessible(mContent, mDoc, const_cast<XULTreeAccessible*>(this),
                               mTree, mTreeView, aRow);
 
   return accessible.forget();
 }
                              
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeItemAccessibleBase
--- a/accessible/xul/XULTreeGridAccessible.cpp
+++ b/accessible/xul/XULTreeGridAccessible.cpp
@@ -123,17 +123,17 @@ XULTreeGridAccessible::CellAt(uint32_t a
   if (!row)
     return nullptr;
 
   nsCOMPtr<nsITreeColumn> column =
     nsCoreUtils::GetSensibleColumnAt(mTree, aColumnIndex);
   if (!column)
     return nullptr;
 
-  nsRefPtr<XULTreeItemAccessibleBase> rowAcc = do_QueryObject(row);
+  RefPtr<XULTreeItemAccessibleBase> rowAcc = do_QueryObject(row);
   if (!rowAcc)
     return nullptr;
 
   return rowAcc->GetCellAccessible(column);
 }
 
 void
 XULTreeGridAccessible::ColDescription(uint32_t aColIdx, nsString& aDescription)
@@ -223,17 +223,17 @@ XULTreeGridAccessible::NativeRole()
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridAccessible: XULTreeAccessible implementation
 
 already_AddRefed<Accessible>
 XULTreeGridAccessible::CreateTreeItemAccessible(int32_t aRow) const
 {
-  nsRefPtr<Accessible> accessible =
+  RefPtr<Accessible> accessible =
     new XULTreeGridRowAccessible(mContent, mDoc,
                                  const_cast<XULTreeGridAccessible*>(this),
                                  mTree, mTreeView, aRow);
 
   return accessible.forget();
 }
 
 
@@ -371,17 +371,17 @@ XULTreeGridRowAccessible::GetCellAccessi
 {
   NS_PRECONDITION(aColumn, "No tree column!");
 
   void* key = static_cast<void*>(aColumn);
   XULTreeGridCellAccessible* cachedCell = mAccessibleCache.GetWeak(key);
   if (cachedCell)
     return cachedCell;
 
-  nsRefPtr<XULTreeGridCellAccessible> cell =
+  RefPtr<XULTreeGridCellAccessible> cell =
     new XULTreeGridCellAccessibleWrap(mContent, mDoc,
                                       const_cast<XULTreeGridRowAccessible*>(this),
                                       mTree, mTreeView, mRow, aColumn);
   mAccessibleCache.Put(key, cell);
   Document()->BindToDocument(cell, nullptr);
   return cell;
 }
 
@@ -732,17 +732,17 @@ XULTreeGridCellAccessible::CellInvalidat
   nsAutoString textEquiv;
 
   int16_t type;
   mColumn->GetType(&type);
   if (type == nsITreeColumn::TYPE_CHECKBOX) {
     mTreeView->GetCellValue(mRow, mColumn, textEquiv);
     if (mCachedTextEquiv != textEquiv) {
       bool isEnabled = textEquiv.EqualsLiteral("true");
-      nsRefPtr<AccEvent> accEvent =
+      RefPtr<AccEvent> accEvent =
         new AccStateChangeEvent(this, states::CHECKED, isEnabled);
       nsEventShell::FireEvent(accEvent);
 
       mCachedTextEquiv = textEquiv;
       return true;
     }
 
     return false;
@@ -779,17 +779,17 @@ XULTreeGridCellAccessible::GetSiblingAtO
       column = nsCoreUtils::GetNextSensibleColumn(columnAtOffset);
       column.swap(columnAtOffset);
     }
   }
 
   if (!columnAtOffset)
     return nullptr;
 
-  nsRefPtr<XULTreeItemAccessibleBase> rowAcc = do_QueryObject(Parent());
+  RefPtr<XULTreeItemAccessibleBase> rowAcc = do_QueryObject(Parent());
   return rowAcc->GetCellAccessible(columnAtOffset);
 }
 
 void
 XULTreeGridCellAccessible::DispatchClickEvent(nsIContent* aContent,
                                               uint32_t aActionIndex)
 {
   if (IsDefunct())
--- a/addon-sdk/source/lib/sdk/addon/events.js
+++ b/addon-sdk/source/lib/sdk/addon/events.js
@@ -46,9 +46,11 @@ function send (eventName, data) {
   return deferred.promise;
 }
 exports.send = send;
 
 /*
  * Implement internal structured cloning algorithm in the future?
  * http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#internal-structured-cloning-algorithm
  */
-function clone (obj) JSON.parse(JSON.stringify(obj || {}))
+function clone (obj) {
+  return JSON.parse(JSON.stringify(obj || {}));
+}
--- a/addon-sdk/source/lib/sdk/addon/runner.js
+++ b/addon-sdk/source/lib/sdk/addon/runner.js
@@ -57,41 +57,43 @@ function setDefaultPrefs(prefsURI) {
   evaluate(sandbox, prefsURI);
 }
 
 function definePseudo(loader, id, exports) {
   let uri = resolveURI(id, loader.mapping);
   loader.modules[uri] = { exports: exports };
 }
 
-function startup(reason, options) Startup.onceInitialized.then(() => {
-  // Inject globals ASAP in order to have console API working ASAP
-  Object.defineProperties(options.loader.globals, descriptor(globals));
+function startup(reason, options) {
+  return Startup.onceInitialized.then(() => {
+    // Inject globals ASAP in order to have console API working ASAP
+    Object.defineProperties(options.loader.globals, descriptor(globals));
 
-  // NOTE: Module is intentionally required only now because it relies
-  // on existence of hidden window, which does not exists until startup.
-  let { ready } = require('../addon/window');
-  // Load localization manifest and .properties files.
-  // Run the addon even in case of error (best effort approach)
-  require('../l10n/loader').
-    load(rootURI).
-    then(null, function failure(error) {
-      if (!isNative)
-        console.info("Error while loading localization: " + error.message);
-    }).
-    then(function onLocalizationReady(data) {
-      // Exports data to a pseudo module so that api-utils/l10n/core
-      // can get access to it
-      definePseudo(options.loader, '@l10n/data', data ? data : null);
-      return ready;
-    }).then(function() {
-      run(options);
-    }).then(null, console.exception);
+    // NOTE: Module is intentionally required only now because it relies
+    // on existence of hidden window, which does not exists until startup.
+    let { ready } = require('../addon/window');
+    // Load localization manifest and .properties files.
+    // Run the addon even in case of error (best effort approach)
+    require('../l10n/loader').
+      load(rootURI).
+      then(null, function failure(error) {
+        if (!isNative)
+          console.info("Error while loading localization: " + error.message);
+      }).
+      then(function onLocalizationReady(data) {
+        // Exports data to a pseudo module so that api-utils/l10n/core
+        // can get access to it
+        definePseudo(options.loader, '@l10n/data', data ? data : null);
+        return ready;
+      }).then(function() {
+        run(options);
+      }).then(null, console.exception);
     return void 0; // otherwise we raise a warning, see bug 910304
-});
+  });
+}
 
 function run(options) {
   try {
     // Try initializing HTML localization before running main module. Just print
     // an exception in case of error, instead of preventing addon to be run.
     try {
       // Do not enable HTML localization while running test as it is hard to
       // disable. Because unit tests are evaluated in a another Loader who
--- a/addon-sdk/source/lib/sdk/browser/events.js
+++ b/addon-sdk/source/lib/sdk/browser/events.js
@@ -12,9 +12,9 @@ const { filter } = require("../event/uti
 const { isBrowser } = require("../window/utils");
 
 // TODO: `isBrowser` detects weather window is a browser by checking
 // `windowtype` attribute, which means that all 'open' events will be
 // filtered out since document is not loaded yet. Maybe we can find a better
 // implementation for `isBrowser`. Either way it's not really needed yet
 // neither window tracker provides this event.
 
-exports.events = filter(events, function({target}) isBrowser(target));
+exports.events = filter(events, ({target}) => isBrowser(target));
--- a/addon-sdk/source/lib/sdk/content/context-menu.js
+++ b/addon-sdk/source/lib/sdk/content/context-menu.js
@@ -133,17 +133,17 @@ CONTEXTS.PageContext = Class({
   getState: function(popupNode) {
     // If there is a selection in the window then this context does not match
     if (!popupNode.ownerDocument.defaultView.getSelection().isCollapsed)
       return false;
 
     // If the clicked node or any of its ancestors is one of the blocked
     // NON_PAGE_CONTEXT_ELTS then this context does not match
     while (!(popupNode instanceof Ci.nsIDOMDocument)) {
-      if (NON_PAGE_CONTEXT_ELTS.some(function(type) popupNode instanceof type))
+      if (NON_PAGE_CONTEXT_ELTS.some(type => popupNode instanceof type))
         return false;
 
       popupNode = popupNode.parentNode;
     }
 
     return true;
   }
 });
--- a/addon-sdk/source/lib/sdk/content/events.js
+++ b/addon-sdk/source/lib/sdk/content/events.js
@@ -44,14 +44,14 @@ function streamEventsFrom({document}) {
   })
 }
 exports.streamEventsFrom = streamEventsFrom;
 
 var opened = windows(null, { includePrivate: true });
 var state = merge(opened.map(streamEventsFrom));
 
 
-var futureReady = filter(windowEvents, function({type})
+var futureReady = filter(windowEvents, ({type}) =>
                                         type === "DOMContentLoaded");
-var futureWindows = map(futureReady, function({target}) target);
+var futureWindows = map(futureReady, ({target}) => target);
 var futureState = expand(futureWindows, streamEventsFrom);
 
 exports.events = merge([insert, create, state, futureState]);
--- a/addon-sdk/source/lib/sdk/content/loader.js
+++ b/addon-sdk/source/lib/sdk/content/loader.js
@@ -58,19 +58,27 @@ exports.validationAttributes = valid;
 
 /**
  * Shortcut function to validate property with validation.
  * @param {Object|Number|String} suspect
  *    value to validate
  * @param {Object} validation
  *    validation rule passed to `api-utils`
  */
-function validate(suspect, validation) validateOptions(
-  { $: suspect },
-  { $: validation }
-).$
+function validate(suspect, validation) {
+  return validateOptions(
+    { $: suspect },
+    { $: validation }
+  ).$;
+}
 
-function Allow(script) ({
-  get script() script,
-  set script(value) script = !!value
-})
+function Allow(script) {
+  return {
+    get script() {
+      return script;
+    },
+    set script(value) {
+      script = !!value;
+    }
+  };
+}
 
 exports.contract = contract(valid);
--- a/addon-sdk/source/lib/sdk/content/sandbox.js
+++ b/addon-sdk/source/lib/sdk/content/sandbox.js
@@ -157,19 +157,25 @@ const WorkerSandbox = Class({
 
     // We have to ensure that window.top and window.parent are the exact same
     // object than window object, i.e. the sandbox global object. But not
     // always, in case of iframes, top and parent are another window object.
     let top = window.top === window ? content : content.top;
     let parent = window.parent === window ? content : content.parent;
     merge(content, {
       // We need 'this === window === top' to be true in toplevel scope:
-      get window() content,
-      get top() top,
-      get parent() parent
+      get window() {
+        return content;
+      },
+      get top() {
+        return top;
+      },
+      get parent() {
+        return parent;
+      }
     });
 
     // Use the Greasemonkey naming convention to provide access to the
     // unwrapped window object so the content script can access document
     // JavaScript values.
     // NOTE: this functionality is experimental and may change or go away
     // at any time!
     //
--- a/addon-sdk/source/lib/sdk/context-menu.js
+++ b/addon-sdk/source/lib/sdk/context-menu.js
@@ -155,26 +155,26 @@ exports.SelectorContext = SelectorContex
 var URLContext = Class({
   extends: Context,
 
   initialize: function initialize(patterns) {
     Context.prototype.initialize.call(this);
     patterns = Array.isArray(patterns) ? patterns : [patterns];
 
     try {
-      internal(this).patterns = patterns.map(function (p) new MatchPattern(p));
+      internal(this).patterns = patterns.map(p => new MatchPattern(p));
     }
     catch (err) {
       throw new Error("Patterns must be a string, regexp or an array of " +
                       "strings or regexps: " + err);
     }
   },
 
   isCurrent: function isCurrent(url) {
-    return internal(this).patterns.some(function (p) p.test(url));
+    return internal(this).patterns.some(p => p.test(url));
   },
 
   serialize: function() {
     return {
       id: internal(this).id,
       type: "URLContext",
       args: []
     }
@@ -207,21 +207,23 @@ var PredicateContext = Class({
       type: "PredicateContext",
       args: []
     }
   }
 });
 exports.PredicateContext = PredicateContext;
 
 function removeItemFromArray(array, item) {
-  return array.filter(function(i) i !== item);
+  return array.filter(i => i !== item);
 }
 
 // Converts anything that isn't false, null or undefined into a string
-function stringOrNull(val) val ? String(val) : val;
+function stringOrNull(val) {
+  return val ? String(val) : val;
+}
 
 // Shared option validation rules for Item, Menu, and Separator
 var baseItemRules = {
   parentMenu: {
     is: ["object", "undefined"],
     ok: function (v) {
       if (!v)
         return true;
@@ -230,33 +232,33 @@ var baseItemRules = {
     msg: "parentMenu must be a Menu or not specified."
   },
   context: {
     is: ["undefined", "object", "array"],
     ok: function (v) {
       if (!v)
         return true;
       let arr = Array.isArray(v) ? v : [v];
-      return arr.every(function (o) o instanceof Context);
+      return arr.every(o => o instanceof Context);
     },
     msg: "The 'context' option must be a Context object or an array of " +
          "Context objects."
   },
   onMessage: {
     is: ["function", "undefined"]
   },
   contentScript: loaderContract.rules.contentScript,
   contentScriptFile: loaderContract.rules.contentScriptFile
 };
 
 var labelledItemRules =  mix(baseItemRules, {
   label: {
     map: stringOrNull,
     is: ["string"],
-    ok: function (v) !!v,
+    ok: v => !!v,
     msg: "The item must have a non-empty string label."
   },
   accesskey: {
     map: stringOrNull,
     is: ["string", "undefined", "null"],
     ok: (v) => {
       if (!v) {
         return true;
--- a/addon-sdk/source/lib/sdk/core/promise.js
+++ b/addon-sdk/source/lib/sdk/core/promise.js
@@ -27,24 +27,26 @@ var promised = (function() {
   // slower property accesses and unnecessary closure creations on each
   // call of this popular function.
 
   var call = Function.call;
   var concat = Array.prototype.concat;
 
   // Utility function that does following:
   // execute([ f, self, args...]) => f.apply(self, args)
-  function execute (args) call.apply(call, args)
+  function execute (args) {
+    return call.apply(call, args);
+  }
 
   // Utility function that takes promise of `a` array and maybe promise `b`
   // as arguments and returns promise for `a.concat(b)`.
   function promisedConcat(promises, unknown) {
     return promises.then(function (values) {
       return resolve(unknown)
-        .then(function (value) values.concat([value]));
+        .then(value => values.concat([value]));
     });
   }
 
   return function promised(f, prototype) {
     /**
     Returns a wrapped `f`, which when called returns a promise that resolves to
     `f(...)` passing all the given arguments to it, which by the way may be
     promises. Optionally second `prototype` argument may be provided to be used
--- a/addon-sdk/source/lib/sdk/deprecated/unit-test.js
+++ b/addon-sdk/source/lib/sdk/deprecated/unit-test.js
@@ -49,17 +49,19 @@ const TestRunner = function TestRunner(o
   this.passed = 0;
   this.failed = 0;
   this.testRunSummary = [];
   this.expectFailNesting = 0;
   this.done = TestRunner.prototype.done.bind(this);
 };
 
 TestRunner.prototype = {
-  toString: function toString() "[object TestRunner]",
+  toString: function toString() {
+    return "[object TestRunner]";
+  },
 
   DEFAULT_PAUSE_TIMEOUT: (cfxArgs.parseable ? 300000 : 15000), //Five minutes (5*60*1000ms)
   PAUSE_DELAY: 500,
 
   _logTestFailed: function _logTestFailed(why) {
     if (!(why in this.test.errors))
       this.test.errors[why] = 0;
     this.test.errors[why]++;
--- a/addon-sdk/source/lib/sdk/deprecated/window-utils.js
+++ b/addon-sdk/source/lib/sdk/deprecated/window-utils.js
@@ -16,17 +16,19 @@ const { ignoreWindow } = require('sdk/pr
 const { isPrivateBrowsingSupported } = require('../self');
 
 const windowWatcher = Cc['@mozilla.org/embedcomp/window-watcher;1'].
                        getService(Ci.nsIWindowWatcher);
 const appShellService = Cc['@mozilla.org/appshell/appShellService;1'].
                         getService(Ci.nsIAppShellService);
 
 // Bug 834961: ignore private windows when they are not supported
-function getWindows() windows(null, { includePrivate: isPrivateBrowsingSupported });
+function getWindows() {
+  return windows(null, { includePrivate: isPrivateBrowsingSupported });
+}
 
 /**
  * An iterator for XUL windows currently in the application.
  *
  * @return A generator that yields XUL windows exposing the
  *         nsIDOMWindow interface.
  */
 function windowIterator() {
--- a/addon-sdk/source/lib/sdk/frame/hidden-frame.js
+++ b/addon-sdk/source/lib/sdk/frame/hidden-frame.js
@@ -43,17 +43,17 @@ function FrameOptions(options) {
   return validateOptions(options, FrameOptions.validator);
 }
 FrameOptions.validator = {
   onReady: {
     is: ["undefined", "function", "array"],
     ok: function(v) {
       if (getTypeOf(v) === "array") {
         // make sure every item is a function
-        return v.every(function (item) typeof(item) === "function")
+        return v.every(item => typeof(item) === "function")
       }
       return true;
     }
   },
   onUnload: {
     is: ["undefined", "function"]
   }
 };
@@ -107,9 +107,9 @@ function removeHiddenFrame(frame) {
   // Remove from cache before calling in order to avoid loop
   cache.delete(frame);
   emit(frame, "unload")
   let element = frame.element
   if (element) element.parentNode.removeChild(element)
 }
 exports.remove = removeHiddenFrame;
 
-unload(function() fromIterator(cache).forEach(removeHiddenFrame));
+unload(() => fromIterator(cache).forEach(removeHiddenFrame));
--- a/addon-sdk/source/lib/sdk/frame/utils.js
+++ b/addon-sdk/source/lib/sdk/frame/utils.js
@@ -90,11 +90,12 @@ function create(target, options) {
     if ("allowWindowControl" in docShell && "allowWindowControl" in options)
       docShell.allowWindowControl = !!options.allowWindowControl;
   }
 
   return frame;
 }
 exports.create = create;
 
-function swapFrameLoaders(from, to)
-  from.QueryInterface(Ci.nsIFrameLoaderOwner).swapFrameLoaders(to)
+function swapFrameLoaders(from, to) {
+  return from.QueryInterface(Ci.nsIFrameLoaderOwner).swapFrameLoaders(to);
+}
 exports.swapFrameLoaders = swapFrameLoaders;
--- a/addon-sdk/source/lib/sdk/io/buffer.js
+++ b/addon-sdk/source/lib/sdk/io/buffer.js
@@ -318,17 +318,19 @@ Object.defineProperties(Buffer.prototype
  ['readInt32BE', 'getInt32', false],
  ['readFloatLE', 'getFloat32', true],
  ['readFloatBE', 'getFloat32', false],
  ['readDoubleLE', 'getFloat64', true],
  ['readDoubleBE', 'getFloat64', false],
  ['readUInt8', 'getUint8'],
  ['readInt8', 'getInt8']].forEach(([alias, name, littleEndian]) => {
   Object.defineProperty(Buffer.prototype, alias, {
-    value: function(offset) this.view[name](offset, littleEndian)
+    value: function(offset) {
+      return this.view[name](offset, littleEndian);
+    }
   });
 });
 
 [['writeUInt16LE', 'setUint16', true],
  ['writeUInt16BE', 'setUint16', false],
  ['writeInt16LE', 'setInt16', true],
  ['writeInt16BE', 'setInt16', false],
  ['writeUInt32LE', 'setUint32', true],
@@ -337,11 +339,13 @@ Object.defineProperties(Buffer.prototype
  ['writeInt32BE', 'setInt32', false],
  ['writeFloatLE', 'setFloat32', true],
  ['writeFloatBE', 'setFloat32', false],
  ['writeDoubleLE', 'setFloat64', true],
  ['writeDoubleBE', 'setFloat64', false],
  ['writeUInt8', 'setUint8'],
  ['writeInt8', 'setInt8']].forEach(([alias, name, littleEndian]) => {
   Object.defineProperty(Buffer.prototype, alias, {
-    value: function(value, offset) this.view[name](offset, value, littleEndian)
+    value: function(value, offset) {
+      return this.view[name](offset, value, littleEndian);
+    }
   });
 });
--- a/addon-sdk/source/lib/sdk/io/fs.js
+++ b/addon-sdk/source/lib/sdk/io/fs.js
@@ -77,30 +77,40 @@ var nsIFileInputStream = accessor();
 var nsIFileOutputStream = accessor();
 var nsIBinaryInputStream = accessor();
 var nsIBinaryOutputStream = accessor();
 
 // Just a contstant object used to signal that all of the file
 // needs to be read.
 const ALL = new String("Read all of the file");
 
-function isWritable(mode) !!(mode & PR_WRONLY || mode & PR_RDWR)
-function isReadable(mode) !!(mode & PR_RDONLY || mode & PR_RDWR)
+function isWritable(mode) {
+  return !!(mode & PR_WRONLY || mode & PR_RDWR);
+}
+function isReadable(mode) {
+  return !!(mode & PR_RDONLY || mode & PR_RDWR);
+}
 
-function isString(value) typeof(value) === "string"
-function isFunction(value) typeof(value) === "function"
+function isString(value) {
+  return typeof(value) === "string";
+}
+function isFunction(value) {
+  return typeof(value) === "function";
+}
 
 function toArray(enumerator) {
   let value = [];
   while(enumerator.hasMoreElements())
     value.push(enumerator.getNext())
   return value
 }
 
-function getFileName(file) file.QueryInterface(Ci.nsIFile).leafName
+function getFileName(file) {
+  return file.QueryInterface(Ci.nsIFile).leafName;
+}
 
 
 function remove(path, recursive) {
   let fd = new nsILocalFile(path)
   if (fd.exists()) {
     fd.remove(recursive || false);
   }
   else {
@@ -244,43 +254,77 @@ exports.createWriteStream = function cre
 };
 
 const Stats = Class({
   initialize: function initialize(path) {
     let file = new nsILocalFile(path);
     if (!file.exists()) throw FSError("stat", "ENOENT", 34, path);
     nsIFile(this, file);
   },
-  isDirectory: function() nsIFile(this).isDirectory(),
-  isFile: function() nsIFile(this).isFile(),
-  isSymbolicLink: function() nsIFile(this).isSymlink(),
-  get mode() nsIFile(this).permissions,
-  get size() nsIFile(this).fileSize,
-  get mtime() nsIFile(this).lastModifiedTime,
-  isBlockDevice: function() nsIFile(this).isSpecial(),
-  isCharacterDevice: function() nsIFile(this).isSpecial(),
-  isFIFO: function() nsIFile(this).isSpecial(),
-  isSocket: function() nsIFile(this).isSpecial(),
+  isDirectory: function() {
+    return nsIFile(this).isDirectory();
+  },
+  isFile: function() {
+    return nsIFile(this).isFile();
+  },
+  isSymbolicLink: function() {
+    return nsIFile(this).isSymlink();
+  },
+  get mode() {
+    return nsIFile(this).permissions;
+  },
+  get size() {
+    return nsIFile(this).fileSize;
+  },
+  get mtime() {
+    return nsIFile(this).lastModifiedTime;
+  },
+  isBlockDevice: function() {
+    return nsIFile(this).isSpecial();
+  },
+  isCharacterDevice: function() {
+    return nsIFile(this).isSpecial();
+  },
+  isFIFO: function() {
+    return nsIFile(this).isSpecial();
+  },
+  isSocket: function() {
+    return nsIFile(this).isSpecial();
+  },
   // non standard
-  get exists() nsIFile(this).exists(),
-  get hidden() nsIFile(this).isHidden(),
-  get writable() nsIFile(this).isWritable(),
-  get readable() nsIFile(this).isReadable()
+  get exists() {
+    return nsIFile(this).exists();
+  },
+  get hidden() {
+    return nsIFile(this).isHidden();
+  },
+  get writable() {
+    return nsIFile(this).isWritable();
+  },
+  get readable() {
+    return nsIFile(this).isReadable();
+  }
 });
 exports.Stats = Stats;
 
 const LStats = Class({
   extends: Stats,
-  get size() this.isSymbolicLink() ? nsIFile(this).fileSizeOfLink :
-                                     nsIFile(this).fileSize,
-  get mtime() this.isSymbolicLink() ? nsIFile(this).lastModifiedTimeOfLink :
-                                      nsIFile(this).lastModifiedTime,
+  get size() {
+    return this.isSymbolicLink() ? nsIFile(this).fileSizeOfLink :
+                                   nsIFile(this).fileSize;
+  },
+  get mtime() {
+    return this.isSymbolicLink() ? nsIFile(this).lastModifiedTimeOfLink :
+                                   nsIFile(this).lastModifiedTime;
+  },
   // non standard
-  get permissions() this.isSymbolicLink() ? nsIFile(this).permissionsOfLink :
-                                            nsIFile(this).permissions
+  get permissions() {
+    return this.isSymbolicLink() ? nsIFile(this).permissionsOfLink :
+                                   nsIFile(this).permissions;
+  }
 });
 
 const FStat = Class({
   extends: Stats,
   initialize: function initialize(fd) {
     nsIFile(this, nsIFile(fd));
   }
 });
--- a/addon-sdk/source/lib/sdk/io/stream.js
+++ b/addon-sdk/source/lib/sdk/io/stream.js
@@ -176,17 +176,19 @@ const InputStream = Class({
     nsIInputStreamPump(this, inputStreamPump);
     nsIBinaryInputStream(this, binaryInputStream);
     nsIStreamListener(this, streamListener);
 
     this.asyncInputStream = asyncInputStream;
     this.inputStreamPump = inputStreamPump;
     this.binaryInputStream = binaryInputStream;
   },
-  get status() nsIInputStreamPump(this).status,
+  get status() {
+    return nsIInputStreamPump(this).status;
+  },
   read: function() {
     nsIInputStreamPump(this).asyncRead(nsIStreamListener(this), null);
   },
   pause: function pause() {
     this.paused = true;
     nsIInputStreamPump(this).suspend();
     emit(this, "paused");
   },
--- a/addon-sdk/source/lib/sdk/l10n/plural-rules.js
+++ b/addon-sdk/source/lib/sdk/l10n/plural-rules.js
@@ -180,18 +180,22 @@ const LOCALES_TO_RULES = {
   "xh": 3, 
   "xog": 3, 
   "yo": 0, 
   "zh": 0, 
   "zu": 3
 };
 
 // Utility functions for plural rules methods
-function isIn(n, list) list.indexOf(n) !== -1;
-function isBetween(n, start, end) start <= n && n <= end;
+function isIn(n, list) {
+  return list.indexOf(n) !== -1;
+}
+function isBetween(n, start, end) {
+  return start <= n && n <= end;
+}
 
 // List of all plural rules methods, that maps an integer to the plural form name to use
 const RULES = {
   "0": function (n) {
     
     return "other"
   },
   "1": function (n) {
--- a/addon-sdk/source/lib/sdk/l10n/properties/core.js
+++ b/addon-sdk/source/lib/sdk/l10n/properties/core.js
@@ -75,9 +75,9 @@ function get(key, n, locales) {
   }
 
   // try next locale
   if (locales.length)
     return get(key, n, locales);
 
   return undefined;
 }
-exports.get = function(k, n) get(k, n, Array.slice(preferedLocales));
+exports.get = (k, n) => get(k, n, Array.slice(preferedLocales));
--- a/addon-sdk/source/lib/sdk/notifications.js
+++ b/addon-sdk/source/lib/sdk/notifications.js
@@ -65,17 +65,17 @@ exports.notify = function notifications_
       notifyWithOpts(notifyUsingConsole);
     }
   }
 };
 
 function notifyUsingConsole(iconURL, title, text) {
   title = title ? "[" + title + "]" : "";
   text = text || "";
-  let str = [title, text].filter(function (s) s).join(" ");
+  let str = [title, text].filter(s => s).join(" ");
   console.log(str);
 }
 
 function validateOptions(options) {
   return apiUtils.validateOptions(options, {
     data: {
       is: ["string", "undefined"]
     },
--- a/addon-sdk/source/lib/sdk/page-worker.js
+++ b/addon-sdk/source/lib/sdk/page-worker.js
@@ -34,20 +34,28 @@ const workers = new WeakMap();
 const pages = new WeakMap();
 
 const readyEventNames = [
   'DOMContentLoaded',
   'document-element-inserted',
   'load'
 ];
 
-function workerFor(page) workers.get(page)
-function pageFor(view) pages.get(view)
-function viewFor(page) views.get(page)
-function isDisposed (page) !views.get(page, false)
+function workerFor(page) {
+  return workers.get(page);
+}
+function pageFor(view) {
+  return pages.get(view);
+}
+function viewFor(page) {
+  return views.get(page);
+}
+function isDisposed (page) {
+  return !views.get(page, false);
+}
 
 var pageContract = contract(merge({
   allow: {
     is: ['object', 'undefined', 'null'],
     map: function (allow) { return { script: !allow || allow.script !== false }}
   },
   onMessage: {
     is: ['function', 'undefined']
@@ -77,17 +85,19 @@ function Allow (page) {
 
 function injectWorker ({page}) {
   let worker = workerFor(page);
   let view = viewFor(page);
   if (isValidURL(page, view.contentDocument.URL))
     attach(worker, view.contentWindow);
 }
 
-function isValidURL(page, url) !page.rules || page.rules.matchesAny(url)
+function isValidURL(page, url) {
+  return !page.rules || page.rules.matchesAny(url);
+}
 
 const Page = Class({
   implements: [
     EventTarget,
     Disposable,
     WeakReference
   ],
   extends: WorkerHost(workerFor),
--- a/addon-sdk/source/lib/sdk/panel.js
+++ b/addon-sdk/source/lib/sdk/panel.js
@@ -90,17 +90,19 @@ function Allow(panel) {
 
 function setScriptState(panel, value) {
   let view = viewFor(panel);
   getDocShell(view.backgroundFrame).allowJavascript = value;
   getDocShell(view.viewFrame).allowJavascript = value;
   view.setAttribute("sdkscriptenabled", "" + value);
 }
 
-function isDisposed(panel) !views.has(panel);
+function isDisposed(panel) {
+  return !views.has(panel);
+}
 
 var panels = new WeakMap();
 var models = new WeakMap();
 var views = new WeakMap();
 var workers = new WeakMap();
 var styles = new WeakMap();
 
 const viewFor = (panel) => views.get(panel);
@@ -196,54 +198,72 @@ const Panel = Class({
     domPanel.dispose(viewFor(this));
 
     // Release circular reference between view and panel instance. This
     // way view will be GC-ed. And panel as well once all the other refs
     // will be removed from it.
     views.delete(this);
   },
   /* Public API: Panel.width */
-  get width() modelFor(this).width,
-  set width(value) this.resize(value, this.height),
+  get width() {
+    return modelFor(this).width;
+  },
+  set width(value) {
+    this.resize(value, this.height);
+  },
   /* Public API: Panel.height */
-  get height() modelFor(this).height,
-  set height(value) this.resize(this.width, value),
+  get height() {
+    return modelFor(this).height;
+  },
+  set height(value) {
+    this.resize(this.width, value);
+  },
 
   /* Public API: Panel.focus */
-  get focus() modelFor(this).focus,
+  get focus() {
+    return modelFor(this).focus;
+  },
 
   /* Public API: Panel.position */
-  get position() modelFor(this).position,
+  get position() {
+    return modelFor(this).position;
+  },
 
   /* Public API: Panel.contextMenu */
-  get contextMenu() modelFor(this).contextMenu,
+  get contextMenu() {
+    return modelFor(this).contextMenu;
+  },
   set contextMenu(allow) {
     let model = modelFor(this);
     model.contextMenu = panelContract({ contextMenu: allow }).contextMenu;
     domPanel.allowContextMenu(viewFor(this), model.contextMenu);
   },
 
-  get contentURL() modelFor(this).contentURL,
+  get contentURL() {
+    return modelFor(this).contentURL;
+  },
   set contentURL(value) {
     let model = modelFor(this);
     model.contentURL = panelContract({ contentURL: value }).contentURL;
     domPanel.setURL(viewFor(this), model.contentURL);
     // Detach worker so that messages send will be queued until it's
     // reatached once panel content is ready.
     workerFor(this).detach();
   },
 
   get allow() { return Allow(this); },
   set allow(value) {
     let allowJavascript = panelContract({ allow: value }).allow.script;
     return setScriptState(this, value);
   },
 
   /* Public API: Panel.isShowing */
-  get isShowing() !isDisposed(this) && domPanel.isOpen(viewFor(this)),
+  get isShowing() {
+    return !isDisposed(this) && domPanel.isOpen(viewFor(this));
+  },
 
   /* Public API: Panel.show */
   show: function show(options={}, anchor) {
     if (options instanceof Ci.nsIDOMElement) {
       [anchor, options] = [options, null];
     }
 
     if (anchor instanceof Ci.nsIDOMElement) {
--- a/addon-sdk/source/lib/sdk/panel/events.js
+++ b/addon-sdk/source/lib/sdk/panel/events.js
@@ -11,16 +11,17 @@ module.metadata = {
   "stability": "experimental"
 };
 
 const events = require("../system/events");
 const { emit } = require("../event/core");
 
 var channel = {};
 
-function forward({ subject, type, data })
-  emit(channel, "data", { target: subject, type: type, data: data });
+function forward({ subject, type, data }) {
+  return emit(channel, "data", { target: subject, type: type, data: data });
+}
 
 ["popupshowing", "popuphiding", "popupshown", "popuphidden",
 "document-element-inserted", "DOMContentLoaded", "load"
-].forEach(function(type) events.on(type, forward));
+].forEach(type => events.on(type, forward));
 
 exports.events = channel;
--- a/addon-sdk/source/lib/sdk/panel/utils.js
+++ b/addon-sdk/source/lib/sdk/panel/utils.js
@@ -424,17 +424,19 @@ function style(panel) {
 exports.style = style;
 
 var getContentFrame = panel =>
     (isOpen(panel) || isOpening(panel)) ?
     panel.firstChild :
     panel.backgroundFrame
 exports.getContentFrame = getContentFrame;
 
-function getContentDocument(panel) getContentFrame(panel).contentDocument
+function getContentDocument(panel) {
+  return getContentFrame(panel).contentDocument;
+}
 exports.getContentDocument = getContentDocument;
 
 function setURL(panel, url) {
   getContentFrame(panel).setAttribute("src", url ? data.url(url) : url);
 }
 
 exports.setURL = setURL;
 
--- a/addon-sdk/source/lib/sdk/passwords/utils.js
+++ b/addon-sdk/source/lib/sdk/passwords/utils.js
@@ -11,18 +11,19 @@ module.metadata = {
 const { Cc, Ci, CC } = require("chrome");
 const { uri: ADDON_URI } = require("../self");
 const loginManager = Cc["@mozilla.org/login-manager;1"].
                      getService(Ci.nsILoginManager);
 const { URL: parseURL } = require("../url");
 const LoginInfo = CC("@mozilla.org/login-manager/loginInfo;1",
                      "nsILoginInfo", "init");
 
-function filterMatchingLogins(loginInfo)
-  Object.keys(this).every(function(key) loginInfo[key] === this[key], this);
+function filterMatchingLogins(loginInfo) {
+  return Object.keys(this).every(key => loginInfo[key] === this[key], this);
+}
 
 /**
  * Removes `user`, `password` and `path` fields from the given `url` if it's
  * 'http', 'https' or 'ftp'. All other URLs are returned unchanged.
  * @example
  * http://user:pass@www.site.com/foo/?bar=baz#bang -> http://www.site.com
  */
 function normalizeURL(url) {
@@ -65,17 +66,19 @@ Login.prototype.toJSON = function toJSON
 Login.prototype.toLoginInfo = function toLoginInfo() {
   let { url, realm, formSubmitURL, username, password, usernameField,
         passwordField } = this.toJSON();
 
   return new LoginInfo(url, formSubmitURL, realm, username, password,
                        usernameField, passwordField);
 };
 
-function loginToJSON(value) Login(value).toJSON()
+function loginToJSON(value) {
+  return Login(value).toJSON();
+}
 
 /**
  * Returns array of `nsILoginInfo` objects that are stored in the login manager
  * and have all the properties with matching values as a given `options` object.
  * @param {Object} options
  * @returns {nsILoginInfo[]}
  */
 exports.search = function search(options) {
--- a/addon-sdk/source/lib/sdk/places/bookmarks.js
+++ b/addon-sdk/source/lib/sdk/places/bookmarks.js
@@ -57,45 +57,45 @@ const BOOKMARK_QUERY = 1;
 const Bookmark = Class({
   extends: [
     bookmarkContract.properties(identity)
   ],
   initialize: function initialize (options) {
     merge(this, bookmarkContract(extend(defaults, options)));
   },
   type: 'bookmark',
-  toString: function () '[object Bookmark]'
+  toString: () => '[object Bookmark]'
 });
 exports.Bookmark = Bookmark;
 
 const Group = Class({
   extends: [
     groupContract.properties(identity)
   ],
   initialize: function initialize (options) {
     // Don't validate if root group
     if (isRootGroup(options))
       merge(this, options);
     else
       merge(this, groupContract(extend(defaults, options)));
   },
   type: 'group',
-  toString: function () '[object Group]'
+  toString: () => '[object Group]'
 });
 exports.Group = Group;
 
 const Separator = Class({
   extends: [
     separatorContract.properties(identity)
   ],
   initialize: function initialize (options) {
     merge(this, separatorContract(extend(defaults, options)));
   },
   type: 'separator',
-  toString: function () '[object Separator]'
+  toString: () => '[object Separator]'
 });
 exports.Separator = Separator;
 
 /*
  * Functions
  */
 
 function save (items, options) {
--- a/addon-sdk/source/lib/sdk/places/contract.js
+++ b/addon-sdk/source/lib/sdk/places/contract.js
@@ -24,17 +24,17 @@ const validItem = {
         (value.toString && value.toString() === '[object Group]') ||
         typeof value === 'number' ||
         value.type === 'group';
     },
     msg: 'The `group` property must be a valid Group object'
   },
   index: {
     is: ['undefined', 'null', 'number'],
-    map: function (value) value == null ? -1 : value,
+    map: value => value == null ? -1 : value,
     msg: 'The `index` property must be a number.'
   },
   updated: {
     is: ['number', 'undefined']
   }
 };
 
 const validTitle = {
@@ -50,17 +50,17 @@ const validURL = {
     ok: isValidURI,
     msg: 'The `url` property must be a valid URL.'
   }
 };
 
 const validTags = {
   tags: {
     is: ['object'],
-    ok: function (tags) tags instanceof Set,
+    ok: tags => tags instanceof Set,
     map: function (tags) {
       if (Array.isArray(tags))
         return new Set(tags);
       if (tags == null)
         return new Set();
       return tags;
     },
     msg: 'The `tags` property must be a Set, or an array'
--- a/addon-sdk/source/lib/sdk/places/host/host-bookmarks.js
+++ b/addon-sdk/source/lib/sdk/places/host/host-bookmarks.js
@@ -58,18 +58,19 @@ function typeMap (type) {
     if (bmsrv.TYPE_SEPARATOR === type) return 'separator';
   } else {
     if ('bookmark' === type) return bmsrv.TYPE_BOOKMARK;
     if ('group' === type) return bmsrv.TYPE_FOLDER;
     if ('separator' === type) return bmsrv.TYPE_SEPARATOR;
   }
 }
 
-function getBookmarkLastUpdated ({id})
-  resolve(bmsrv.getItemLastModified(id))
+function getBookmarkLastUpdated ({id}) {
+  return resolve(bmsrv.getItemLastModified(id));
+}
 exports.getBookmarkLastUpdated;
 
 function createBookmarkItem (data) {
   let error;
 
   if (data.group == null) data.group = UNSORTED_ID;
   if (data.index == null) data.index = DEFAULT_INDEX;
 
--- a/addon-sdk/source/lib/sdk/places/host/host-query.js
+++ b/addon-sdk/source/lib/sdk/places/host/host-query.js
@@ -150,16 +150,16 @@ function normalize (historyObj) {
     return obj;
   }, {});
 }
 
 /*
  * Hook into host
  */
 
-var reqStream = filter(request, function (data) /sdk-places-query/.test(data.event));
+var reqStream = filter(request, data => /sdk-places-query/.test(data.event));
 on(reqStream, 'data', function (e) {
   if (EVENT_MAP[e.event]) EVENT_MAP[e.event](e);
 });
 
 function respond (data) {
   emit(response, 'data', data);
 }
--- a/addon-sdk/source/lib/sdk/places/host/host-tags.js
+++ b/addon-sdk/source/lib/sdk/places/host/host-tags.js
@@ -55,17 +55,17 @@ function untag (message) {
 function getURLsByTag (message) {
   let data = message.data;
   let resData = {
     id: message.id,
     event: message.event
   };
 
   resData.data = taggingService
-    .getURIsForTag(data.tag).map(function (uri) uri.spec);
+    .getURIsForTag(data.tag).map(uri => uri.spec);
   respond(resData);
 }
 
 function getTagsByURL (message) {
   let data = message.data;
   let resData = {
     id: message.id,
     event: message.event
--- a/addon-sdk/source/lib/sdk/places/utils.js
+++ b/addon-sdk/source/lib/sdk/places/utils.js
@@ -39,17 +39,17 @@ var TreeNode = Class({
   get length () {
     let count = 0;
     this.walk(() => count++);
     // Do not count the current node
     return --count;
   },
   get: method(get),
   walk: method(walk),
-  toString: function () '[object TreeNode]'
+  toString: () => '[object TreeNode]'
 });
 exports.TreeNode = TreeNode;
 
 /*
  * Descends down from `node` applying `fn` to each in order.
  * `fn` can return values or promises -- if promise returned,
  * children are not processed until resolved. `fn` is passed
  * one argument, the current node, `curr`.
@@ -98,18 +98,19 @@ function constructTree (items) {
   return root;
 }
 exports.constructTree = constructTree;
 
 /*
  * Shortcut for converting an id, or an object with an id, into
  * an object with corresponding bookmark data
  */
-function fetchItem (item)
-  send('sdk-places-bookmarks-get', { id: item.id || item })
+function fetchItem (item) {
+  return send('sdk-places-bookmarks-get', { id: item.id || item });
+}
 exports.fetchItem = fetchItem;
 
 /*
  * Takes an ID or an object with ID and checks it against
  * the root bookmark folders
  */
 function isRootGroup (id) {
   id = id && id.id;
--- a/addon-sdk/source/lib/sdk/platform/xpcom.js
+++ b/addon-sdk/source/lib/sdk/platform/xpcom.js
@@ -16,18 +16,18 @@ const { merge } = require('../util/objec
 const { Class, extend, mix } = require('../core/heritage');
 const { uuid } = require('../util/uuid');
 
 // This is a base prototype, that provides bare bones of XPCOM. JS based
 // components can be easily implement by extending it.
 const Unknown = new function() {
   function hasInterface(component, iid) {
     return component && component.interfaces &&
-      ( component.interfaces.some(function(id) iid.equals(Ci[id])) ||
-        component.implements.some(function($) hasInterface($, iid)) ||
+      ( component.interfaces.some(id => iid.equals(Ci[id])) ||
+        component.implements.some($ => hasInterface($, iid)) ||
         hasInterface(Object.getPrototypeOf(component), iid));
   }
 
   return Class({
     /**
      * The `QueryInterface` method provides runtime type discovery used by XPCOM.
      * This method return queried instance of `this` if given `iid` is listed in
      * the `interfaces` property or in equivalent properties of objects in it's
@@ -80,17 +80,19 @@ const Factory = Class({
    * human-readable description for the given class and does not needs to be
    * globally unique.
    */
   description: 'Jetpack generated factory',
   /**
    * This method is required by `nsIFactory` interfaces, but as in most
    * implementations it does nothing interesting.
    */
-  lockFactory: function lockFactory(lock) undefined,
+  lockFactory: function lockFactory(lock) {
+    return undefined;
+  },
   /**
    * If property is `true` XPCOM service / factory will be registered
    * automatically on creation.
    */
   register: true,
   /**
    * If property is `true` XPCOM factory will be unregistered prior to add-on
    * unload.
@@ -126,38 +128,44 @@ const Factory = Class({
       if (outer)
         throw Cr.NS_ERROR_NO_AGGREGATION;
       return this.create().QueryInterface(iid);
     }
     catch (error) {
       throw error instanceof Ci.nsIException ? error : Cr.NS_ERROR_FAILURE;
     }
   },
-  create: function create() this.Component()
+  create: function create() {
+    return this.Component();
+  }
 });
 exports.Factory = Factory;
 
 // Exemplar for creating services that implement `nsIFactory` interface, that
 // can be registered into runtime via call to `register`. This services return
 // enclosed `component` on `getService`.
 const Service = Class({
   extends: Factory,
   initialize: function initialize(options) {
     this.component = options.Component();
     Factory.prototype.initialize.call(this, options);
   },
   description: 'Jetpack generated service',
   /**
    * Creates an instance of the class associated with this factory.
    */
-  create: function create() this.component
+  create: function create() {
+    return this.component;
+  }
 });
 exports.Service = Service;
 
-function isRegistered({ id }) isCIDRegistered(id)
+function isRegistered({ id }) {
+  return isCIDRegistered(id);
+}
 exports.isRegistered = isRegistered;
 
 /**
  * Registers given `component` object to be used to instantiate a particular
  * class identified by `component.id`, and creates an association of class
  * name and `component.contract` with the class.
  */
 function register(factory) {
@@ -211,19 +219,23 @@ function autoRegister(path) {
   Cm.QueryInterface(Ci.nsIComponentRegistrar);
   Cm.autoRegister(file);
 }
 exports.autoRegister = autoRegister;
 
 /**
  * Returns registered factory that has a given `id` or `null` if not found.
  */
-function factoryByID(id) classesByID[id] || null
+function factoryByID(id) {
+  return classesByID[id] || null;
+}
 exports.factoryByID = factoryByID;
 
 /**
  * Returns factory registered with a given `contract` or `null` if not found.
  * In contrast to `Cc[contract]` that does ignores new factory registration
  * with a given `contract` this will return a factory currently associated
  * with a `contract`.
  */
-function factoryByContract(contract) factoryByID(Cm.contractIDToCID(contract))
+function factoryByContract(contract) {
+  return factoryByID(Cm.contractIDToCID(contract));
+}
 exports.factoryByContract = factoryByContract;
--- a/addon-sdk/source/lib/sdk/request.js
+++ b/addon-sdk/source/lib/sdk/request.js
@@ -21,37 +21,37 @@ const { isValidURI } = require("./url.js
 const response = ns();
 const request = ns();
 
 // Instead of creating a new validator for each request, just make one and
 // reuse it.
 const { validateOptions, validateSingleOption } = new OptionsValidator({
   url: {
     // Also converts a URL instance to string, bug 857902
-    map: function (url) url.toString(),
+    map: url => url.toString(),
     ok: isValidURI
   },
   headers: {
-    map: function (v) v || {},
+    map: v => v || {},
     is:  ["object"],
   },
   content: {
-    map: function (v) v || null,
+    map: v => v || null,
     is:  ["string", "object", "null"],
   },
   contentType: {
-    map: function (v) v || "application/x-www-form-urlencoded",
+    map: v => v || "application/x-www-form-urlencoded",
     is:  ["string"],
   },
   overrideMimeType: {
-    map: function(v) v || null,
+    map: v => v || null,
     is: ["string", "null"],
   },
   anonymous: {
-    map: function(v) v || false,
+    map: v => v || false,
     is: ["boolean", "null"],
   }
 });
 
 const REUSE_ERROR = "This request object has been used already. You must " +
                     "create a new one to make a new request."
 
 // Utility function to prep the request since it's the same between
@@ -160,24 +160,32 @@ const Request = Class({
 });
 exports.Request = Request;
 
 const Response = Class({
   initialize: function initialize(request) {
     response(this).request = request;
   },
   // more about responseURL: https://bugzilla.mozilla.org/show_bug.cgi?id=998076
-  get url() response(this).request.responseURL,
-  get text() response(this).request.responseText,
+  get url() {
+    return response(this).request.responseURL;
+  },
+  get text() {
+    return response(this).request.responseText;
+  },
   get xml() {
     throw new Error("Sorry, the 'xml' property is no longer available. " +
                     "see bug 611042 for more information.");
   },
-  get status() response(this).request.status,
-  get statusText() response(this).request.statusText,
+  get status() {
+    return response(this).request.status;
+  },
+  get statusText() {
+    return response(this).request.statusText;
+  },
   get json() {
     try {
       return JSON.parse(this.text);
     } catch(error) {
       return null;
     }
   },
   get headers() {
@@ -207,17 +215,19 @@ const Response = Class({
         lastKey = key;
       }
       else {
         headers[lastKey] += "\n" + val;
       }
     });
     return headers;
   },
-  get anonymous() response(this).request.mozAnon
+  get anonymous() {
+    return response(this).request.mozAnon;
+  }
 });
 
 // apiUtils.validateOptions doesn't give the ability to easily validate single
 // options, so this is a wrapper that provides that ability.
 function OptionsValidator(rules) {
   return {
     validateOptions: function (options) {
       return apiUtils.validateOptions(options, rules);
--- a/addon-sdk/source/lib/sdk/selection.js
+++ b/addon-sdk/source/lib/sdk/selection.js
@@ -75,17 +75,17 @@ const Selection = Class({
         break;
 
     return count === 1;
   }
 });
 
 const selectionListener = {
   notifySelectionChanged: function (document, selection, reason) {
-    if (!["SELECTALL", "KEYPRESS", "MOUSEUP"].some(function(type) reason &
+    if (!["SELECTALL", "KEYPRESS", "MOUSEUP"].some(type => reason &
       Ci.nsISelectionListener[type + "_REASON"]) || selection.toString() == "")
         return;
 
     this.onSelect();
   },
 
   onSelect: function() {
     emit(module.exports, "select");
--- a/addon-sdk/source/lib/sdk/system/environment.js
+++ b/addon-sdk/source/lib/sdk/system/environment.js
@@ -10,51 +10,55 @@ module.metadata = {
 
 const { Cc, Ci } = require('chrome');
 const { get, set, exists } = Cc['@mozilla.org/process/environment;1'].
                              getService(Ci.nsIEnvironment);
 
 exports.env = Proxy.create({
   // XPCOM does not provides a way to enumerate environment variables, so we
   // just don't support enumeration.
-  getPropertyNames: function() [],
-  getOwnPropertyNames: function() [],
-  enumerate: function() [],
-  keys: function() [],
+  getPropertyNames: () => [],
+  getOwnPropertyNames: () => [],
+  enumerate: () => [],
+  keys: () => [],
   // We do not support freezing, cause it would make it impossible to set new
   // environment variables.
-  fix: function() undefined,
+  fix: () => undefined,
   // We present all environment variables as own properties of this object,
   // so we just delegate this call to `getOwnPropertyDescriptor`.
-  getPropertyDescriptor: function(name) this.getOwnPropertyDescriptor(name),
+  getPropertyDescriptor: function(name) {
+    return this.getOwnPropertyDescriptor(name);
+  },
   // If environment variable with this name is defined, we generate proprety
   // descriptor for it, otherwise fall back to `undefined` so that for consumer
   // this property does not exists.
   getOwnPropertyDescriptor: function(name) {
     return !exists(name) ? undefined : {
       value: get(name),
       enumerable: false,    // Non-enumerable as we don't support enumeration.
       configurable: true,   // Configurable as it may be deleted.
       writable: true        // Writable as we do support set.
     }
   },
 
   // New environment variables can be defined just by defining properties
   // on this object.
-  defineProperty: function(name, { value }) set(name, value),
+  defineProperty: (name, { value }) => set(name, value),
   delete: function(name) {
     set(name, null);
     return true;
   },
 
   // We present all properties as own, there for we just delegate to `hasOwn`.
-  has: function(name) this.hasOwn(name),
+  has: function(name) {
+    return this.hasOwn(name);
+  },
   // We do support checks for existence of an environment variable, via `in`
   // operator on this object.
-  hasOwn: function(name) exists(name),
+  hasOwn: name => exists(name),
 
   // On property get / set we do read / write appropriate environment variables,
   // please note though, that variables with names of standard object properties
   // intentionally (so that this behaves as normal object) can not be
   // read / set.
-  get: function(proxy, name) Object.prototype[name] || get(name) || undefined,
-  set: function(proxy, name, value) Object.prototype[name] || set(name, value)
+  get: (proxy, name) => Object.prototype[name] || get(name) || undefined,
+  set: (proxy, name, value) => Object.prototype[name] || set(name, value)
 });
--- a/addon-sdk/source/lib/sdk/tab/events.js
+++ b/addon-sdk/source/lib/sdk/tab/events.js
@@ -30,24 +30,24 @@ const TYPES = ["TabOpen","TabClose","Tab
                "TabUnpinned"];
 
 // Utility function that given a browser `window` returns stream of above
 // defined tab events for all tabs on the given window.
 function tabEventsFor(window) {
   // Map supported event types to a streams of those events on the given
   // `window` and than merge these streams into single form stream off
   // all events.
-  let channels = TYPES.map(function(type) open(window, type));
+  let channels = TYPES.map(type => open(window, type));
   return merge(channels);
 }
 
 // Filter DOMContentLoaded events from all the browser events.
-var readyEvents = filter(events, function(e) e.type === "DOMContentLoaded");
+var readyEvents = filter(events, e => e.type === "DOMContentLoaded");
 // Map DOMContentLoaded events to it's target browser windows.
-var futureWindows = map(readyEvents, function(e) e.target);
+var futureWindows = map(readyEvents, e => e.target);
 // Expand all browsers that will become interactive to supported tab events
 // on these windows. Result will be a tab events from all tabs of all windows
 // that will become interactive.
 var eventsFromFuture = expand(futureWindows, tabEventsFor);
 
 // Above covers only windows that will become interactive in a future, but some
 // windows may already be interactive so we pick those and expand to supported
 // tab events for them too.
--- a/addon-sdk/source/lib/sdk/tabs/tab-fennec.js
+++ b/addon-sdk/source/lib/sdk/tabs/tab-fennec.js
@@ -53,28 +53,34 @@ const Tab = Class({
     unload(cleanupTab.bind(null, this));
   },
 
   /**
    * The title of the page currently loaded in the tab.
    * Changing this property changes an actual title.
    * @type {String}
    */
-  get title() getTabTitle(tabNS(this).tab),
-  set title(title) setTabTitle(tabNS(this).tab, title),
+  get title() {
+    return getTabTitle(tabNS(this).tab);
+  },
+  set title(title) {
+    setTabTitle(tabNS(this).tab, title);
+  },
 
   /**
    * Location of the page currently loaded in this tab.
    * Changing this property will loads page under under the specified location.
    * @type {String}
    */
   get url() {
     return tabNS(this).closed ? undefined : getTabURL(tabNS(this).tab);
   },
-  set url(url) setTabURL(tabNS(this).tab, url),
+  set url(url) {
+    setTabURL(tabNS(this).tab, url);
+  },
 
   getThumbnail: function() {
     // TODO: implement!
     console.error(ERR_FENNEC_MSG);
 
     // return 80x45 blank default
     return BLANK;
   },
@@ -126,17 +132,19 @@ const Tab = Class({
     console.error(ERR_FENNEC_MSG); // TODO
   },
 
   /**
    * Returns the MIME type that the document loaded in the tab is being
    * rendered as.
    * @type {String}
    */
-  get contentType() getTabContentType(tabNS(this).tab),
+  get contentType() {
+    return getTabContentType(tabNS(this).tab);
+  },
 
   /**
    * Create a worker for this tab, first argument is options given to Worker.
    * @type {Worker}
    */
   attach: function attach(options) {
     // BUG 792946 https://bugzilla.mozilla.org/show_bug.cgi?id=792946
     // TODO: fix this circular dependency
--- a/addon-sdk/source/lib/sdk/tabs/utils.js
+++ b/addon-sdk/source/lib/sdk/tabs/utils.js
@@ -12,17 +12,19 @@ module.metadata = {
 
 
 const { Ci } = require('chrome');
 const { defer } = require("../lang/functional");
 const { windows, isBrowser } = require('../window/utils');
 const { isPrivateBrowsingSupported } = require('../self');
 
 // Bug 834961: ignore private windows when they are not supported
-function getWindows() windows(null, { includePrivate: isPrivateBrowsingSupported });
+function getWindows() {
+  return windows(null, { includePrivate: isPrivateBrowsingSupported });
+}
 
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
 // Define predicate functions that can be used to detech weather
 // we deal with fennec tabs or firefox tabs.
 
 // Predicate to detect whether tab is XUL "Tab" node.
 const isXULTab = tab =>
@@ -86,17 +88,17 @@ function getTabs(window) {
                reduce((tabs, window) => tabs.concat(getTabs(window)), []);
   }
 
   // fennec
   if (window.BrowserApp)
     return window.BrowserApp.tabs;
 
   // firefox - default
-  return Array.filter(getTabContainer(window).children, function(t) !t.closing);
+  return Array.filter(getTabContainer(window).children, t => !t.closing);
 }
 exports.getTabs = getTabs;
 
 function getActiveTab(window) {
   return getSelectedTab(window);
 }
 exports.getActiveTab = getActiveTab;
 
@@ -316,17 +318,19 @@ exports.pin = pin;
 
 function unpin(tab) {
   let gBrowser = getTabBrowserForTab(tab);
   // TODO: Implement Fennec support
   if (gBrowser) gBrowser.unpinTab(tab);
 }
 exports.unpin = unpin;
 
-function isPinned(tab) !!tab.pinned
+function isPinned(tab) {
+  return !!tab.pinned;
+}
 exports.isPinned = isPinned;
 
 function reload(tab) {
   getBrowserForTab(tab).reload();
 }
 exports.reload = reload
 
 function getIndex(tab) {
--- a/addon-sdk/source/lib/sdk/test/harness.js
+++ b/addon-sdk/source/lib/sdk/test/harness.js
@@ -322,17 +322,19 @@ function getPotentialLeaks() {
         return;
       }
 
       let item = {
         path: matches[1],
         principal: details[1],
         location: details[2] ? details[2].replace(/\\/g, "/") : undefined,
         source: details[3] ? details[3].split(" -> ").reverse() : undefined,
-        toString: function() this.location
+        toString: function() {
+          return this.location;
+        }
       };
 
       if (!isPossibleLeak(item))
         return;
 
       compartments[matches[1]] = item;
       return;
     }
@@ -346,17 +348,19 @@ function getPotentialLeaks() {
         console.error("Unable to parse window detail " + matches[1]);
         return;
       }
 
       let item = {
         path: matches[1],
         location: details[1].replace(/\\/g, "/"),
         source: [details[1].replace(/\\/g, "/")],
-        toString: function() this.location
+        toString: function() {
+          return this.location;
+        }
       };
 
       if (!isPossibleLeak(item))
         return;
 
       windows[matches[1]] = item;
     }
   }
@@ -626,17 +630,17 @@ var runTests = exports.runTests = functi
                     Error.prototype;
     let stack = serializeStack(frames.reverse());
 
     let error = Object.create(prototype, {
       message: { value: e.message, writable: true, configurable: true },
       fileName: { value: e.fileName, writable: true, configurable: true },
       lineNumber: { value: e.lineNumber, writable: true, configurable: true },
       stack: { value: stack, writable: true, configurable: true },
-      toString: { value: function() String(e), writable: true, configurable: true },
+      toString: { value: () => String(e), writable: true, configurable: true },
     });
 
     print("Error: " + error + " \n " + format(error));
     onDone({passed: 0, failed: 1});
   }
 };
 
 unload(_ => consoleListener.unregister());
--- a/addon-sdk/source/lib/sdk/ui/button/action.js
+++ b/addon-sdk/source/lib/sdk/ui/button/action.js
@@ -66,17 +66,19 @@ const ActionButton = Class({
 
     off(this);
 
     view.dispose(id);
 
     unregister(this);
   },
 
-  get id() this.state().id,
+  get id() {
+    return this.state().id;
+  },
 
   click: function click() { view.click(toWidgetId(this.id)) }
 });
 exports.ActionButton = ActionButton;
 
 identify.define(ActionButton, ({id}) => toWidgetId(id));
 
 getNodeView.define(ActionButton, button =>
--- a/addon-sdk/source/lib/sdk/ui/button/toggle.js
+++ b/addon-sdk/source/lib/sdk/ui/button/toggle.js
@@ -67,19 +67,23 @@ const ToggleButton = Class({
 
     off(this);
 
     view.dispose(id);
 
     unregister(this);
   },
 
-  get id() this.state().id,
+  get id() {
+    return this.state().id;
+  },
 
-  click: function click() view.click(toWidgetId(this.id))
+  click: function click() {
+    return view.click(toWidgetId(this.id));
+  }
 });
 exports.ToggleButton = ToggleButton;
 
 identify.define(ToggleButton, ({id}) => toWidgetId(id));
 
 getNodeView.define(ToggleButton, button =>
   view.nodeFor(toWidgetId(button.id))
 );
--- a/addon-sdk/source/lib/sdk/ui/sidebar.js
+++ b/addon-sdk/source/lib/sdk/ui/sidebar.js
@@ -207,48 +207,58 @@ const Sidebar = Class({
         }
       }
     });
 
     views.set(this, bars);
 
     add(sidebars, this);
   },
-  get id() (modelFor(this) || {}).id,
-  get title() (modelFor(this) || {}).title,
+  get id() {
+    return (modelFor(this) || {}).id;
+  },
+  get title() {
+    return (modelFor(this) || {}).title;
+  },
   set title(v) {
     // destroyed?
     if (!modelFor(this))
       return;
     // validation
     if (typeof v != 'string')
       throw Error('title must be a string');
     validateTitleAndURLCombo(this, v, this.url);
     // do update
     updateTitle(this, v);
     return modelFor(this).title = v;
   },
-  get url() (modelFor(this) || {}).url,
+  get url() {
+    return (modelFor(this) || {}).url;
+  },
   set url(v) {
     // destroyed?
     if (!modelFor(this))
       return;
 
     // validation
     if (!isLocalURL(v))
       throw Error('the url must be a valid local url');
 
     validateTitleAndURLCombo(this, this.title, v);
 
     // do update
     updateURL(this, v);
     modelFor(this).url = v;
   },
-  show: function(window) showSidebar(viewFor(window), this),
-  hide: function(window) hideSidebar(viewFor(window), this),
+  show: function(window) {
+    return showSidebar(viewFor(window), this);
+  },
+  hide: function(window) {
+    return hideSidebar(viewFor(window), this);
+  },
   dispose: function() {
     const internals = sidebarNS(this);
 
     off(this);
 
     remove(sidebars, this);
 
     // stop tracking windows
--- a/addon-sdk/source/lib/sdk/ui/sidebar/contract.js
+++ b/addon-sdk/source/lib/sdk/ui/sidebar/contract.js
@@ -16,12 +16,12 @@ exports.contract = contract({
   },
   title: {
   	is: [ 'string' ],
   	ok: v => v.length
   },
   url: {
     is: [ 'string' ],
     ok: v => isLocalURL(v),
-    map: function(v) v.toString(),
+    map: v => v.toString(),
     msg: 'The option "url" must be a valid local URI.'
   }
 });
--- a/addon-sdk/source/lib/sdk/ui/sidebar/namespace.js
+++ b/addon-sdk/source/lib/sdk/ui/sidebar/namespace.js
@@ -2,10 +2,14 @@
  * 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';
 
 const models = exports.models = new WeakMap();
 const views = exports.views = new WeakMap();
 exports.buttons = new WeakMap();
 
-exports.viewsFor = function viewsFor(sidebar) views.get(sidebar);
-exports.modelFor = function modelFor(sidebar) models.get(sidebar);
+exports.viewsFor = function viewsFor(sidebar) {
+  return views.get(sidebar);
+};
+exports.modelFor = function modelFor(sidebar) {
+  return models.get(sidebar);
+};
--- a/addon-sdk/source/lib/sdk/url.js
+++ b/addon-sdk/source/lib/sdk/url.js
@@ -132,28 +132,28 @@ function URL(url, base) {
     { value: queryPos }, { value: queryLen },
     { value: refPos }, { value: refLen }] = uriData.slice(2);
 
   let hash = uri.ref ? "#" + uri.ref : "";
   let pathname = uri.path.substr(filepathPos, filepathLen);
   let search = uri.path.substr(queryPos, queryLen);
   search = search ? "?" + search : "";
 
-  this.__defineGetter__("scheme", function() uri.scheme);
-  this.__defineGetter__("userPass", function() userPass);
-  this.__defineGetter__("host", function() host);
-  this.__defineGetter__("hostname", function() host);
-  this.__defineGetter__("port", function() port);
-  this.__defineGetter__("path", function() uri.path);
-  this.__defineGetter__("pathname", function() pathname);
-  this.__defineGetter__("hash", function() hash);
-  this.__defineGetter__("href", function() uri.spec);
-  this.__defineGetter__("origin", function() uri.prePath);
-  this.__defineGetter__("protocol", function() uri.scheme + ":");
-  this.__defineGetter__("search", function() search);
+  this.__defineGetter__("scheme", () => uri.scheme);
+  this.__defineGetter__("userPass", () => userPass);
+  this.__defineGetter__("host", () => host);
+  this.__defineGetter__("hostname", () => host);
+  this.__defineGetter__("port", () => port);
+  this.__defineGetter__("path", () => uri.path);
+  this.__defineGetter__("pathname", () => pathname);
+  this.__defineGetter__("hash", () => hash);
+  this.__defineGetter__("href", () => uri.spec);
+  this.__defineGetter__("origin", () => uri.prePath);
+  this.__defineGetter__("protocol", () => uri.scheme + ":");
+  this.__defineGetter__("search", () => search);
 
   Object.defineProperties(this, {
     toString: {
       value() {
         return new String(uri.spec).toString();
       },
       enumerable: false
     },
--- a/addon-sdk/source/lib/sdk/url/utils.js
+++ b/addon-sdk/source/lib/sdk/url/utils.js
@@ -17,13 +17,13 @@ const { method } = require("../../method
 function newURI (uri) {
   if (!isValidURI(uri))
     throw new Error("malformed URI: " + uri);
   return IOService.newURI(uri, null, null);
 }
 exports.newURI = newURI;
 
 var getURL = method('sdk/url:getURL');
-getURL.define(String, function (url) url);
+getURL.define(String, url => url);
 getURL.define(function (object) {
   return null;
 });
 exports.getURL = getURL;
--- a/addon-sdk/source/lib/sdk/util/list.js
+++ b/addon-sdk/source/lib/sdk/util/list.js
@@ -22,22 +22,26 @@ const listOptions = {
 
     for (let i = 0, ii = arguments.length; i < ii; i++)
       addListItem(this, arguments[i]);
   },
   /**
    * Number of elements in this list.
    * @type {Number}
    */
-  get length() listNS(this).keyValueMap.length,
+  get length() {
+    return listNS(this).keyValueMap.length;
+  },
    /**
     * Returns a string representing this list.
     * @returns {String}
     */
-  toString: function toString() 'List(' + listNS(this).keyValueMap + ')',
+  toString: function toString() {
+    return 'List(' + listNS(this).keyValueMap + ')';
+  },
   /**
    * Custom iterator providing `List`s enumeration behavior.
    * We cant reuse `_iterator` that is defined by `Iterable` since it provides
    * iteration in an arbitrary order.
    * @see https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in
    * @param {Boolean} onKeys
    */
   __iterator__: function __iterator__(onKeys, onKeyValue) {
--- a/addon-sdk/source/lib/sdk/util/match-pattern.js
+++ b/addon-sdk/source/lib/sdk/util/match-pattern.js
@@ -102,12 +102,12 @@ MatchPattern.prototype = {
       return true;
 
     if (this.urlPrefix && 0 == urlStr.indexOf(this.urlPrefix))
       return true;
 
     return false;
   },
 
-  toString: function () '[object MatchPattern]'
+  toString: () => '[object MatchPattern]'
 };
 
 exports.MatchPattern = MatchPattern;
--- a/addon-sdk/source/lib/sdk/util/object.js
+++ b/addon-sdk/source/lib/sdk/util/object.js
@@ -51,17 +51,19 @@ exports.merge = merge;
  */
 function extend(source) {
   let rest = Array.slice(arguments, 1);
   rest.unshift(Object.create(source));
   return merge.apply(null, rest);
 }
 exports.extend = extend;
 
-function has(obj, key) obj.hasOwnProperty(key);
+function has(obj, key) {
+  return obj.hasOwnProperty(key);
+}
 exports.has = has;
 
 function each(obj, fn) {
   for (let key in obj) has(obj, key) && fn(obj[key], key, obj);
 }
 exports.each = each;
 
 /**
--- a/addon-sdk/source/lib/sdk/util/rules.js
+++ b/addon-sdk/source/lib/sdk/util/rules.js
@@ -14,32 +14,38 @@ const { EventTarget } = require('../even
 const { List, addListItem, removeListItem } = require('./list');
 
 // Should deprecate usage of EventEmitter/compose
 const Rules = Class({
   implements: [
     EventTarget,
     List
   ],
-  add: function(...rules) [].concat(rules).forEach(function onAdd(rule) {
-    addListItem(this, rule);
-    emit(this, 'add', rule);
-  }, this),
-  remove: function(...rules) [].concat(rules).forEach(function onRemove(rule) {
-    removeListItem(this, rule);
-    emit(this, 'remove', rule);
-  }, this),
+  add: function(...rules) {
+    return [].concat(rules).forEach(function onAdd(rule) {
+      addListItem(this, rule);
+      emit(this, 'add', rule);
+    }, this);
+  },
+  remove: function(...rules) {
+    return [].concat(rules).forEach(function onRemove(rule) {
+      removeListItem(this, rule);
+      emit(this, 'remove', rule);
+    }, this);
+  },
   get: function(rule) {
     let found = false;
     for (let i in this) if (this[i] === rule) found = true;
     return found;
   },
   // Returns true if uri matches atleast one stored rule
-  matchesAny: function(uri) !!filterMatches(this, uri).length,
-  toString: function() '[object Rules]'
+  matchesAny: function(uri) {
+    return !!filterMatches(this, uri).length;
+  },
+  toString: () => '[object Rules]'
 });
 exports.Rules = Rules;
 
 function filterMatches(instance, uri) {
   let matches = [];
   for (let i in instance) {
     if (new MatchPattern(instance[i]).test(uri)) matches.push(instance[i]);
   }
--- a/addon-sdk/source/lib/sdk/util/uuid.js
+++ b/addon-sdk/source/lib/sdk/util/uuid.js
@@ -9,9 +9,11 @@ module.metadata = {
 };
 
 const { Cc, Ci, components: { ID: parseUUID } } = require('chrome');
 const { generateUUID } = Cc['@mozilla.org/uuid-generator;1'].
                           getService(Ci.nsIUUIDGenerator);
 
 // Returns `uuid`. If `id` is passed then it's parsed to `uuid` and returned
 // if not then new one is generated.
-exports.uuid = function uuid(id) id ? parseUUID(id) : generateUUID()
+exports.uuid = function uuid(id) {
+  return id ? parseUUID(id) : generateUUID();
+};
--- a/addon-sdk/source/lib/sdk/window/browser.js
+++ b/addon-sdk/source/lib/sdk/window/browser.js
@@ -24,22 +24,28 @@ const BrowserWindow = Class({
   activate: function activate() {
     // TODO
     return null;
   },
   close: function() {
     throw new Error(ERR_FENNEC_MSG);
     return null;
   },
-  get title() getWindowTitle(windowNS(this).window),
+  get title() {
+    return getWindowTitle(windowNS(this).window);
+  },
   // NOTE: Fennec only has one window, which is assumed below
   // TODO: remove assumption below
   // NOTE: tabs requires windows
-  get tabs() require('../tabs'),
-  get activeTab() require('../tabs').activeTab,
+  get tabs() {
+    return require('../tabs');
+  },
+  get activeTab() {
+    return require('../tabs').activeTab;
+  },
   on: method(on),
   removeListener: method(off),
   once: method(once)
 });
 exports.BrowserWindow = BrowserWindow;
 
 const getWindowView = window => windowNS(window).window;
 
--- a/addon-sdk/source/lib/sdk/window/events.js
+++ b/addon-sdk/source/lib/sdk/window/events.js
@@ -14,17 +14,17 @@ const { windows } = require("../window/u
 const { filter, merge, map, expand } = require("../event/utils");
 
 // Function registers single shot event listeners for relevant window events
 // that forward events to exported event stream.
 function eventsFor(window) {
   let interactive = open(window, "DOMContentLoaded", { capture: true });
   let complete = open(window, "load", { capture: true });
   let states = merge([interactive, complete]);
-  let changes = filter(states, function({target}) target === window.document);
+  let changes = filter(states, ({target}) => target === window.document);
   return map(changes, function({type, target}) {
     return { type: type, target: target.defaultView }
   });
 }
 
 // In addition to observing windows that are open we also observe windows
 // that are already already opened in case they're in process of loading.
 var opened = windows(null, { includePrivate: true });
@@ -34,13 +34,13 @@ var currentEvents = merge(opened.map(eve
 function rename({type, target, data}) {
   return { type: rename[type], target: target, data: data }
 }
 rename.domwindowopened = "open";
 rename.domwindowclosed = "close";
 
 var openEvents = map(observe("domwindowopened"), rename);
 var closeEvents = map(observe("domwindowclosed"), rename);
-var futureEvents = expand(openEvents, function({target}) eventsFor(target));
+var futureEvents = expand(openEvents, ({target}) => eventsFor(target));
 
 var channel = merge([currentEvents, futureEvents,
                      openEvents, closeEvents]);
 exports.events = channel;
--- a/addon-sdk/source/lib/sdk/window/utils.js
+++ b/addon-sdk/source/lib/sdk/window/utils.js
@@ -137,17 +137,19 @@ function getToplevelWindow(window) {
                .getInterface(Ci.nsIWebNavigation)
                .QueryInterface(Ci.nsIDocShellTreeItem)
                .rootTreeItem
                .QueryInterface(Ci.nsIInterfaceRequestor)
                .getInterface(Ci.nsIDOMWindow);
 }
 exports.getToplevelWindow = getToplevelWindow;
 
-function getWindowDocShell(window) window.gBrowser.docShell;
+function getWindowDocShell(window) {
+  return window.gBrowser.docShell;
+}
 exports.getWindowDocShell = getWindowDocShell;
 
 function getWindowLoadingContext(window) {
   return getWindowDocShell(window).
          QueryInterface(Ci.nsILoadContext);
 }
 exports.getWindowLoadingContext = getWindowLoadingContext;
 
--- a/addon-sdk/source/lib/sdk/windows/tabs-fennec.js
+++ b/addon-sdk/source/lib/sdk/windows/tabs-fennec.js
@@ -130,20 +130,20 @@ function onTabOpen(event) {
     let rawTab = getRawTabForBrowser(browser);
 
     // create a Tab instance for this new tab
     tab = addTab(Tab(rawTab));
   }
 
   tabNS(tab).opened = true;
 
-  tab.on('ready', function() emit(gTabs, 'ready', tab));
+  tab.on('ready', () => emit(gTabs, 'ready', tab));
   tab.once('close', onTabClose);
 
-  tab.on('pageshow', function(_tab, persisted)
+  tab.on('pageshow', (_tab, persisted) =>
     emit(gTabs, 'pageshow', tab, persisted));
 
   emit(tab, 'open', tab);
   emit(gTabs, 'open', tab);
 }
 
 // TabSelect
 function onTabSelect(event) {
--- a/addon-sdk/source/lib/toolkit/loader.js
+++ b/addon-sdk/source/lib/toolkit/loader.js
@@ -358,17 +358,17 @@ const load = iced(function load(loader, 
     let prototype = typeof(error) === "object" ? error.constructor.prototype :
                     Error.prototype;
 
     throw create(prototype, {
       message: { value: message, writable: true, configurable: true },
       fileName: { value: fileName, writable: true, configurable: true },
       lineNumber: { value: lineNumber, writable: true, configurable: true },
       stack: { value: serializeStack(frames), writable: true, configurable: true },
-      toString: { value: function() toString, writable: true, configurable: true },
+      toString: { value: () => toString, writable: true, configurable: true },
     });
   }
 
   if (loader.checkCompatibility) {
     let err = XulApp.incompatibility(module);
     if (err) {
       throw err;
     }
--- a/addon-sdk/source/python-lib/plural-rules-generator.py
+++ b/addon-sdk/source/python-lib/plural-rules-generator.py
@@ -147,18 +147,22 @@ print """/* This Source Code Form is sub
 
 // This file is automatically generated with /python-lib/plural-rules-generator.py
 // Fetching data from: %s
 
 // Mapping of short locale name == to == > rule index in following list
 const LOCALES_TO_RULES = %s;
 
 // Utility functions for plural rules methods
-function isIn(n, list) list.indexOf(n) !== -1;
-function isBetween(n, start, end) start <= n && n <= end;
+function isIn(n, list) {
+  return list.indexOf(n) !== -1;
+}
+function isBetween(n, start, end) {
+  return start <= n && n <= end;
+}
 
 // List of all plural rules methods, that maps an integer to the plural form name to use
 const RULES = {
   %s
 };
 
 /**
   * Return a function that gives the plural form name for a given integer
--- a/addon-sdk/source/test/addons/e10s-content/lib/test-content-script.js
+++ b/addon-sdk/source/test/addons/e10s-content/lib/test-content-script.js
@@ -629,18 +629,22 @@ exports["test Prototype Inheritance"] = 
       done();
     }
   );
 
 });
 
 exports["test Functions"] = createProxyTest("", function (helper) {
 
-  helper.rawWindow.callFunction = function callFunction(f) f();
-  helper.rawWindow.isEqual = function isEqual(a, b) a == b;
+  helper.rawWindow.callFunction = function callFunction(f) {
+    return f();
+  };
+  helper.rawWindow.isEqual = function isEqual(a, b) {
+    return a == b;
+  };
   // bug 784116: workaround in order to allow proxy code to cache proxies on
   // these functions:
   helper.rawWindow.callFunction.__exposedProps__ = {__proxy: 'rw'};
   helper.rawWindow.isEqual.__exposedProps__ = {__proxy: 'rw'};
 
   helper.createWorker(
     'new ' + function ContentScriptScope() {
       // Check basic usage of functions
--- a/addon-sdk/source/test/addons/e10s-content/lib/test-page-worker.js
+++ b/addon-sdk/source/test/addons/e10s-content/lib/test-page-worker.js
@@ -61,19 +61,19 @@ exports.testWrappedDOM = function(assert
 
 /*
 // We do not offer unwrapped access to DOM since bug 601295 landed
 // See 660780 to track progress of unwrap feature
 exports.testUnwrappedDOM = function(assert, done) {
   let page = Page({
     allow: { script: true },
     contentURL: "data:text/html;charset=utf-8,<script>document.getElementById=3;window.scrollTo=3;</script>",
-    contentScript: "window.addEventListener('load', function () " +
-                   "self.postMessage([typeof(unsafeWindow.document.getElementById), " +
-                   "typeof(unsafeWindow.scrollTo)]), true)",
+    contentScript: "window.addEventListener('load', function () { " +
+                   "return self.postMessage([typeof(unsafeWindow.document.getElementById), " +
+                   "typeof(unsafeWindow.scrollTo)]); }, true)",
     onMessage: function (message) {
       assert.equal(message[0],
                        "number",
                        "document inside page is free to be changed");
 
       assert.equal(message[1],
                        "number",
                        "window inside page is free to be changed");
@@ -88,17 +88,17 @@ exports.testPageProperties = function(as
   let page = new Page();
 
   for (let prop of ['contentURL', 'allow', 'contentScriptFile',
                          'contentScript', 'contentScriptWhen', 'on',
                          'postMessage', 'removeListener']) {
     assert.ok(prop in page, prop + " property is defined on page.");
   }
 
-  assert.ok(function () page.postMessage("foo") || true,
+  assert.ok(() => page.postMessage("foo") || true,
               "postMessage doesn't throw exception on page.");
 }
 
 exports.testConstructorAndDestructor = function(assert, done) {
   let loader = Loader(module);
   let { Page } = loader.require("sdk/page-worker");
   let global = loader.sandbox("sdk/page-worker");
 
@@ -144,23 +144,23 @@ exports.testAutoDestructor = function(as
       assert.ok(isDestroyed(page), "Page correctly unloaded.");
       done();
     }
   });
 }
 
 exports.testValidateOptions = function(assert) {
   assert.throws(
-    function () Page({ contentURL: 'home' }),
+    () => Page({ contentURL: 'home' }),
     /The `contentURL` option must be a valid URL\./,
     "Validation correctly denied a non-URL contentURL"
   );
 
   assert.throws(
-    function () Page({ onMessage: "This is not a function."}),
+    () => Page({ onMessage: "This is not a function."}),
     /The option "onMessage" must be one of the following types: function/,
     "Validation correctly denied a non-function onMessage."
   );
 
   assert.pass("Options validation is working.");
 }
 
 exports.testContentAndAllowGettersAndSetters = function(assert, done) {
@@ -316,17 +316,17 @@ exports.testAllowScript = function(asser
                    "                 document.documentElement.getAttribute('foo') == 3)",
     contentScriptWhen: "ready"
   });
 }
 
 exports.testPingPong = function(assert, done) {
   let page = Page({
     contentURL: 'data:text/html;charset=utf-8,ping-pong',
-    contentScript: 'self.on("message", function(message) self.postMessage("pong"));'
+    contentScript: 'self.on("message", function(message) { return self.postMessage("pong"); });'
       + 'self.postMessage("ready");',
     onMessage: function(message) {
       if ('ready' == message) {
         page.postMessage('ping');
       }
       else {
         assert.ok(message, 'pong', 'Callback from contentScript');
         done();
--- a/addon-sdk/source/test/addons/main/main.js
+++ b/addon-sdk/source/test/addons/main/main.js
@@ -25,11 +25,11 @@ exports.main = function main(options, ca
 
 // this causes a fail if main does not start
 setTimeout(function() {
   if (mainStarted)
   	return;
 
   // main didn't start, fail..
   require("sdk/test/runner").runTestsFromModule({exports: {
-  	testFail: function(assert) assert.fail('Main did not start..')
+  	testFail: assert => assert.fail('Main did not start..')
   }});
 }, 500);
--- a/addon-sdk/source/test/addons/places/lib/test-places-bookmarks.js
+++ b/addon-sdk/source/test/addons/places/lib/test-places-bookmarks.js
@@ -794,17 +794,19 @@ exports.testCaching = function (assert, 
   }).then(results => {
     // Should query for each bookmark (5) from the query (id -> data),
     // their parent during `construct` (1) and the root shouldn't
     // require a lookup
     assert.equal(count, 6, 'lookup occurs once for each item and parent');
     off(stream, 'data', handle);
   }).then(done).catch(assert.fail);
 
-  function handle ({data}) count++
+  function handle ({data}) {
+    return count++;
+  }
 };
 
 /*
  * Search Query Options
  */
 
 exports.testSearchCount = function (assert, done) {
   let max = 8;
--- a/addon-sdk/source/test/addons/places/lib/test-places-history.js
+++ b/addon-sdk/source/test/addons/places/lib/test-places-history.js
@@ -90,17 +90,17 @@ exports.testSearchURLForHistory = functi
 /*
 exports.testSearchTimeRange = function (assert, done) {
   let firstTime, secondTime;
   addVisits([
     'http://earlyvisit.org', 'http://earlyvisit.org/earlytown.html'
   ]).then(searchP).then(results => {
     firstTime = results[0].time;
     var deferred = defer();
-    setTimeout(function () deferred.resolve(), 1000);
+    setTimeout(() => deferred.resolve(), 1000);
     return deferred.promise;
   }).then(() => {
     return addVisits(['http://newvisit.org', 'http://newvisit.org/whoawhoa.html']);
   }).then(searchP).then(results => {
     results.filter(({url, time}) => {
       if (/newvisit/.test(url)) secondTime = time;
     });
     return searchP({ from: firstTime - 1000 });
--- a/addon-sdk/source/test/addons/private-browsing-supported/test-page-mod.js
+++ b/addon-sdk/source/test/addons/private-browsing-supported/test-page-mod.js
@@ -8,48 +8,50 @@ const { PageMod } = require("sdk/page-mo
 const { getActiveTab, setTabURL, openTab, closeTab } = require('sdk/tabs/utils');
 const xulApp = require('sdk/system/xul-app');
 const windowHelpers = require('sdk/window/helpers');
 const { defer } = require("sdk/core/promise");
 const { isPrivate } = require('sdk/private-browsing');
 const { isTabPBSupported, isWindowPBSupported } = require('sdk/private-browsing/utils');
 const { cleanUI } = require('sdk/test/utils');
 
-function openWebpage(url, enablePrivate) new Promise((resolve, reject) => {
-  if (xulApp.is("Fennec")) {
-    let chromeWindow = getMostRecentBrowserWindow();
-    let rawTab = openTab(chromeWindow, url, {
-      isPrivate: enablePrivate
-    });
+function openWebpage(url, enablePrivate) {
+  return new Promise((resolve, reject) => {
+    if (xulApp.is("Fennec")) {
+      let chromeWindow = getMostRecentBrowserWindow();
+      let rawTab = openTab(chromeWindow, url, {
+        isPrivate: enablePrivate
+      });
 
-    resolve(() => new Promise(resolve => {
-      closeTab(rawTab);
-      resolve();
-    }));
-  }
-  else {
-    windowHelpers.open("", {
-      features: {
-        toolbar: true,
-        private: enablePrivate
-      }
-    }).
-    then((chromeWindow) => {
-      if (isPrivate(chromeWindow) !== !!enablePrivate) {
-        reject(new Error("Window should have Private set to " + !!enablePrivate));
-      }
+      resolve(() => new Promise(resolve => {
+        closeTab(rawTab);
+        resolve();
+      }));
+    }
+    else {
+      windowHelpers.open("", {
+        features: {
+          toolbar: true,
+          private: enablePrivate
+        }
+      }).
+        then((chromeWindow) => {
+          if (isPrivate(chromeWindow) !== !!enablePrivate) {
+            reject(new Error("Window should have Private set to " + !!enablePrivate));
+          }
 
-      let tab = getActiveTab(chromeWindow);
-      setTabURL(tab, url);
+          let tab = getActiveTab(chromeWindow);
+          setTabURL(tab, url);
 
-      resolve(() => windowHelpers.close(chromeWindow));
-    }).
-    catch(reject);
-  }
-})
+          resolve(() => windowHelpers.close(chromeWindow));
+        }).
+        catch(reject);
+    }
+  });
+}
 
 exports["test page-mod on private tab"] = function*(assert) {
   // Only set private mode when explicitely supported.
   // (fennec 19 has some intermediate PB support where isTabPBSupported
   // will be false, but isPrivate(worker.tab) will be true if we open a private
   // tab)
   let setPrivate = isTabPBSupported || isWindowPBSupported;
 
--- a/addon-sdk/source/test/addons/private-browsing-supported/test-selection.js
+++ b/addon-sdk/source/test/addons/private-browsing-supported/test-selection.js
@@ -213,17 +213,17 @@ exports["test PWPB Selection Listener"] 
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL, {private: true, title: "PWPB Selection Listener"}).
     then(function(window) {
       selection.once("select", function() {
         assert.equal(browserWindows.length, 2, "there should be only two windows open.");
         assert.equal(getTabs().length, 2, "there should be only two tabs open: '" +
-                     getTabs().map(function(tab) getTabTitle(tab)).join("', '") +
+                     getTabs().map(tab => getTabTitle(tab)).join("', '") +
                      "'."
         );
 
         // window should be focused, but force the focus anyhow.. see bug 841823
         focus(window).then(function() {
           // check state of window
           assert.ok(isFocused(window), "the window is focused");
           assert.ok(isPrivate(window), "the window should be a private window");
@@ -247,17 +247,17 @@ exports["test PWPB Textarea OnSelect Lis
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL, {private: true, title: "PWPB OnSelect Listener"}).
     then(function(window) {
       selection.once("select", function() {
         assert.equal(browserWindows.length, 2, "there should be only two windows open.");
         assert.equal(getTabs().length, 2, "there should be only two tabs open: '" +
-                     getTabs().map(function(tab) getTabTitle(tab)).join("', '") +
+                     getTabs().map(tab => getTabTitle(tab)).join("', '") +
                      "'."
         );
 
         // window should be focused, but force the focus anyhow.. see bug 841823
         focus(window).then(function() {
           assert.equal(selection.text, "noodles");
 
           closeWindow(window).
--- a/addon-sdk/source/test/addons/private-browsing-supported/test-windows.js
+++ b/addon-sdk/source/test/addons/private-browsing-supported/test-windows.js
@@ -85,17 +85,17 @@ exports.testSettingActiveWindowDoesNotIg
   assert.equal(winUtils.activeBrowserWindow, browserWindow,
                "Browser window is the active browser window.");
   assert.ok(!isPrivate(browserWindow), "Browser window is not private.");
 
   // make a new private window
   makeEmptyBrowserWindow({
     private: true
   }).then(function(window) {
-    let continueAfterFocus = function(window) onFocus(window).then(nextTest);
+    let continueAfterFocus = window => onFocus(window).then(nextTest);
 
     // PWPB case
     if (isWindowPBSupported) {
       assert.ok(isPrivate(window), "window is private");
       assert.notStrictEqual(winUtils.activeBrowserWindow, browserWindow);
     }
     // Global case
     else {
--- a/addon-sdk/source/test/context-menu/test-helper.js
+++ b/addon-sdk/source/test/context-menu/test-helper.js
@@ -267,17 +267,19 @@ TestHelper.prototype = {
       }
     };
 
     if (this.contextMenuPopup.state == "closed") {
       closeBrowserWindow.call(this);
     }
     else {
       this.delayedEventListener(this.contextMenuPopup, "popuphidden",
-                                function () closeBrowserWindow.call(this),
+                                function () {
+                                  return closeBrowserWindow.call(this);
+                                },
                                 false);
       this.contextMenuPopup.hidePopup();
     }
   },
 
   closeTab: function() {
     if (this.tab) {
       this.tabBrowser.removeTab(this.tab);
--- a/addon-sdk/source/test/event/helpers.js
+++ b/addon-sdk/source/test/event/helpers.js
@@ -58,51 +58,55 @@ exports.wait = wait;
 function scenario(setup) {
   return function(unit) {
     return function(assert) {
       let actual = [];
       let input = {};
       unit(input, function(output, events, expected, message) {
         let result = setup(output, expected, actual);
 
-        events.forEach(function(event) emit(input, "data", event));
+        events.forEach(event => emit(input, "data", event));
 
         assert.deepEqual(actual, result, message);
       });
     }
   }
 }
 
 exports.emits = scenario(function(output, expected, actual) {
-  on(output, "data", function(data) actual.push(this, data));
+  on(output, "data", function(data) {
+    return actual.push(this, data);
+  });
 
-  return expected.reduce(function($$, $) $$.concat(output, $), []);
+  return expected.reduce(($$, $) => $$.concat(output, $), []);
 });
 
 exports.registerOnce = scenario(function(output, expected, actual) {
-  function listener(data) actual.push(data);
+  function listener(data) {
+    return actual.push(data);
+  }
   on(output, "data", listener);
   on(output, "data", listener);
   on(output, "data", listener);
 
   return expected;
 });
 
 exports.ignoreNew = scenario(function(output, expected, actual) {
   on(output, "data", function(data) {
     actual.push(data + "#1");
     on(output, "data", function(data) {
       actual.push(data + "#2");
     });
   });
 
-  return expected.map(function($) $ + "#1");
+  return expected.map($ => $ + "#1");
 });
 
 exports.FIFO = scenario(function(target, expected, actual) {
-  on(target, "data", function($) actual.push($ + "#1"));
-  on(target, "data", function($) actual.push($ + "#2"));
-  on(target, "data", function($) actual.push($ + "#3"));
+  on(target, "data", $ => actual.push($ + "#1"));
+  on(target, "data", $ => actual.push($ + "#2"));
+  on(target, "data", $ => actual.push($ + "#3"));
 
   return expected.reduce(function(result, value) {
     return result.concat(value + "#1", value + "#2", value + "#3");
   }, []);
 });
--- a/addon-sdk/source/test/fixtures/test-context-menu.js
+++ b/addon-sdk/source/test/fixtures/test-context-menu.js
@@ -1,5 +1,5 @@
 /* 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/. */
 
-self.on("context", function () true);
+self.on("context", () => true);
--- a/addon-sdk/source/test/page-mod/helpers.js
+++ b/addon-sdk/source/test/page-mod/helpers.js
@@ -43,17 +43,17 @@ function testPageMod(assert, done, testU
     b.removeEventListener("load", onPageLoad, true);
     // Delay callback execute as page-mod content scripts may be executed on
     // load event. So page-mod actions may not be already done.
     // If we delay even more contentScriptWhen:'end', we may want to modify
     // this code again.
     setTimeout(testCallback, timeout,
       b.contentWindow.wrappedJSObject,  // TODO: remove this CPOW
       function () {
-        pageMods.forEach(function(mod) mod.destroy());
+        pageMods.forEach(mod => mod.destroy());
         // XXX leaks reported if we don't close the tab?
         closeTab(newTab);
         loader.unload();
         done();
       }
     );
   }
   b.addEventListener("load", onPageLoad, true);
--- a/addon-sdk/source/test/private-browsing/windows.js
+++ b/addon-sdk/source/test/private-browsing/windows.js
@@ -70,17 +70,17 @@ exports.testIsPrivateOnWindowOpenFromPri
       let { promise, resolve } = defer();
 
       assert.equal(isPrivate(window), true, 'the only open window is private');
 
       windows.open({
         url: 'about:blank',
         onOpen: function(w) {
           assert.equal(isPrivate(w), false, 'new test window is not private');
-          w.close(function() resolve(window));
+          w.close(() => resolve(window));
         }
       });
 
       return promise;
     }).then(close).
        then(done, assert.fail);
 };
 
--- a/addon-sdk/source/test/tabs/test-fennec-tabs.js
+++ b/addon-sdk/source/test/tabs/test-fennec-tabs.js
@@ -124,28 +124,28 @@ exports.testTabProperties = function(ass
 exports.testTabsIteratorAndLength = function(assert, done) {
   let newTabs = [];
   let startCount = 0;
   for (let t of tabs) startCount++;
 
   assert.equal(startCount, tabs.length, "length property is correct");
 
   let url = "data:text/html;charset=utf-8,testTabsIteratorAndLength";
-  tabs.open({url: url, onOpen: function(tab) newTabs.push(tab)});
-  tabs.open({url: url, onOpen: function(tab) newTabs.push(tab)});
+  tabs.open({url: url, onOpen: tab => newTabs.push(tab)});
+  tabs.open({url: url, onOpen: tab => newTabs.push(tab)});
   tabs.open({
     url: url,
     onOpen: function(tab) {
       let count = 0;
       for (let t of tabs) count++;
       assert.equal(count, startCount + 3, "iterated tab count matches");
       assert.equal(startCount + 3, tabs.length, "iterated tab count matches length property");
 
       let newTabsLength = newTabs.length;
-      newTabs.forEach(function(t) t.close(function() {
+      newTabs.forEach(t => t.close(function() {
         if (--newTabsLength > 0) return;
 
         tab.close(done);
       }));
     }
   });
 };
 
@@ -190,17 +190,17 @@ exports.testTabMove = function(assert, d
           let i = tab.index;
           assert.ok(tab.index > tab1.index, "2nd tab has valid index");
           tab.index = 0;
           assert.equal(tab.index, i, "tab index after move matches");
           assert.equal(JSON.stringify(messages),
                            JSON.stringify([ERR_FENNEC_MSG]),
                            "setting tab.index logs error");
           // end test
-          tab1.close(function() tab.close(function() {
+          tab1.close(() => tab.close(function() {
             loader.unload();
             done();
           }));
         }
       });
     }
   });
 };
@@ -403,29 +403,29 @@ exports.testTabsEvent_onCloseWindow = fu
         done();
       }
     });
   }
 
   tabs.open({
     url: "data:text/html;charset=utf-8,tab2",
     onOpen: testCasePossiblyLoaded,
-    onClose: function() individualCloseCount++
+    onClose: () => individualCloseCount++
   });
 
   tabs.open({
     url: "data:text/html;charset=utf-8,tab3",
     onOpen: testCasePossiblyLoaded,
-    onClose: function() individualCloseCount++
+    onClose: () => individualCloseCount++
   });
 
   tabs.open({
     url: "data:text/html;charset=utf-8,tab4",
     onOpen: testCasePossiblyLoaded,
-    onClose: function() individualCloseCount++
+    onClose: () => individualCloseCount++
   });
 };
 
 // TEST: onReady event handler
 exports.testTabsEvent_onReady = function(assert, done) {
   let url = "data:text/html;charset=utf-8,onready";
   let eventCount = 0;
 
--- a/addon-sdk/source/test/tabs/test-firefox-tabs.js
+++ b/addon-sdk/source/test/tabs/test-firefox-tabs.js
@@ -329,17 +329,17 @@ exports.testTabClose = function(assert, 
 
   assert.notEqual(tabs.activeTab.url, url, "tab is not the active tab");
   tabs.once('ready', function onReady(tab) {
     assert.equal(tabs.activeTab.url, tab.url, "tab is now the active tab");
     assert.equal(url, tab.url, "tab url is the test url");
     let secondOnCloseCalled = false;
 
     // Bug 699450: Multiple calls to tab.close should not throw
-    tab.close(function() secondOnCloseCalled = true);
+    tab.close(() => secondOnCloseCalled = true);
     try {
       tab.close(function () {
         assert.notEqual(tabs.activeTab.url, url, "tab is no longer the active tab");
         assert.ok(secondOnCloseCalled,
           "The immediate second call to tab.close happened");
         assert.notEqual(tabs.activeTab.url, url, "tab is no longer the active tab");
 
         done();
@@ -798,17 +798,17 @@ exports.testAttachOnMultipleDocuments = 
 
     tabs.open({
       url: firstLocation,
       onReady: function (tab) {
         onReadyCount++;
         if (onReadyCount == 1) {
           worker1 = tab.attach({
             contentScript: 'self.on("message", ' +
-                           '  function () self.postMessage(document.location.href)' +
+                           '  function () { return self.postMessage(document.location.href); }' +
                            ');',
             onMessage: function (msg) {
               assert.equal(msg, firstLocation,
                                "Worker url is equal to the 1st document");
               tab.url = secondLocation;
             },
             onDetach: function () {
               detachEventCount++;
@@ -822,17 +822,17 @@ exports.testAttachOnMultipleDocuments = 
             }
           });
           worker1.postMessage("new-doc-1");
         }
         else if (onReadyCount == 2) {
 
           worker2 = tab.attach({
             contentScript: 'self.on("message", ' +
-                           '  function () self.postMessage(document.location.href)' +
+                           '  function () { return self.postMessage(document.location.href); }' +
                            ');',
             onMessage: function (msg) {
               assert.equal(msg, secondLocation,
                                "Worker url is equal to the 2nd document");
               tab.url = thirdLocation;
             },
             onDetach: function () {
               detachEventCount++;
--- a/addon-sdk/source/test/test-api-utils.js
+++ b/addon-sdk/source/test/test-api-utils.js
@@ -26,46 +26,46 @@ exports.testValidateOptionsNonempty = fu
   val = apiUtils.validateOptions({ foo: 123, bar: 456 },
                                  { foo: {}, bar: {}, baz: {} });
 
   assert.deepEqual(val, { foo: 123, bar: 456 });
 };
 
 exports.testValidateOptionsMap = function (assert) {
   let val = apiUtils.validateOptions({ foo: 3, bar: 2 }, {
-    foo: { map: function (v) v * v },
-    bar: { map: function (v) undefined }
+    foo: { map: v => v * v },
+    bar: { map: v => undefined }
   });
   assert.deepEqual(val, { foo: 9, bar: undefined });
 };
 
 exports.testValidateOptionsMapException = function (assert) {
   let val = apiUtils.validateOptions({ foo: 3 }, {
     foo: { map: function () { throw new Error(); }}
   });
   assert.deepEqual(val, { foo: 3 });
 };
 
 exports.testValidateOptionsOk = function (assert) {
   let val = apiUtils.validateOptions({ foo: 3, bar: 2, baz: 1 }, {
-    foo: { ok: function (v) v },
-    bar: { ok: function (v) v }
+    foo: { ok: v => v },
+    bar: { ok: v => v }
   });
   assert.deepEqual(val, { foo: 3, bar: 2 });
 
   assert.throws(
-    function () apiUtils.validateOptions({ foo: 2, bar: 2 }, {
-      bar: { ok: function (v) v > 2 }
+    () => apiUtils.validateOptions({ foo: 2, bar: 2 }, {
+      bar: { ok: v => v > 2 }
     }),
     /^The option "bar" is invalid/,
     "ok should raise exception on invalid option"
   );
 
   assert.throws(
-    function () apiUtils.validateOptions(null, { foo: { ok: function (v) v }}),
+    () => apiUtils.validateOptions(null, { foo: { ok: v => v }}),
     /^The option "foo" is invalid/,
     "ok should raise exception on invalid option"
   );
 };
 
 exports.testValidateOptionsIs = function (assert) {
   let opts = {
     array: [],
@@ -87,17 +87,17 @@ exports.testValidateOptionsIs = function
     string: { is: ["string"] },
     undef1: { is: ["undefined"] },
     undef2: { is: ["undefined"] }
   };
   let val = apiUtils.validateOptions(opts, requirements);
   assert.deepEqual(val, opts);
 
   assert.throws(
-    function () apiUtils.validateOptions(null, {
+    () => apiUtils.validateOptions(null, {
       foo: { is: ["object", "number"] }
     }),
     /^The option "foo" must be one of the following types: object, number/,
     "Invalid type should raise exception"
   );
 };
 
 exports.testValidateOptionsIsWithExportedValue = function (assert) {
@@ -218,69 +218,69 @@ exports.testValidateOptionsWithExportedV
   assert.deepEqual(val, {});
 };
 
 
 exports.testValidateOptionsMapIsOk = function (assert) {
   let [map, is, ok] = [false, false, false];
   let val = apiUtils.validateOptions({ foo: 1337 }, {
     foo: {
-      map: function (v) v.toString(),
+      map: v => v.toString(),
       is: ["string"],
-      ok: function (v) v.length > 0
+      ok: v => v.length > 0
     }
   });
   assert.deepEqual(val, { foo: "1337" });
 
   let requirements = {
     foo: {
       is: ["object"],
-      ok: function () assert.fail("is should have caused us to throw by now")
+      ok: () => assert.fail("is should have caused us to throw by now")
     }
   };
   assert.throws(
-    function () apiUtils.validateOptions(null, requirements),
+    () => apiUtils.validateOptions(null, requirements),
     /^The option "foo" must be one of the following types: object/,
     "is should be used before ok is called"
   );
 };
 
 exports.testValidateOptionsErrorMsg = function (assert) {
   assert.throws(
-    function () apiUtils.validateOptions(null, {
-      foo: { ok: function (v) v, msg: "foo!" }
+    () => apiUtils.validateOptions(null, {
+      foo: { ok: v => v, msg: "foo!" }
     }),
     /^foo!/,
     "ok should raise exception with customized message"
   );
 };
 
 exports.testValidateMapWithMissingKey = function (assert) {
   let val = apiUtils.validateOptions({ }, {
     foo: {
-      map: function (v) v || "bar"
+      map: v => v || "bar"
     }
   });
   assert.deepEqual(val, { foo: "bar" });
 
   val = apiUtils.validateOptions({ }, {
     foo: {
-      map: function (v) { throw "bar" }
+      map: v => { throw "bar" }
     }
   });
   assert.deepEqual(val, { });
 };
 
 exports.testValidateMapWithMissingKeyAndThrown = function (assert) {
   let val = apiUtils.validateOptions({}, {
     bar: {
       map: function(v) { throw "bar" }
     },
     baz: {
-      map: function(v) "foo"
+      map: v => "foo"
     }
   });
   assert.deepEqual(val, { baz: "foo" });
 };
 
 exports.testAddIterator = function testAddIterator (assert) {
   let obj = {};
   let keys = ["foo", "bar", "baz"];
--- a/addon-sdk/source/test/test-browser-events.js
+++ b/addon-sdk/source/test/test-browser-events.js
@@ -52,17 +52,19 @@ exports["test browser events"] = functio
 exports["test browser events ignore other wins"] = function(assert, done) {
   let loader = Loader(module);
   let { events: windowEvents } = loader.require("sdk/window/events");
   let { events: browserEvents } = loader.require("sdk/browser/events");
   let { on, off } = loader.require("sdk/event/core");
   let actualBrowser = [];
   let actualWindow = [];
 
-  function browserEventHandler(e) actualBrowser.push(e)
+  function browserEventHandler(e) {
+    return actualBrowser.push(e);
+  }
   on(browserEvents, "data", browserEventHandler);
   on(windowEvents, "data", function handler(e) {
     actualWindow.push(e);
     // Delay close so that if "load" is also emitted on `browserEvents`
     // `browserEventHandler` will be invoked.
     if (e.type === "load") setTimeout(window.close);
     if (e.type === "close") {
       assert.deepEqual(actualBrowser, [], "browser events were not triggered");
--- a/addon-sdk/source/test/test-byte-streams.js
+++ b/addon-sdk/source/test/test-byte-streams.js
@@ -17,29 +17,29 @@ exports.testWriteRead = function (assert
 
   // Write a small string less than the stream's buffer size...
   let str = "exports.testWriteRead data!";
   let stream = open(assert, fname, true);
   assert.ok(!stream.closed, "stream.closed after open should be false");
   stream.write(str);
   stream.close();
   assert.ok(stream.closed, "Stream should be closed after stream.close");
-  assert.throws(function () stream.write("This shouldn't be written!"),
+  assert.throws(() => stream.write("This shouldn't be written!"),
     STREAM_CLOSED_ERROR,
     "stream.write after close should raise error");
 
   // ... and read it.
   stream = open(assert, fname);
   assert.equal(stream.read(), str,
     "stream.read should return string written");
   assert.equal(stream.read(), "",
     "stream.read at EOS should return empty string");
   stream.close();
   assert.ok(stream.closed, "Stream should be closed after stream.close");
-  assert.throws(function () stream.read(),
+  assert.throws(() => stream.read(),
     STREAM_CLOSED_ERROR,
     "stream.read after close should raise error");
 
   file.remove(fname);
 };
 
 // Write a big string many times the size of the stream's buffer and read it.
 exports.testWriteReadBig = function (assert) {
--- a/addon-sdk/source/test/test-content-events.js
+++ b/addon-sdk/source/test/test-content-events.js
@@ -27,20 +27,20 @@ var when = curry(function(options, tab) 
       target.removeEventListener(type, handler, capture);
       resolve(tab);
     }
   }, capture);
 
   return promise;
 });
 
-var use = function(value) function() value;
+var use = use = value => () => value;
 
 
-var open = curry(function(url, window) openTab(window, url));
+var open = curry((url, window) => openTab(window, url));
 var close = function(tab) {
   let promise = when("pagehide", tab);
   closeTab(tab);
   return promise;
 }
 
 exports["test multiple tabs"] = function(assert, done) {
   let loader = Loader(module);
--- a/addon-sdk/source/test/test-content-script.js
+++ b/addon-sdk/source/test/test-content-script.js
@@ -629,18 +629,22 @@ exports["test Prototype Inheritance"] = 
       done();
     }
   );
 
 });
 
 exports["test Functions"] = createProxyTest("", function (helper) {
 
-  helper.rawWindow.callFunction = function callFunction(f) f();
-  helper.rawWindow.isEqual = function isEqual(a, b) a == b;
+  helper.rawWindow.callFunction = function callFunction(f) {
+    return f();
+  };
+  helper.rawWindow.isEqual = function isEqual(a, b) {
+    return a == b;
+  };
   // bug 784116: workaround in order to allow proxy code to cache proxies on
   // these functions:
   helper.rawWindow.callFunction.__exposedProps__ = {__proxy: 'rw'};
   helper.rawWindow.isEqual.__exposedProps__ = {__proxy: 'rw'};
 
   helper.createWorker(
     'new ' + function ContentScriptScope() {
       // Check basic usage of functions
--- a/addon-sdk/source/test/test-context-menu.js
+++ b/addon-sdk/source/test/test-context-menu.js
@@ -436,17 +436,17 @@ exports.testURLContextNoMatch = function
 // Loading a new page in the same tab should correctly start a new worker for
 // any content scripts
 exports.testPageReload = function (assert, done) {
   let test = new TestHelper(assert, done);
   let loader = test.newLoader();
 
   let item = loader.cm.Item({
     label: "Item",
-    contentScript: "var doc = document; self.on('context', function(node) doc.body.getAttribute('showItem') == 'true');"
+    contentScript: "var doc = document; self.on('context', node => doc.body.getAttribute('showItem') == 'true');"
   });
 
   test.withTestDoc(function (window, doc) {
     // Set a flag on the document that the item uses
     doc.body.setAttribute("showItem", "true");
 
     test.showMenu(null, function (popup) {
       // With the attribute true the item should be visible in the menu
@@ -520,17 +520,17 @@ exports.testPageReload = function (asser
 // Content contexts that return true should cause their items to be present
 // in the menu.
 exports.testContentContextMatch = function (assert, done) {
   let test = new TestHelper(assert, done);
   let loader = test.newLoader();
 
   let item = new loader.cm.Item({
     label: "item",
-    contentScript: 'self.on("context", function () true);'
+    contentScript: 'self.on("context", () => true);'
   });
 
   test.showMenu(null, function (popup) {
     test.checkMenu([item], [], []);
     test.done();
   });
 };
 
@@ -538,17 +538,17 @@ exports.testContentContextMatch = functi
 // Content contexts that return false should cause their items to be absent
 // from the menu.
 exports.testContentContextNoMatch = function (assert, done) {
   let test = new TestHelper(assert, done);
   let loader = test.newLoader();
 
   let item = new loader.cm.Item({
     label: "item",
-    contentScript: 'self.on("context", function () false);'
+    contentScript: 'self.on("context", () => false);'
   });
 
   test.showMenu(null, function (popup) {
     test.checkMenu([item], [item], []);
     test.done();
   });
 };
 
@@ -574,17 +574,17 @@ exports.testContentContextUndefined = fu
 // Content contexts that return an empty string should cause their items to be
 // absent from the menu and shouldn't wipe the label
 exports.testContentContextEmptyString = function (assert, done) {
   let test = new TestHelper(assert, done);
   let loader = test.newLoader();
 
   let item = new loader.cm.Item({
     label: "item",
-    contentScript: 'self.on("context", function () "");'
+    contentScript: 'self.on("context", () => "");'
   });
 
   test.showMenu(null, function (popup) {
     test.checkMenu([item], [item], []);
     assert.equal(item.label, "item", "Label should still be correct");
     test.done();
   });
 };
@@ -593,18 +593,18 @@ exports.testContentContextEmptyString = 
 // If any content contexts returns true then their items should be present in
 // the menu.
 exports.testMultipleContentContextMatch1 = function (assert, done) {
   let test = new TestHelper(assert, done);
   let loader = test.newLoader();
 
   let item = new loader.cm.Item({
     label: "item",
-    contentScript: 'self.on("context", function () true); ' +
-                   'self.on("context", function () false);',
+    contentScript: 'self.on("context", () => true); ' +
+                   'self.on("context", () => false);',
     onMessage: function() {
       test.fail("Should not have called the second context listener");
     }
   });
 
   test.showMenu(null, function (popup) {
     test.checkMenu([item], [], []);
     test.done();
@@ -615,18 +615,18 @@ exports.testMultipleContentContextMatch1
 // If any content contexts returns true then their items should be present in
 // the menu.
 exports.testMultipleContentContextMatch2 = function (assert, done) {
   let test = new TestHelper(assert, done);
   let loader = test.newLoader();
 
   let item = new loader.cm.Item({
     label: "item",
-    contentScript: 'self.on("context", function () false); ' +
-                   'self.on("context", function () true);'
+    contentScript: 'self.on("context", () => false); ' +
+                   'self.on("context", () => true);'
   });
 
   test.showMenu(null, function (popup) {
     test.checkMenu([item], [], []);
     test.done();
   });
 };
 
@@ -634,18 +634,18 @@ exports.testMultipleContentContextMatch2
 // If any content contexts returns a string then their items should be present
 // in the menu.
 exports.testMultipleContentContextString1 = function (assert, done) {
   let test = new TestHelper(assert, done);
   let loader = test.newLoader();
 
   let item = new loader.cm.Item({
     label: "item",
-    contentScript: 'self.on("context", function () "new label"); ' +
-                   'self.on("context", function () false);'
+    contentScript: 'self.on("context", () => "new label"); ' +
+                   'self.on("context", () => false);'
   });
 
   test.showMenu(null, function (popup) {
     test.checkMenu([item], [], []);
     assert.equal(item.label, "new label", "Label should have changed");
     test.done();
   });
 };
@@ -654,18 +654,18 @@ exports.testMultipleContentContextString
 // If any content contexts returns a string then their items should be present
 // in the menu.
 exports.testMultipleContentContextString2 = function (assert, done) {
   let test = new TestHelper(assert, done);
   let loader = test.newLoader();
 
   let item = new loader.cm.Item({
     label: "item",
-    contentScript: 'self.on("context", function () false); ' +
-                   'self.on("context", function () "new label");'
+    contentScript: 'self.on("context", () => false); ' +
+                   'self.on("context", () => "new label");'
   });
 
   test.showMenu(null, function (popup) {
     test.checkMenu([item], [], []);
     assert.equal(item.label, "new label", "Label should have changed");
     test.done();
   });
 };
@@ -673,18 +673,18 @@ exports.testMultipleContentContextString
 
 // If many content contexts returns a string then the first should take effect
 exports.testMultipleContentContextString3 = function (assert, done) {
   let test = new TestHelper(assert, done);
   let loader = test.newLoader();
 
   let item = new loader.cm.Item({
     label: "item",
-    contentScript: 'self.on("context", function () "new label 1"); ' +
-                   'self.on("context", function () "new label 2");'
+    contentScript: 'self.on("context", () => "new label 1"); ' +
+                   'self.on("context", () => "new label 2");'
   });
 
   test.showMenu(null, function (popup) {
     test.checkMenu([item], [], []);
     assert.equal(item.label, "new label 1", "Label should have changed");
     test.done();
   });
 };
@@ -694,33 +694,33 @@ exports.testMultipleContentContextString
 // in the menu when context clicking an active element.
 exports.testContentContextMatchActiveElement = function (assert, done) {
   let test = new TestHelper(assert, done);
   let loader = test.newLoader();
 
   let items = [
     new loader.cm.Item({
       label: "item 1",
-      contentScript: 'self.on("context", function () true);'
+      contentScript: 'self.on("context", () => true);'
     }),
     new loader.cm.Item({
       label: "item 2",
       context: undefined,
-      contentScript: 'self.on("context", function () true);'
+      contentScript: 'self.on("context", () => true);'
     }),
     // These items will always be hidden by the declarative usage of PageContext
     new loader.cm.Item({
       label: "item 3",
       context: loader.cm.PageContext(),
-      contentScript: 'self.on("context", function () true);'
+      contentScript: 'self.on("context", () => true);'
     }),
     new loader.cm.Item({
       label: "item 4",
       context: [loader.cm.PageContext()],
-      contentScript: 'self.on("context", function () true);'
+      contentScript: 'self.on("context", () => true);'
     })
   ];
 
   test.withTestDoc(function (window, doc) {
     test.showMenu("#image", function (popup) {
       test.checkMenu(items, [items[2], items[3]], []);
       test.done();
     });
@@ -732,33 +732,33 @@ exports.testContentContextMatchActiveEle
 // from the menu when context clicking an active element.
 exports.testContentContextNoMatchActiveElement = function (assert, done) {
   let test = new TestHelper(assert, done);
   let loader = test.newLoader();
 
   let items = [
     new loader.cm.Item({
       label: "item 1",
-      contentScript: 'self.on("context", function () false);'
+      contentScript: 'self.on("context", () => false);'
     }),
     new loader.cm.Item({
       label: "item 2",
       context: undefined,
-      contentScript: 'self.on("context", function () false);'
+      contentScript: 'self.on("context", () => false);'
     }),
     // These items will always be hidden by the declarative usage of PageContext
     new loader.cm.Item({
       label: "item 3",
       context: loader.cm.PageContext(),
-      contentScript: 'self.on("context", function () false);'
+      contentScript: 'self.on("context", () => false);'
     }),
     new loader.cm.Item({
       label: "item 4",
       context: [loader.cm.PageContext()],
-      contentScript: 'self.on("context", function () false);'
+      contentScript: 'self.on("context", () => false);'
     })
   ];
 
   test.withTestDoc(function (window, doc) {
     test.showMenu("#image", function (popup) {
       test.checkMenu(items, items, []);
       test.done();
     });
@@ -770,33 +770,33 @@ exports.testContentContextNoMatchActiveE
 // from the menu when context clicking an active element.
 exports.testContentContextNoMatchActiveElement = function (assert, done) {
   let test = new TestHelper(assert, done);
   let loader = test.newLoader();
 
   let items = [
     new loader.cm.Item({
       label: "item 1",
-      contentScript: 'self.on("context", function () {});'
+      contentScript: 'self.on("context", () => {});'
     }),
     new loader.cm.Item({
       label: "item 2",
       context: undefined,
-      contentScript: 'self.on("context", function () {});'
+      contentScript: 'self.on("context", () => {});'
     }),
     // These items will always be hidden by the declarative usage of PageContext
     new loader.cm.Item({
       label: "item 3",
       context: loader.cm.PageContext(),
-      contentScript: 'self.on("context", function () {});'
+      contentScript: 'self.on("context", () => {});'
     }),
     new loader.cm.Item({
       label: "item 4",
       context: [loader.cm.PageContext()],
-      contentScript: 'self.on("context", function () {});'
+      contentScript: 'self.on("context", () => {});'
     })
   ];
 
   test.withTestDoc(function (window, doc) {
     test.showMenu("#image", function (popup) {
       test.checkMenu(items, items, []);
       test.done();
     });
@@ -807,17 +807,17 @@ exports.testContentContextNoMatchActiveE
 // Content contexts that return a string should cause their items to be present
 // in the menu and the items' labels to be updated.
 exports.testContentContextMatchString = function (assert, done) {
   let test = new TestHelper(assert, done);
   let loader = test.newLoader();
 
   let item = new loader.cm.Item({
     label: "first label",
-    contentScript: 'self.on("context", function () "second label");'
+    contentScript: 'self.on("context", () => "second label");'
   });
 
   test.showMenu(null, function (popup) {
     test.checkMenu([item], [], []);
     assert.equal(item.label, "second label",
                      "item's label should be updated");
     test.done();
   });
@@ -2208,17 +2208,17 @@ exports.testContentCommunication = funct
 // should function as expected.
 exports.testLoadWithOpenTab = function (assert, done) {
   let test = new TestHelper(assert, done);
   test.withTestDoc(function (window, doc) {
     let loader = test.newLoader();
     let item = new loader.cm.Item({
       label: "item",
       contentScript:
-        'self.on("click", function () self.postMessage("click"));',
+        'self.on("click", () => self.postMessage("click"));',
       onMessage: function (msg) {
         if (msg === "click")
           test.done();
       }
     });
     test.showMenu(null, function (popup) {
       test.checkMenu([item], [], []);
       test.getItemElt(popup, item).click();
@@ -2638,29 +2638,29 @@ exports.testItemNoData = function (asser
   let loader = test.newLoader();
 
   function checkData(data) {
     assert.equal(data, undefined, "Data should be undefined");
   }
 
   let item1 = new loader.cm.Item({
     label: "item 1",
-    contentScript: 'self.on("click", function(node, data) self.postMessage(data))',
+    contentScript: 'self.on("click", (node, data) => self.postMessage(data))',
     onMessage: checkData
   });
   let item2 = new loader.cm.Item({
     label: "item 2",
     data: null,
-    contentScript: 'self.on("click", function(node, data) self.postMessage(data))',
+    contentScript: 'self.on("click", (node, data) => self.postMessage(data))',
     onMessage: checkData
   });
   let item3 = new loader.cm.Item({
     label: "item 3",
     data: undefined,
-    contentScript: 'self.on("click", function(node, data) self.postMessage(data))',
+    contentScript: 'self.on("click", (node, data) => self.postMessage(data))',
     onMessage: checkData
   });
 
   assert.equal(item1.data, undefined, "Should be no defined data");
   assert.equal(item2.data, null, "Should be no defined data");
   assert.equal(item3.data, undefined, "Should be no defined data");
 
   test.showMenu(null, function (popup) {
@@ -2887,30 +2887,30 @@ exports.testSubItemContextNoMatchHideMen
         })
       ]
     }),
     loader.cm.Menu({
       label: "menu 2",
       items: [
         loader.cm.Item({
           label: "subitem 2",
-          contentScript: 'self.on("context", function () false);'
+          contentScript: 'self.on("context", () => false);'
         })
       ]
     }),
     loader.cm.Menu({
       label: "menu 3",
       items: [
         loader.cm.Item({
           label: "subitem 3",
           context: loader.cm.SelectorContext(".foo")
         }),
         loader.cm.Item({
           label: "subitem 4",
-          contentScript: 'self.on("context", function () false);'
+          contentScript: 'self.on("context", () => false);'
         })
       ]
     })
   ];
 
   test.showMenu(null, function (popup) {
     test.checkMenu(items, items, []);
     test.done();
@@ -2926,17 +2926,17 @@ exports.testSubItemContextMatch = functi
 
   let hiddenItems = [
     loader.cm.Item({
       label: "subitem 3",
       context: loader.cm.SelectorContext(".foo")
     }),
     loader.cm.Item({
       label: "subitem 6",
-      contentScript: 'self.on("context", function () false);'
+      contentScript: 'self.on("context", () => false);'
     })
   ];
 
   let items = [
     loader.cm.Menu({
       label: "menu 1",
       items: [
         loader.cm.Item({
@@ -2945,27 +2945,27 @@ exports.testSubItemContextMatch = functi
         })
       ]
     }),
     loader.cm.Menu({
       label: "menu 2",
       items: [
         loader.cm.Item({
           label: "subitem 2",
-          contentScript: 'self.on("context", function () true);'
+          contentScript: 'self.on("context", () => true);'
         })
       ]
     }),
     loader.cm.Menu({
       label: "menu 3",
       items: [
         hiddenItems[0],
         loader.cm.Item({
           label: "subitem 4",
-          contentScript: 'self.on("context", function () true);'
+          contentScript: 'self.on("context", () => true);'
         })
       ]
     }),
     loader.cm.Menu({
       label: "menu 4",
       items: [
         loader.cm.Item({
           label: "subitem 5",
@@ -2978,17 +2978,17 @@ exports.testSubItemContextMatch = functi
       label: "menu 5",
       items: [
         loader.cm.Item({
           label: "subitem 7",
           context: loader.cm.URLContext(TEST_DOC_URL)
         }),
         loader.cm.Item({
           label: "subitem 8",
-          contentScript: 'self.on("context", function () true);'
+          contentScript: 'self.on("context", () => true);'
         })
       ]
     })
   ];
 
   test.withTestDoc(function (window, doc) {
     test.showMenu(null, function (popup) {
       test.checkMenu(items, hiddenItems, []);
--- a/addon-sdk/source/test/test-event-core.js
+++ b/addon-sdk/source/test/test-event-core.js
@@ -66,17 +66,19 @@ exports['test no side-effects in emit'] 
       assert.fail('second listener is called');
     });
   });
   emit(target, 'message');
 };
 
 exports['test can remove next listener'] = function(assert) {
   let target = { name: 'target' };
-  function fail() assert.fail('Listener should be removed');
+  function fail() {
+    return assert.fail('Listener should be removed');
+  };
 
   on(target, 'data', function() {
     assert.pass('first litener called');
     off(target, 'data', fail);
   });
   on(target, 'data', fail);
 
   emit(target, 'data', 'hello');
--- a/addon-sdk/source/test/test-event-utils.js
+++ b/addon-sdk/source/test/test-event-utils.js
@@ -2,26 +2,30 @@
  * 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';
 
 const { on, emit } = require("sdk/event/core");
 const { filter, map, merge, expand, pipe, stripListeners } = require("sdk/event/utils");
 const $ = require("./event/helpers");
 
-function isEven(x) !(x % 2)
-function inc(x) x + 1
+function isEven(x) {
+  return !(x % 2);
+}
+function inc(x) {
+  return x + 1;
+}
 
 exports["test filter events"] = function(assert) {
   let input = {};
   let evens = filter(input, isEven);
   let actual = [];
-  on(evens, "data", function(e) actual.push(e));
+  on(evens, "data", e => actual.push(e));
 
-  [1, 2, 3, 4, 5, 6, 7].forEach(function(x) emit(input, "data", x));
+  [1, 2, 3, 4, 5, 6, 7].forEach(x => emit(input, "data", x));
 
   assert.deepEqual(actual, [2, 4, 6], "only even numbers passed through");
 };
 
 exports["test filter emits"] = $.emits(function(input, assert) {
   let output = filter(input, isEven);
   assert(output,  [1, 2, 3, 4, 5], [2, 4], "this is `output` & evens passed");
 });;
@@ -40,19 +44,19 @@ exports["test filter is FIFO"] = $.FIFO(
   assert(filter(input, isEven), [1, 2, 3, 4], [2, 4],
          "listeners are invoked in fifo order")
 });
 
 exports["test map events"] = function(assert) {
   let input = {};
   let incs = map(input, inc);
   let actual = [];
-  on(incs, "data", function(e) actual.push(e));
+  on(incs, "data", e => actual.push(e));
 
-  [1, 2, 3, 4].forEach(function(x) emit(input, "data", x));
+  [1, 2, 3, 4].forEach(x => emit(input, "data", x));
 
   assert.deepEqual(actual, [2, 3, 4, 5], "all numbers were incremented");
 };
 
 exports["test map emits"] = $.emits(function(input, assert) {
   let output = map(input, inc);
   assert(output,  [1, 2, 3], [2, 3, 4], "this is `output` & evens passed");
 });
@@ -72,17 +76,17 @@ exports["test map is FIFO"] = $.FIFO(fun
          "listeners are invoked in fifo order")
 });
 
 exports["test merge stream[stream]"] = function(assert) {
   let a = {}, b = {}, c = {};
   let inputs = {};
   let actual = [];
 
-  on(merge(inputs), "data", function($) actual.push($))
+  on(merge(inputs), "data", $ => actual.push($))
 
   emit(inputs, "data", a);
   emit(a, "data", "a1");
   emit(inputs, "data", b);
   emit(b, "data", "b1");
   emit(a, "data", "a2");
   emit(inputs, "data", c);
   emit(c, "data", "c1");
@@ -94,17 +98,17 @@ exports["test merge stream[stream]"] = f
                    "all inputs data merged into one");
 };
 
 exports["test merge array[stream]"] = function(assert) {
   let a = {}, b = {}, c = {};
   let inputs = {};
   let actual = [];
 
-  on(merge([a, b, c]), "data", function($) actual.push($))
+  on(merge([a, b, c]), "data", $ => actual.push($))
 
   emit(a, "data", "a1");
   emit(b, "data", "b1");
   emit(a, "data", "a2");
   emit(c, "data", "c1");
   emit(c, "data", "c2");
   emit(b, "data", "b2");
   emit(a, "data", "a3");
@@ -142,24 +146,24 @@ exports["test marge is FIFO"] = $.FIFO(f
          "listeners are invoked in fifo order")
 });
 
 exports["test expand"] = function(assert) {
   let a = {}, b = {}, c = {};
   let inputs = {};
   let actual = [];
 
-  on(expand(inputs, function($) $()), "data", function($) actual.push($))
+  on(expand(inputs, $ => $()), "data", $ => actual.push($))
 
-  emit(inputs, "data", function() a);
+  emit(inputs, "data", () => a);
   emit(a, "data", "a1");
-  emit(inputs, "data", function() b);
+  emit(inputs, "data", () => b);
   emit(b, "data", "b1");
   emit(a, "data", "a2");
-  emit(inputs, "data", function() c);
+  emit(inputs, "data", () => c);
   emit(c, "data", "c1");
   emit(c, "data", "c2");
   emit(b, "data", "b2");
   emit(a, "data", "a3");
 
   assert.deepEqual(actual, ["a1", "b1", "a2", "c1", "c2", "b2", "a3"],
                    "all inputs data merged into one");
 };
--- a/addon-sdk/source/test/test-file.js
+++ b/addon-sdk/source/test/test-file.js
@@ -228,47 +228,47 @@ exports.testMkpathTwice = function (asse
   file.rmdir(path);
   assert.ok(!file.exists(path), "rmdir should remove path: " + path);
 };
 
 exports.testMkpathExistingNondirectory = function (assert) {
   var fname = file.join(profilePath, 'conflict.txt');
   file.open(fname, "w").close();
   assert.ok(file.exists(fname), "File should exist");
-  assert.throws(function() file.mkpath(fname),
+  assert.throws(() => file.mkpath(fname),
                     /^The path already exists and is not a directory: .+$/,
                     "mkpath on file should raise error");
   file.remove(fname);
 };
 
 exports.testRmdirNondirectory = function (assert) {
   var fname = file.join(profilePath, 'not-a-dir')
   file.open(fname, "w").close();
   assert.ok(file.exists(fname), "File should exist");
   assert.throws(function() {
     file.rmdir(fname);
   }, ERRORS.NOT_A_DIRECTORY, "rmdir on file should raise error");
   file.remove(fname);
   assert.ok(!file.exists(fname), "File should not exist");
-  assert.throws(function () file.rmdir(fname),
+  assert.throws(() => file.rmdir(fname),
                     ERRORS.FILE_NOT_FOUND,
                     "rmdir on non-existing file should raise error");
 };
 
 exports.testRmdirNonempty = function (assert) {
   let dir = profilePath;
   let path = file.join(dir, "test-file-dir");
   assert.ok(!file.exists(path),
               "Sanity check: path should not exist: " + path);
   file.mkpath(path);
   let filePath = file.join(path, "file");
   file.open(filePath, "w").close();
   assert.ok(file.exists(filePath),
               "Sanity check: path should exist: " + filePath);
-  assert.throws(function () file.rmdir(path),
+  assert.throws(() => file.rmdir(path),
                     /^The directory is not empty: .+$/,
                     "rmdir on non-empty directory should raise error");
   file.remove(filePath);
   file.rmdir(path);
   assert.ok(!file.exists(path), "Path should not exist");
 };
 
 require('sdk/test').run(exports);
--- a/addon-sdk/source/test/test-match-pattern.js
+++ b/addon-sdk/source/test/test-match-pattern.js
@@ -81,42 +81,42 @@ exports.testMatchPatternTestFalse = func
   ok('*.zilla.com', 'http://bugzilla.mozilla.com');
   ok('*.zilla.com', 'http://mo-zilla.com');
   ok('*.amp.le.com', 'http://amp-le.com');
   ok('*.amp.le.com', 'http://examp.le.com');
 };
 
 exports.testMatchPatternErrors = function(assert) {
   assert.throws(
-    function() new MatchPattern("*.google.com/*"),
+    () => new MatchPattern("*.google.com/*"),
     /There can be at most one/,
     "MatchPattern throws when supplied multiple '*'"
   );
 
   assert.throws(
-    function() new MatchPattern("google.com"),
+    () => new MatchPattern("google.com"),
     /expected to be either an exact URL/,
     "MatchPattern throws when the wildcard doesn't use '*' and doesn't " +
     "look like a URL"
   );
 
   assert.throws(
-    function() new MatchPattern("http://google*.com"),
+    () => new MatchPattern("http://google*.com"),
     /expected to be the first or the last/,
     "MatchPattern throws when a '*' is in the middle of the wildcard"
   );
 
   assert.throws(
-    function() new MatchPattern(/ /g),
+    () => new MatchPattern(/ /g),
     /^A RegExp match pattern cannot be set to `global` \(i\.e\. \/\/g\)\.$/,
     "MatchPattern throws on a RegExp set to `global` (i.e. //g)."
   );
 
   assert.throws(
-    function() new MatchPattern( / /m ),
+    () => new MatchPattern( / /m ),
     /^A RegExp match pattern cannot be set to `multiline` \(i\.e\. \/\/m\)\.$/,
     "MatchPattern throws on a RegExp set to `multiline` (i.e. //m)."
   );
 };
 
 exports.testMatchPatternInternals = function(assert) {
   assert.equal(
     new MatchPattern("http://google.com/test").exactURL,
--- a/addon-sdk/source/test/test-page-worker.js
+++ b/addon-sdk/source/test/test-page-worker.js
@@ -63,19 +63,19 @@ exports.testWrappedDOM = function(assert
 
 /*
 // We do not offer unwrapped access to DOM since bug 601295 landed
 // See 660780 to track progress of unwrap feature
 exports.testUnwrappedDOM = function(assert, done) {
   let page = Page({
     allow: { script: true },
     contentURL: "data:text/html;charset=utf-8,<script>document.getElementById=3;window.scrollTo=3;</script>",
-    contentScript: "window.addEventListener('load', function () " +
-                   "self.postMessage([typeof(unsafeWindow.document.getElementById), " +
-                   "typeof(unsafeWindow.scrollTo)]), true)",
+    contentScript: "window.addEventListener('load', function () {" +
+                   "return self.postMessage([typeof(unsafeWindow.document.getElementById), " +
+                   "typeof(unsafeWindow.scrollTo)]); }, true)",
     onMessage: function (message) {
       assert.equal(message[0],
                        "number",
                        "document inside page is free to be changed");
 
       assert.equal(message[1],
                        "number",
                        "window inside page is free to be changed");
@@ -90,17 +90,17 @@ exports.testPageProperties = function(as
   let page = new Page();
 
   for (let prop of ['contentURL', 'allow', 'contentScriptFile',
                          'contentScript', 'contentScriptWhen', 'on',
                          'postMessage', 'removeListener']) {
     assert.ok(prop in page, prop + " property is defined on page.");
   }
 
-  assert.ok(function () page.postMessage("foo") || true,
+  assert.ok(() => page.postMessage("foo") || true,
               "postMessage doesn't throw exception on page.");
 }
 
 exports.testConstructorAndDestructor = function(assert, done) {
   let loader = Loader(module);
   let { Page } = loader.require("sdk/page-worker");
   let global = loader.sandbox("sdk/page-worker");
 
@@ -146,23 +146,23 @@ exports.testAutoDestructor = function(as
       assert.ok(isDestroyed(page), "Page correctly unloaded.");
       done();
     }
   });
 }
 
 exports.testValidateOptions = function(assert) {
   assert.throws(
-    function () Page({ contentURL: 'home' }),
+    () => Page({ contentURL: 'home' }),
     /The `contentURL` option must be a valid URL\./,
     "Validation correctly denied a non-URL contentURL"
   );
 
   assert.throws(
-    function () Page({ onMessage: "This is not a function."}),
+    () => Page({ onMessage: "This is not a function."}),
     /The option "onMessage" must be one of the following types: function/,
     "Validation correctly denied a non-function onMessage."
   );
 
   assert.pass("Options validation is working.");
 }
 
 exports.testContentAndAllowGettersAndSetters = function(assert, done) {
@@ -340,17 +340,17 @@ exports.testGetActiveViewAndDestroy = fu
   assert.ok(frame.parentNode, "there is a parent node");
   page.destroy();
   assert.ok(!frame.parentNode, "there is not a parent node");
 }
 
 exports.testPingPong = function(assert, done) {
   let page = Page({
     contentURL: 'data:text/html;charset=utf-8,ping-pong',
-    contentScript: 'self.on("message", function(message) self.postMessage("pong"));'
+    contentScript: 'self.on("message", message => self.postMessage("pong"));'
       + 'self.postMessage("ready");',
     onMessage: function(message) {
       if ('ready' == message) {
         page.postMessage('ping');
       }
       else {
         assert.ok(message, 'pong', 'Callback from contentScript');
         done();
--- a/addon-sdk/source/test/test-panel.js
+++ b/addon-sdk/source/test/test-panel.js
@@ -47,17 +47,17 @@ function makeEmptyPrivateBrowserWindow(o
   });
 }
 
 exports["test Panel"] = function(assert, done) {
   const { Panel } = require('sdk/panel');
 
   let panel = Panel({
     contentURL: "about:buildconfig",
-    contentScript: "self.postMessage(1); self.on('message', function() self.postMessage(2));",
+    contentScript: "self.postMessage(1); self.on('message', () => self.postMessage(2));",
     onMessage: function (message) {
       assert.equal(this, panel, "The 'this' object is the panel.");
       switch(message) {
         case 1:
           assert.pass("The panel was loaded.");
           panel.postMessage('');
           break;
         case 2:
@@ -72,17 +72,17 @@ exports["test Panel"] = function(assert,
 
 exports["test Panel Emit"] = function(assert, done) {
   const { Panel } = require('sdk/panel');
 
   let panel = Panel({
     contentURL: "about:buildconfig",
     contentScript: "self.port.emit('loaded');" +
                    "self.port.on('addon-to-content', " +
-                   "             function() self.port.emit('received'));",
+                   "             () => self.port.emit('received'));",
   });
   panel.port.on("loaded", function () {
     assert.pass("The panel was loaded and sent a first event.");
     panel.port.emit("addon-to-content");
   });
   panel.port.on("received", function () {
     assert.pass("The panel posted a message and received a response.");
     panel.destroy();
@@ -91,17 +91,17 @@ exports["test Panel Emit"] = function(as
 };
 
 exports["test Panel Emit Early"] = function(assert, done) {
   const { Panel } = require('sdk/panel');
 
   let panel = Panel({
     contentURL: "about:buildconfig",
     contentScript: "self.port.on('addon-to-content', " +
-                   "             function() self.port.emit('received'));",
+                   "             () => self.port.emit('received'));",
   });
   panel.port.on("received", function () {
     assert.pass("The panel posted a message early and received a response.");
     panel.destroy();
     done();
   });
   panel.port.emit("addon-to-content");
 };
@@ -143,17 +143,17 @@ exports["test Document Reload"] = functi
     '}, false);' +
     "</script>";
   let messageCount = 0;
   let panel = Panel({
     // using URL here is intentional, see bug 859009
     contentURL: URL("data:text/html;charset=utf-8," + encodeURIComponent(content)),
     contentScript: "self.postMessage(window.location.href);" +
                    // initiate change to url2
-                   "self.port.once('move', function() document.defaultView.postMessage('move', '*'));",
+                   "self.port.once('move', () => document.defaultView.postMessage('move', '*'));",
     onMessage: function (message) {
       messageCount++;
       assert.notEqual(message, "about:blank", "about:blank is not a message " + messageCount);
 
       if (messageCount == 1) {
         assert.ok(/data:text\/html/.test(message), "First document had a content script; " + message);
         panel.port.emit('move');
         assert.pass('move message was sent');
@@ -528,17 +528,17 @@ function makeEventOrderTest(options) {
   }
 }
 
 exports["test Automatic Destroy"] = function(assert) {
   let loader = Loader(module);
   let panel = loader.require("sdk/panel").Panel({
     contentURL: "about:buildconfig",
     contentScript:
-      "self.port.on('event', function() self.port.emit('event-back'));"
+      "self.port.on('event', () => self.port.emit('event-back'));"
   });
 
   loader.unload();
 
   assert.throws(() => {
     panel.port.emit("event");
   }, /already have been unloaded/, "check automatic destroy");
 };
@@ -580,17 +580,17 @@ exports["test Content URL Option"] = fun
   panel = Panel({ contentURL: dataURL });
   assert.pass("contentURL accepts a data: URL.");
   panel.destroy();
 
   panel = Panel({});
   assert.ok(panel.contentURL == null, "contentURL is undefined.");
   panel.destroy();
 
-  assert.throws(function () Panel({ contentURL: "foo" }),
+  assert.throws(() => Panel({ contentURL: "foo" }),
                     /The `contentURL` option must be a valid URL./,
                     "Panel throws an exception if contentURL is not a URL.");
 };
 
 exports["test SVG Document"] = function(assert) {
   let panel = require("sdk/panel").Panel({ contentURL: SVG_URL });
 
   panel.show();
--- a/addon-sdk/source/test/test-plain-text-console.js
+++ b/addon-sdk/source/test/test-plain-text-console.js
@@ -68,17 +68,17 @@ exports.testPlainTextConsole = function(
   assert.equal(lastPrint(), "console.log: " + name + ": testing undefined\n",
                    "PlainTextConsole.log() must stringify undefined.");
 
   con.log('testing', null);
   assert.equal(lastPrint(), "console.log: " + name + ": testing null\n",
                    "PlainTextConsole.log() must stringify null.");
 
   // TODO: Fix console.jsm to detect custom toString.
-  con.log("testing", { toString: function() "obj.toString()" });
+  con.log("testing", { toString: () => "obj.toString()" });
   assert.equal(lastPrint(), "console.log: " + name + ": testing {}\n",
                    "PlainTextConsole.log() doesn't printify custom toString.");
 
   con.log("testing", { toString: function() { throw "fail!"; } });
   assert.equal(lastPrint(), "console.log: " + name + ": testing {}\n",
                    "PlainTextConsole.log() must stringify custom bad toString.");
 
   con.exception(new Error("blah"));
--- a/addon-sdk/source/test/test-rules.js
+++ b/addon-sdk/source/test/test-rules.js
@@ -36,17 +36,17 @@ exports.testRemove = function (test, don
   on(rules, 'remove', function (rule) {
     if (count < urls.length) {
       test.ok(!rules.get(rule), 'rule removed to internal registry');
       test.equal(rule, urls[count], 'remove event fired with proper params');
       if (++count < urls.length) rules.remove(urls[count]);
       else done();
     }
   });
-  urls.forEach(function (url) rules.add(url));
+  urls.forEach(url => rules.add(url));
   rules.remove(urls[0]);
 };
 
 exports.testMatchesAny = function(test) {
   let rules = Rules();
   rules.add('*.mozilla.org');
   rules.add('data:*');
   matchTest('http://mozilla.org', true);
--- a/addon-sdk/source/test/test-sandbox.js
+++ b/addon-sdk/source/test/test-sandbox.js
@@ -38,17 +38,17 @@ exports['test non-privileged'] = functio
   fixture.sandbox = sandbox;
   assert.throws(function() {
     evaluate(fixture, sandbox('http://foo.com'));
   }, 'Can not call privileged code');
 };
 
 exports['test injection'] = function(assert) {
   let fixture = sandbox();
-  fixture.hi = function(name) 'Hi ' + name
+  fixture.hi = name => 'Hi ' + name;
   assert.equal(evaluate(fixture, 'hi("sandbox");'), 'Hi sandbox',
                 'injected functions are callable');
 };
 
 exports['test exceptions'] = function(assert) {
   let fixture = sandbox();
   try {
     evaluate(fixture, '!' + function() {
@@ -95,17 +95,17 @@ exports['test load'] = function(assert) 
   let fixture = sandbox();
   load(fixture, fixturesURI + 'sandbox-normal.js');
   assert.equal(fixture.a, 1, 'global variable defined');
   assert.equal(fixture.b, 2, 'global via `this` property was set');
   assert.equal(fixture.f(), 4, 'function was defined');
 };
 
 exports['test load with data: URL'] = function(assert) {
-  let code = "var a = 1; this.b = 2; function f() 4";
+  let code = "var a = 1; this.b = 2; function f() { return 4; }";
   let fixture = sandbox();
   load(fixture, "data:," + encodeURIComponent(code));
 
   assert.equal(fixture.a, 1, 'global variable defined');
   assert.equal(fixture.b, 2, 'global via `this` property was set');
   assert.equal(fixture.f(), 4, 'function was defined');
 };
 
--- a/addon-sdk/source/test/test-simple-storage.js
+++ b/addon-sdk/source/test/test-simple-storage.js
@@ -279,17 +279,17 @@ exports.testSetNoSetRead = function (ass
   let val = "foo";
   ss.storage.foo = val;
   assert.equal(ss.storage.foo, val, "Value read should be value set");
   loader.unload();
 };
 
 
 function setGetRoot(assert, done, val, compare) {
-  compare = compare || function (a, b) a === b;
+  compare = compare || (a, b) => a === b;
 
   // Load the module once, set a value.
   let loader = Loader(module);
   let ss = loader.require("sdk/simple-storage");
   manager(loader).jsonStore.onWrite = function () {
     assert.ok(file.exists(storeFilename), "Store file should exist");
 
     // Load the module again and make sure the value stuck.
@@ -307,14 +307,14 @@ function setGetRoot(assert, done, val, c
   loader.unload();
 }
 
 function setGetRootError(assert, done, val, msg) {
   let pred = new RegExp("storage must be one of the following types: " +
              "array, boolean, null, number, object, string");
   let loader = Loader(module);
   let ss = loader.require("sdk/simple-storage");
-  assert.throws(function () ss.storage = val, pred, msg);
+  assert.throws(() => ss.storage = val, pred, msg);
   done();
   loader.unload();
 }
 
 require('sdk/test').run(exports);
--- a/addon-sdk/source/test/test-tabs-common.js
+++ b/addon-sdk/source/test/test-tabs-common.js
@@ -204,17 +204,17 @@ exports.testAttachOnMultipleDocuments_al
 
   tabs.open({
     url: firstLocation,
     onReady: function (tab) {
       onReadyCount++;
       if (onReadyCount == 1) {
         worker1 = tab.attach({
           contentScript: 'self.on("message", ' +
-                         '  function () self.postMessage(document.location.href)' +
+                         '  () => self.postMessage(document.location.href)' +
                          ');',
           onMessage: function (msg) {
             assert.equal(msg, firstLocation,
                              "Worker url is equal to the 1st document");
             tab.url = secondLocation;
           },
           onDetach: function () {
             detachEventCount++;
@@ -227,17 +227,17 @@ exports.testAttachOnMultipleDocuments_al
             checkEnd();
           }
         });
         worker1.postMessage("new-doc-1");
       }
       else if (onReadyCount == 2) {
         worker2 = tab.attach({
           contentScript: 'self.on("message", ' +
-                         '  function () self.postMessage(document.location.href)' +
+                         '  () => self.postMessage(document.location.href)' +
                          ');',
           onMessage: function (msg) {
             assert.equal(msg, secondLocation,
                              "Worker url is equal to the 2nd document");
             tab.url = thirdLocation;
           },
           onDetach: function () {
             detachEventCount++;
@@ -283,17 +283,17 @@ exports.testAttachWrappers_alt = functio
                        '  self.postMessage(!("globalJSVar" in window));' +
                        '  self.postMessage(typeof window.globalJSVar == "undefined");' +
                        '} catch(e) {' +
                        '  self.postMessage(e.message);' +
                        '}',
         onMessage: function (msg) {
           assert.equal(msg, true, "Worker has wrapped objects ("+count+")");
           if (count++ == 1)
-            tab.close(function() done());
+            tab.close(() => done());
         }
       });
     }
   });
 };
 
 // TEST: activeWindow getter and activeTab getter on tab 'activate' event
 exports.testActiveWindowActiveTabOnActivate_alt = function(assert, done) {
@@ -320,21 +320,21 @@ exports.testActiveWindowActiveTabOnActiv
     }
     else if (activateCount > 2) {
       assert.fail("activateCount is greater than 2 for some reason..");
     }
   });
 
   tabs.open({
     url: URL.replace("#title#", "tabs.open1"),
-    onOpen: function(tab) newTabs.push(tab)
+    onOpen: tab => newTabs.push(tab)
   });
   tabs.open({
     url: URL.replace("#title#", "tabs.open2"),
-    onOpen: function(tab) newTabs.push(tab)
+    onOpen: tab => newTabs.push(tab)
   });
 };
 
 // TEST: tab properties
 exports.testTabContentTypeAndReload = function(assert, done) {
 
   let url = "data:text/html;charset=utf-8,<html><head><title>foo</title></head><body>foo</body></html>";
   let urlXML = "data:text/xml;charset=utf-8,<foo>bar</foo>";
@@ -449,17 +449,17 @@ exports.testTabReload = function(assert,
       tab.removeListener('ready', onReady);
 
       tab.once(
         'ready',
         function onReload() {
           assert.pass("the tab was loaded again");
           assert.equal(tab.url, url, "the tab has the same URL");
 
-          tab.close(function() done());
+          tab.close(() => done());
         }
       );
 
       tab.reload();
     }
   });
 };
 
@@ -493,18 +493,22 @@ exports.testOnPageShowEvent = function (
             'pageshow', 'pageshow'].map((type, i) => {
           assert.equal(type, events[i], 'correct ordering of events');
         });
         done()
       });
     }
   }
 
-  function onOpen () events.push('open');
-  function onReady () events.push('ready');
+  function onOpen () {
+    return events.push('open');
+  }
+  function onReady () {
+    return events.push('ready');
+  }
 
   tabs.on('pageshow', onPageShow);
   tabs.on('open', onOpen);
   tabs.on('ready', onReady);
   tabs.open({
     url: firstUrl
   });
 };
@@ -539,18 +543,22 @@ exports.testOnPageShowEventDeclarative =
             'pageshow', 'pageshow'].map((type, i) => {
           assert.equal(type, events[i], 'correct ordering of events');
         });
         done()
       });
     }
   }
 
-  function onOpen () events.push('open');
-  function onReady () events.push('ready');
+  function onOpen () {
+    return events.push('open');
+  }
+  function onReady () {
+    return events.push('ready');
+  }
 
   tabs.open({
     url: firstUrl,
     onPageShow: onPageShow,
     onOpen: onOpen,
     onReady: onReady
   });
 };
--- a/addon-sdk/source/test/test-text-streams.js
+++ b/addon-sdk/source/test/test-text-streams.js
@@ -16,36 +16,36 @@ exports.testWriteRead = function (assert
 
   // Write a small string less than the stream's buffer size...
   let str = "exports.testWriteRead data!";
   let stream = file.open(fname, "w");
   assert.ok(!stream.closed, "stream.closed after open should be false");
   stream.write(str);
   stream.close();
   assert.ok(stream.closed, "stream.closed after close should be true");
-  assert.throws(function () stream.close(),
+  assert.throws(() => stream.close(),
                     STREAM_CLOSED_ERROR,
                     "stream.close after already closed should raise error");
-  assert.throws(function () stream.write("This shouldn't be written!"),
+  assert.throws(() => stream.write("This shouldn't be written!"),
                     STREAM_CLOSED_ERROR,
                     "stream.write after close should raise error");
 
   // ... and read it.
   stream = file.open(fname);
   assert.ok(!stream.closed, "stream.closed after open should be false");
   assert.equal(stream.read(), str,
                    "stream.read should return string written");
   assert.equal(stream.read(), "",
                    "stream.read at EOS should return empty string");
   stream.close();
   assert.ok(stream.closed, "stream.closed after close should be true");
-  assert.throws(function () stream.close(),
+  assert.throws(() => stream.close(),
                     STREAM_CLOSED_ERROR,
                     "stream.close after already closed should raise error");
-  assert.throws(function () stream.read(),
+  assert.throws(() => stream.read(),
                     STREAM_CLOSED_ERROR,
                     "stream.read after close should raise error");
 
   // Write a big string many times the size of the stream's buffer and read it.
   // Since it comes after the previous test, this also ensures that the file is
   // truncated when it's opened for writing.
   str = "";
   let bufLen = BUFFER_BYTE_LEN;
@@ -111,20 +111,20 @@ exports.testWriteAsync = function (asser
   assert.ok(!stream.closed, "stream.closed after open should be false");
 
   // Write.
   stream.writeAsync(str, function (err) {
     assert.equal(this, stream, "|this| should be the stream object");
     assert.equal(err, undefined,
                      "stream.writeAsync should not cause error");
     assert.ok(stream.closed, "stream.closed after write should be true");
-    assert.throws(function () stream.close(),
+    assert.throws(() => stream.close(),
                       STREAM_CLOSED_ERROR,
                       "stream.close after already closed should raise error");
-    assert.throws(function () stream.writeAsync("This shouldn't work!"),
+    assert.throws(() => stream.writeAsync("This shouldn't work!"),
                       STREAM_CLOSED_ERROR,
                       "stream.writeAsync after close should raise error");
 
     // Read.
     stream = file.open(fname, "r");
     assert.ok(!stream.closed, "stream.closed after open should be false");
     let readStr = stream.read();
     assert.equal(readStr, str,
--- a/addon-sdk/source/test/test-unit-test.js
+++ b/addon-sdk/source/test/test-unit-test.js
@@ -42,18 +42,18 @@ exports.testATeardownAsyncTestPart1 = fu
 
 exports.testATeardownAsyncTestPart2 = function(test) {
     test.assertEqual(true, teardownCalled, "teardown called after done");
 };
 
 exports.testWaitUntilInstant = function(test) {
   test.waitUntilDone();
 
-  test.waitUntil(function () true, "waitUntil with instant true pass")
-      .then(function () test.done());
+  test.waitUntil(() => true, "waitUntil with instant true pass")
+      .then(() => test.done());
 }
 
 exports.testWaitUntil = function(test) {
   test.waitUntilDone();
   let succeed = false;
 
   test.waitUntil(_ => succeed, "waitUntil pass")
       .then(test.done);
@@ -162,17 +162,17 @@ exports.testWaitUntilTimeoutInCallback =
     }
   });
 
   runner.start({
     test: {
       name: "wait4ever",
       testFunction: function(test) {
         test.waitUntilDone(100);
-        test.waitUntil(function() false);
+        test.waitUntil(() => false);
       }
     },
     onDone: function() {}
   });
 };
 
 exports.testExpectFail = function(test) {
     test.expectFail(function() {
--- a/addon-sdk/source/test/test-url.js
+++ b/addon-sdk/source/test/test-url.js
@@ -170,35 +170,35 @@ exports.testFromFilename = function(asse
   var fileUrl = fromFilename(profileDirName);
   assert.equal(URL(fileUrl).scheme, 'file',
                    'toFilename() should return a file: url');
   assert.equal(fromFilename(toFilename(fileUrl)), fileUrl);
 };
 
 exports.testURL = function(assert) {
   assert.ok(URL('h:foo') instanceof URL, 'instance is of correct type');
-  assert.throws(function() URL(),
+  assert.throws(() => URL(),
                     /malformed URI: undefined/i,
                     'url.URL should throw on undefined');
-  assert.throws(function() URL(''),
+  assert.throws(() => URL(''),
                     /malformed URI: /i,
                     'url.URL should throw on empty string');
-  assert.throws(function() URL('foo'),
+  assert.throws(() => URL('foo'),
                     /malformed URI: foo/i,
                     'url.URL should throw on invalid URI');
   assert.ok(URL('h:foo').scheme, 'has scheme');
   assert.equal(URL('h:foo').toString(),
                    'h:foo',
                    'toString should roundtrip');
   // test relative + base
   assert.equal(URL('mypath', 'http://foo').toString(),
                    'http://foo/mypath',
                    'relative URL resolved to base');
   // test relative + no base
-  assert.throws(function() URL('path').toString(),
+  assert.throws(() => URL('path').toString(),
                     /malformed URI: path/i,
                     'no base for relative URI should throw');
 
   let a = URL('h:foo');
   let b = URL(a);
   assert.equal(b.toString(),
                    'h:foo',
                    'a URL can be initialized from another URL');
@@ -338,17 +338,17 @@ exports.testWindowLocationMatch = functi
     url: aUrl,
     onReady: function (tab) {
       tab.attach({
         onMessage: function (loc) {
           for (let prop in loc) {
             assert.equal(urlObject[prop], loc[prop], prop + ' matches');
           }
 
-          tab.close(function() server.stop(done));
+          tab.close(() => server.stop(done));
         },
         contentScript: '(' + function () {
           let res = {};
           // `origin` is `null` in this context???
           let props = 'hostname,port,pathname,hash,href,protocol,search'.split(',');
           props.forEach(function (prop) {
             res[prop] = window.location[prop];
           });
--- a/addon-sdk/source/test/test-window-utils.js
+++ b/addon-sdk/source/test/test-window-utils.js
@@ -169,17 +169,17 @@ exports['test window watcher without unt
     }
   });
 
   myWindow = makeEmptyWindow();
 };
 
 exports['test active window'] = function(assert, done) {
   let browserWindow = WM.getMostRecentWindow("navigator:browser");
-  let continueAfterFocus = function(window) onFocus(window).then(nextTest);
+  let continueAfterFocus = window => onFocus(window).then(nextTest);
 
   assert.equal(windowUtils.activeBrowserWindow, browserWindow,
                "Browser window is the active browser window.");
 
 
   let testSteps = [
     function() {
       continueAfterFocus(windowUtils.activeWindow = browserWindow);
--- a/addon-sdk/source/test/test-xpcom.js
+++ b/addon-sdk/source/test/test-xpcom.js
@@ -52,29 +52,33 @@ exports['test implement xpcom interfaces
                'derived component implements supers interface');
   assert.equal(observer.QueryInterface(Ci.nsIObserver),
                observer.QueryInterface(Ci.nsIRequestObserver),
                'derived component implements specified interfaces');
 };
 
 exports['test implement factory without contract'] = function(assert) {
   let actual = xpcom.Factory({
-    get wrappedJSObject() this,
+    get wrappedJSObject() {
+      return this;
+    },
   });
 
   assert.ok(isCIDRegistered(actual.id), 'factory is regiseterd');
   xpcom.unregister(actual);
   assert.ok(!isCIDRegistered(actual.id), 'factory is unregistered');
 };
 
 exports['test implement xpcom factory'] = function(assert) {
   let Component = Class({
     extends: xpcom.Unknown,
     interfaces: [ 'nsIObserver' ],
-    get wrappedJSObject() this,
+    get wrappedJSObject() {
+      return this;
+    },
     observe: function() {}
   });
 
   let factory = xpcom.Factory({
     register: false,
     contract: '@jetpack/test/factory;1',
     Component: Component
   });
@@ -95,17 +99,19 @@ exports['test implement xpcom factory'] 
 
 exports['test implement xpcom service'] = function(assert) {
   let actual = xpcom.Service({
     contract: '@jetpack/test/service;1',
     register: false,
     Component: Class({
       extends: xpcom.Unknown,
       interfaces: [ 'nsIObserver'],
-      get wrappedJSObject() this,
+      get wrappedJSObject() {
+        return this;
+      },
       observe: function() {},
       name: 'my-service'
     })
   });
 
   assert.ok(!isCIDRegistered(actual.id), 'component is not registered');
   xpcom.register(actual);
   assert.ok(isCIDRegistered(actual.id), 'service is regiseterd');
@@ -122,17 +128,19 @@ exports['test implement xpcom service'] 
 function testRegister(assert, text) {
 
   const service = xpcom.Service({
     description: 'test about:boop page',
     contract: '@mozilla.org/network/protocol/about;1?what=boop',
     register: false,
     Component: Class({
       extends: xpcom.Unknown,
-      get wrappedJSObject() this,
+      get wrappedJSObject() {
+        return this;
+      },
       interfaces: [ 'nsIAboutModule' ],
       newChannel : function(aURI, aLoadInfo) {
         var ios = Cc["@mozilla.org/network/io-service;1"].
                   getService(Ci.nsIIOService);
 
         var uri = ios.newURI("data:text/plain;charset=utf-8," + text,
                              null, null);
         var channel = ios.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
--- a/b2g/locales/en-US/chrome/overrides/appstrings.properties
+++ b/b2g/locales/en-US/chrome/overrides/appstrings.properties
@@ -31,8 +31,9 @@ externalProtocolChkMsg=Remember my choic
 externalProtocolLaunchBtn=Launch application
 malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
 unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences.
 phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.
 cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
 corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected.
 remoteXUL=This page uses an unsupported technology that is no longer available by default in Firefox.
 sslv3Used=Firefox cannot guarantee the safety of your data on %S because it uses SSLv3, a broken security protocol.
+weakCryptoUsed=The owner of %S has configured their website improperly. To protect your information from being stolen, Firefox has not connected to this website.
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -726,22 +726,16 @@
               </prefs>
     </emItem>
       <emItem  blockID="i107" os="WINNT" id="{ABDE892B-13A8-4d1b-88E6-365A6E755758}">
                         <versionRange  minVersion="0" maxVersion="15.0.5" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i890" id="551f2920-3c19-11e1-b86c-0800200c9a66@jetpack">
-                        <versionRange  minVersion="2.3" maxVersion="*" severity="3">
-                    </versionRange>
-                    <prefs>
-              </prefs>
-    </emItem>
       <emItem  blockID="i688" id="firefox-extension@mozilla.org">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i162" id="{EB7508CA-C7B2-46E0-8C04-3E94A035BD49}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -64,16 +64,19 @@ pref("extensions.blocklist.itemURL", "ht
 
 pref("extensions.update.autoUpdateDefault", true);
 
 pref("extensions.hotfix.id", "firefox-hotfix@mozilla.org");
 pref("extensions.hotfix.cert.checkAttributes", true);
 pref("extensions.hotfix.certs.1.sha1Fingerprint", "91:53:98:0C:C1:86:DF:47:8F:35:22:9E:11:C9:A7:31:04:49:A1:AA");
 pref("extensions.hotfix.certs.2.sha1Fingerprint", "39:E7:2B:7A:5B:CF:37:78:F9:5D:4A:E0:53:2D:2F:3D:68:53:C5:60");
 
+// Check AUS for system add-on updates.
+pref("extensions.systemAddon.update.url", "https://aus5.mozilla.org/update/3/SystemAddons/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/update.xml");
+
 // Disable add-ons that are not installed by the user in all scopes by default.
 // See the SCOPE constants in AddonManager.jsm for values to use here.
 pref("extensions.autoDisableScopes", 15);
 
 // Require signed add-ons by default
 pref("xpinstall.signatures.required", true);
 pref("xpinstall.signatures.devInfoURL", "https://wiki.mozilla.org/Addons/Extension_Signing");
 
@@ -1406,18 +1409,16 @@ pref("loop.CSP", "default-src 'self' abo
 #else
 pref("loop.CSP", "default-src 'self' about: file: chrome:; img-src * data:; font-src 'none'; connect-src wss://*.tokbox.com https://*.opentok.com https://*.tokbox.com wss://*.mozilla.com https://*.mozilla.org wss://*.mozaws.net; media-src blob:");
 #endif
 pref("loop.oauth.google.redirect_uri", "urn:ietf:wg:oauth:2.0:oob:auto");
 pref("loop.oauth.google.scope", "https://www.google.com/m8/feeds");
 pref("loop.fxa_oauth.tokendata", "");
 pref("loop.fxa_oauth.profile", "");
 pref("loop.support_url", "https://support.mozilla.org/kb/group-conversations-firefox-hello-webrtc");
-pref("loop.contacts.gravatars.show", false);
-pref("loop.contacts.gravatars.promo", true);
 pref("loop.browserSharing.showInfoBar", true);
 
 pref("social.sidebar.unload_timeout_ms", 10000);
 
 // Activation from inside of share panel is possible if activationPanelEnabled
 // is true. Pref'd off for release while usage testing is done through beta.
 pref("social.share.activationPanelEnabled", true);
 pref("social.shareDirectory", "https://activations.cdn.mozilla.net/sharePanel.html");
@@ -1622,24 +1623,24 @@ pref("browser.pocket.enabled", true);
 pref("browser.pocket.api", "api.getpocket.com");
 pref("browser.pocket.site", "getpocket.com");
 pref("browser.pocket.oAuthConsumerKey", "40249-e88c401e1b1f2242d9e441c4");
 pref("browser.pocket.useLocaleList", true);
 pref("browser.pocket.enabledLocales", "cs de en-GB en-US en-ZA es-ES es-MX fr hu it ja ja-JP-mac ko nl pl pt-BR pt-PT ru zh-CN zh-TW");
 
 pref("view_source.tab", true);
 
+#ifndef RELEASE_BUILD
 // Enable ServiceWorkers for Push API consumers.
 // Interception is still disabled on beta and release.
 pref("dom.serviceWorkers.enabled", true);
 
-#ifndef RELEASE_BUILD
 pref("dom.serviceWorkers.interception.enabled", true);
-#endif
 
 // 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);
--- a/browser/base/content/aboutNetError.xhtml
+++ b/browser/base/content/aboutNetError.xhtml
@@ -86,16 +86,22 @@
         } catch (e) {
           // We probably tried to reload a URI that caused an exception to
           // occur;  e.g. a nonexistent file.
         }
 
         buttonEl.disabled = true;
       }
 
+      function doOverride(buttonEl) {
+        var event = new CustomEvent("AboutNetErrorOverride", {bubbles:true});
+        document.dispatchEvent(event);
+        retryThis(buttonEl);
+      }
+
       function toggleDisplay(node) {
         toggle = {
           '': 'block',
           'none': 'block',
           'block': 'none'
         };
         node.style.display = toggle[node.style.display];
       }
@@ -116,16 +122,33 @@
           if (panel.style.display == "block") {
             // send event to trigger telemetry ping
             var event = new CustomEvent("AboutNetErrorUIExpanded", {bubbles:true});
             document.dispatchEvent(event);
           }
         });
       }
 
+      function showWeakCryptoAdvanced() {
+        // Display weak crypto advanced UI
+        document.getElementById("weakCryptoAdvanced").style.display = "block";
+
+        // Get the hostname and add it to the panel
+        var panel = document.getElementById("weakCryptoAdvancedPanel");
+        for (var span of panel.querySelectorAll("span.hostname")) {
+          span.textContent = document.location.hostname;
+        }
+
+        // Register click handler for the weakCryptoAdvancedPanel
+        document.getElementById("showWeakCryptoAdvancedPanel")
+                .addEventListener("click", () => toggleDisplay(panel));
+
+        var overrideLink = document.getElementById("overrideWeakCrypto");
+        overrideLink.addEventListener("click", () => doOverride(overrideLink), false);
+      }
 
       function sendErrorReport() {
         var event = new CustomEvent("AboutNetErrorSendReport", {bubbles:true});
 
         document.dispatchEvent(event);
       }
 
       function initPage()
@@ -167,16 +190,26 @@
 
           document.getElementById("errorTitle").setAttribute("sslv3", "true");
 
           var retryBtn = document.getElementById("errorTryAgain");
           retryBtn.textContent = learnMoreText.textContent;
           retryBtn.setAttribute("onclick", "learnMoreSSLV3()");
         }
 
+        if (err == "weakCryptoUsed") {
+          var learnMoreText = document.getElementById("learn_more_weak_crypto");
+
+          document.getElementById("errorTitle").setAttribute("weakCrypto", "true");
+
+          var retryBtn = document.getElementById("errorTryAgain");
+          retryBtn.textContent = learnMoreText.textContent;
+          retryBtn.setAttribute("onclick", "learnMoreWeakCrypto()");
+        }
+
         // remove undisplayed errors to avoid bug 39098
         var errContainer = document.getElementById("errorContainer");
         errContainer.parentNode.removeChild(errContainer);
 
         var className = getCSSClass();
         if (className && className != "expertBadCert") {
           // Associate a CSS class with the root of the page, if one was passed in,
           // to allow custom styling.
@@ -235,16 +268,19 @@
 
               var reportBtn = document.getElementById('reportCertificateError');
               var retryBtn = document.getElementById('reportCertificateErrorRetry');
 
               reportBtn.addEventListener('click', sendErrorReport, false);
               retryBtn.addEventListener('click', sendErrorReport, false);
             }
           }
+          if (getErrorCode() == "weakCryptoUsed") {
+            showWeakCryptoAdvanced();
+          }
         }.bind(this), true, true);
 
         var event = new CustomEvent("AboutNetErrorLoad", {bubbles:true});
         document.dispatchEvent(event);
 
         if (err == "nssBadCert") {
           // Remove the "Try again" button for security exceptions, since it's
           // almost certainly useless.
@@ -346,16 +382,22 @@
         return haystack.slice(-needle.length) == needle;
       }
 
       function learnMoreSSLV3() {
         location.href = "https://support.mozilla.org/kb/how-resolve-sslv3-error-messages-firefox";
         // Ensure users don't re-click the button:
         e.target.disabled = true;
       }
+
+      function learnMoreWeakCrypto() {
+        location.href = "https://support.mozilla.org/kb/how-resolve-weak-crypto-error-messages-firefox";
+        // Ensure users don't re-click the button:
+        e.target.disabled = true;
+      }
     ]]></script>
   </head>
 
   <body dir="&locale.dir;">
 
     <!-- ERROR ITEM CONTAINER (removed during loading to avoid bug 39098) -->
     <div id="errorContainer">
       <div id="errorTitlesContainer">
@@ -380,16 +422,17 @@
         <h1 id="et_nssFailure2">&nssFailure2.title;</h1>
         <h1 id="et_nssBadCert">&nssBadCert.title;</h1>
         <h1 id="et_malwareBlocked">&malwareBlocked.title;</h1>
         <h1 id="et_unwantedBlocked">&unwantedBlocked.title;</h1>
         <h1 id="et_cspBlocked">&cspBlocked.title;</h1>
         <h1 id="et_remoteXUL">&remoteXUL.title;</h1>
         <h1 id="et_corruptedContentError">&corruptedContentError.title;</h1>
         <h1 id="et_sslv3Used">&sslv3Used.title;</h1>
+        <h1 id="et_weakCryptoUsed">&weakCryptoUsed.title;</h1>
       </div>
       <div id="errorDescriptionsContainer">
         <div id="ed_generic">&generic.longDesc;</div>
         <div id="ed_dnsNotFound">&dnsNotFound.longDesc;</div>
         <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
         <div id="ed_malformedURI">&malformedURI.longDesc;</div>
         <div id="ed_unknownProtocolFound">&unknownProtocolFound.longDesc;</div>
         <div id="ed_connectionFailure">&connectionFailure.longDesc;</div>
@@ -409,16 +452,18 @@
         <div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
         <div id="ed_malwareBlocked">&malwareBlocked.longDesc;</div>
         <div id="ed_unwantedBlocked">&unwantedBlocked.longDesc;</div>
         <div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
         <div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
         <div id="ed_corruptedContentError">&corruptedContentError.longDesc;</div>
         <div id="ed_sslv3Used">&sslv3Used.longDesc;</div>
         <div id="learn_more_ssl3">&sslv3Used.learnMore;</div>
+        <div id="ed_weakCryptoUsed">&weakCryptoUsed.longDesc;</div>
+        <div id="learn_more_weak_crypto">&weakCryptoUsed.learnMore;</div>
       </div>
     </div>
 
     <!-- PAGE CONTAINER (for styling purposes only) -->
     <div id="errorPageContainer">
 
       <!-- Error Title -->
       <div id="errorTitle">
@@ -483,16 +528,31 @@
             <button id="reportCertificateError">&errorReporting.report;</button>
             <button id="reportCertificateErrorRetry">&errorReporting.tryAgain;</button>
             <span id="reportSendingMessage">&errorReporting.sending;</span>
             <span id="reportSentMessage">&errorReporting.sent;</span>
           </span>
         </div>
       </div>
 
+      <!-- UI for option to override weak crypto errors. Removed on
+           init for other error types .-->
+      <div id="weakCryptoAdvanced">
+        <a id="showWeakCryptoAdvancedPanel" href="#">&weakCryptoAdvanced.title;<span class="downArrow"> &#x25bc;</span></a>
+      </div>
+
+      <div id="weakCryptoAdvancedPanel">
+        <div id="weakCryptoAdvancedDescription">
+          <p>&weakCryptoAdvanced.longDesc;</p>
+        </div>
+        <div id="overrideWeakCryptoPanel">
+          <a id="overrideWeakCrypto" href="#">&weakCryptoAdvanced.override;</a>
+        </div>
+      </div>
+
     </div>
 
     <!--
     - Note: It is important to run the script this way, instead of using
     - an onload handler. This is because error pages are loaded as
     - LOAD_BACKGROUND, which means that onload handlers will not be executed.
     -->
     <script type="application/javascript">initPage();</script>
--- a/browser/base/content/browser-loop.js
+++ b/browser/base/content/browser-loop.js
@@ -271,28 +271,58 @@ var LoopUI;
      *                   successfully. This is used so the state can be
      *                   temporarily shown until the next state change.
      */
     updateToolbarState: function(aReason = null) {
       if (!this.toolbarButton.node) {
         return;
       }
       let state = "";
+      let mozL10nId = "loop-call-button3";
+      let suffix = ".tooltiptext";
       if (this.MozLoopService.errors.size) {
         state = "error";
+        mozL10nId += "-error";
       } else if (this.MozLoopService.screenShareActive) {
         state = "action";
+        mozL10nId += "-screensharing";
       } else if (aReason == "login" && this.MozLoopService.userProfile) {
         state = "active";
+        mozL10nId += "-active";
       } else if (this.MozLoopService.doNotDisturb) {
         state = "disabled";
+        mozL10nId += "-donotdisturb";
       } else if (this.MozLoopService.roomsParticipantsCount > 0) {
         state = "active";
+        this.roomsWithNonOwners().then(roomsWithNonOwners => {
+          if (roomsWithNonOwners.length > 0) {
+            mozL10nId += "-participantswaiting";
+          } else {
+            mozL10nId += "-active";
+          }
+
+          this.updateTooltiptext(mozL10nId + suffix);
+          this.toolbarButton.node.setAttribute("state", state);
+        });
+        return;
       }
       this.toolbarButton.node.setAttribute("state", state);
+      this.updateTooltiptext(mozL10nId + suffix);
+    },
+
+    /**
+     * Updates the tootltiptext to reflect Loop status.
+     *
+     * @param {string} [mozL10nId] l10n ID that refelct the current
+     *                           Loop status.
+     */
+    updateTooltiptext: function(mozL10nId) {
+      this.toolbarButton.node.setAttribute("tooltiptext", mozL10nId);
+      var tooltiptext = CustomizableUI.getLocalizedProperty(this.toolbarButton, "tooltiptext");
+      this.toolbarButton.node.setAttribute("tooltiptext", tooltiptext);
     },
 
     /**
      * Show a desktop notification when 'do not disturb' isn't enabled.
      *
      * @param {Object} options Set of options that may tweak the appearance and
      *                         behavior of the notification.
      *                         Option params:
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2743,26 +2743,28 @@ var BrowserOnClick = {
   init: function () {
     let mm = window.messageManager;
     mm.addMessageListener("Browser:CertExceptionError", this);
     mm.addMessageListener("Browser:SiteBlockedError", this);
     mm.addMessageListener("Browser:EnableOnlineMode", this);
     mm.addMessageListener("Browser:SendSSLErrorReport", this);
     mm.addMessageListener("Browser:SetSSLErrorReportAuto", this);
     mm.addMessageListener("Browser:SSLErrorReportTelemetry", this);
+    mm.addMessageListener("Browser:OverrideWeakCrypto", this);
   },
 
   uninit: function () {
     let mm = window.messageManager;
     mm.removeMessageListener("Browser:CertExceptionError", this);
     mm.removeMessageListener("Browser:SiteBlockedError", this);
     mm.removeMessageListener("Browser:EnableOnlineMode", this);
     mm.removeMessageListener("Browser:SendSSLErrorReport", this);
     mm.removeMessageListener("Browser:SetSSLErrorReportAuto", this);
     mm.removeMessageListener("Browser:SSLErrorReportTelemetry", this);
+    mm.removeMessageListener("Browser:OverrideWeakCrypto", this);
   },
 
   handleEvent: function (event) {
     if (!event.isTrusted || // Don't trust synthetic events
         event.button == 2) {
       return;
     }
 
@@ -2810,16 +2812,24 @@ var BrowserOnClick = {
         }
         Services.telemetry.getHistogramById("TLS_ERROR_REPORT_UI").add(bin);
       break;
       case "Browser:SSLErrorReportTelemetry":
         let reportStatus = msg.data.reportStatus;
         Services.telemetry.getHistogramById("TLS_ERROR_REPORT_UI")
           .add(reportStatus);
       break;
+      case "Browser:OverrideWeakCrypto":
+        let weakCryptoOverride = Cc["@mozilla.org/security/weakcryptooverride;1"]
+                                   .getService(Ci.nsIWeakCryptoOverride);
+        weakCryptoOverride.addWeakCryptoOverride(
+          msg.data.location.hostname,
+          PrivateBrowsingUtils.isBrowserPrivate(gBrowser.selectedBrowser),
+          true /* temporary */);
+      break;
     }
   },
 
   onSSLErrorReport: function(browser, elementId, documentURI, location, securityInfo) {
     function showReportStatus(reportStatus) {
       gBrowser.selectedBrowser
           .messageManager
           .sendAsyncMessage("Browser:SSLErrorReportStatus",
@@ -7016,16 +7026,17 @@ var gIdentityHandler = {
    *
    * @param state
    *        Bitmask provided by nsIWebProgressListener.onSecurityChange.
    * @param uri
    *        nsIURI for which the identity UI should be displayed, already
    *        processed by nsIURIFixup.createExposableURI.
    */
   updateIdentity(state, uri) {
+    let shouldHidePopup = this._uri && (this._uri.spec != uri.spec);
     this._state = state;
     this._uri = uri;
 
     // Firstly, populate the state properties required to display the UI. See
     // the documentation of the individual properties for details.
 
     try {
       this._uri.host;
@@ -7040,25 +7051,29 @@ var gIdentityHandler = {
     this._sslStatus = gBrowser.securityUI
                               .QueryInterface(Ci.nsISSLStatusProvider)
                               .SSLStatus;
     if (this._sslStatus) {
       this._sslStatus.QueryInterface(Ci.nsISSLStatus);
     }
 
     // Then, update the user interface with the available data.
-
     if (this._identityBox) {
       this.refreshIdentityBlock();
     }
+    // Handle a location change while the Control Center is focused
+    // by closing the popup (bug 1207542)
+    if (shouldHidePopup) {
+      this._identityPopup.hidePopup();
+    }
 
     // NOTE: We do NOT update the identity popup (the control center) when
-    // we receive a new security state. If the user opened the popup and looks
-    // at the provided information we don't want to suddenly change the panel
-    // contents.
+    // we receive a new security state on the existing page (i.e. from a
+    // subframe). If the user opened the popup and looks at the provided
+    // information we don't want to suddenly change the panel contents.
   },
 
   /**
    * Attempt to provide proper IDN treatment for host names
    */
   getEffectiveHost: function() {
     if (!this._IDNService)
       this._IDNService = Cc["@mozilla.org/network/idn-service;1"]
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -208,16 +208,17 @@ const TLS_ERROR_REPORT_TELEMETRY_SUCCESS
 const TLS_ERROR_REPORT_TELEMETRY_FAILURE  = 7;
 
 var AboutNetErrorListener = {
   init: function(chromeGlobal) {
     chromeGlobal.addEventListener('AboutNetErrorLoad', this, false, true);
     chromeGlobal.addEventListener('AboutNetErrorSetAutomatic', this, false, true);
     chromeGlobal.addEventListener('AboutNetErrorSendReport', this, false, true);
     chromeGlobal.addEventListener('AboutNetErrorUIExpanded', this, false, true);
+    chromeGlobal.addEventListener('AboutNetErrorOverride', this, false, true);
   },
 
   get isAboutNetError() {
     return content.document.documentURI.startsWith("about:neterror");
   },
 
   handleEvent: function(aEvent) {
     if (!this.isAboutNetError) {
@@ -233,16 +234,19 @@ var AboutNetErrorListener = {
       break;
     case "AboutNetErrorSendReport":
       this.onSendReport(aEvent);
       break;
     case "AboutNetErrorUIExpanded":
       sendAsyncMessage("Browser:SSLErrorReportTelemetry",
                        {reportStatus: TLS_ERROR_REPORT_TELEMETRY_EXPANDED});
       break;
+    case "AboutNetErrorOverride":
+      this.onOverride(aEvent);
+      break;
     }
   },
 
   onPageLoad: function(evt) {
     let automatic = Services.prefs.getBoolPref("security.ssl.errorReporting.automatic");
     content.dispatchEvent(new content.CustomEvent("AboutNetErrorOptions", {
             detail: JSON.stringify({
               enabled: Services.prefs.getBoolPref("security.ssl.errorReporting.enabled"),
@@ -325,16 +329,26 @@ var AboutNetErrorListener = {
     let serializedSecurityInfo = serhelper.serializeToString(serializable);
 
     sendAsyncMessage("Browser:SendSSLErrorReport", {
         elementId: evt.target.id,
         documentURI: contentDoc.documentURI,
         location: {hostname: contentDoc.location.hostname, port: contentDoc.location.port},
         securityInfo: serializedSecurityInfo
       });
+  },
+
+  onOverride: function(evt) {
+    let contentDoc = content.document;
+    let location = contentDoc.location;
+
+    sendAsyncMessage("Browser:OverrideWeakCrypto", {
+      documentURI: contentDoc.documentURI,
+      location: {hostname: location.hostname, port: location.port}
+    });
   }
 }
 
 AboutNetErrorListener.init(this);
 
 
 var ClickEventHandler = {
   init: function init() {
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1574,16 +1574,21 @@
 
               // Register the new outerWindowID.
               this._outerWindowIDBrowserMap.set(aBrowser.outerWindowID, aBrowser);
             }
 
             if (wasActive)
               aBrowser.focus();
 
+            // If the findbar has been initialised, reset its browser reference.
+            if (this.isFindBarInitialized(tab)) {
+              this.getFindBar(tab).browser = aBrowser;
+            }
+
             let evt = document.createEvent("Events");
             evt.initEvent("TabRemotenessChange", true, false);
             tab.dispatchEvent(evt);
 
             return true;
           ]]>
         </body>
       </method>
--- a/browser/base/content/test/general/browser_identity_UI.js
+++ b/browser/base/content/test/general/browser_identity_UI.js
@@ -1,19 +1,20 @@
 /* Tests for correct behaviour of getEffectiveHost on identity handler */
+
 function test() {
   waitForExplicitFinish();
   requestLongerTimeout(2);
 
   ok(gIdentityHandler, "gIdentityHandler should exist");
 
-  gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.selectedBrowser.addEventListener("load", checkResult, true);
-
-  nextTest();
+  BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", true).then(() => {
+    gBrowser.selectedBrowser.addEventListener("load", checkResult, true);
+    nextTest();
+  });
 }
 
 // Greek IDN for 'example.test'.
 var idnDomain = "\u03C0\u03B1\u03C1\u03AC\u03B4\u03B5\u03B9\u03B3\u03BC\u03B1.\u03B4\u03BF\u03BA\u03B9\u03BC\u03AE";
 var tests = [
   {
     name: "normal domain",
     location: "http://test1.example.org/",
@@ -54,17 +55,17 @@ var tests = [
   },
   {
     name: "IP address",
     location: "http://127.0.0.1:8888/",
     effectiveHost: "127.0.0.1"
   },
 ]
 
-var gCurrentTest, gCurrentTestIndex = -1, gTestDesc;
+var gCurrentTest, gCurrentTestIndex = -1, gTestDesc, gPopupHidden;
 // Go through the tests in both directions, to add additional coverage for
 // transitions between different states.
 var gForward = true;
 var gCheckETLD = false;
 function nextTest() {
   if (!gCheckETLD) {
     if (gForward)
       gCurrentTestIndex++;
@@ -86,17 +87,35 @@ function nextTest() {
 
     gCurrentTest = tests[gCurrentTestIndex];
     gTestDesc = "#" + gCurrentTestIndex + " (" + gCurrentTest.name + ")";
     if (!gForward)
       gTestDesc += " (second time)";
     if (gCurrentTest.isHTTPS) {
       gCheckETLD = true;
     }
-    content.location = gCurrentTest.location;
+
+    // Navigate to the next page, which will cause checkResult to fire.
+    let spec = gBrowser.selectedBrowser.currentURI.spec;
+    if (spec == "about:blank" || spec == gCurrentTest.location) {
+      BrowserTestUtils.loadURI(gBrowser.selectedBrowser, gCurrentTest.location);
+    } else {
+      // Open the Control Center and make sure it closes after nav (Bug 1207542).
+      let popupShown = promisePopupShown(gIdentityHandler._identityPopup);
+      gPopupHidden = promisePopupHidden(gIdentityHandler._identityPopup);
+      gIdentityHandler._identityBox.click();
+      info("Waiting for the Control Center to be shown");
+      popupShown.then(() => {
+        is_element_visible(gIdentityHandler._identityPopup, "Control Center is visible");
+        // Show the subview, which is an easy way in automation to reproduce
+        // Bug 1207542, where the CC wouldn't close on navigation.
+        gBrowser.ownerDocument.querySelector("#identity-popup-security-expander").click();
+        BrowserTestUtils.loadURI(gBrowser.selectedBrowser, gCurrentTest.location);
+      });
+    }
   } else {
     gCheckETLD = false;
     gTestDesc = "#" + gCurrentTestIndex + " (" + gCurrentTest.name + " without eTLD in identity icon label)";
     if (!gForward)
       gTestDesc += " (second time)";
     content.location.reload(true);
   }
 }
@@ -108,10 +127,19 @@ function checkResult() {
   if (gCurrentTest.effectiveHost === null) {
     let identityBox = document.getElementById("identity-box");
     ok(identityBox.className == "unknownIdentity" ||
        identityBox.className == "chromeUI", "mode matched");
   } else {
     is(gIdentityHandler.getEffectiveHost(), gCurrentTest.effectiveHost, "effectiveHost matches for test " + gTestDesc);
   }
 
-  executeSoon(nextTest);
+  if (gPopupHidden) {
+    info("Waiting for the Control Center to hide");
+    gPopupHidden.then(() => {
+      gPopupHidden = null;
+      is_element_hidden(gIdentityHandler._identityPopup, "control center is hidden");
+      executeSoon(nextTest);
+    });
+  } else {
+    executeSoon(nextTest);
+  }
 }
--- a/browser/components/loop/.eslintignore
+++ b/browser/components/loop/.eslintignore
@@ -10,17 +10,16 @@ content/shared/libs
 standalone/content/libs
 standalone/node_modules
 # Libs we don't need to check
 test/shared/vendor
 # Coverage files
 test/coverage
 test/node_modules
 # These are generated react files that we don't need to check
-content/js/contacts.js
 content/js/conversation.js
 content/js/conversationViews.js
 content/js/panel.js
 content/js/roomViews.js
 content/js/feedbackViews.js
 content/shared/js/textChatView.js
 content/shared/js/linkifiedTextView.js
 content/shared/js/views.js
deleted file mode 100644
--- a/browser/components/loop/content/css/contacts.css
+++ /dev/null
@@ -1,491 +0,0 @@
-/* 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/. */
-
-html {
-  font-size: 10px;
-  font-family: sans-serif; /* XXX will be changed to a system font in bug 1191398 */
-}
-
-.contacts-container {
-  flex: 1;
-  display: flex;
-  flex-flow: column nowrap;
-  overflow: auto;
-}
-
-.contact-list-container {
-  flex: 1;
-  display: flex;
-  flex-direction: column;
-  overflow: auto;
-}
-/* Don't show the Gravatar if we're showing a contacts list. */
-.contact-list ~ .contacts-gravatar-promo {
-  display: none;
-}
-
-.contact-list-wrapper {
-  flex: 1;
-  overflow-x: hidden;
-  overflow-y: auto;
-}
-
-/* Don't show the empty contacts image if we're showing gravatar promo. */
-.contacts-gravatar-promo ~ .contact-list-empty {
-  background-image: none;
-  padding-top: 0;
-  padding-bottom: 0;
-  margin-top: 2px;
-}
-
-.contact-list-empty-container {
-  flex: 1;
-  overflow-x: hidden;
-  overflow-y: auto;
-}
-
-.contact-list-empty,
-.contact-search-list-empty {
-  margin-top: 4rem;
-  padding-top: 11.5rem;
-  padding-bottom: 0;
-}
-
-.contact-search-list-empty {
-  background-image: url("../shared/img/empty_search.svg");
-}
-
-.contact-list-empty {
-  background-image: url("../shared/img/empty_contacts.svg");
-}
-
-.contact-import-spinner {
-  display: none;
-}
-
-.contact-import-spinner.busy {
-  display: inline-block;
-  vertical-align: middle;
-  -moz-margin-start: 10px;
-}
-
-.contact-filter-container {
-  display: flex;
-  height: 2em;
-}
-
-.contact-filter {
-  margin: 0;
-  -moz-padding-start: 34px;
-  width: 100%;
-  height: 28px;
-  border: 0;
-  border-bottom: 1px solid #ddd;
-  background-image: url("../shared/img/icons-14x14.svg#magnifier");
-  background-position: 10px center;
-  background-size: 14px;
-  background-repeat: no-repeat;
-  color: #999;
-  font-size: 1.2rem;
-}
-
-html[dir="rtl"] .contact-filter {
-  background-position: right 10px center;
-}
-
-.contact-filter:focus + .clear-search,
-.contact-filter:focus {
-  border-bottom: 1px solid #5cccee;
-  color: #4a4a4a;
-}
-
-.clear-search {
-  width: 34px;
-  height: 28px;
-  border: none;
-  border-bottom: 1px solid #ddd;
-  background-color: #fff;
-  background-image: url("../shared/img/icons-14x14.svg#clear");
-  background-position: center;
-  background-size: 14px;
-  background-repeat: no-repeat;
-  cursor: pointer;
-  flex: 0 1 auto;
-  align-self: stretch;
-}
-
-.contact-list {
-  /* Space for six contacts, not affected by filtering.  This is enough space
-     to show the dropdown menu when there is only one contact. */
-  /* Contact list title goes away when searching, needed for spacing. */
-  margin-top: 4px;
-}
-
-.contact-list-title {
-  padding: 0.75rem 1rem;
-  color: #666;
-  font-weight: 500;
-  font-size: .9em;
-}
-
-.contact,
-.contact-separator {
-  padding: .5rem 15px;
-  font-size: 13px;
-}
-
-.contact {
-  display: flex;
-  flex-direction: row;
-  align-items: center;
-  color: #666;
-}
-
-.contact-separator {
-  background-color: #eee;
-  color: #888;
-}
-
-.contact-separator:not(:first-child) {
-  border-top: 1px solid #ccc;
-}
-
-.contact:hover {
-  background-color: #E3F7FE;
-}
-
-.contact:hover > .icons {
-  display: block;
-  z-index: 1;
-}
-
-.contact > .details {
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-  flex: auto;
-}
-
-.contact > .avatar {
-  width: 40px;
-  height: 40px;
-  background-color: #ccc;
-  border-radius: 50%;
-  -moz-margin-end: 10px;
-  overflow: hidden;
-  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3);
-  background-image: url("../shared/img/audio-call-avatar.svg");
-  background-repeat: no-repeat;
-  background-color: #4ba6e7;
-  background-size: contain;
-  -moz-user-select: none;
-  flex: none;
-}
-
-/*
- * Loop through all 12 default avatars.
- */
-.contact:nth-child(12n + 1) > .avatar.defaultAvatar {
-  background-image: url("../shared/img/avatars.svg#blue-avatar");
-  background-color: #4A90E2;
-}
-
-.contact:nth-child(12n + 2) > .avatar.defaultAvatar {
-  background-image: url("../shared/img/avatars.svg#orange-avatar");
-  background-color: #F3A35C;
-}
-
-.contact:nth-child(12n + 3) > .avatar.defaultAvatar {
-  background-image: url("../shared/img/avatars.svg#mintgreen-avatar");
-  background-color: #50E2C2;
-}
-
-.contact:nth-child(12n + 4) > .avatar.defaultAvatar {
-  background-image: url("../shared/img/avatars.svg#lightpink-avatar");
-  background-color: #E364A1;
-}
-
-.contact:nth-child(12n + 5) > .avatar.defaultAvatar {
-  background-image: url("../shared/img/avatars.svg#grey-avatar");
-  background-color: #9B9B9B;
-}
-
-.contact:nth-child(12n + 6) > .avatar.defaultAvatar {
-  background-image: url("../shared/img/avatars.svg#yellow-avatar");
-  background-color: #F3E968;
-}
-
-.contact:nth-child(12n + 7) > .avatar.defaultAvatar {
-  background-image: url("../shared/img/avatars.svg#purple-avatar");
-  background-color: #9C61AF;
-}
-
-.contact:nth-child(12n + 8) > .avatar.defaultAvatar {
-  background-image: url("../shared/img/avatars.svg#lightgreen-avatar");
-  background-color: #9AC967;
-}
-
-.contact:nth-child(12n + 9) > .avatar.defaultAvatar {
-  background-image: url("../shared/img/avatars.svg#darkblue-avatar");
-  background-color: #607CAE;
-}
-
-.contact:nth-child(12n + 10) > .avatar.defaultAvatar {
-  background-image: url("../shared/img/avatars.svg#darkpink-avatar");
-  background-color: #CE4D6E;
-}
-
-.contact:nth-child(12n + 11) > .avatar.defaultAvatar {
-  background-image: url("../shared/img/avatars.svg#brown-avatar");
-  background-color: #8A572A;
-}
-
-.contact:nth-child(12n + 12) > .avatar.defaultAvatar {
-  background-image: url("../shared/img/avatars.svg#green-avatar");
-  background-color: #56B397;
-}
-
-.contact > .avatar > img {
-  width: 100%;
-}
-
-.panel-text-medium{
-  margin: 3px;
-  color: #4a4a4a;
-  font-size: 1.3rem;
-}
-
-.contact > .details > .username {
-  font-size: 1.3rem;
-  line-height: 20px;
-  color: #000;
-}
-
-.contact.blocked > .details > .username {
-  color: #d74345;
-}
-
-.contact > .details > .username > strong {
-  font-weight: bold;
-}
-
-.contact > .details > .username > i.icon-blocked {
-  display: inline-block;
-  width: 10px;
-  height: 20px;
-  -moz-margin-start: 3px;
-  background-image: url("../shared/img/icons-16x16.svg#block-red");
-  background-position: center;
-  background-size: 10px 10px;
-  background-repeat: no-repeat;
-}
-
-.contact > .details > .email {
-  color: #4a4a4a;
-  font-size: 11px;
-  line-height: 14px;
-}
-
-.icons {
-  cursor: pointer;
-  display: none;
-  -moz-margin-start: 10px;
-  color: #fff;
-  -moz-user-select: none;
-  flex: none;
-}
-
-.icons:hover {
-  display: block;
-}
-
-.icons i {
-  display: inline-block;
-  background-position: center;
-  background-repeat: no-repeat;
-}
-
-.icon-contact-video-call {
-  padding: 15px;
-  width: 16px;
-  height: 16px;
-  border-radius: 50%;
-  background-color: #5bc0a4;
-  background-image: url("../shared/img/icons-14x14.svg#video-white");
-  background-size: 14px 14px;
-}
-
-.icon-contact-video-call:hover,
-.icon-contact-video-call:active {
-  background-color: #50E3C2;
-}
-
-.icon-vertical-ellipsis {
-  /* Added padding for a larger click area. */
-  padding: 0 10px;
-  margin: 6px 0;
-  -moz-margin-start: 5px;
-  -moz-margin-end: -8px;
-  width: 4px;
-  height: 20px;
-  background-image: url("../shared/img/ellipsis-v.svg");
-  background-size: contain;
-}
-
-.contact > .dropdown-menu {
-  z-index: 2;
-  top: 37px;
-  right: 22px;
-  bottom: auto;
-  left: auto;
-  z-index: 2;
-}
-
-html[dir="rtl"] .contact > .dropdown-menu {
-  right: auto;
-  left: 22px;
-}
-
-.contact > .dropdown-menu-up {
-  bottom: 25px;
-  top: auto;
-}
-
-.contact-form {
-  padding: 14px 15px 0 15px; /* Override based on spacing in Mockup */
-  flex: 1;
-  display: flex;
-  flex-direction: column;
-}
-/* This will effect the header displayed at the top of the contact details form
- */
-.contact-form header {
-  text-align: center;
-  font-size: 1.3rem;
-  font-weight: 500;
-  color: #4a4a4a;
-}
-
-.contact-form .form-content-container {
-  /* flex is needed to fill and place the buttons above the footer */
-  flex: 1;
-  padding-top: 4px; /* Based on spacing in Mockup
-                    replaced margin-top
-                    See http://stackoverflow.com/questions/6204670/css-clean-solution-to-the-margin-collapse-issue-when-floating-an-element
-                    */
-}
-
-.contacts-gravatar-promo {
-  border: 1px solid #5cccee;
-  border-radius: 2px;
-  background-color: #fff;
-  font-size: 1.2rem;
-  margin: 1.5rem;
-  padding: 1.5rem 1rem;
-  position: relative;
-}
-
-.contacts-gravatar-promo > p {
-  margin-top: 0;
-  word-wrap: break-word;
-}
-
-.contacts-gravatar-promo > p > a {
-  color: #0295df;
-  text-decoration: none;
-}
-
-.contacts-gravatar-promo > p > a:hover {
-  text-decoration: underline;
-}
-
-.contacts-gravatar-promo > .button-close {
-  position: absolute;
-  top: 8px;
-  right: 8px;
-}
-
-html[dir="rtl"] .contacts-gravatar-promo > .button-close {
-  right: auto;
-  left: 8px;
-}
-
-.contacts-gravatar-avatars {
-  height: 50px;
-  margin: 1.5rem auto;
-  text-align: center;
-  width: 200px;
-}
-
-.contacts-gravatar-avatars img {
-  margin: 0 1.5rem;
-  vertical-align: middle;
-  width: 50px;
-}
-
-/* Adjust the Firefox avatar because it has pointy ears. */
-.contacts-gravatar-avatars img:last-child {
-  transform: scale(1.08) translateY(-2px);
-}
-
-.contacts-gravatar-arrow {
-  border-color: #9b9b9b;
-  border-style: solid solid none none;
-  border-width: 2px;
-  display: inline-block;
-  height: 1.5rem;
-  -moz-margin-start: -.75rem;
-  transform: rotateZ(45deg);
-  vertical-align: middle;
-  width: 1.5rem;
-}
-
-html[dir="rtl"] .contacts-gravatar-arrow {
-  transform: rotateZ(225deg);
-}
-
-.contacts-gravatar-buttons {
-  padding: 0 .5rem;
-}
-
-.contact-controls {
-  padding-left: 15px;
-  padding-right: 15px;
-  border-top: 1px solid #D8D8D8;
-}
-
-.contact-controls > .button {
-  padding: .5em;
-  border: none;
-  border-radius: 5px;
-}
-
-.button.primary {
-  background: #00A9DC;
-  color: #fff;
-}
-
-.button.primary:active,
-.button.primary:hover {
-  background: #5cccee;
-}
-
-.button.secondary {
-  background: #ebebeb;
-  color: #4D4D4D;
-}
-
-.button.secondary:hover,
-.button.secondary:active {
-  background: #dad6d6;
-  color: #4D4D4D;
-}
-
-.contact-controls > .primary {
-  flex: 5;
-}
-
-.contact-controls > .secondary {
-  flex: 3;
-}
--- a/browser/components/loop/content/css/panel.css
+++ b/browser/components/loop/content/css/panel.css
@@ -125,39 +125,32 @@ body {
 .content-area input:not(.pristine):invalid {
   border: 0.1rem solid #d13f1a;
 }
 
 .content-area input:focus {
   border: 0.1rem solid #5cccee;
 }
 
-/* Rooms and contacts shared CSS */
+/* Rooms CSS */
 
-.contact-list-empty,
-.contact-search-list-empty,
 .no-conversations-message {
-  background-repeat: no-repeat;
-  background-position: top center;
+  /* example of vertical aligning a container in an element see:
+     http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css/ */
   text-align: center;
   color: #4a4a4a;
   font-weight: lighter;
-}
-
-
-
-.no-conversations-message {
-  /* example of vertical aligning a container in an element
-    see: http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css/ */
   position: relative;
   top: 50%;
   transform: translateY(-50%);
   padding-top: 11rem;
   padding-bottom: 1rem;
   background-image: url("../shared/img/empty_conversations.svg");
+  background-repeat: no-repeat;
+  background-position: top center;
 }
 
 .panel-text-medium,
 .panel-text-large {
   margin: 3px 0;
 }
 
 .panel-text-medium {
deleted file mode 100644
--- a/browser/components/loop/content/js/contacts.js
+++ /dev/null
@@ -1,1030 +0,0 @@
-/* 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/. */
-
-var loop = loop || {};
-loop.contacts = (function(_, mozL10n) {
-  "use strict";
-
-  var sharedMixins = loop.shared.mixins;
-
-  const Button = loop.shared.views.Button;
-  const ButtonGroup = loop.shared.views.ButtonGroup;
-  const CALL_TYPES = loop.shared.utils.CALL_TYPES;
-
-  // Number of contacts to add to the list at the same time.
-  const CONTACTS_CHUNK_SIZE = 100;
-
-  // At least this number of contacts should be present for the filter to appear.
-  const MIN_CONTACTS_FOR_FILTERING = 7;
-
-  let getContactNames = function(contact) {
-    // The model currently does not enforce a name to be present, but we're
-    // going to assume it is awaiting more advanced validation of required fields
-    // by the model. (See bug 1069918)
-    // NOTE: this method of finding a firstname and lastname is not i18n-proof.
-    let names = contact.name[0].split(" ");
-    return {
-      firstName: names.shift(),
-      lastName: names.join(" ")
-    };
-  };
-
-  /** Used to retrieve the preferred email or phone number
-   *  for the contact. Both fields are optional.
-   * @param   {object} contact
-   *          The contact object to get the field from.
-   * @param   {string} field
-   *          The field that should be read out of the contact object.
-   * @returns {object} An object with a 'value' property that hold a string value.
-   */
-  let getPreferred = function(contact, field) {
-    if (!contact[field] || !contact[field].length) {
-      return { value: "" };
-    }
-    return contact[field].find(e => e.pref) || contact[field][0];
-  };
-
-  /** Used to set the preferred email or phone number
-   *  for the contact. Both fields are optional.
-   * @param   {object} contact
-   *          The contact object to get the field from.
-   * @param   {string} field
-   *          The field within the contact to set.
-   * @param   {string} value
-   *          The value that the field should be set to.
-   */
-  let setPreferred = function(contact, field, value) {
-    // Don't clear the field if it doesn't exist.
-    if (!value && (!contact[field] || !contact[field].length)) {
-      return;
-    }
-
-    if (!contact[field]) {
-      contact[field] = [];
-    }
-
-    if (!contact[field].length) {
-      contact[field][0] = {"value": value};
-      return;
-    }
-    // Set the value in the preferred tuple and return.
-    for (let i in contact[field]) {
-      if (contact[field][i].pref) {
-        contact[field][i].value = value;
-        return;
-      }
-    }
-    contact[field][0].value = value;
-  };
-
-  const GravatarPromo = React.createClass({displayName: "GravatarPromo",
-    mixins: [sharedMixins.WindowCloseMixin],
-
-    propTypes: {
-      handleUse: React.PropTypes.func.isRequired
-    },
-
-    getInitialState: function() {
-      return {
-        showMe: navigator.mozLoop.getLoopPref("contacts.gravatars.promo") &&
-          !navigator.mozLoop.getLoopPref("contacts.gravatars.show")
-      };
-    },
-
-    handleCloseButtonClick: function() {
-      navigator.mozLoop.setLoopPref("contacts.gravatars.promo", false);
-      this.setState({ showMe: false });
-    },
-
-    handleLinkClick: function(event) {
-      if (!event.target || !event.target.href) {
-        return;
-      }
-
-      event.preventDefault();
-      navigator.mozLoop.openURL(event.target.href);
-      this.closeWindow();
-    },
-
-    handleUseButtonClick: function() {
-      navigator.mozLoop.setLoopPref("contacts.gravatars.promo", false);
-      navigator.mozLoop.setLoopPref("contacts.gravatars.show", true);
-      this.setState({ showMe: false });
-      this.props.handleUse();
-    },
-
-    render: function() {
-      if (!this.state.showMe) {
-        return null;
-      }
-
-      let privacyUrl = navigator.mozLoop.getLoopPref("legal.privacy_url");
-      let message = mozL10n.get("gravatars_promo_message", {
-        "learn_more": React.renderToStaticMarkup(
-          React.createElement("a", {href: privacyUrl, target: "_blank"}, 
-            mozL10n.get("gravatars_promo_message_learnmore")
-          )
-        )
-      });
-      return (
-        React.createElement("div", {className: "contacts-gravatar-promo"}, 
-          React.createElement(Button, {additionalClass: "button-close", 
-                  caption: "", 
-                  onClick: this.handleCloseButtonClick}), 
-          React.createElement("p", {dangerouslySetInnerHTML: {__html: message}, 
-             onClick: this.handleLinkClick}), 
-          React.createElement("div", {className: "contacts-gravatar-avatars"}, 
-            React.createElement("img", {src: "loop/shared/img/avatars.svg#orange-avatar"}), 
-            React.createElement("span", {className: "contacts-gravatar-arrow"}), 
-            React.createElement("img", {src: "loop/shared/img/firefox-avatar.svg"})
-          ), 
-          React.createElement(ButtonGroup, {additionalClass: "contacts-gravatar-buttons"}, 
-            React.createElement(Button, {additionalClass: "secondary", 
-                    caption: mozL10n.get("gravatars_promo_button_nothanks2"), 
-                    onClick: this.handleCloseButtonClick}), 
-            React.createElement(Button, {additionalClass: "secondary", 
-                    caption: mozL10n.get("gravatars_promo_button_use2"), 
-                    onClick: this.handleUseButtonClick})
-          )
-        )
-      );
-    }
-  });
-
-  const ContactDropdown = React.createClass({displayName: "ContactDropdown",
-    propTypes: {
-      // If the contact is blocked or not.
-      blocked: React.PropTypes.bool,
-      canEdit: React.PropTypes.bool,
-      // Position of mouse when opening menu
-      eventPosY: React.PropTypes.number.isRequired,
-      // callback function that provides height and top coordinate for contacts container
-      getContainerCoordinates: React.PropTypes.func.isRequired,
-      handleAction: React.PropTypes.func.isRequired
-    },
-
-    getInitialState: function() {
-      return {
-        openDirUp: false
-      };
-    },
-
-    onItemClick: function(event) {
-      this.props.handleAction(event.currentTarget.dataset.action);
-    },
-
-    componentDidMount: function() {
-      var menuNode = this.getDOMNode();
-      var menuNodeRect = menuNode.getBoundingClientRect();
-      var listNodeCoords = this.props.getContainerCoordinates();
-
-      // Click offset to not display the menu right next to the area clicked.
-      var offset = 10;
-
-      if (this.props.eventPosY + menuNodeRect.height >=
-        listNodeCoords.top + listNodeCoords.height) {
-
-        // Position above click area.
-        menuNode.style.top = this.props.eventPosY - menuNodeRect.height
-          - offset + "px";
-      } else {
-        // Position below click area.
-        menuNode.style.top = this.props.eventPosY + offset + "px";
-      }
-    },
-
-    render: function() {
-      var cx = React.addons.classSet;
-      var dropdownClasses = cx({
-        "dropdown-menu": true,
-        "dropdown-menu-up": this.state.openDirUp
-      });
-      let blockAction = this.props.blocked ? "unblock" : "block";
-      let blockLabel = this.props.blocked ? "unblock_contact_menu_button"
-                                          : "block_contact_menu_button";
-
-      return (
-        React.createElement("ul", {className: dropdownClasses}, 
-          React.createElement("li", {className: cx({ "dropdown-menu-item": true,
-                              "disabled": this.props.blocked,
-                              "video-call-item": true }), 
-              "data-action": "video-call", 
-              onClick: this.onItemClick}, 
-            mozL10n.get("video_call_menu_button")
-          ), 
-          React.createElement("li", {className: cx({ "dropdown-menu-item": true,
-                              "disabled": this.props.blocked,
-                              "audio-call-item": true }), 
-              "data-action": "audio-call", 
-              onClick: this.onItemClick}, 
-            mozL10n.get("audio_call_menu_button")
-          ), 
-          React.createElement("li", {className: cx({ "dropdown-menu-item": true,
-                              "disabled": !this.props.canEdit }), 
-              "data-action": "edit", 
-              onClick: this.onItemClick}, 
-            mozL10n.get("edit_contact_title")
-          ), 
-          React.createElement("li", {className: "dropdown-menu-item", 
-              "data-action": blockAction, 
-              onClick: this.onItemClick}, 
-            mozL10n.get(blockLabel)
-          ), 
-          React.createElement("li", {className: cx({ "dropdown-menu-item": true,
-                              "disabled": !this.props.canEdit }), 
-              "data-action": "remove", 
-              onClick: this.onItemClick}, 
-            mozL10n.get("confirm_delete_contact_remove_button")
-          )
-        )
-      );
-    }
-  });
-
-  const ContactDetail = React.createClass({displayName: "ContactDetail",
-    propTypes: {
-      contact: React.PropTypes.object.isRequired,
-      getContainerCoordinates: React.PropTypes.func.isRequired,
-      handleContactAction: React.PropTypes.func
-    },
-
-    mixins: [
-      sharedMixins.DropdownMenuMixin()
-    ],
-
-    getInitialState: function() {
-      return {
-        eventPosY: 0
-      };
-    },
-
-    handleShowDropdownClick: function(e) {
-      e.preventDefault();
-      e.stopPropagation();
-
-      this.setState({
-        eventPosY: e.pageY
-      });
-
-      this.toggleDropdownMenu();
-    },
-
-    hideDropdownMenuHandler: function() {
-      // Since this call may be deferred, we need to guard it, for example in
-      // case the contact was removed in the meantime.
-      if (this.isMounted()) {
-        this.hideDropdownMenu();
-      }
-    },
-
-    shouldComponentUpdate: function(nextProps, nextState) {
-      let currContact = this.props.contact;
-      let nextContact = nextProps.contact;
-      let currContactEmail = getPreferred(currContact, "email").value;
-      let nextContactEmail = getPreferred(nextContact, "email").value;
-      return (
-        currContact.name[0] !== nextContact.name[0] ||
-        currContact.blocked !== nextContact.blocked ||
-        currContactEmail !== nextContactEmail ||
-        nextState.showMenu !== this.state.showMenu
-      );
-    },
-
-    handleAction: function(actionName) {
-      if (this.props.handleContactAction) {
-        this.props.handleContactAction(this.props.contact, actionName);
-        this.hideDropdownMenuHandler();
-      }
-    },
-
-    canEdit: function() {
-      // We cannot modify imported contacts.  For the moment, the check for
-      // determining whether the contact is imported is based on its category.
-      return this.props.contact.category[0] !== "google";
-    },
-
-    /**
-     * Callback called when moving cursor away from the conversation entry.
-     * Will close the dropdown menu.
-     */
-    _handleMouseOut: function() {
-      if (this.state.showMenu) {
-        this.toggleDropdownMenu();
-      }
-    },
-
-    render: function() {
-      let names = getContactNames(this.props.contact);
-      let email = getPreferred(this.props.contact, "email");
-      let avatarSrc = navigator.mozLoop.getUserAvatar(email.value);
-      let cx = React.addons.classSet;
-      let contactCSSClass = cx({
-        contact: true,
-        blocked: this.props.contact.blocked
-      });
-      let avatarCSSClass = cx({
-        avatar: true,
-        defaultAvatar: !avatarSrc
-      });
-      return (
-        React.createElement("li", {className: contactCSSClass, 
-            onMouseLeave: this._handleMouseOut}, 
-          React.createElement("div", {className: avatarCSSClass}, 
-            avatarSrc ? React.createElement("img", {src: avatarSrc}) : null
-          ), 
-          React.createElement("div", {className: "details"}, 
-            React.createElement("div", {className: "username"}, React.createElement("strong", null, names.firstName), " ", names.lastName, 
-              React.createElement("i", {className: cx({"icon icon-blocked": this.props.contact.blocked})})
-            ), 
-            React.createElement("div", {className: "email"}, email.value)
-          ), 
-          React.createElement("div", {className: "icons"}, 
-            React.createElement("i", {className: "icon icon-contact-video-call", 
-               onClick: this.handleAction.bind(null, "video-call")}), 
-            React.createElement("i", {className: "icon icon-vertical-ellipsis icon-contact-menu-button", 
-               onClick: this.handleShowDropdownClick})
-          ), 
-          this.state.showMenu
-            ? React.createElement(ContactDropdown, {blocked: this.props.contact.blocked, 
-                               canEdit: this.canEdit(), 
-                               eventPosY: this.state.eventPosY, 
-                               getContainerCoordinates: this.props.getContainerCoordinates, 
-                               handleAction: this.handleAction})
-            : null
-          
-        )
-      );
-    }
-  });
-
-  const ContactsList = React.createClass({displayName: "ContactsList",
-    mixins: [
-      React.addons.LinkedStateMixin,
-      loop.shared.mixins.WindowCloseMixin
-    ],
-
-    propTypes: {
-      mozLoop: React.PropTypes.object.isRequired,
-      notifications: React.PropTypes.instanceOf(loop.shared.models.NotificationCollection).isRequired,
-      switchToContactAdd: React.PropTypes.func.isRequired,
-      switchToContactEdit: React.PropTypes.func.isRequired
-    },
-
-    /**
-     * Contacts collection object
-     */
-    contacts: null,
-
-    /**
-     * User profile
-     */
-    _userProfile: null,
-
-    getInitialState: function() {
-      return {
-        importBusy: false,
-        filter: ""
-      };
-    },
-
-    refresh: function(callback = function() {}) {
-      let contactsAPI = this.props.mozLoop.contacts;
-
-      this.handleContactRemoveAll();
-
-      contactsAPI.getAll((err, contacts) => {
-        if (err) {
-          callback(err);
-          return;
-        }
-
-        // Add contacts already present in the DB. We do this in timed chunks to
-        // circumvent blocking the main event loop.
-        let addContactsInChunks = () => {
-          contacts.splice(0, CONTACTS_CHUNK_SIZE).forEach(contact => {
-            this.handleContactAddOrUpdate(contact, false);
-          });
-          if (contacts.length) {
-            setTimeout(addContactsInChunks, 0);
-          } else {
-            callback();
-          }
-          this.forceUpdate();
-        };
-
-        addContactsInChunks(contacts);
-      });
-    },
-
-    componentWillMount: function() {
-      // Take the time to initialize class variables that are used outside
-      // `this.state`.
-      this.contacts = {};
-      this._userProfile = this.props.mozLoop.userProfile;
-    },
-
-    componentDidMount: function() {
-      window.addEventListener("LoopStatusChanged", this._onStatusChanged);
-
-      this.refresh(err => {
-        if (err) {
-          throw err;
-        }
-
-        let contactsAPI = this.props.mozLoop.contacts;
-
-        // Listen for contact changes/ updates.
-        contactsAPI.on("add", (eventName, contact) => {
-          this.handleContactAddOrUpdate(contact);
-        });
-        contactsAPI.on("remove", (eventName, contact) => {
-          this.handleContactRemove(contact);
-        });
-        contactsAPI.on("removeAll", () => {
-          this.handleContactRemoveAll();
-        });
-        contactsAPI.on("update", (eventName, contact) => {
-          this.handleContactAddOrUpdate(contact);
-        });
-      });
-    },
-
-    componentWillUnmount: function() {
-      window.removeEventListener("LoopStatusChanged", this._onStatusChanged);
-    },
-
-    /*
-     * Filter a user by name, email or phone number.
-     * Takes in an input to filter by and returns a filter function which
-     * expects a contact.
-     *
-     * @returns {Function}
-     */
-    filterContact: function(filter) {
-      return function(contact) {
-        return getPreferred(contact, "name").toLocaleLowerCase().includes(filter) ||
-          getPreferred(contact, "email").value.toLocaleLowerCase().includes(filter) ||
-          getPreferred(contact, "tel").value.toLocaleLowerCase().includes(filter);
-      };
-    },
-
-    /*
-     * Takes all contacts, it groups and filters them before rendering.
-     */
-    _filterContactsList: function() {
-      let shownContacts = _.groupBy(this.contacts, function(contact) {
-        return contact.blocked ? "blocked" : "available";
-      });
-
-      if (this._shouldShowFilter()) {
-        let filter = this.state.filter.trim().toLocaleLowerCase();
-        let filterFn = this.filterContact(filter);
-        if (filter) {
-          if (shownContacts.available) {
-            shownContacts.available = shownContacts.available.filter(filterFn);
-            // Filter can return an empty array.
-            if (!shownContacts.available.length) {
-              shownContacts.available = null;
-            }
-          }
-          if (shownContacts.blocked) {
-            shownContacts.blocked = shownContacts.blocked.filter(filterFn);
-            // Filter can return an empty array.
-            if (!shownContacts.blocked.length) {
-              shownContacts.blocked = null;
-            }
-          }
-        }
-      }
-
-      return shownContacts;
-    },
-
-    /*
-     * Decide to render contacts filter based on the number of contacts.
-     *
-     * @returns {bool}
-     */
-    _shouldShowFilter: function() {
-      return Object.getOwnPropertyNames(this.contacts).length >=
-        MIN_CONTACTS_FOR_FILTERING;
-    },
-
-    _onStatusChanged: function() {
-      let profile = this.props.mozLoop.userProfile;
-      let currUid = this._userProfile ? this._userProfile.uid : null;
-      let newUid = profile ? profile.uid : null;
-      if (currUid !== newUid) {
-        // On profile change (login, logout), reload all contacts.
-        this._userProfile = profile;
-        // The following will do a forceUpdate() for us.
-        this.refresh();
-      }
-    },
-
-    handleContactAddOrUpdate: function(contact, render = true) {
-      let contacts = this.contacts;
-      let guid = String(contact._guid);
-      contacts[guid] = contact;
-      if (render) {
-        this.forceUpdate();
-      }
-    },
-
-    handleContactRemove: function(contact) {
-      let contacts = this.contacts;
-      let guid = String(contact._guid);
-      if (!contacts[guid]) {
-        return;
-      }
-      delete contacts[guid];
-      this.forceUpdate();
-    },
-
-    handleContactRemoveAll: function() {
-      // Do not allow any race conditions when removing all contacts.
-      this.contacts = {};
-      this.forceUpdate();
-    },
-
-    handleImportButtonClick: function() {
-      this.setState({ importBusy: true });
-      this.props.mozLoop.startImport({
-        service: "google"
-      }, (err, stats) => {
-        this.setState({ importBusy: false });
-        if (err) {
-          console.error("Contact import error", err);
-          this.props.notifications.errorL10n("import_contacts_failure_message");
-          return;
-        }
-        this.props.notifications.successL10n("import_contacts_success_message", {
-          num: stats.success,
-          total: stats.success
-        });
-      });
-    },
-
-    handleAddContactButtonClick: function() {
-      this.props.switchToContactAdd();
-    },
-
-    handleContactAction: function(contact, actionName) {
-      switch (actionName) {
-        case "edit":
-          this.props.switchToContactEdit(contact);
-          break;
-        case "remove":
-          this.props.mozLoop.confirm({
-            message: mozL10n.get("confirm_delete_contact_alert"),
-            okButton: mozL10n.get("confirm_delete_contact_remove_button"),
-            cancelButton: mozL10n.get("confirm_delete_contact_cancel_button")
-          }, (error, result) => {
-            if (error) {
-              throw error;
-            }
-
-            if (!result) {
-              return;
-            }
-
-            this.props.mozLoop.contacts.remove(contact._guid, err => {
-              if (err) {
-                throw err;
-              }
-            });
-          });
-          break;
-        case "block":
-        case "unblock":
-          // Invoke the API named like the action.
-          this.props.mozLoop.contacts[actionName](contact._guid, err => {
-            if (err) {
-              throw err;
-            }
-          });
-          break;
-        case "video-call":
-          if (!contact.blocked) {
-            this.props.mozLoop.calls.startDirectCall(contact, CALL_TYPES.AUDIO_VIDEO);
-            this.closeWindow();
-          }
-          break;
-        case "audio-call":
-          if (!contact.blocked) {
-            this.props.mozLoop.calls.startDirectCall(contact, CALL_TYPES.AUDIO_ONLY);
-            this.closeWindow();
-          }
-          break;
-        default:
-          console.error("Unrecognized action: " + actionName);
-          break;
-      }
-    },
-
-    handleUseGravatar: function() {
-      // We got permission to use Gravatar icons now, so we need to redraw the
-      // list entirely to show them.
-      this.refresh();
-    },
-
-    /*
-     * Callback triggered when clicking the `X` from the contacts filter.
-     * Clears the search query.
-     */
-    _handleFilterClear: function() {
-      this.setState({
-        filter: ""
-      });
-    },
-
-    sortContacts: function(contact1, contact2) {
-      let comp = contact1.name[0].localeCompare(contact2.name[0]);
-      if (comp !== 0) {
-        return comp;
-      }
-      // If names are equal, compare against unique ids to make sure we have
-      // consistent ordering.
-      return contact1._guid - contact2._guid;
-    },
-
-    getCoordinates: function() {
-      // Returns coordinates for use by child elements to place menus etc that are absolutely positioned
-      var domNode = this.getDOMNode();
-      var domNodeRect = domNode.getBoundingClientRect();
-
-      return {
-        "top": domNodeRect.top,
-        "height": domNodeRect.height
-      };
-    },
-
-    _renderFilterClearButton: function() {
-      if (this.state.filter) {
-        return (
-          React.createElement("button", {className: "clear-search", 
-                  onClick: this._handleFilterClear})
-        );
-      }
-
-      return null;
-    },
-
-    _renderContactsFilter: function() {
-      if (this._shouldShowFilter()) {
-        return (
-          React.createElement("div", {className: "contact-filter-container"}, 
-            React.createElement("input", {className: "contact-filter", 
-                   placeholder: mozL10n.get("contacts_search_placesholder2"), 
-                   valueLink: this.linkState("filter")}), 
-            this._renderFilterClearButton()
-          )
-        );
-      }
-
-      return null;
-    },
-
-    _renderContactsList: function() {
-      let cx = React.addons.classSet;
-      let shownContacts = this._filterContactsList();
-      let viewForItem = item => {
-        return (
-          React.createElement(ContactDetail, {contact: item, 
-                         getContainerCoordinates: this.getCoordinates, 
-                         handleContactAction: this.handleContactAction, 
-                         key: item._guid})
-        );
-      };
-
-      // If no contacts to show and filter is set, then none match the search.
-      if (!shownContacts.available && !shownContacts.blocked &&
-          this.state.filter) {
-        return (
-          React.createElement("div", {className: "contact-search-list-empty"}, 
-            React.createElement("p", {className: "panel-text-medium"}, 
-              mozL10n.get("contacts_no_search_results")
-            )
-          )
-        );
-      }
-
-      // If no contacts to show and filter is not set, we don't have contacts.
-      if (!shownContacts.available && !shownContacts.blocked &&
-          !this.state.filter) {
-        return (
-            React.createElement("div", {className: "contact-list-empty-container"}, 
-              this._renderGravatarPromoMessage(), 
-              React.createElement("div", {className: "contact-list-empty"}, 
-                React.createElement("p", {className: "panel-text-large"}, 
-                  mozL10n.get("no_contacts_message_heading2")
-                ), 
-                React.createElement("p", {className: "panel-text-medium"}, 
-                  mozL10n.get("no_contacts_import_or_add2")
-                )
-              )
-            )
-        );
-      }
-
-      return (
-          React.createElement("div", {className: "contact-list-container"}, 
-            !this.state.filter ? React.createElement("div", {className: "contact-list-title"}, 
-              mozL10n.get("contact_list_title")
-            ) : null, 
-            React.createElement("div", {className: "contact-list-wrapper"}, 
-              this._renderGravatarPromoMessage(), 
-              React.createElement("ul", {className: "contact-list"}, 
-                shownContacts.available ?
-                    shownContacts.available.sort(this.sortContacts).map(viewForItem) :
-                    null, 
-                shownContacts.blocked && shownContacts.blocked.length > 0 ?
-                    React.createElement("div", {className: "contact-separator"}, mozL10n.get("contacts_blocked_contacts")) :
-                    null, 
-                shownContacts.blocked ?
-                    shownContacts.blocked.sort(this.sortContacts).map(viewForItem) :
-                    null
-              )
-            )
-          )
-      );
-    },
-
-    _renderAddContactButtons: function() {
-      let cx = React.addons.classSet;
-
-      if (this.state.filter) {
-        return null;
-      }
-
-      return (
-        React.createElement(ButtonGroup, {additionalClass: "contact-controls"}, 
-          React.createElement(Button, {additionalClass: "secondary", 
-            caption: this.state.importBusy ? mozL10n.get("importing_contacts_progress_button") :
-                                             mozL10n.get("import_contacts_button3"), 
-              disabled: this.state.importBusy, 
-              onClick: this.handleImportButtonClick}, 
-              React.createElement("div", {className: cx({"contact-import-spinner": true,
-                                 spinner: true,
-              busy: this.state.importBusy})})
-          ), 
-          React.createElement(Button, {additionalClass: "primary", 
-            caption: mozL10n.get("new_contact_button2"), 
-            onClick: this.handleAddContactButtonClick})
-        )
-      );
-    },
-
-    _renderGravatarPromoMessage: function() {
-      if (this.state.filter) {
-        return null;
-      }
-
-      return (
-        React.createElement(GravatarPromo, {handleUse: this.handleUseGravatar})
-      );
-    },
-
-    render: function() {
-      return (
-        React.createElement("div", {className: "contacts-container"}, 
-          this._renderContactsFilter(), 
-          this._renderContactsList(), 
-          this._renderAddContactButtons()
-        )
-      );
-    }
-  });
-
-  const ContactsControllerView = React.createClass({displayName: "ContactsControllerView",
-    propTypes: {
-      initialSelectedTabComponent: React.PropTypes.string,
-      mozLoop: React.PropTypes.object.isRequired,
-      notifications: React.PropTypes.object.isRequired
-    },
-
-    getInitialState: function() {
-      return {
-        currentComponent: this.props.initialSelectedTabComponent || "contactList",
-        contactFormData: {}
-      };
-    },
-
-    /* XXX We should have success/Fail callbacks that the children call instead of this
-    * Children should not have knowledge of other views
-    * However, this is being implemented in this way so the view can be directed appropriately
-    * without making it too complex
-    */
-    switchComponentView: function(componentName) {
-      return function() {
-        this.setState({currentComponent: componentName});
-      }.bind(this);
-    },
-
-    handleAddEditContact: function(componentName) {
-      return function(contactFormData) {
-        this.setState({
-          contactFormData: contactFormData || {},
-          currentComponent: componentName
-        });
-      }.bind(this);
-    },
-
-    /* XXX Consider whether linkedStated makes sense for this */
-    render: function() {
-      switch(this.state.currentComponent) {
-        case "contactAdd":
-          return (
-            React.createElement(ContactDetailsForm, {
-              contactFormData: this.state.contactFormData, 
-              mode: "add", 
-              mozLoop: this.props.mozLoop, 
-              ref: "contacts_add", 
-              switchToInitialView: this.switchComponentView("contactList")})
-          );
-        case "contactEdit":
-          return (
-            React.createElement(ContactDetailsForm, {
-              contactFormData: this.state.contactFormData, 
-              mode: "edit", 
-              mozLoop: this.props.mozLoop, 
-              ref: "contacts_edit", 
-              switchToInitialView: this.switchComponentView("contactList")})
-          );
-        case "contactList":
-        default:
-          return (
-            React.createElement(ContactsList, {
-              mozLoop: this.props.mozLoop, 
-              notifications: this.props.notifications, 
-              ref: "contacts_list", 
-              switchToContactAdd: this.handleAddEditContact("contactAdd"), 
-              switchToContactEdit: this.handleAddEditContact("contactEdit")})
-          );
-      }
-    }
-  });
-
-  const ContactDetailsForm = React.createClass({displayName: "ContactDetailsForm",
-    mixins: [React.addons.LinkedStateMixin],
-
-    propTypes: {
-      contactFormData: React.PropTypes.object.isRequired,
-      mode: React.PropTypes.string,
-      mozLoop: React.PropTypes.object.isRequired,
-      switchToInitialView: React.PropTypes.func.isRequired
-    },
-
-    componentDidMount: function() {
-      this.initForm(this.props.contactFormData);
-    },
-
-    getInitialState: function() {
-      return {
-        contact: null,
-        pristine: true,
-        name: "",
-        email: "",
-        tel: ""
-      };
-    },
-
-    initForm: function(contact) {
-      let state = this.getInitialState();
-      // Test for an empty contact object
-      if (_.keys(contact).length > 0) {
-        state.contact = contact;
-        state.name = contact.name[0];
-        state.email = getPreferred(contact, "email").value;
-        state.tel = getPreferred(contact, "tel").value;
-      }
-
-      this.setState(state);
-    },
-
-    handleAcceptButtonClick: function() {
-      // Allow validity error indicators to be displayed.
-      this.setState({
-        pristine: false
-      });
-
-      let emailInput = this.refs.email.getDOMNode();
-      let telInput = this.refs.tel.getDOMNode();
-      if (!this.refs.name.getDOMNode().checkValidity() ||
-          ((emailInput.required || emailInput.value) && !emailInput.checkValidity()) ||
-          ((telInput.required || telInput.value) && !telInput.checkValidity())) {
-        return;
-      }
-
-      let contactsAPI = this.props.mozLoop.contacts;
-      switch (this.props.mode) {
-        case "edit":
-          this.state.contact.name[0] = this.state.name.trim();
-          setPreferred(this.state.contact, "email", this.state.email.trim());
-          setPreferred(this.state.contact, "tel", this.state.tel.trim());
-          contactsAPI.update(this.state.contact, err => {
-            if (err) {
-              throw err;
-            }
-          });
-          this.setState({
-            contact: null
-          });
-          break;
-        case "add":
-          var contact = {
-            id: this.props.mozLoop.generateUUID(),
-            name: [this.state.name.trim()],
-            email: [{
-              pref: true,
-              type: ["home"],
-              value: this.state.email.trim()
-            }],
-            category: ["local"]
-          };
-          var tel = this.state.tel.trim();
-          if (tel) {
-            contact.tel = [{
-              pref: true,
-              type: ["fxos"],
-              value: tel
-            }];
-          }
-          contactsAPI.add(contact, err => {
-            if (err) {
-              throw err;
-            }
-          });
-          break;
-      }
-
-      this.props.switchToInitialView();
-    },
-
-    handleCancelButtonClick: function() {
-      this.props.switchToInitialView();
-    },
-
-    render: function() {
-      let cx = React.addons.classSet;
-      let phoneOrEmailRequired = !this.state.email && !this.state.tel;
-      let contactFormMode = "contact-form-mode-" + this.props.mode;
-      let contentAreaClassesLiteral = {
-        "content-area": true,
-        "contact-form": true
-      };
-      contentAreaClassesLiteral[contactFormMode] = true;
-      let contentAreaClasses = cx(contentAreaClassesLiteral);
-
-      return (
-        React.createElement("div", {className: contentAreaClasses}, 
-          React.createElement("header", null, this.props.mode === "add"
-                   ? mozL10n.get("add_contact_title")
-                   : mozL10n.get("edit_contact_title")), 
-          React.createElement("div", {className: cx({"form-content-container": true})}, 
-            React.createElement("input", {className: cx({pristine: this.state.pristine}), 
-                   pattern: "\\s*\\S.*", 
-                   placeholder: mozL10n.get("contact_form_name_placeholder"), 
-                   ref: "name", 
-                   required: true, 
-                   type: "text", 
-                   valueLink: this.linkState("name")}), 
-            React.createElement("input", {className: cx({pristine: this.state.pristine}), 
-                   placeholder: mozL10n.get("contact_form_email_placeholder"), 
-                   ref: "email", 
-                   required: phoneOrEmailRequired, 
-                   type: "email", 
-                   valueLink: this.linkState("email")}), 
-            React.createElement("input", {className: cx({pristine: this.state.pristine}), 
-                   placeholder: mozL10n.get("contact_form_fxos_phone_placeholder"), 
-                   ref: "tel", 
-                   required: phoneOrEmailRequired, 
-                   type: "tel", 
-                   valueLink: this.linkState("tel")})
-          ), 
-          React.createElement(ButtonGroup, null, 
-            React.createElement(Button, {additionalClass: "button-cancel", 
-                    caption: mozL10n.get("cancel_button"), 
-                    onClick: this.handleCancelButtonClick}), 
-            React.createElement(Button, {additionalClass: "button-accept", 
-                    caption: this.props.mode === "add"
-                             ? mozL10n.get("add_contact_button")
-                             : mozL10n.get("edit_contact_done_button"), 
-                    onClick: this.handleAcceptButtonClick})
-          )
-        )
-      );
-    }
-  });
-
-  return {
-    ContactDropdown: ContactDropdown,
-    ContactsList: ContactsList,
-    ContactDetail: ContactDetail,
-    ContactDetailsForm: ContactDetailsForm,
-    ContactsControllerView: ContactsControllerView,
-    _getPreferred: getPreferred,
-    _setPreferred: setPreferred
-  };
-})(_, document.mozL10n);
deleted file mode 100644
--- a/browser/components/loop/content/js/contacts.jsx
+++ /dev/null
@@ -1,1030 +0,0 @@
-/* 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/. */
-
-var loop = loop || {};
-loop.contacts = (function(_, mozL10n) {
-  "use strict";
-
-  var sharedMixins = loop.shared.mixins;
-
-  const Button = loop.shared.views.Button;
-  const ButtonGroup = loop.shared.views.ButtonGroup;
-  const CALL_TYPES = loop.shared.utils.CALL_TYPES;
-
-  // Number of contacts to add to the list at the same time.
-  const CONTACTS_CHUNK_SIZE = 100;
-
-  // At least this number of contacts should be present for the filter to appear.
-  const MIN_CONTACTS_FOR_FILTERING = 7;
-
-  let getContactNames = function(contact) {
-    // The model currently does not enforce a name to be present, but we're
-    // going to assume it is awaiting more advanced validation of required fields
-    // by the model. (See bug 1069918)
-    // NOTE: this method of finding a firstname and lastname is not i18n-proof.
-    let names = contact.name[0].split(" ");
-    return {
-      firstName: names.shift(),
-      lastName: names.join(" ")
-    };
-  };
-
-  /** Used to retrieve the preferred email or phone number
-   *  for the contact. Both fields are optional.
-   * @param   {object} contact
-   *          The contact object to get the field from.
-   * @param   {string} field
-   *          The field that should be read out of the contact object.
-   * @returns {object} An object with a 'value' property that hold a string value.
-   */
-  let getPreferred = function(contact, field) {
-    if (!contact[field] || !contact[field].length) {
-      return { value: "" };
-    }
-    return contact[field].find(e => e.pref) || contact[field][0];
-  };
-
-  /** Used to set the preferred email or phone number
-   *  for the contact. Both fields are optional.
-   * @param   {object} contact
-   *          The contact object to get the field from.
-   * @param   {string} field
-   *          The field within the contact to set.
-   * @param   {string} value
-   *          The value that the field should be set to.
-   */
-  let setPreferred = function(contact, field, value) {
-    // Don't clear the field if it doesn't exist.
-    if (!value && (!contact[field] || !contact[field].length)) {
-      return;
-    }
-
-    if (!contact[field]) {
-      contact[field] = [];
-    }
-
-    if (!contact[field].length) {
-      contact[field][0] = {"value": value};
-      return;
-    }
-    // Set the value in the preferred tuple and return.
-    for (let i in contact[field]) {
-      if (contact[field][i].pref) {
-        contact[field][i].value = value;
-        return;
-      }
-    }
-    contact[field][0].value = value;
-  };
-
-  const GravatarPromo = React.createClass({
-    mixins: [sharedMixins.WindowCloseMixin],
-
-    propTypes: {
-      handleUse: React.PropTypes.func.isRequired
-    },
-
-    getInitialState: function() {
-      return {
-        showMe: navigator.mozLoop.getLoopPref("contacts.gravatars.promo") &&
-          !navigator.mozLoop.getLoopPref("contacts.gravatars.show")
-      };
-    },
-
-    handleCloseButtonClick: function() {
-      navigator.mozLoop.setLoopPref("contacts.gravatars.promo", false);
-      this.setState({ showMe: false });
-    },
-
-    handleLinkClick: function(event) {
-      if (!event.target || !event.target.href) {
-        return;
-      }
-
-      event.preventDefault();
-      navigator.mozLoop.openURL(event.target.href);
-      this.closeWindow();
-    },
-
-    handleUseButtonClick: function() {
-      navigator.mozLoop.setLoopPref("contacts.gravatars.promo", false);
-      navigator.mozLoop.setLoopPref("contacts.gravatars.show", true);
-      this.setState({ showMe: false });
-      this.props.handleUse();
-    },
-
-    render: function() {
-      if (!this.state.showMe) {
-        return null;
-      }
-
-      let privacyUrl = navigator.mozLoop.getLoopPref("legal.privacy_url");
-      let message = mozL10n.get("gravatars_promo_message", {
-        "learn_more": React.renderToStaticMarkup(
-          <a href={privacyUrl} target="_blank">
-            {mozL10n.get("gravatars_promo_message_learnmore")}
-          </a>
-        )
-      });
-      return (
-        <div className="contacts-gravatar-promo">
-          <Button additionalClass="button-close"
-                  caption=""
-                  onClick={this.handleCloseButtonClick} />
-          <p dangerouslySetInnerHTML={{__html: message}}
-             onClick={this.handleLinkClick}></p>
-          <div className="contacts-gravatar-avatars">
-            <img src="loop/shared/img/avatars.svg#orange-avatar" />
-            <span className="contacts-gravatar-arrow" />
-            <img src="loop/shared/img/firefox-avatar.svg" />
-          </div>
-          <ButtonGroup additionalClass="contacts-gravatar-buttons">
-            <Button additionalClass="secondary"
-                    caption={mozL10n.get("gravatars_promo_button_nothanks2")}
-                    onClick={this.handleCloseButtonClick}/>
-            <Button additionalClass="secondary"
-                    caption={mozL10n.get("gravatars_promo_button_use2")}
-                    onClick={this.handleUseButtonClick}/>
-          </ButtonGroup>
-        </div>
-      );
-    }
-  });
-
-  const ContactDropdown = React.createClass({
-    propTypes: {
-      // If the contact is blocked or not.
-      blocked: React.PropTypes.bool,
-      canEdit: React.PropTypes.bool,
-      // Position of mouse when opening menu
-      eventPosY: React.PropTypes.number.isRequired,
-      // callback function that provides height and top coordinate for contacts container
-      getContainerCoordinates: React.PropTypes.func.isRequired,
-      handleAction: React.PropTypes.func.isRequired
-    },
-
-    getInitialState: function() {
-      return {
-        openDirUp: false
-      };
-    },
-
-    onItemClick: function(event) {
-      this.props.handleAction(event.currentTarget.dataset.action);
-    },
-
-    componentDidMount: function() {
-      var menuNode = this.getDOMNode();
-      var menuNodeRect = menuNode.getBoundingClientRect();
-      var listNodeCoords = this.props.getContainerCoordinates();
-
-      // Click offset to not display the menu right next to the area clicked.
-      var offset = 10;
-
-      if (this.props.eventPosY + menuNodeRect.height >=
-        listNodeCoords.top + listNodeCoords.height) {
-
-        // Position above click area.
-        menuNode.style.top = this.props.eventPosY - menuNodeRect.height
-          - offset + "px";
-      } else {
-        // Position below click area.
-        menuNode.style.top = this.props.eventPosY + offset + "px";
-      }
-    },
-
-    render: function() {
-      var cx = React.addons.classSet;
-      var dropdownClasses = cx({
-        "dropdown-menu": true,
-        "dropdown-menu-up": this.state.openDirUp
-      });
-      let blockAction = this.props.blocked ? "unblock" : "block";
-      let blockLabel = this.props.blocked ? "unblock_contact_menu_button"
-                                          : "block_contact_menu_button";
-
-      return (
-        <ul className={dropdownClasses}>
-          <li className={cx({ "dropdown-menu-item": true,
-                              "disabled": this.props.blocked,
-                              "video-call-item": true })}
-              data-action="video-call"
-              onClick={this.onItemClick}>
-            {mozL10n.get("video_call_menu_button")}
-          </li>
-          <li className={cx({ "dropdown-menu-item": true,
-                              "disabled": this.props.blocked,
-                              "audio-call-item": true })}
-              data-action="audio-call"
-              onClick={this.onItemClick}>
-            {mozL10n.get("audio_call_menu_button")}
-          </li>
-          <li className={cx({ "dropdown-menu-item": true,
-                              "disabled": !this.props.canEdit })}
-              data-action="edit"
-              onClick={this.onItemClick}>
-            {mozL10n.get("edit_contact_title")}
-          </li>
-          <li className="dropdown-menu-item"
-              data-action={blockAction}
-              onClick={this.onItemClick}>
-            {mozL10n.get(blockLabel)}
-          </li>
-          <li className={cx({ "dropdown-menu-item": true,
-                              "disabled": !this.props.canEdit })}
-              data-action="remove"
-              onClick={this.onItemClick}>
-            {mozL10n.get("confirm_delete_contact_remove_button")}
-          </li>
-        </ul>
-      );
-    }
-  });
-
-  const ContactDetail = React.createClass({
-    propTypes: {
-      contact: React.PropTypes.object.isRequired,
-      getContainerCoordinates: React.PropTypes.func.isRequired,
-      handleContactAction: React.PropTypes.func
-    },
-
-    mixins: [
-      sharedMixins.DropdownMenuMixin()
-    ],
-
-    getInitialState: function() {
-      return {
-        eventPosY: 0
-      };
-    },
-
-    handleShowDropdownClick: function(e) {
-      e.preventDefault();
-      e.stopPropagation();
-
-      this.setState({
-        eventPosY: e.pageY
-      });
-
-      this.toggleDropdownMenu();
-    },
-
-    hideDropdownMenuHandler: function() {
-      // Since this call may be deferred, we need to guard it, for example in
-      // case the contact was removed in the meantime.
-      if (this.isMounted()) {
-        this.hideDropdownMenu();
-      }
-    },
-
-    shouldComponentUpdate: function(nextProps, nextState) {
-      let currContact = this.props.contact;
-      let nextContact = nextProps.contact;
-      let currContactEmail = getPreferred(currContact, "email").value;
-      let nextContactEmail = getPreferred(nextContact, "email").value;
-      return (
-        currContact.name[0] !== nextContact.name[0] ||
-        currContact.blocked !== nextContact.blocked ||
-        currContactEmail !== nextContactEmail ||
-        nextState.showMenu !== this.state.showMenu
-      );
-    },
-
-    handleAction: function(actionName) {
-      if (this.props.handleContactAction) {
-        this.props.handleContactAction(this.props.contact, actionName);
-        this.hideDropdownMenuHandler();
-      }
-    },
-
-    canEdit: function() {
-      // We cannot modify imported contacts.  For the moment, the check for
-      // determining whether the contact is imported is based on its category.
-      return this.props.contact.category[0] !== "google";
-    },
-
-    /**
-     * Callback called when moving cursor away from the conversation entry.
-     * Will close the dropdown menu.
-     */
-    _handleMouseOut: function() {
-      if (this.state.showMenu) {
-        this.toggleDropdownMenu();
-      }
-    },
-
-    render: function() {
-      let names = getContactNames(this.props.contact);
-      let email = getPreferred(this.props.contact, "email");
-      let avatarSrc = navigator.mozLoop.getUserAvatar(email.value);
-      let cx = React.addons.classSet;
-      let contactCSSClass = cx({
-        contact: true,
-        blocked: this.props.contact.blocked
-      });
-      let avatarCSSClass = cx({
-        avatar: true,
-        defaultAvatar: !avatarSrc
-      });
-      return (
-        <li className={contactCSSClass}
-            onMouseLeave={this._handleMouseOut}>
-          <div className={avatarCSSClass}>
-            {avatarSrc ? <img src={avatarSrc} /> : null}
-          </div>
-          <div className="details">
-            <div className="username"><strong>{names.firstName}</strong> {names.lastName}
-              <i className={cx({"icon icon-blocked": this.props.contact.blocked})} />
-            </div>
-            <div className="email">{email.value}</div>
-          </div>
-          <div className="icons">
-            <i className="icon icon-contact-video-call"
-               onClick={this.handleAction.bind(null, "video-call")} />
-            <i className="icon icon-vertical-ellipsis icon-contact-menu-button"
-               onClick={this.handleShowDropdownClick} />
-          </div>
-          {this.state.showMenu
-            ? <ContactDropdown blocked={this.props.contact.blocked}
-                               canEdit={this.canEdit()}
-                               eventPosY={this.state.eventPosY}
-                               getContainerCoordinates={this.props.getContainerCoordinates}
-                               handleAction={this.handleAction} />
-            : null
-          }
-        </li>
-      );
-    }
-  });
-
-  const ContactsList = React.createClass({
-    mixins: [
-      React.addons.LinkedStateMixin,
-      loop.shared.mixins.WindowCloseMixin
-    ],
-
-    propTypes: {
-      mozLoop: React.PropTypes.object.isRequired,
-      notifications: React.PropTypes.instanceOf(loop.shared.models.NotificationCollection).isRequired,
-      switchToContactAdd: React.PropTypes.func.isRequired,
-      switchToContactEdit: React.PropTypes.func.isRequired
-    },
-
-    /**
-     * Contacts collection object
-     */
-    contacts: null,
-
-    /**
-     * User profile
-     */
-    _userProfile: null,
-
-    getInitialState: function() {
-      return {
-        importBusy: false,
-        filter: ""
-      };
-    },
-
-    refresh: function(callback = function() {}) {
-      let contactsAPI = this.props.mozLoop.contacts;
-
-      this.handleContactRemoveAll();
-
-      contactsAPI.getAll((err, contacts) => {
-        if (err) {
-          callback(err);
-          return;
-        }
-
-        // Add contacts already present in the DB. We do this in timed chunks to
-        // circumvent blocking the main event loop.
-        let addContactsInChunks = () => {
-          contacts.splice(0, CONTACTS_CHUNK_SIZE).forEach(contact => {
-            this.handleContactAddOrUpdate(contact, false);
-          });
-          if (contacts.length) {
-            setTimeout(addContactsInChunks, 0);
-          } else {
-            callback();
-          }
-          this.forceUpdate();
-        };
-
-        addContactsInChunks(contacts);
-      });
-    },
-
-    componentWillMount: function() {
-      // Take the time to initialize class variables that are used outside
-      // `this.state`.
-      this.contacts = {};
-      this._userProfile = this.props.mozLoop.userProfile;
-    },
-
-    componentDidMount: function() {
-      window.addEventListener("LoopStatusChanged", this._onStatusChanged);
-
-      this.refresh(err => {
-        if (err) {
-          throw err;
-        }
-
-        let contactsAPI = this.props.mozLoop.contacts;
-
-        // Listen for contact changes/ updates.
-        contactsAPI.on("add", (eventName, contact) => {
-          this.handleContactAddOrUpdate(contact);
-        });
-        contactsAPI.on("remove", (eventName, contact) => {
-          this.handleContactRemove(contact);
-        });
-        contactsAPI.on("removeAll", () => {
-          this.handleContactRemoveAll();
-        });
-        contactsAPI.on("update", (eventName, contact) => {
-          this.handleContactAddOrUpdate(contact);
-        });
-      });
-    },
-
-    componentWillUnmount: function() {
-      window.removeEventListener("LoopStatusChanged", this._onStatusChanged);
-    },
-
-    /*
-     * Filter a user by name, email or phone number.
-     * Takes in an input to filter by and returns a filter function which
-     * expects a contact.
-     *
-     * @returns {Function}
-     */
-    filterContact: function(filter) {
-      return function(contact) {
-        return getPreferred(contact, "name").toLocaleLowerCase().includes(filter) ||
-          getPreferred(contact, "email").value.toLocaleLowerCase().includes(filter) ||
-          getPreferred(contact, "tel").value.toLocaleLowerCase().includes(filter);
-      };
-    },
-
-    /*
-     * Takes all contacts, it groups and filters them before rendering.
-     */
-    _filterContactsList: function() {
-      let shownContacts = _.groupBy(this.contacts, function(contact) {
-        return contact.blocked ? "blocked" : "available";
-      });
-
-      if (this._shouldShowFilter()) {
-        let filter = this.state.filter.trim().toLocaleLowerCase();
-        let filterFn = this.filterContact(filter);
-        if (filter) {
-          if (shownContacts.available) {
-            shownContacts.available = shownContacts.available.filter(filterFn);
-            // Filter can return an empty array.
-            if (!shownContacts.available.length) {
-              shownContacts.available = null;
-            }
-          }
-          if (shownContacts.blocked) {
-            shownContacts.blocked = shownContacts.blocked.filter(filterFn);
-            // Filter can return an empty array.
-            if (!shownContacts.blocked.length) {
-              shownContacts.blocked = null;
-            }
-          }
-        }
-      }
-
-      return shownContacts;
-    },
-
-    /*
-     * Decide to render contacts filter based on the number of contacts.
-     *
-     * @returns {bool}
-     */
-    _shouldShowFilter: function() {
-      return Object.getOwnPropertyNames(this.contacts).length >=
-        MIN_CONTACTS_FOR_FILTERING;
-    },
-
-    _onStatusChanged: function() {
-      let profile = this.props.mozLoop.userProfile;
-      let currUid = this._userProfile ? this._userProfile.uid : null;
-      let newUid = profile ? profile.uid : null;
-      if (currUid !== newUid) {
-        // On profile change (login, logout), reload all contacts.
-        this._userProfile = profile;
-        // The following will do a forceUpdate() for us.
-        this.refresh();
-      }
-    },
-
-    handleContactAddOrUpdate: function(contact, render = true) {
-      let contacts = this.contacts;
-      let guid = String(contact._guid);
-      contacts[guid] = contact;
-      if (render) {
-        this.forceUpdate();
-      }
-    },
-
-    handleContactRemove: function(contact) {
-      let contacts = this.contacts;
-      let guid = String(contact._guid);
-      if (!contacts[guid]) {
-        return;
-      }
-      delete contacts[guid];
-      this.forceUpdate();
-    },
-
-    handleContactRemoveAll: function() {
-      // Do not allow any race conditions when removing all contacts.
-      this.contacts = {};
-      this.forceUpdate();
-    },
-
-    handleImportButtonClick: function() {
-      this.setState({ importBusy: true });
-      this.props.mozLoop.startImport({
-        service: "google"
-      }, (err, stats) => {
-        this.setState({ importBusy: false });
-        if (err) {
-          console.error("Contact import error", err);
-          this.props.notifications.errorL10n("import_contacts_failure_message");
-          return;
-        }
-        this.props.notifications.successL10n("import_contacts_success_message", {
-          num: stats.success,
-          total: stats.success
-        });
-      });
-    },
-
-    handleAddContactButtonClick: function() {
-      this.props.switchToContactAdd();
-    },
-
-    handleContactAction: function(contact, actionName) {
-      switch (actionName) {
-        case "edit":
-          this.props.switchToContactEdit(contact);
-          break;
-        case "remove":
-          this.props.mozLoop.confirm({
-            message: mozL10n.get("confirm_delete_contact_alert"),
-            okButton: mozL10n.get("confirm_delete_contact_remove_button"),
-            cancelButton: mozL10n.get("confirm_delete_contact_cancel_button")
-          }, (error, result) => {
-            if (error) {
-              throw error;
-            }
-
-            if (!result) {
-              return;
-            }
-
-            this.props.mozLoop.contacts.remove(contact._guid, err => {
-              if (err) {
-                throw err;
-              }
-            });
-          });
-          break;
-        case "block":
-        case "unblock":
-          // Invoke the API named like the action.
-          this.props.mozLoop.contacts[actionName](contact._guid, err => {
-            if (err) {
-              throw err;
-            }
-          });
-          break;
-        case "video-call":
-          if (!contact.blocked) {
-            this.props.mozLoop.calls.startDirectCall(contact, CALL_TYPES.AUDIO_VIDEO);
-            this.closeWindow();
-          }
-          break;
-        case "audio-call":
-          if (!contact.blocked) {
-            this.props.mozLoop.calls.startDirectCall(contact, CALL_TYPES.AUDIO_ONLY);
-            this.closeWindow();
-          }
-          break;
-        default:
-          console.error("Unrecognized action: " + actionName