Merge fx-team to m-c. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Sat, 29 Oct 2016 09:20:42 -0400
changeset 320148 1b170b39ed6bdbde366233ab84594bdaaa960a5a
parent 320147 409d8a10d867013fd454ae4e27a42d5b0e40aa31 (diff)
parent 319840 71536044069576fc877bf7ef0ba13a4ada793706 (current diff)
child 320149 950739a54a07f38d8659da430429892a65967983
child 320186 a3b6b6e39c7965561fc750d022bee96055731226
push id20749
push userryanvm@gmail.com
push dateSat, 29 Oct 2016 13:21:21 +0000
treeherderfx-team@1b170b39ed6b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone52.0a1
Merge fx-team to m-c. a=merge
--- a/accessible/atk/UtilInterface.cpp
+++ b/accessible/atk/UtilInterface.cpp
@@ -256,18 +256,24 @@ mai_util_add_key_event_listener(AtkKeySn
   if (MOZ_UNLIKELY(!listener)) {
     return 0;
   }
 
   static guint key = 0;
 
   if (!sKey_listener_list) {
     sKey_listener_list = g_hash_table_new(nullptr, nullptr);
+  }
+
+  // If we have no registered event listeners then we need to (re)install the
+  // key event snooper.
+  if (g_hash_table_size(sKey_listener_list) == 0) {
     sKey_snooper_id = gtk_key_snooper_install(mai_key_snooper, data);
   }
+
   AtkKeySnoopFuncPointer atkKeySnoop;
   atkKeySnoop.func_ptr = listener;
   key++;
   g_hash_table_insert(sKey_listener_list, GUINT_TO_POINTER(key),
                       atkKeySnoop.data);
   return key;
 }
 
--- a/accessible/base/DocManager.cpp
+++ b/accessible/base/DocManager.cpp
@@ -508,18 +508,25 @@ DocManager::CreateDocOrRootAccessible(ns
         nsCOMPtr<nsITabChild> tabChild = docShell->GetTabChild();
 
         // XXX We may need to handle the case that we don't have a tab child
         // differently.  It may be that this will cause us to fail to notify
         // the parent process about important accessible documents.
         if (tabChild) {
           DocAccessibleChild* ipcDoc = new DocAccessibleChild(docAcc);
           docAcc->SetIPCDoc(ipcDoc);
+
           static_cast<TabChild*>(tabChild.get())->
-            SendPDocAccessibleConstructor(ipcDoc, nullptr, 0);
+            SendPDocAccessibleConstructor(ipcDoc, nullptr, 0,
+#if defined(XP_WIN)
+                                          AccessibleWrap::GetChildIDFor(docAcc)
+#else
+                                          0
+#endif
+                                          );
 
 #if defined(XP_WIN)
           IAccessibleHolder holder(CreateHolderFromAccessible(docAcc));
           ipcDoc->SendCOMProxy(holder);
 #endif
         }
       }
     }
--- a/accessible/base/NotificationController.cpp
+++ b/accessible/base/NotificationController.cpp
@@ -417,22 +417,25 @@ NotificationController::WillRefresh(mozi
         continue;
       }
 
       ipcDoc = new DocAccessibleChild(childDoc);
       childDoc->SetIPCDoc(ipcDoc);
       nsCOMPtr<nsITabChild> tabChild =
         do_GetInterface(mDocument->DocumentNode()->GetDocShell());
       if (tabChild) {
+        MOZ_ASSERT(parentIPCDoc);
         static_cast<TabChild*>(tabChild.get())->
-          SendPDocAccessibleConstructor(ipcDoc, parentIPCDoc, id);
+          SendPDocAccessibleConstructor(ipcDoc, parentIPCDoc, id,
 #if defined(XP_WIN)
-        MOZ_ASSERT(parentIPCDoc);
-        ipcDoc->SendMsaaID(AccessibleWrap::GetChildIDFor(childDoc));
+                                        AccessibleWrap::GetChildIDFor(childDoc)
+#else
+                                        0
 #endif
+                                        );
       }
     }
   }
 
   mObservingState = eRefreshObserving;
   if (!mDocument)
     return;
 
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -39,16 +39,17 @@
 #include "xpcAccessibleDocument.h"
 
 #ifdef MOZ_ACCESSIBILITY_ATK
 #include "AtkSocketAccessible.h"
 #endif
 
 #ifdef XP_WIN
 #include "mozilla/a11y/Compatibility.h"
+#include "mozilla/dom/ContentChild.h"
 #include "HTMLWin32ObjectAccessible.h"
 #include "mozilla/StaticPtr.h"
 #endif
 
 #ifdef A11Y_LOG
 #include "Logging.h"
 #endif
 
@@ -1259,20 +1260,33 @@ nsAccessibilityService::Init()
 
 #ifdef A11Y_LOG
   logging::CheckEnv();
 #endif
 
   gAccessibilityService = this;
   NS_ADDREF(gAccessibilityService); // will release in Shutdown()
 
-  if (XRE_IsParentProcess())
+  if (XRE_IsParentProcess()) {
     gApplicationAccessible = new ApplicationAccessibleWrap();
-  else
+  } else {
+#if defined(XP_WIN)
+    dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
+    MOZ_ASSERT(contentChild);
+    // If we were instantiated by the chrome process, GetMsaaID() will return
+    // a non-zero value and we may safely continue with initialization.
+    if (!contentChild->GetMsaaID()) {
+      // Since we were not instantiated by chrome, we need to synchronously
+      // obtain a MSAA content process id.
+      contentChild->SendGetA11yContentId();
+    }
+#endif // defined(XP_WIN)
+
     gApplicationAccessible = new ApplicationAccessible();
+  }
 
   NS_ADDREF(gApplicationAccessible); // will release in Shutdown()
   gApplicationAccessible->Init();
 
 #ifdef MOZ_CRASHREPORTER
   CrashReporter::
     AnnotateCrashReport(NS_LITERAL_CSTRING("Accessibility"),
                         NS_LITERAL_CSTRING("Active"));
--- a/accessible/ipc/DocAccessibleParent.cpp
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -455,45 +455,33 @@ DocAccessibleParent::GetXPCAccessible(Pr
   xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this);
   MOZ_ASSERT(doc);
 
   return doc->GetXPCAccessible(aProxy);
 }
 
 #if defined(XP_WIN)
 /**
- * @param aMsaaID The MSAA ID that was generated by content that the chrome
- *        process should assign to this DocAccessibleParent.
  * @param aCOMProxy COM Proxy to the document in the content process.
  * @param aParentCOMProxy COM Proxy to the OuterDocAccessible that is
  *        the parent of the document. The content process will use this
  *        proxy when traversing up across the content/chrome boundary.
  */
 bool
-DocAccessibleParent::RecvCOMProxy(const int32_t& aMsaaID,
-                                  const IAccessibleHolder& aCOMProxy,
+DocAccessibleParent::RecvCOMProxy(const IAccessibleHolder& aCOMProxy,
                                   IAccessibleHolder* aParentCOMProxy)
 {
-  WrapperFor(this)->SetID(aMsaaID);
-
   RefPtr<IAccessible> ptr(aCOMProxy.Get());
   SetCOMInterface(ptr);
 
   Accessible* outerDoc = OuterDocOfRemoteBrowser();
   IAccessible* rawNative = nullptr;
   if (outerDoc) {
     outerDoc->GetNativeInterface((void**) &rawNative);
   }
 
   aParentCOMProxy->Set(IAccessibleHolder::COMPtrType(rawNative));
   return true;
 }
-
-bool
-DocAccessibleParent::RecvMsaaID(const int32_t& aMsaaID)
-{
-  WrapperFor(this)->SetID(aMsaaID);
-  return true;
-}
 #endif // defined(XP_WIN)
 
 } // a11y
 } // mozilla
--- a/accessible/ipc/DocAccessibleParent.h
+++ b/accessible/ipc/DocAccessibleParent.h
@@ -139,21 +139,18 @@ public:
   const ProxyAccessible* GetAccessible(uintptr_t aID) const
     { return const_cast<DocAccessibleParent*>(this)->GetAccessible(aID); }
 
   size_t ChildDocCount() const { return mChildDocs.Length(); }
   const DocAccessibleParent* ChildDocAt(size_t aIdx) const
     { return mChildDocs[aIdx]; }
 
 #if defined(XP_WIN)
-  virtual bool RecvCOMProxy(const int32_t& aMsaaID,
-                            const IAccessibleHolder& aCOMProxy,
+  virtual bool RecvCOMProxy(const IAccessibleHolder& aCOMProxy,
                             IAccessibleHolder* aParentCOMProxy) override;
-
-  virtual bool RecvMsaaID(const int32_t& aMsaaID) override;
 #endif
 
 private:
 
   class ProxyEntry : public PLDHashEntryHdr
   {
   public:
     explicit ProxyEntry(const void*) : mProxy(nullptr) {}
--- a/accessible/ipc/win/DocAccessibleChild.cpp
+++ b/accessible/ipc/win/DocAccessibleChild.cpp
@@ -28,17 +28,16 @@ DocAccessibleChild::DocAccessibleChild(D
 DocAccessibleChild::~DocAccessibleChild()
 {
   MOZ_COUNT_DTOR_INHERITED(DocAccessibleChild, DocAccessibleChildBase);
 }
 
 void
 DocAccessibleChild::SendCOMProxy(const IAccessibleHolder& aProxy)
 {
-  int32_t msaaID = AccessibleWrap::GetChildIDFor(mDoc);
   IAccessibleHolder parentProxy;
-  PDocAccessibleChild::SendCOMProxy(msaaID, aProxy, &parentProxy);
+  PDocAccessibleChild::SendCOMProxy(aProxy, &parentProxy);
   mParentProxy.reset(parentProxy.Release());
 }
 
 } // namespace a11y
 } // namespace mozilla
 
--- a/accessible/ipc/win/PDocAccessible.ipdl
+++ b/accessible/ipc/win/PDocAccessible.ipdl
@@ -58,19 +58,17 @@ parent:
   /*
    * Tell the parent document to bind the existing document as a new child
    * document.
    */
   async BindChildDoc(PDocAccessible aChildDoc, uint64_t aID);
 
   // For now we'll add the command to send the proxy here. This might move to
   // PDocAccessible constructor in PBrowser.
-  sync COMProxy(int32_t aMsaaID, IAccessibleHolder aDocCOMProxy)
+  sync COMProxy(IAccessibleHolder aDocCOMProxy)
     returns(IAccessibleHolder aParentCOMProxy);
 
-  async MsaaID(int32_t aMsaaID);
-
 child:
   async __delete__();
 };
 
 }
 }
--- a/accessible/ipc/win/ProxyAccessible.cpp
+++ b/accessible/ipc/win/ProxyAccessible.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "Accessible2.h"
 #include "ProxyAccessible.h"
+#include "ia2AccessibleValue.h"
 #include "mozilla/a11y/DocAccessibleParent.h"
 #include "DocAccessible.h"
 #include "mozilla/a11y/DocManager.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/Unused.h"
 #include "mozilla/a11y/Platform.h"
 #include "RelationType.h"
@@ -44,16 +45,55 @@ ProxyAccessible::GetCOMInterface(void** 
     thisPtr->mCOMProxy = wrap->GetIAccessibleFor(realId, &isDefunct);
   }
 
   RefPtr<IAccessible> addRefed = mCOMProxy;
   addRefed.forget(aOutAccessible);
   return !!mCOMProxy;
 }
 
+/**
+ * Specializations of this template map an IAccessible type to its IID
+ */
+template<typename Interface> struct InterfaceIID {};
+
+template<>
+struct InterfaceIID<IAccessibleValue>
+{
+  static REFIID Value() { return IID_IAccessibleValue; }
+};
+
+template<>
+struct InterfaceIID<IAccessibleText>
+{
+  static REFIID Value() { return IID_IAccessibleText; }
+};
+
+/**
+ * Get the COM proxy for this proxy accessible and QueryInterface it with the
+ * correct IID
+ */
+template<typename Interface>
+static already_AddRefed<Interface>
+QueryInterface(const ProxyAccessible* aProxy)
+{
+  RefPtr<IAccessible> acc;
+  if (!aProxy->GetCOMInterface((void**)getter_AddRefs(acc))) {
+    return nullptr;
+  }
+
+  RefPtr<Interface> acc2;
+  if (FAILED(acc->QueryInterface(InterfaceIID<Interface>::Value(),
+                                 (void**)getter_AddRefs(acc2)))) {
+    return nullptr;
+  }
+
+  return acc2.forget();
+}
+
 void
 ProxyAccessible::Name(nsString& aName) const
 {
   aName.Truncate();
   RefPtr<IAccessible> acc;
   if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
     return;
   }
@@ -272,10 +312,288 @@ ProxyAccessible::Attributes(nsTArray<Att
     return;
   }
 
   ConvertBSTRAttributesToArray(nsDependentString((wchar_t*)attrs,
                                                  attrsWrap.length()),
                                aAttrs);
 }
 
+double
+ProxyAccessible::CurValue()
+{
+  RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this);
+  if (!acc) {
+    return UnspecifiedNaN<double>();
+  }
+
+  VARIANT currentValue;
+  HRESULT hr = acc->get_currentValue(&currentValue);
+  if (FAILED(hr) || currentValue.vt != VT_R8) {
+    return UnspecifiedNaN<double>();
+  }
+
+  return currentValue.dblVal;
+}
+
+bool
+ProxyAccessible::SetCurValue(double aValue)
+{
+  RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this);
+  if (!acc) {
+    return false;
+  }
+
+  VARIANT currentValue;
+  VariantInit(&currentValue);
+  currentValue.vt = VT_R8;
+  currentValue.dblVal = aValue;
+  HRESULT hr = acc->setCurrentValue(currentValue);
+  return SUCCEEDED(hr);
+}
+
+double
+ProxyAccessible::MinValue()
+{
+  RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this);
+  if (!acc) {
+    return UnspecifiedNaN<double>();
+  }
+
+  VARIANT minimumValue;
+  HRESULT hr = acc->get_minimumValue(&minimumValue);
+  if (FAILED(hr) || minimumValue.vt != VT_R8) {
+    return UnspecifiedNaN<double>();
+  }
+
+  return minimumValue.dblVal;
+}
+
+double
+ProxyAccessible::MaxValue()
+{
+  RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this);
+  if (!acc) {
+    return UnspecifiedNaN<double>();
+  }
+
+  VARIANT maximumValue;
+  HRESULT hr = acc->get_maximumValue(&maximumValue);
+  if (FAILED(hr) || maximumValue.vt != VT_R8) {
+    return UnspecifiedNaN<double>();
+  }
+
+  return maximumValue.dblVal;
+}
+
+static IA2TextBoundaryType
+GetIA2TextBoundary(AccessibleTextBoundary aGeckoBoundaryType)
+{
+  switch (aGeckoBoundaryType) {
+    case nsIAccessibleText::BOUNDARY_CHAR:
+      return IA2_TEXT_BOUNDARY_CHAR;
+    case nsIAccessibleText::BOUNDARY_WORD_START:
+      return IA2_TEXT_BOUNDARY_WORD;
+    case nsIAccessibleText::BOUNDARY_LINE_START:
+      return IA2_TEXT_BOUNDARY_LINE;
+    default:
+      MOZ_RELEASE_ASSERT(false);
+  }
+}
+
+bool
+ProxyAccessible::TextSubstring(int32_t aStartOffset, int32_t aEndOffset,
+                               nsString& aText) const
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return false;
+  }
+
+  BSTR result;
+  HRESULT hr = acc->get_text(static_cast<long>(aStartOffset),
+                             static_cast<long>(aEndOffset), &result);
+  if (FAILED(hr)) {
+    return false;
+  }
+
+  _bstr_t resultWrap(result, false);
+  aText = (wchar_t*)result;
+
+  return true;
+}
+
+void
+ProxyAccessible::GetTextBeforeOffset(int32_t aOffset,
+                                    AccessibleTextBoundary aBoundaryType,
+                                    nsString& aText, int32_t* aStartOffset,
+                                    int32_t* aEndOffset)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return;
+  }
+
+  BSTR result;
+  long start, end;
+  HRESULT hr = acc->get_textBeforeOffset(aOffset,
+                                         GetIA2TextBoundary(aBoundaryType),
+                                         &start, &end, &result);
+  if (FAILED(hr)) {
+    return;
+  }
+
+  _bstr_t resultWrap(result, false);
+  *aStartOffset = start;
+  *aEndOffset = end;
+  aText = (wchar_t*)result;
+}
+
+void
+ProxyAccessible::GetTextAfterOffset(int32_t aOffset,
+                                    AccessibleTextBoundary aBoundaryType,
+                                    nsString& aText, int32_t* aStartOffset,
+                                    int32_t* aEndOffset)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return;
+  }
+
+  BSTR result;
+  long start, end;
+  HRESULT hr = acc->get_textAfterOffset(aOffset,
+                                        GetIA2TextBoundary(aBoundaryType),
+                                        &start, &end, &result);
+  if (FAILED(hr)) {
+    return;
+  }
+
+  _bstr_t resultWrap(result, false);
+  aText = (wchar_t*)result;
+  *aStartOffset = start;
+  *aEndOffset = end;
+}
+
+void
+ProxyAccessible::GetTextAtOffset(int32_t aOffset,
+                                    AccessibleTextBoundary aBoundaryType,
+                                    nsString& aText, int32_t* aStartOffset,
+                                    int32_t* aEndOffset)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return;
+  }
+
+  BSTR result;
+  long start, end;
+  HRESULT hr = acc->get_textAtOffset(aOffset, GetIA2TextBoundary(aBoundaryType),
+                                     &start, &end, &result);
+  if (FAILED(hr)) {
+    return;
+  }
+
+  _bstr_t resultWrap(result, false);
+  aText = (wchar_t*)result;
+  *aStartOffset = start;
+  *aEndOffset = end;
+}
+
+bool
+ProxyAccessible::AddToSelection(int32_t aStartOffset, int32_t aEndOffset)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return false;
+  }
+
+  return SUCCEEDED(acc->addSelection(static_cast<long>(aStartOffset),
+                                     static_cast<long>(aEndOffset)));
+}
+
+bool
+ProxyAccessible::RemoveFromSelection(int32_t aSelectionNum)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return false;
+  }
+
+  return SUCCEEDED(acc->removeSelection(static_cast<long>(aSelectionNum)));
+}
+
+int32_t
+ProxyAccessible::CaretOffset()
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return -1;
+  }
+
+  long offset;
+  HRESULT hr = acc->get_caretOffset(&offset);
+  if (FAILED(hr)) {
+    return -1;
+  }
+
+  return static_cast<int32_t>(offset);
+}
+
+void
+ProxyAccessible::SetCaretOffset(int32_t aOffset)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return;
+  }
+
+  acc->setCaretOffset(static_cast<long>(aOffset));
+}
+
+/**
+ * aScrollType should be one of the nsIAccessiblescrollType constants.
+ */
+void
+ProxyAccessible::ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
+                                   uint32_t aScrollType)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return;
+  }
+
+  acc->scrollSubstringTo(static_cast<long>(aStartOffset),
+                         static_cast<long>(aEndOffset),
+                         static_cast<IA2ScrollType>(aScrollType));
+}
+
+/**
+ * aCoordinateType is one of the nsIAccessibleCoordinateType constants.
+ */
+void
+ProxyAccessible::ScrollSubstringToPoint(int32_t aStartOffset, int32_t aEndOffset,
+                                        uint32_t aCoordinateType, int32_t aX,
+                                        int32_t aY)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return;
+  }
+
+  IA2CoordinateType coordType;
+  if (aCoordinateType == nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE) {
+    coordType = IA2_COORDTYPE_SCREEN_RELATIVE;
+  } else if (aCoordinateType == nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE) {
+    coordType = IA2_COORDTYPE_PARENT_RELATIVE;
+  } else {
+    MOZ_RELEASE_ASSERT(false, "unsupported coord type");
+  }
+
+  acc->scrollSubstringToPoint(static_cast<long>(aStartOffset),
+                              static_cast<long>(aEndOffset),
+                              coordType,
+                              static_cast<long>(aX),
+                              static_cast<long>(aY));
+}
+
 } // namespace a11y
 } // namespace mozilla
--- a/accessible/tests/browser/e10s/events.js
+++ b/accessible/tests/browser/e10s/events.js
@@ -63,17 +63,21 @@ function waitForEvent(eventType, expecte
   return new Promise(resolve => {
     let eventObserver = {
       observe(subject, topic, data) {
         if (topic !== 'accessible-event') {
           return;
         }
 
         let event = subject.QueryInterface(nsIAccessibleEvent);
-        Logger.log(eventToString(event));
+        if (Logger.enabled) {
+          // Avoid calling eventToString if the logger isn't enabled in order
+          // to avoid an intermittent crash (bug 1307645).
+          Logger.log(eventToString(event));
+        }
 
         // If event type does not match expected type, skip the event.
         if (event.eventType !== eventType) {
           return;
         }
 
         let acc = event.accessible;
         let id = getAccessibleDOMNodeID(acc);
--- a/accessible/windows/ia2/ia2AccessibleHyperlink.cpp
+++ b/accessible/windows/ia2/ia2AccessibleHyperlink.cpp
@@ -69,18 +69,17 @@ ia2AccessibleHyperlink::get_anchor(long 
   if (!anchor)
     return S_FALSE;
 
   void* instancePtr = nullptr;
   HRESULT result = anchor->QueryInterface(IID_IUnknown, &instancePtr);
   if (FAILED(result))
     return result;
 
-  IUnknown* unknownPtr = static_cast<IUnknown*>(instancePtr);
-  aAnchor->ppunkVal = &unknownPtr;
+  aAnchor->punkVal = static_cast<IUnknown*>(instancePtr);
   aAnchor->vt = VT_UNKNOWN;
   return S_OK;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleHyperlink::get_anchorTarget(long aIndex, VARIANT* aAnchorTarget)
--- a/accessible/windows/msaa/MsaaIdGenerator.cpp
+++ b/accessible/windows/msaa/MsaaIdGenerator.cpp
@@ -80,36 +80,34 @@ public:
 private:
   MsaaID  mID;
 };
 
 } // namespace detail
 
 constexpr MsaaIdGenerator::MsaaIdGenerator()
   : mIDSet(kNumUniqueIDBits)
-  , mContentProcessID(0)
 {}
 
 uint32_t
 MsaaIdGenerator::GetID()
 {
-  static const uint32_t kContentProcessId = ResolveContentProcessID();
   uint32_t id = mIDSet.GetID();
   MOZ_ASSERT(id <= ((1UL << kNumUniqueIDBits) - 1UL));
-  return detail::BuildMsaaID(id, kContentProcessId);
+  return detail::BuildMsaaID(id, ResolveContentProcessID());
 }
 
 void
 MsaaIdGenerator::ReleaseID(AccessibleWrap* aAccWrap)
 {
   MOZ_ASSERT(aAccWrap);
   uint32_t id = aAccWrap->GetExistingID();
   MOZ_ASSERT(id != AccessibleWrap::kNoID);
   detail::MsaaIDCracker cracked(id);
-  if (cracked.GetContentProcessId() != mContentProcessID) {
+  if (cracked.GetContentProcessId() != ResolveContentProcessID()) {
     // This may happen if chrome holds a proxy whose ID was originally generated
     // by a content process. Since ReleaseID only has meaning in the process
     // that originally generated that ID, we ignore ReleaseID calls for any ID
     // that did not come from the current process.
     MOZ_ASSERT(aAccWrap->IsProxy());
     return;
   }
   mIDSet.ReleaseID(cracked.GetUniqueId());
@@ -121,19 +119,18 @@ MsaaIdGenerator::IsChromeID(uint32_t aID
   detail::MsaaIDCracker cracked(aID);
   return cracked.GetContentProcessId() == 0;
 }
 
 bool
 MsaaIdGenerator::IsIDForThisContentProcess(uint32_t aID)
 {
   MOZ_ASSERT(XRE_IsContentProcess());
-  static const uint32_t kContentProcessId = ResolveContentProcessID();
   detail::MsaaIDCracker cracked(aID);
-  return cracked.GetContentProcessId() == kContentProcessId;
+  return cracked.GetContentProcessId() == ResolveContentProcessID();
 }
 
 bool
 MsaaIdGenerator::IsIDForContentProcess(uint32_t aID,
                                        dom::ContentParentId aIPCContentProcessId)
 {
   MOZ_ASSERT(XRE_IsParentProcess());
   detail::MsaaIDCracker cracked(aID);
@@ -153,20 +150,20 @@ MsaaIdGenerator::IsSameContentProcessFor
 uint32_t
 MsaaIdGenerator::ResolveContentProcessID()
 {
   if (XRE_IsParentProcess()) {
     return 0;
   }
 
   dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
-  Unused << contentChild->SendGetA11yContentId(&mContentProcessID);
+  uint32_t result = contentChild->GetMsaaID();
 
-  MOZ_ASSERT(mContentProcessID);
-  return mContentProcessID;
+  MOZ_ASSERT(result);
+  return result;
 }
 
 /**
  * Each dom::ContentParent has a 64-bit ID. This ID is monotonically increasing
  * with each new content process, so those IDs are effectively single-use. OTOH,
  * MSAA requires 32-bit IDs. Since we only allocate kNumContentProcessIDBits for
  * the content process ID component, the MSAA content process ID value must be
  * reusable. sContentParentIdMap holds the current associations between
--- a/accessible/windows/msaa/MsaaIdGenerator.h
+++ b/accessible/windows/msaa/MsaaIdGenerator.h
@@ -43,15 +43,14 @@ public:
   uint32_t GetContentProcessIDFor(dom::ContentParentId aIPCContentProcessID);
   void ReleaseContentProcessIDFor(dom::ContentParentId aIPCContentProcessID);
 
 private:
   uint32_t ResolveContentProcessID();
 
 private:
   IDSet     mIDSet;
-  uint32_t  mContentProcessID;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif // mozilla_a11y_MsaaIdGenerator_h
--- a/accessible/xpcom/xpcAccessibleHyperText.cpp
+++ b/accessible/xpcom/xpcAccessibleHyperText.cpp
@@ -63,23 +63,19 @@ xpcAccessibleHyperText::GetText(int32_t 
   aText.Truncate();
 
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->TextSubstring(aStartOffset, aEndOffset, aText);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     nsString text;
     mIntl.AsProxy()->TextSubstring(aStartOffset, aEndOffset, text);
     aText = text;
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetTextBeforeOffset(int32_t aOffset,
                                             AccessibleTextBoundary aBoundaryType,
                                             int32_t* aStartOffset,
@@ -93,24 +89,20 @@ xpcAccessibleHyperText::GetTextBeforeOff
 
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->TextBeforeOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, 
                              aText);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     nsString text;
     mIntl.AsProxy()->GetTextBeforeOffset(aOffset, aBoundaryType, text,
                                          aStartOffset, aEndOffset);
     aText = text;
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetTextAtOffset(int32_t aOffset,
                                         AccessibleTextBoundary aBoundaryType,
                                         int32_t* aStartOffset,
@@ -123,24 +115,20 @@ xpcAccessibleHyperText::GetTextAtOffset(
 
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->TextAtOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, 
                          aText);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     nsString text;
     mIntl.AsProxy()->GetTextAtOffset(aOffset, aBoundaryType, text, 
                                      aStartOffset, aEndOffset);
     aText = text;
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetTextAfterOffset(int32_t aOffset,
                                            AccessibleTextBoundary aBoundaryType,
                                            int32_t* aStartOffset,
@@ -153,24 +141,20 @@ xpcAccessibleHyperText::GetTextAfterOffs
 
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->TextAfterOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, 
                             aText);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     nsString text;
     mIntl.AsProxy()->GetTextAfterOffset(aOffset, aBoundaryType, text, 
                                         aStartOffset, aEndOffset);
     aText = text;
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetCharacterAtOffset(int32_t aOffset,
                                              char16_t* aCharacter)
 {
@@ -350,39 +334,31 @@ xpcAccessibleHyperText::GetCaretOffset(i
   *aCaretOffset = -1;
 
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     *aCaretOffset = Intl()->CaretOffset();
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     *aCaretOffset = mIntl.AsProxy()->CaretOffset();
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::SetCaretOffset(int32_t aCaretOffset)
 {
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->SetCaretOffset(aCaretOffset);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     mIntl.AsProxy()->SetCaretOffset(aCaretOffset);
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetSelectionCount(int32_t* aSelectionCount)
 {
   NS_ENSURE_ARG_POINTER(aSelectionCount);
@@ -468,59 +444,47 @@ NS_IMETHODIMP
 xpcAccessibleHyperText::AddSelection(int32_t aStartOffset, int32_t aEndOffset)
 {
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->AddToSelection(aStartOffset, aEndOffset);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     mIntl.AsProxy()->AddToSelection(aStartOffset, aEndOffset);
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::RemoveSelection(int32_t aSelectionNum)
 {
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->RemoveFromSelection(aSelectionNum);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     mIntl.AsProxy()->RemoveFromSelection(aSelectionNum);
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::ScrollSubstringTo(int32_t aStartOffset,
                                           int32_t aEndOffset,
                                           uint32_t aScrollType)
 {
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     mIntl.AsProxy()->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType);
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::ScrollSubstringToPoint(int32_t aStartOffset,
                                                int32_t aEndOffset,
                                                uint32_t aCoordinateType,
@@ -528,22 +492,18 @@ xpcAccessibleHyperText::ScrollSubstringT
 {
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->ScrollSubstringToPoint(aStartOffset, aEndOffset, aCoordinateType,
                                    aX, aY);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     mIntl.AsProxy()->ScrollSubstringToPoint(aStartOffset, aEndOffset,
                                             aCoordinateType, aX, aY);
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetEnclosingRange(nsIAccessibleTextRange** aRange)
 {
   NS_ENSURE_ARG_POINTER(aRange);
--- a/accessible/xpcom/xpcAccessibleValue.cpp
+++ b/accessible/xpcom/xpcAccessibleValue.cpp
@@ -21,21 +21,17 @@ xpcAccessibleValue::GetMaximumValue(doub
 
   if (Intl().IsAccessible() && Intl().AsAccessible()->IsDefunct())
     return NS_ERROR_FAILURE;
 
   double value;
   if (Intl().IsAccessible()) {
     value = Intl().AsAccessible()->MaxValue();
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     value = Intl().AsProxy()->MaxValue();
-#endif
   }
 
   if (!IsNaN(value))
     *aValue = value;
 
   return NS_OK;
 }
 
@@ -50,21 +46,17 @@ xpcAccessibleValue::GetMinimumValue(doub
 
   if (Intl().IsAccessible() && Intl().AsAccessible()->IsDefunct())
     return NS_ERROR_FAILURE;
 
   double value;
   if (Intl().IsAccessible()) {
     value = Intl().AsAccessible()->MinValue();
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     value = Intl().AsProxy()->MinValue();
-#endif
   }
 
   if (!IsNaN(value))
     *aValue = value;
 
   return NS_OK;
 }
 
@@ -79,21 +71,17 @@ xpcAccessibleValue::GetCurrentValue(doub
 
   if (Intl().IsAccessible() && Intl().AsAccessible()->IsDefunct())
     return NS_ERROR_FAILURE;
 
   double value;
   if (Intl().IsAccessible()) {
     value = Intl().AsAccessible()->CurValue();
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     value = Intl().AsProxy()->CurValue();
-#endif
   }
 
   if (!IsNaN(value))
     *aValue = value;
 
   return NS_OK;
 }
 
@@ -104,21 +92,17 @@ xpcAccessibleValue::SetCurrentValue(doub
     return NS_ERROR_FAILURE;
 
   if (Intl().IsAccessible() && Intl().AsAccessible()->IsDefunct())
     return NS_ERROR_FAILURE;
 
   if (Intl().IsAccessible()) {
     Intl().AsAccessible()->SetCurValue(aValue);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     Intl().AsProxy()->SetCurValue(aValue);
-#endif
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleValue::GetMinimumIncrement(double* aValue)
 {
--- a/addon-sdk/source/app-extension/bootstrap.js
+++ b/addon-sdk/source/app-extension/bootstrap.js
@@ -293,21 +293,18 @@ function loadSandbox(uri) {
       CC: bind(CC, Components), components: Components,
       ChromeWorker: ChromeWorker });
   };
   scriptLoader.loadSubScript(uri, sandbox, 'UTF-8');
   return sandbox;
 }
 
 function unloadSandbox(sandbox) {
-  if ("nukeSandbox" in Cu) {
-    try {
-      Cu.nukeSandbox(sandbox);
-    } catch (e) {}
-  }
+  if (Cu.getClassName(sandbox, true) == "Sandbox")
+    Cu.nukeSandbox(sandbox);
 }
 
 function setTimeout(callback, delay) {
   let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
   timer.initWithCallback({ notify: callback }, delay,
                          Ci.nsITimer.TYPE_ONE_SHOT);
   return timer;
 }
--- a/addon-sdk/source/lib/sdk/addon/bootstrap.js
+++ b/addon-sdk/source/lib/sdk/addon/bootstrap.js
@@ -152,21 +152,19 @@ Bootstrap.prototype = {
     return new Promise(resolve => {
       const { loader } = this;
       if (loader) {
         this.loader = null;
         unload(loader, reason);
 
         setTimeout(() => {
           for (let uri of Object.keys(loader.sandboxes)) {
-            try {
-              Cu.nukeSandbox(loader.sandboxes[uri]);
-            } catch (e) {
-              // This will throw for shared sandboxes.
-            }
+            let sandbox = loader.sandboxes[uri];
+            if (Cu.getClassName(sandbox, true) == "Sandbox")
+              Cu.nukeSandbox(sandbox);
             delete loader.sandboxes[uri];
             delete loader.modules[uri];
           }
 
           try {
             Cu.nukeSandbox(loader.sharedGlobalSandbox);
           } catch (e) {
             Cu.reportError(e);
--- a/addon-sdk/source/test/addons/l10n-properties/app-extension/bootstrap.js
+++ b/addon-sdk/source/test/addons/l10n-properties/app-extension/bootstrap.js
@@ -275,17 +275,17 @@ function loadSandbox(uri) {
       CC: bind(CC, Components), components: Components,
       ChromeWorker: ChromeWorker });
   };
   scriptLoader.loadSubScript(uri, sandbox, 'UTF-8');
   return sandbox;
 }
 
 function unloadSandbox(sandbox) {
-  if ("nukeSandbox" in Cu)
+  if (Cu.getClassName(sandbox, true) == "Sandbox")
     Cu.nukeSandbox(sandbox);
 }
 
 function setTimeout(callback, delay) {
   let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
   timer.initWithCallback({ notify: callback }, delay,
                          Ci.nsITimer.TYPE_ONE_SHOT);
   return timer;
--- a/addon-sdk/source/test/addons/simple-prefs-regression/app-extension/bootstrap.js
+++ b/addon-sdk/source/test/addons/simple-prefs-regression/app-extension/bootstrap.js
@@ -275,17 +275,17 @@ function loadSandbox(uri) {
       CC: bind(CC, Components), components: Components,
       ChromeWorker: ChromeWorker });
   };
   scriptLoader.loadSubScript(uri, sandbox, 'UTF-8');
   return sandbox;
 }
 
 function unloadSandbox(sandbox) {
-  if ("nukeSandbox" in Cu)
+  if (Cu.getClassName(sandbox, true) == "Sandbox")
     Cu.nukeSandbox(sandbox);
 }
 
 function setTimeout(callback, delay) {
   let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
   timer.initWithCallback({ notify: callback }, delay,
                          Ci.nsITimer.TYPE_ONE_SHOT);
   return timer;
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<blocklist lastupdate="1477571825638" xmlns="http://www.mozilla.org/2006/addons-blocklist">
+<blocklist lastupdate="1477745530875" xmlns="http://www.mozilla.org/2006/addons-blocklist">
   <emItems>
     <emItem blockID="i988" id="{b12785f5-d8d0-4530-a3ea-5c4263b85bef}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i398" id="{377e5d4d-77e5-476a-8716-7e70a9272da0}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
@@ -87,25 +87,25 @@
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i487" id="{df6bb2ec-333b-4267-8c4f-3f27dc8c6e07}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i543" id="{badea1ae-72ed-4f6a-8c37-4db9a4ac7bc9}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i53" id="{a3a5c777-f583-4fef-9380-ab4add1bc2a8}">
       <prefs/>
       <versionRange minVersion="2.0.3" maxVersion="2.0.3"/>
       <versionRange minVersion="4.2" maxVersion="4.2" severity="3"/>
     </emItem>
+    <emItem blockID="i543" id="{badea1ae-72ed-4f6a-8c37-4db9a4ac7bc9}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i1040" id="frhegnejkgner@grhjgewfewf.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i1030" id="support@todoist.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="3.9" severity="1"/>
     </emItem>
@@ -176,21 +176,21 @@
     <emItem blockID="i626" id="{20AD702C-661E-4534-8CE9-BA4EC9AD6ECC}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i334" id="{0F827075-B026-42F3-885D-98981EE7B1AE}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i501" id="xivars@aol.com">
+    <emItem blockID="i716" id="{cc6cc772-f121-49e0-b1f0-c26583cb0c5e}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i716" id="{cc6cc772-f121-49e0-b1f0-c26583cb0c5e}">
+    <emItem blockID="i501" id="xivars@aol.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i360" id="ytd@mybrowserbar.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i666" id="wecarereminder@bryan">
@@ -278,24 +278,24 @@
     <emItem blockID="i91" id="crossriderapp4926@crossrider.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="0.81.43" severity="1"/>
     </emItem>
     <emItem blockID="i376" id="{9e09ac65-43c0-4b9d-970f-11e2e9616c55}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i76" id="crossriderapp3924@crossrider.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
     <emItem blockID="i870" id="M1uwW0@47z8gRpK8sULXXLivB.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i76" id="crossriderapp3924@crossrider.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*"/>
-    </emItem>
     <emItem blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
       <prefs/>
       <versionRange minVersion="2.0" maxVersion="2.0"/>
     </emItem>
     <emItem blockID="i778" id="{f2456568-e603-43db-8838-ffa7c4a685c7}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
@@ -359,24 +359,24 @@
     <emItem blockID="i15" id="personas@christopher.beard">
       <prefs/>
       <versionRange minVersion="1.6" maxVersion="1.6">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="3.6.*" minVersion="3.6"/>
         </targetApplication>
       </versionRange>
     </emItem>
+    <emItem blockID="i529" id="/^(torntv@torntv\.com|trtv3@trtv\.com|torntv2@torntv\.com|e2fd07a6-e282-4f2e-8965-85565fcb6384@b69158e6-3c3b-476c-9d98-ae5838c5b707\.com)$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i784" id="{41e5ef7a-171d-4ab5-8351-951c65a29908}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i529" id="/^(torntv@torntv\.com|trtv3@trtv\.com|torntv2@torntv\.com|e2fd07a6-e282-4f2e-8965-85565fcb6384@b69158e6-3c3b-476c-9d98-ae5838c5b707\.com)$/">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i486" id="xz123@ya456.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i57" id="youtube@youtube3.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
@@ -451,28 +451,28 @@
     <emItem blockID="i1232" id="nosquint@urandom.ca">
       <prefs/>
       <versionRange minVersion="0" maxVersion="2.1.9.1-signed.1-signed" severity="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="47"/>
         </targetApplication>
       </versionRange>
     </emItem>
+    <emItem blockID="i650" id="jid1-qj0w91o64N7Eeg@jetpack">
+      <prefs/>
+      <versionRange minVersion="39.5.1" maxVersion="47.0.4" severity="3"/>
+    </emItem>
     <emItem blockID="i748" id="{32da2f20-827d-40aa-a3b4-2fc4a294352e}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i544" id="/^(93abedcf-8e3a-4d02-b761-d1441e437c09@243f129d-aee2-42c2-bcd1-48858e1c22fd\.com|9acfc440-ac2d-417a-a64c-f6f14653b712@09f9a966-9258-4b12-af32-da29bdcc28c5\.com|58ad0086-1cfb-48bb-8ad2-33a8905572bc@5715d2be-69b9-4930-8f7e-64bdeb961cfd\.com)$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i650" id="jid1-qj0w91o64N7Eeg@jetpack">
-      <prefs/>
-      <versionRange minVersion="39.5.1" maxVersion="47.0.4" severity="3"/>
-    </emItem>
     <emItem blockID="i640" id="jid0-l9BxpNUhx1UUgRfKigWzSfrZqAc@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i628" id="ffxtlbr@iminent.com">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
@@ -524,49 +524,49 @@
     <emItem blockID="i996" id="9598582LLKmjasieijkaslesae@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i88" id="anttoolbar@ant.com">
       <prefs/>
       <versionRange minVersion="2.4.6.4" maxVersion="2.4.6.4" severity="1"/>
     </emItem>
-    <emItem blockID="i67" id="youtube2@youtube2.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*"/>
-    </emItem>
     <emItem blockID="i358" id="lfind@nijadsoft.net">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i586" id="jid1-0xtMKhXFEs4jIg@jetpack">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i438" id="{02edb56b-9b33-435b-b7df-b2843273a694}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i546" id="firefox@browsefox.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i67" id="youtube2@youtube2.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i586" id="jid1-0xtMKhXFEs4jIg@jetpack">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i786" id="{63eb5ed4-e1b3-47ec-a253-f8462f205350}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i115" id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i1229" id="/^(.*@(unblocker\.yt|sparpilot\.com))|(axtara@axtara\.com)$/">
+    <emItem blockID="i510" id="{3c9a72a0-b849-40f3-8c84-219109c27554}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i510" id="{3c9a72a0-b849-40f3-8c84-219109c27554}">
+    <emItem blockID="i1229" id="/^(.*@(unblocker\.yt|sparpilot\.com))|(axtara@axtara\.com)$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i530" id="{739df940-c5ee-4bab-9d7e-270894ae687a}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i431" id="chinaescapeone@facebook.com">
@@ -657,64 +657,64 @@
     <emItem blockID="i1038" id="344141-fasf9jas08hasoiesj9ia8ws@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i471" id="firefox@luckyleap.net">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i396" id="/@(ft|putlocker|clickmovie|m2k|sharerepo|smarter-?)downloader\.com$/">
+    <emItem blockID="i560" id="adsremoval@adsremoval.net">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i560" id="adsremoval@adsremoval.net">
+    <emItem blockID="i396" id="/@(ft|putlocker|clickmovie|m2k|sharerepo|smarter-?)downloader\.com$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i538" id="{354dbb0a-71d5-4e9f-9c02-6c88b9d387ba}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i968" id="{184AA5E6-741D-464a-820E-94B3ABC2F3B4}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i742" id="{f894a29a-f065-40c3-bb19-da6057778493}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i792" id="{8f894ed3-0bf2-498e-a103-27ef6e88899f}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i658" id="low_quality_flash@pie2k.com">
       <prefs/>
       <versionRange minVersion="46.2" maxVersion="47.1" severity="3"/>
     </emItem>
+    <emItem blockID="i742" id="{f894a29a-f065-40c3-bb19-da6057778493}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
       <prefs/>
       <versionRange minVersion="2.2" maxVersion="2.2"/>
     </emItem>
     <emItem blockID="i109" id="{392e123b-b691-4a5e-b52f-c4c1027e749c}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i814" id="liiros@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i172" id="info@bflix.info">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i167" id="{b64982b1-d112-42b5-b1e4-d3867c4533f8}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i172" id="info@bflix.info">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i352" id="vpyekkifgv@vpyekkifgv.org">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i1278" id="dodatek@firefox.pl">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
@@ -745,36 +745,36 @@
     <emItem blockID="i380" id="{cc8f597b-0765-404e-a575-82aefbd81daf}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i432" id="lugcla21@gmail.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i392" id="{EEE6C361-6118-11DC-9C72-001320C79847}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i724" id="{1cdbda58-45f8-4d91-b566-8edce18f8d0a}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i429" id="{B40794A0-7477-4335-95C5-8CB9BBC5C4A5}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i392" id="{EEE6C361-6118-11DC-9C72-001320C79847}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    <emItem blockID="i638" id="{7b1bf0b6-a1b9-42b0-b75d-252036438bdc}">
+      <prefs/>
+      <versionRange minVersion="27.8" maxVersion="27.9" severity="3"/>
     </emItem>
     <emItem blockID="i533" id="extension@Fast_Free_Converter.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i638" id="{7b1bf0b6-a1b9-42b0-b75d-252036438bdc}">
-      <prefs/>
-      <versionRange minVersion="27.8" maxVersion="27.9" severity="3"/>
-    </emItem>
     <emItem blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
       <prefs/>
       <versionRange minVersion="3.3.1" maxVersion="*">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="5.0a1"/>
         </targetApplication>
       </versionRange>
       <versionRange minVersion="0.1" maxVersion="3.3.0.*">
@@ -782,35 +782,39 @@
           <versionRange maxVersion="*" minVersion="3.7a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
     <emItem blockID="i746" id="{58d2a791-6199-482f-a9aa-9b725ec61362}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
-      <prefs/>
-      <versionRange minVersion="0.1" maxVersion="5.2.0.7164" severity="1"/>
-    </emItem>
     <emItem blockID="i686" id="{a7f2cb14-0472-42a1-915a-8adca2280a2c}">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i434" id="afurladvisor@anchorfree.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    <emItem blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
+      <prefs/>
+      <versionRange minVersion="0.1" maxVersion="5.2.0.7164" severity="1"/>
+    </emItem>
+    <emItem blockID="i1279" id="dodatek@flash2.pl">
+      <prefs/>
+      <versionRange minVersion="1.3" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i998" id="meOYKQEbBBjH5Ml91z0p9Aosgus8P55bjTa4KPfl@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i434" id="afurladvisor@anchorfree.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i872" id="search-snacks@search-snacks.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i966" id="{5C655500-E712-41e7-9349-CE462F844B19}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="1.0.1-signed" severity="1"/>
     </emItem>
@@ -842,73 +846,73 @@
     </emItem>
     <emItem blockID="i774" id="x77IjS@xU.net">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i1022" id="g99hiaoekjoasiijdkoleabsy278djasi@jetpack">
+    <emItem blockID="i165" id="{EEF73632-A085-4fd3-A778-ECD82C8CB297}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i165" id="{EEF73632-A085-4fd3-A778-ECD82C8CB297}">
+    <emItem blockID="i1022" id="g99hiaoekjoasiijdkoleabsy278djasi@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i718" id="G4Ce4@w.net">
       <prefs>
         <pref>browser.startup.homepage</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i499" id="{babb9931-ad56-444c-b935-38bffe18ad26}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i21" id="support@update-firefox.com">
+      <prefs/>
+    </emItem>
     <emItem blockID="i75" id="firebug@software.joehewitt.com" os="Darwin,Linux">
       <prefs/>
       <versionRange minVersion="1.9.0" maxVersion="1.9.0" severity="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="9.*" minVersion="9.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
-    <emItem blockID="i499" id="{babb9931-ad56-444c-b935-38bffe18ad26}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
-    <emItem blockID="i21" id="support@update-firefox.com">
-      <prefs/>
+    <emItem blockID="i491" id="{515b2424-5911-40bd-8a2c-bdb20286d8f5}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i65" id="activity@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i532" id="249911bc-d1bd-4d66-8c17-df533609e6d8@c76f3de9-939e-4922-b73c-5d7a3139375d.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i1264" id="suchpony@suchpony.de">
       <prefs/>
       <versionRange minVersion="0" maxVersion="1.6.7" severity="3"/>
     </emItem>
-    <emItem blockID="i491" id="{515b2424-5911-40bd-8a2c-bdb20286d8f5}">
+    <emItem blockID="i532" id="249911bc-d1bd-4d66-8c17-df533609e6d8@c76f3de9-939e-4922-b73c-5d7a3139375d.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i476" id="mbroctone@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i656" id="hdv@vovcacik.addons.mozilla.org">
+      <prefs/>
+      <versionRange minVersion="102.0" maxVersion="102.0" severity="3"/>
+    </emItem>
     <emItem blockID="i722" id="{9802047e-5a84-4da3-b103-c55995d147d1}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i656" id="hdv@vovcacik.addons.mozilla.org">
-      <prefs/>
-      <versionRange minVersion="102.0" maxVersion="102.0" severity="3"/>
-    </emItem>
     <emItem blockID="i228" id="crossriderapp5060@crossrider.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i470" id="extension@FastFreeConverter.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
@@ -932,54 +936,54 @@
     <emItem blockID="i1077" id="helper@vidscrab.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i55" id="youtube@youtube7.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i664" id="123456789@offeringmedia.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i630" id="webbooster@iminent.com">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i664" id="123456789@offeringmedia.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i93" id="{68b8676b-99a5-46d1-b390-22411d8bcd61}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i624" id="/^({b95faac1-a3d7-4d69-8943-ddd5a487d966}|{ecce0073-a837-45a2-95b9-600420505f7e}|{2713b394-286f-4d7c-89ea-4174eeab9f5a}|{da7a20cf-bef4-4342-ad78-0240fdf87055})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i868" id="{6e7f6f9f-8ce6-4611-add2-05f0f7049ee6}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i842" id="{746505DC-0E21-4667-97F8-72EA6BCF5EEF}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
+      <prefs/>
+    </emItem>
     <emItem blockID="i924" id="{DAC3F861-B30D-40dd-9166-F4E75327FAC7}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="39.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
-    <emItem blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
-      <prefs/>
-    </emItem>
-    <emItem blockID="i868" id="{6e7f6f9f-8ce6-4611-add2-05f0f7049ee6}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i101" id="{3a12052a-66ef-49db-8c39-e5b0bd5c83fa}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i107" id="{ABDE892B-13A8-4d1b-88E6-365A6E755758}" os="WINNT">
       <prefs/>
       <versionRange minVersion="0" maxVersion="15.0.5" severity="1"/>
     </emItem>
@@ -989,79 +993,83 @@
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i505" id="extacylife@a.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i1414" id="new@kuot.pro">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i528" id="008abed2-b43a-46c9-9a5b-a771c87b82da@1ad61d53-2bdc-4484-a26b-b888ecae1906.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i712" id="{a2bfe612-4cf5-48ea-907c-f3fb25bc9d6b}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i652" id="garg_sms@yahoo.in">
       <prefs/>
       <versionRange minVersion="67.9" maxVersion="67.9" severity="3"/>
     </emItem>
-    <emItem blockID="i453" id="/^brasilescape.*\@facebook\.com$/">
+    <emItem blockID="i712" id="{a2bfe612-4cf5-48ea-907c-f3fb25bc9d6b}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i47" id="youtube@youtube2.com">
       <prefs/>
     </emItem>
-    <emItem blockID="i816" id="noOpus@outlook.com">
+    <emItem blockID="i453" id="/^brasilescape.*\@facebook\.com$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i485" id="/^brasilescape.*\@facebook\.com$//">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i816" id="noOpus@outlook.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i1262" id="my7thfakeid@gmail.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i86" id="{45147e67-4020-47e2-8f7a-55464fb535aa}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i402" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
+    <emItem blockID="i451" id="{e44a1809-4d10-4ab8-b343-3326b64c7cdd}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i451" id="{e44a1809-4d10-4ab8-b343-3326b64c7cdd}">
+    <emItem blockID="i402" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i598" id="{29b136c9-938d-4d3d-8df8-d649d9b74d02}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i108" id="{28bfb930-7620-11e1-b0c4-0800200c9a66}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
+    <emItem blockID="i350" id="sqlmoz@facebook.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i1056" id="{82AF8DCA-6DE9-405D-BD5E-43525BDAD38A}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="7.5.0.9082" severity="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="43.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
-    <emItem blockID="i350" id="sqlmoz@facebook.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i446" id="{E90FA778-C2B7-41D0-9FA9-3FEC1CA54D66}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}">
       <prefs/>
     </emItem>
     <emItem blockID="i117" id="{ce7e73df-6a44-4028-8079-5927a588c948}">
@@ -1071,92 +1079,92 @@
     <emItem blockID="i226" id="{462be121-2b54-4218-bf00-b9bf8135b23f}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i258" id="helperbar@helperbar.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="1.0" severity="1"/>
     </emItem>
-    <emItem blockID="i44" id="sigma@labs.mozilla">
-      <prefs/>
-    </emItem>
     <emItem blockID="i96" id="youtubeee@youtuber3.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
+    <emItem blockID="i44" id="sigma@labs.mozilla">
+      <prefs/>
+    </emItem>
+    <emItem blockID="i564" id="/^(firefox@vebergreat\.net|EFGLQA@78ETGYN-0W7FN789T87\.COM)$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i500" id="{2aab351c-ad56-444c-b935-38bffe18ad26}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i97" id="support3_en@adobe122.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i564" id="/^(firefox@vebergreat\.net|EFGLQA@78ETGYN-0W7FN789T87\.COM)$/">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i439" id="{d2cf9842-af95-48cd-b873-bfbb48cd7f5e}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i576" id="newmoz@facebook.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i46" id="{841468a1-d7f4-4bd3-84e6-bb0f13a06c64}">
       <prefs/>
       <versionRange minVersion="0.1" maxVersion="*">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="9.0" minVersion="9.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
+    <emItem blockID="i576" id="newmoz@facebook.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i776" id="g@uzcERQ6ko.net">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i494" id="/^({e9df9360-97f8-4690-afe6-996c80790da4}|{687578b9-7132-4a7a-80e4-30ee31099e03}|{46a3135d-3683-48cf-b94c-82655cbc0e8a}|{49c795c2-604a-4d18-aeb1-b3eba27e5ea2}|{7473b6bd-4691-4744-a82b-7854eb3d70b6}|{96f454ea-9d38-474f-b504-56193e00c1a5})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i668" id="/^(matchersite(pro(srcs?)?)?\@matchersite(pro(srcs?)?)?\.com)|((pro)?sitematcher(_srcs?|pro|site|sitesrc|-generic)?\@(pro)?sitematcher(_srcs?|pro|site|sitesrc|-generic)?\.com)$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i174" id="info@thebflix.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i668" id="/^(matchersite(pro(srcs?)?)?\@matchersite(pro(srcs?)?)?\.com)|((pro)?sitematcher(_srcs?|pro|site|sitesrc|-generic)?\@(pro)?sitematcher(_srcs?|pro|site|sitesrc|-generic)?\.com)$/">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i822" id="{6af08a71-380e-42dd-9312-0111d2bc0630}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i846" id="PDVDZDW52397720@XDDWJXW57740856.com">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i972" id="831778-poidjao88DASfsAnindsd@jetpack">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i888" id="istart_ffnt@gmail.com">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i972" id="831778-poidjao88DASfsAnindsd@jetpack">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i515" id="/^({bf9194c2-b86d-4ebc-9b53-1c08b6ff779e}|{61a83e16-7198-49c6-8874-3e4e8faeb4f3}|{f0af464e-5167-45cf-9cf0-66b396d1918c}|{5d9968c3-101c-4944-ba71-72d77393322d}|{01e86e69-a2f8-48a0-b068-83869bdba3d0})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i216" id="fdm_ffext@freedownloadmanager.org">
       <prefs/>
       <versionRange minVersion="1.0" maxVersion="1.3.1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
@@ -1167,28 +1175,28 @@
     </emItem>
     <emItem blockID="i844" id="e9d197d59f2f45f382b1aa5c14d82@8706aaed9b904554b5cb7984e9.com">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i461" id="{8E9E3331-D360-4f87-8803-52DE43566502}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i596" id="{b99c8534-7800-48fa-bd71-519a46cdc7e1}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i818" id="contentarget@maildrop.cc">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i461" id="{8E9E3331-D360-4f87-8803-52DE43566502}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i23" id="firefox@bandoo.com">
       <prefs/>
       <versionRange minVersion="5.0" maxVersion="5.0" severity="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="3.7a1pre"/>
         </targetApplication>
       </versionRange>
     </emItem>
@@ -1199,24 +1207,24 @@
     <emItem blockID="i714" id="{25dd52dc-89a8-469d-9e8f-8d483095d1e8}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i59" id="ghostviewer@youtube2.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
+    <emItem blockID="i78" id="socialnetworktools@mozilla.doslash.org">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
     <emItem blockID="i526" id="/^({83a8ce1b-683c-4784-b86d-9eb601b59f38}|{ef1feedd-d8da-4930-96f1-0a1a598375c6}|{79ff1aae-701f-4ca5-aea3-74b3eac6f01b}|{8a184644-a171-4b05-bc9a-28d75ffc9505}|{bc09c55d-0375-4dcc-836e-0e3c8addfbda}|{cef81415-2059-4dd5-9829-1aef3cf27f4f})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i78" id="socialnetworktools@mozilla.doslash.org">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*"/>
-    </emItem>
     <emItem blockID="i708" id="{849ded12-59e9-4dae-8f86-918b70d213dc}">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i448" id="{0134af61-7a0c-4649-aeca-90d776060cb3}">
@@ -1264,63 +1272,63 @@
     </emItem>
     <emItem blockID="i696" id="/^({fa95f577-07cb-4470-ac90-e843f5f83c52}|ffxtlbr@speedial\.com)$/">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i1212" id="unblocker20@unblocker.yt">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="2.0.0" severity="3"/>
+    </emItem>
     <emItem blockID="i354" id="{c0c2693d-2ee8-47b4-9df7-b67a0ee31988}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i1212" id="unblocker20@unblocker.yt">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="2.0.0" severity="3"/>
-    </emItem>
     <emItem blockID="i84" id="pink@rosaplugin.info">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i547" id="{87934c42-161d-45bc-8cef-ef18abe2a30c}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="3.7.9999999999" severity="1"/>
     </emItem>
     <emItem blockID="i364" id="{FE1DEEEA-DB6D-44b8-83F0-34FC0F9D1052}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i356" id="{341f4dac-1966-47ff-aacf-0ce175f1498a}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i336" id="CortonExt@ext.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i536" id="{25D77636-38B1-1260-887C-2D4AFA92D6A4}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i336" id="CortonExt@ext.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i374" id="update@firefox.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i452" id="{77beece6-3997-403a-92fa-0055bfcf88e5}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i858" id="fftoolbar2014@etech.com">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i452" id="{77beece6-3997-403a-92fa-0055bfcf88e5}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i1018" id="grjkntbhr@hgergerherg.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i850" id="P2@D.edu">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
@@ -1363,44 +1371,44 @@
     <emItem blockID="i916" id="{97E22097-9A2F-45b1-8DAF-36AD648C7EF4}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="39.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
-    <emItem blockID="i970" id="hha8771ui3-Fo9j9h7aH98jsdfa8sda@jetpack">
+    <emItem blockID="i430" id="1chtw@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i430" id="1chtw@facebook.com">
+    <emItem blockID="i970" id="hha8771ui3-Fo9j9h7aH98jsdfa8sda@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i344" id="lrcsTube@hansanddeta.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i79" id="GifBlock@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i780" id="{b6ef1336-69bb-45b6-8cba-e578fc0e4433}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i483" id="brasilescapefive@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i469" id="OKitSpace@OKitSpace.es">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i780" id="{b6ef1336-69bb-45b6-8cba-e578fc0e4433}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i1058" id="amo-validator-bypass@example.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i48" id="admin@youtubespeedup.com">
       <prefs/>
     </emItem>
     <emItem blockID="i766" id="/^[a-z0-9]+@foxysecure[a-z0-9]*\.com$/">
@@ -1437,28 +1445,28 @@
     <emItem blockID="i58" id="webmaster@buzzzzvideos.info">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i5" id="support@daemon-tools.cc">
       <prefs/>
       <versionRange minVersion=" " maxVersion="1.0.0.5"/>
     </emItem>
+    <emItem blockID="i449" id="gystqfr@ylgga.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i378" id="{a7aae4f0-bc2e-a0dd-fb8d-68ce32c9261f}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i545" id="superlrcs@svenyor.net">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i449" id="gystqfr@ylgga.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i163" id="info@allpremiumplay.info">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i994" id="addonhack@mozilla.kewis.ch">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
@@ -1523,33 +1531,33 @@
     <emItem blockID="i492" id="{af95cc15-3b9b-45ae-8d9b-98d08eda3111}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i488" id="jid1-4P0kohSJxU1qGg@jetpack">
       <prefs/>
       <versionRange minVersion="1.2.50" maxVersion="1.2.50" severity="1"/>
     </emItem>
+    <emItem blockID="i262" id="{167d9323-f7cc-48f5-948a-6f012831a69f}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i314" id="crossriderapp8812@crossrider.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i262" id="{167d9323-f7cc-48f5-948a-6f012831a69f}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i838" id="{87b5a11e-3b54-42d2-9102-0a7cb1f79ebf}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i678" id="{C4A4F5A0-4B89-4392-AFAC-D58010E349AF}">
+    <emItem blockID="i570" id="jid1-vW9nopuIAJiRHw@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i570" id="jid1-vW9nopuIAJiRHw@jetpack">
+    <emItem blockID="i678" id="{C4A4F5A0-4B89-4392-AFAC-D58010E349AF}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i14" id="mozilla_cc@internetdownloadmanager.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="6.9.8">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="3.7a1pre"/>
@@ -1630,41 +1638,41 @@
     <emItem blockID="i710" id="{e0352044-1439-48ba-99b6-b05ed1a4d2de}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i506" id="/^ext@bettersurfplus/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i672" id="/^(saamazon@mybrowserbar\.com)|(saebay@mybrowserbar\.com)$/">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i864" id="{0A92F062-6AC6-8180-5881-B6E0C0DC2CC5}">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i672" id="/^(saamazon@mybrowserbar\.com)|(saebay@mybrowserbar\.com)$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i634" id="jid1-4vUehhSALFNqCw@jetpack">
       <prefs/>
       <versionRange minVersion="99.7" maxVersion="99.7" severity="3"/>
       <versionRange minVersion="100.7" maxVersion="100.7" severity="3"/>
     </emItem>
     <emItem blockID="i162" id="{EB7508CA-C7B2-46E0-8C04-3E94A035BD49}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i103" id="kdrgun@gmail.com">
+    <emItem blockID="i62" id="jid0-EcdqvFOgWLKHNJPuqAnawlykCGZ@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i62" id="jid0-EcdqvFOgWLKHNJPuqAnawlykCGZ@jetpack">
+    <emItem blockID="i103" id="kdrgun@gmail.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i1119" id="/^(test3@test.org|test2@test.org|test@test.org|support@mozilla.org)$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i484" id="plugin@getwebcake.com">
@@ -1674,74 +1682,74 @@
     <emItem blockID="i519" id="703db0db-5fe9-44b6-9f53-c6a91a0ad5bd@7314bc82-969e-4d2a-921b-e5edd0b02cf1.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i477" id="mbrnovone@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i836" id="hansin@topvest.id">
+    <emItem blockID="i495" id="kallow@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i495" id="kallow@facebook.com">
+    <emItem blockID="i836" id="hansin@topvest.id">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i542" id="/^({bf67a47c-ea97-4caf-a5e3-feeba5331231}|{24a0cfe1-f479-4b19-b627-a96bf1ea3a56})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i286" id="{58bd07eb-0ee0-4df0-8121-dc9b693373df}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i52" id="ff-ext@youtube">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
     <emItem blockID="i676" id="SpecialSavings@SpecialSavings.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i52" id="ff-ext@youtube">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*"/>
-    </emItem>
-    <emItem blockID="i540" id="/^(ffxtlbr@mixidj\.com|{c0c2693d-2ee8-47b4-9df7-b67a0ee31988}|{67097627-fd8e-4f6b-af4b-ecb65e50112e}|{f6f0f973-a4a3-48cf-9a7a-b7a69c30d71a}|{a3d0e35f-f1da-4ccb-ae77-e9d27777e68d}|{1122b43d-30ee-403f-9bfa-3cc99b0caddd})$/">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i720" id="FXqG@xeeR.net">
       <prefs>
         <pref>browser.startup.homepage</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i540" id="/^(ffxtlbr@mixidj\.com|{c0c2693d-2ee8-47b4-9df7-b67a0ee31988}|{67097627-fd8e-4f6b-af4b-ecb65e50112e}|{f6f0f973-a4a3-48cf-9a7a-b7a69c30d71a}|{a3d0e35f-f1da-4ccb-ae77-e9d27777e68d}|{1122b43d-30ee-403f-9bfa-3cc99b0caddd})$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i1265" id="@video_downloader_pro">
       <prefs/>
       <versionRange minVersion="1.2.1" maxVersion="1.2.5" severity="1"/>
     </emItem>
     <emItem blockID="i493" id="12x3q@3244516.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i348" id="{13c9f1f9-2322-4d5c-81df-6d4bf8476ba4}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i442" id="pennerdu@faceobooks.ws">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i99" id="pfzPXmnzQRXX6@2iABkVe.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
     <emItem blockID="i450" id="{dff137ae-1ffd-11e3-8277-b8ac6f996f26}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i99" id="pfzPXmnzQRXX6@2iABkVe.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*"/>
-    </emItem>
     <emItem blockID="i238" id="/^pink@.*\.info$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="18.0"/>
         </targetApplication>
       </versionRange>
     </emItem>
@@ -1788,28 +1796,28 @@
     <emItem blockID="i926" id="{B1FC07E1-E05B-4567-8891-E63FBE545BA8}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="39.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
+    <emItem blockID="i782" id="safebrowse@safebrowse.co">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i806" id="{d9284e50-81fc-11da-a72b-0800200c9a66}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="7.7.34" severity="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="34.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
-    <emItem blockID="i782" id="safebrowse@safebrowse.co">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i382" id="{6926c7f7-6006-42d1-b046-eba1b3010315}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i812" id="{1e4ea5fc-09e5-4f45-a43b-c048304899fc}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
@@ -1828,21 +1836,21 @@
     <emItem blockID="i472" id="linksicle@linksicle.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i98" id="youtubeeing@youtuberie.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i578" id="jid1-XLjasWL55iEE1Q@jetpack">
+    <emItem blockID="i1213" id="unblocker20__web@unblocker.yt">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i1213" id="unblocker20__web@unblocker.yt">
+    <emItem blockID="i578" id="jid1-XLjasWL55iEE1Q@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i1233" id="cloudmask@cloudmask.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="2.0.788"/>
     </emItem>
     <emItem blockID="i582" id="discoverypro@discoverypro.com">
@@ -1935,37 +1943,37 @@
     <emItem blockID="i920" id="{FCE04E1F-9378-4f39-96F6-5689A9159E45}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="39.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
+    <emItem blockID="i224" id="{336D0C35-8A85-403a-B9D2-65C292C39087}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i507" id="4zffxtbr-bs@VideoDownloadConverter_4z.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="5.75.3.25126" severity="1"/>
     </emItem>
-    <emItem blockID="i224" id="{336D0C35-8A85-403a-B9D2-65C292C39087}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i1050" id="87aukfkausiopoawjsuifhasefgased278djasi@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i22" id="ShopperReports@ShopperReports.com">
       <prefs/>
       <versionRange minVersion="3.1.22.0" maxVersion="3.1.22.0"/>
     </emItem>
-    <emItem blockID="i1137" id="/^({d50bfa5f-291d-48a8-909c-5f1a77b31948}|{d54bc985-6e7b-46cd-ad72-a4a266ad879e}|{d89e5de3-5543-4363-b320-a98cf150f86a}|{f3465017-6f51-4980-84a5-7bee2f961eba}|{fae25f38-ff55-46ea-888f-03b49aaf8812})$/">
+    <emItem blockID="i1230" id="addon@gemaoff">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i1230" id="addon@gemaoff">
+    <emItem blockID="i1137" id="/^({d50bfa5f-291d-48a8-909c-5f1a77b31948}|{d54bc985-6e7b-46cd-ad72-a4a266ad879e}|{d89e5de3-5543-4363-b320-a98cf150f86a}|{f3465017-6f51-4980-84a5-7bee2f961eba}|{fae25f38-ff55-46ea-888f-03b49aaf8812})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i342" id="lbmsrvfvxcblvpane@lpaezhjez.org">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i840" id="{4889ddce-7a83-45e6-afc9-1e4f1149fff4}">
@@ -2144,16 +2152,21 @@
       <versionRange maxVersion="*" minVersion="0"/>
     </pluginItem>
     <pluginItem blockID="p80">
       <match exp="\(TM\)" name="name"/>
       <match exp="(npjp2\.dll)|(libnpjp2\.so)" name="filename"/>
       <match exp="[^\d\._]((0(\.\d+(\.\d+([_\.]\d+)?)?)?)|(1\.(([0-5](\.\d+([_\.]\d+)?)?)|(6(\.0([_\.](0?\d|1\d|2\d|30))?)?)|(7(\.0([_\.][0-2])?)?))))([^\d\._]|$)" name="description"/>
       <versionRange severity="1"/>
     </pluginItem>
+    <pluginItem blockID="p1415">
+      <match exp="(NPSWF32.*\.dll)|(NPSWF64.*\.dll)|(Flash\ Player\.plugin)" name="filename"/>
+      <infoURL>https://get.adobe.com/flashplayer/</infoURL>
+      <versionRange maxVersion="18.0.0.382" minVersion="18.0.0.366" severity="0" vulnerabilitystatus="1"/>
+    </pluginItem>
     <pluginItem blockID="p182">
       <match exp="Java\(TM\) Platform SE 7 U([0-9]|(1[0-1]))(\s[^\d\._U]|$)" name="name"/>
       <match exp="npjp2\.dll" name="filename"/>
       <versionRange severity="0" vulnerabilitystatus="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="17.0"/>
         </targetApplication>
       </versionRange>
@@ -2239,16 +2252,21 @@
       <match exp="(nppdf32\.dll)|(AdobePDFViewerNPAPI\.plugin)" name="filename"/>
       <infoURL>https://get.adobe.com/reader</infoURL>
       <versionRange maxVersion="11.0.16 " minVersion="10.1.6" severity="0" vulnerabilitystatus="1"/>
     </pluginItem>
     <pluginItem blockID="p408">
       <match exp="QuickTime Plugin\.plugin" name="filename"/>
       <versionRange maxVersion="7.6.5" minVersion="0" severity="0" vulnerabilitystatus="1"/>
     </pluginItem>
+    <pluginItem blockID="p1413">
+      <match exp="(NPSWF32.*\.dll)|(NPSWF64.*\.dll)|(Flash\ Player\.plugin)" name="filename"/>
+      <infoURL>https://get.adobe.com/flashplayer/</infoURL>
+      <versionRange maxVersion="23.0.0.185" minVersion="22.0.0.211" severity="0" vulnerabilitystatus="1"/>
+    </pluginItem>
     <pluginItem blockID="p946">
       <match exp="(NPSWF32.*\.dll)|(NPSWF64.*\.dll)|(Flash\ Player\.plugin)" name="filename"/>
       <infoURL>https://get.adobe.com/flashplayer/</infoURL>
       <versionRange maxVersion="18.0.0.203" minVersion="18.0.0.203" severity="0" vulnerabilitystatus="1"/>
     </pluginItem>
     <pluginItem blockID="p214">
       <match exp="Java\(TM\) Platform SE 7 U7(\s[^\d\._U]|$)" name="name"/>
       <match exp="npjp2\.dll" name="filename"/>
@@ -2709,16 +2727,21 @@
       <infoURL>https://java.com/</infoURL>
       <versionRange maxVersion="Java 7 Update 11" minVersion="Java 7 Update 11" severity="0" vulnerabilitystatus="1"/>
     </pluginItem>
     <pluginItem blockID="p1272" os="Linux">
       <match exp="libflashplayer\.so" name="filename"/>
       <infoURL>https://get.adobe.com/flashplayer/</infoURL>
       <versionRange maxVersion="11.2.202.632" minVersion="11.2.202.626" severity="0" vulnerabilitystatus="1"/>
     </pluginItem>
+    <pluginItem blockID="p1412" os="Linux">
+      <match exp="libflashplayer\.so" name="filename"/>
+      <infoURL>https://get.adobe.com/flashplayer/</infoURL>
+      <versionRange maxVersion="11.2.202.637" minVersion="11.2.202.632" severity="0" vulnerabilitystatus="1"/>
+    </pluginItem>
     <pluginItem blockID="p1121">
       <match exp="(NPSWF32.*\.dll)|(NPSWF64.*\.dll)|(Flash\ Player\.plugin)" name="filename"/>
       <infoURL>https://get.adobe.com/flashplayer/</infoURL>
       <versionRange maxVersion="20.0.0.286" minVersion="20.0.0.235" severity="0" vulnerabilitystatus="1"/>
     </pluginItem>
     <pluginItem blockID="p574">
       <match exp="NPDjVu\.plugin" name="filename"/>
       <versionRange maxVersion="6.1.1" minVersion="0" severity="0" vulnerabilitystatus="1"/>
@@ -3398,226 +3421,451 @@
       <serialNumber>Os2rnHWYhryvdOXfgan06A==</serialNumber>
     </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>d8AtKymQwkOPDBj+hjPzFg==</serialNumber>
     </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABHkSHlSo=</serialNumber>
     </certItem>
+    <certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
+      <serialNumber>VLm3Xe60+1YgPpXCGtXLng==</serialNumber>
+    </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESBqoILo90ntDW7OTK43MS2F</serialNumber>
+    </certItem>
+    <certItem issuerName="MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=">
+      <serialNumber>BAAAAAABIBnBjWg=</serialNumber>
+    </certItem>
     <certItem issuerName="MEExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxUaGF3dGUsIEluYy4xGzAZBgNVBAMTElRoYXd0ZSBTR0MgQ0EgLSBHMg==">
       <serialNumber>e0bEFhI16xx9U1yvlI56rA==</serialNumber>
     </certItem>
     <certItem issuerName="MEExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxUaGF3dGUsIEluYy4xGzAZBgNVBAMTElRoYXd0ZSBTR0MgQ0EgLSBHMg==">
       <serialNumber>cDggUYfwJ3A1YcdoeT6s4A==</serialNumber>
     </certItem>
+    <certItem issuerName="MFYxCzAJBgNVBAYTAkpQMQ8wDQYDVQQKEwZKSVBERUMxGjAYBgNVBAsTEUpDQU4gU3ViIFJvb3QgQ0EwMRowGAYDVQQDExFKQ0FOIFN1YiBSb290IENBMA==">
+      <serialNumber>BAAAAAABK84ykc0=</serialNumber>
+    </certItem>
+    <certItem issuerName="MFYxCzAJBgNVBAYTAkpQMQ8wDQYDVQQKEwZKSVBERUMxGjAYBgNVBAsTEUpDQU4gU3ViIFJvb3QgQ0EwMRowGAYDVQQDExFKQ0FOIFN1YiBSb290IENBMA==">
+      <serialNumber>BAAAAAABL07hTcY=</serialNumber>
+    </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABKUXDqxw=</serialNumber>
     </certItem>
     <certItem issuerName="MIGQMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDE2MDQGA1UEAxMtQ09NT0RPIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB">
       <serialNumber>D9UltDPl4XVfSSqQOvdiwQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIzMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu">
+      <serialNumber>BAAAAAABMYnGRuw=</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>DHmmaw==</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
+      <serialNumber>Bydp0g==</serialNumber>
+    </certItem>
     <certItem issuerName="MFAxCzAJBgNVBAYTAkpQMRgwFgYDVQQKEw9TRUNPTSBUcnVzdC5uZXQxJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmljYXRpb24gUm9vdENBMQ==">
       <serialNumber>Ermwxw==</serialNumber>
     </certItem>
+    <certItem issuerName="MFYxCzAJBgNVBAYTAkpQMQ8wDQYDVQQKEwZKSVBERUMxGjAYBgNVBAsTEUpDQU4gU3ViIFJvb3QgQ0EwMRowGAYDVQQDExFKQ0FOIFN1YiBSb290IENBMA==">
+      <serialNumber>BAAAAAABL07hUBg=</serialNumber>
+    </certItem>
     <certItem issuerName="MEQxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHjAcBgNVBAMTFXRoYXd0ZSBFViBTU0wgQ0EgLSBHMw==">
       <serialNumber>CrTHPEE6AZSfI3jysin2bA==</serialNumber>
     </certItem>
+    <certItem issuerName="MFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBSb290IENB">
+      <serialNumber>AJiWmg==</serialNumber>
+    </certItem>
     <certItem issuerName="MDcxJDAiBgNVBAMTG1JDUyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEPMA0GA1UEChMGSFQgc3Js">
       <serialNumber>AN9bfYOvlR1t</serialNumber>
     </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABJZbEU4I=</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>CqL7CA==</serialNumber>
+    </certItem>
     <certItem issuerName="MF8xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRQwEgYDVQQLEwtQYXJ0bmVycyBDQTEfMB0GA1UEAxMWR2xvYmFsU2lnbiBQYXJ0bmVycyBDQQ==">
       <serialNumber>BAAAAAABHhw1vwc=</serialNumber>
     </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESJJweWBPhoXAaB9c8SHwI4O</serialNumber>
+    </certItem>
+    <certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
+      <serialNumber>GN2Hrh9Ltm4=</serialNumber>
+    </certItem>
     <certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzI=">
       <serialNumber>P6G7IYSL2RZxtzTh8I6qPA==</serialNumber>
     </certItem>
+    <certItem issuerName="MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIzMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu">
+      <serialNumber>BAAAAAABJQcQRNU=</serialNumber>
+    </certItem>
+    <certItem issuerName="MG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3Q=">
+      <serialNumber>RurwlgVMxeP6Zepun0LGZA==</serialNumber>
+    </certItem>
+    <certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
+      <serialNumber>AQAAAAU=</serialNumber>
+    </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABAJmPjfQ=</serialNumber>
     </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>UUFV3S2cUidOOv7ESN65Ng==</serialNumber>
     </certItem>
+    <certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
+      <serialNumber>AQAAAAQ=</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>CcHC1w==</serialNumber>
+    </certItem>
     <certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
       <serialNumber>O2S99lVUxErLSk56GvWRv+E=</serialNumber>
     </certItem>
     <certItem issuerName="MHExCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNEZXV0c2NoZSBUZWxla29tIEFHMR8wHQYDVQQLExZULVRlbGVTZWMgVHJ1c3QgQ2VudGVyMSMwIQYDVQQDExpEZXV0c2NoZSBUZWxla29tIFJvb3QgQ0EgMg==">
       <serialNumber>ARQ=</serialNumber>
     </certItem>
+    <certItem issuerName="MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=">
+      <serialNumber>CjM=</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>F5BhE0zbgQ==</serialNumber>
+    </certItem>
     <certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
       <serialNumber>UW3oKZKTDsrPy/rfwmGNaQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp">
+      <serialNumber>TA6BjA==</serialNumber>
+    </certItem>
     <certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzQ=">
       <serialNumber>H08=</serialNumber>
     </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESISuBo/wdW2tBztKmHdFCFz</serialNumber>
+    </certItem>
+    <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
+      <serialNumber>BAAAAAABFqoAZoI=</serialNumber>
+    </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESCEUbthDurBjJw0/h/FfuNY</serialNumber>
+    </certItem>
+    <certItem issuerName="MG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3Q=">
+      <serialNumber>U3t2Vk8pfxTcaUPpIq0seQ==</serialNumber>
+    </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>Gd/pPu+qLnXUdvP9sW73CQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
+      <serialNumber>Byc68g==</serialNumber>
+    </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABGMG0Gmw=</serialNumber>
     </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>By7fBTreouRwX/qrpgSUsg==</serialNumber>
     </certItem>
     <certItem issuerName="MFkxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKjAoBgNVBAMTIVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPdmVyaGVpZCBDQQ==">
       <serialNumber>ATFpsA==</serialNumber>
     </certItem>
+    <certItem issuerName="MIGCMQswCQYDVQQGEwJVUzEeMBwGA1UECxMVd3d3LnhyYW1wc2VjdXJpdHkuY29tMSQwIgYDVQQKExtYUmFtcCBTZWN1cml0eSBTZXJ2aWNlcyBJbmMxLTArBgNVBAMTJFhSYW1wIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==">
+      <serialNumber>QZCrvA==</serialNumber>
+    </certItem>
+    <certItem issuerName="MDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMCREU=">
+      <serialNumber>a12RvBNhznU=</serialNumber>
+    </certItem>
+    <certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
+      <serialNumber>GN2Hrh9LtnI=</serialNumber>
+    </certItem>
     <certItem issuerName="MH8xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEwMC4GA1UEAxMnU3ltYW50ZWMgQ2xhc3MgMyBFQ0MgMjU2IGJpdCBFViBDQSAtIEcy">
       <serialNumber>OhrtngFwotLcm4i+z00SjA==</serialNumber>
     </certItem>
     <certItem issuerName="MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==">
       <serialNumber>Eg==</serialNumber>
     </certItem>
     <certItem issuerName="MGExCzAJBgNVBAYTAlVTMRIwEAYDVQQKEwlJZGVuVHJ1c3QxIDAeBgNVBAsTF0lkZW5UcnVzdCBQdWJsaWMgU2VjdG9yMRwwGgYDVQQDExNJZGVuVHJ1c3QgQUNFUyBDQSAx">
       <serialNumber>fwAAAQAAAUrz/HmrAAAAAg==</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
+      <serialNumber>Bydxog==</serialNumber>
+    </certItem>
     <certItem issuerName="MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=">
       <serialNumber>GdXz4L1b6FKNCMG9Jz2tjA==</serialNumber>
     </certItem>
     <certItem issuerName="MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==">
       <serialNumber>EA==</serialNumber>
     </certItem>
     <certItem issuerName="MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=">
       <serialNumber>CqZgEvHAsnzkT//QV9KjXw==</serialNumber>
     </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESCyHU+xOECnh9Rf2IvgR8zS</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>CqnbFQ==</serialNumber>
+    </certItem>
+    <certItem issuerName="MIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEdMBsGA1UEAxMUVVROLVVTRVJGaXJzdC1PYmplY3Q=">
+      <serialNumber>Jq6jgeApiT9O4W2Tx/NTRQ==</serialNumber>
+    </certItem>
     <certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
       <serialNumber>YRJNfMoc12IpmW+Enpv3Pdo=</serialNumber>
     </certItem>
     <certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
       <serialNumber>YNOos6YJoPC77qwSGCpb7w==</serialNumber>
     </certItem>
     <certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
       <serialNumber>F7PAjw2k0dTX5escPnyVOBo=</serialNumber>
     </certItem>
+    <certItem issuerName="MG0xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRswGQYDVQQLExJQcmltYXJ5IENsYXNzIDMgQ0ExJjAkBgNVBAMTHUdsb2JhbFNpZ24gUHJpbWFyeSBDbGFzcyAzIENB">
+      <serialNumber>BAAAAAABHkSl6mw=</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>CcL+EA==</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>Cd/dug==</serialNumber>
+    </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>Sx51x7V8pYe8rp7PMP/3qg==</serialNumber>
     </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABMrS7t2g=</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>F5Bg/C8eXg==</serialNumber>
+    </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>VOcIuNbTqkpOMUyI108FOg==</serialNumber>
     </certItem>
+    <certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
+      <serialNumber>fMTRbGCp280pnyE/u53zbA==</serialNumber>
+    </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>HZyLf+K70FKc+jomm8DiDw==</serialNumber>
     </certItem>
+    <certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
+      <serialNumber>GN2Hrh9Ltms=</serialNumber>
+    </certItem>
     <certItem issuerName="MFkxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKjAoBgNVBAMTIVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPdmVyaGVpZCBDQQ==">
       <serialNumber>ATFEdg==</serialNumber>
     </certItem>
+    <certItem issuerName="MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu">
+      <serialNumber>BAAAAAABIg08D3U=</serialNumber>
+    </certItem>
     <certItem issuerName="ME0xCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIgU2VjdXJlIFNlcnZlciBDQQ==">
       <serialNumber>Aa8e+91erglSMgsk/mtVaA==</serialNumber>
     </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>A9GPKQ8jv9oIxfwiOy7qxQ==</serialNumber>
     </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>LnfcUaXG/pxV2CpXM5+YSg==</serialNumber>
     </certItem>
+    <certItem issuerName="MHExCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNEZXV0c2NoZSBUZWxla29tIEFHMR8wHQYDVQQLExZULVRlbGVTZWMgVHJ1c3QgQ2VudGVyMSMwIQYDVQQDExpEZXV0c2NoZSBUZWxla29tIFJvb3QgQ0EgMg==">
+      <serialNumber>AImQERVYPoeb</serialNumber>
+    </certItem>
     <certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
       <serialNumber>UU3AP1SMxmyhBFq7MRFZmf0=</serialNumber>
     </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESByNJZ5TPjg9iZyL6a/h5Zx</serialNumber>
+    </certItem>
     <certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
       <serialNumber>XLhHIg7vP+tWfRqvuKeAxw==</serialNumber>
     </certItem>
+    <certItem issuerName="MDsxGDAWBgNVBAoTD0N5YmVydHJ1c3QsIEluYzEfMB0GA1UEAxMWQ3liZXJ0cnVzdCBHbG9iYWwgUm9vdA==">
+      <serialNumber>BAAAAAABJpQ0AbA=</serialNumber>
+    </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAAA+X/GIyk=</serialNumber>
     </certItem>
+    <certItem issuerName="MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=">
+      <serialNumber>NTgf4iwIfeyJPIomw2dwSXEwtxQ=</serialNumber>
+    </certItem>
+    <certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
+      <serialNumber>Xbevr3ut3Z9m1GuXC9SonA==</serialNumber>
+    </certItem>
     <certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
       <serialNumber>Mq0P6o03FDk0B2bnJ+mYPGo=</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>F5Bg6C237Q==</serialNumber>
+    </certItem>
     <certItem issuerName="MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=">
       <serialNumber>DYifRdP6aQQ8MLbXZY2f5g==</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>Cfk9lw==</serialNumber>
+    </certItem>
     <certItem issuerName="MG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3Q=">
       <serialNumber>U3t2Vk8pfxTcaUPpIq0seQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MIGQMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxOzA5BgNVBAMTMkFyaXN0b3RsZSBVbml2ZXJzaXR5IG9mIFRoZXNzYWxvbmlraSBDZW50cmFsIENBIFI0">
+      <serialNumber>EqthLKdUgwI=</serialNumber>
+    </certItem>
     <certItem issuerName="MF8xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRQwEgYDVQQLEwtQYXJ0bmVycyBDQTEfMB0GA1UEAxMWR2xvYmFsU2lnbiBQYXJ0bmVycyBDQQ==">
       <serialNumber>BAAAAAABCFiEp9s=</serialNumber>
     </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABJ/ufRdg=</serialNumber>
     </certItem>
+    <certItem issuerName="MHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWU=">
+      <serialNumber>M64Z5ufZzDRVTHkJR1uXzw==</serialNumber>
+    </certItem>
     <certItem issuerName="MG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3Q=">
       <serialNumber>RurwlgVMxeP6Zepun0LGZA==</serialNumber>
     </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABGMGjftY=</serialNumber>
     </certItem>
     <certItem issuerName="MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=">
       <serialNumber>TqfXw+FkhxfVgE9GVMgjWQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESC8DawWRiAyEMd38UXbfgPR</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>EAdmaA==</serialNumber>
+    </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABJ/ufQg8=</serialNumber>
     </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABLM/7qjk=</serialNumber>
     </certItem>
     <certItem issuerName="MIGBMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTElMCMGA1UECxMcUHJpbWFyeSBPYmplY3QgUHVibGlzaGluZyBDQTEwMC4GA1UEAxMnR2xvYmFsU2lnbiBQcmltYXJ5IE9iamVjdCBQdWJsaXNoaW5nIENB">
       <serialNumber>BAAAAAABHkSl7L4=</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>F5Bg+EziQQ==</serialNumber>
+    </certItem>
+    <certItem issuerName="MIGFMQswCQYDVQQGEwJVUzEgMB4GA1UECgwXV2VsbHMgRmFyZ28gV2VsbHNTZWN1cmUxHDAaBgNVBAsME1dlbGxzIEZhcmdvIEJhbmsgTkExNjA0BgNVBAMMLVdlbGxzU2VjdXJlIFB1YmxpYyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eQ==">
+      <serialNumber>Aw==</serialNumber>
+    </certItem>
     <certItem issuerName="MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=">
       <serialNumber>IIxFSyNM6mWtCgTG0IL3Og==</serialNumber>
     </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>DjIvBkX+ECVbB/C3i6w2Gg==</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>Cbssdw==</serialNumber>
+    </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESAyW/JX3+hZIp44EAMlXU2b</serialNumber>
+    </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABKB/OGqI=</serialNumber>
     </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>bzTw0uq05TUYEGS98bh0Ww==</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
+      <serialNumber>BydKkg==</serialNumber>
+    </certItem>
+    <certItem issuerName="MIGCMQswCQYDVQQGEwJVUzEeMBwGA1UECxMVd3d3LnhyYW1wc2VjdXJpdHkuY29tMSQwIgYDVQQKExtYUmFtcCBTZWN1cml0eSBTZXJ2aWNlcyBJbmMxLTArBgNVBAMTJFhSYW1wIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==">
+      <serialNumber>QZCrvQ==</serialNumber>
+    </certItem>
+    <certItem issuerName="MH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
+      <serialNumber>Qh/QbQ==</serialNumber>
+    </certItem>
+    <certItem issuerName="MG0xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRswGQYDVQQLExJQcmltYXJ5IENsYXNzIDIgQ0ExJjAkBgNVBAMTHUdsb2JhbFNpZ24gUHJpbWFyeSBDbGFzcyAyIENB">
+      <serialNumber>BAAAAAABHkSl6Co=</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>F5BhENPfVw==</serialNumber>
+    </certItem>
     <certItem issuerName="MHsxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEsMCoGA1UEAxMjU3ltYW50ZWMgQ2xhc3MgMyBFQ0MgMjU2IGJpdCBTU0wgQ0E=">
       <serialNumber>U3SgRR3J+D6575WuCxuXeQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
+      <serialNumber>Qh/SnQ==</serialNumber>
+    </certItem>
     <certItem issuerName="MGgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEiMCAGA1UEAxMZR2VvVHJ1c3QgRFYgU1NMIFNIQTI1NiBDQQ==">
       <serialNumber>ZgwfEqZnBsUNvNuZ77FbQA==</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
+      <serialNumber>ByfHkw==</serialNumber>
+    </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESCVop+Q4/OBgtf4WJkr01Gh</serialNumber>
+    </certItem>
     <certItem issuerName="MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==">
       <serialNumber>BA==</serialNumber>
     </certItem>
+    <certItem issuerName="MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=">
+      <serialNumber>CSU=</serialNumber>
+    </certItem>
     <certItem issuerName="MIG1MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMS8wLQYDVQQDEyZWZXJpU2lnbiBDbGFzcyAzIFNlY3VyZSBTZXJ2ZXIgQ0EgLSBHMw==">
       <serialNumber>OqQ2rV0ISTc308Z/oQgzFw==</serialNumber>
     </certItem>
+    <certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
+      <serialNumber>FJl6tXgNpSk=</serialNumber>
+    </certItem>
     <certItem issuerName="MIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp">
       <serialNumber>TA6EVg==</serialNumber>
     </certItem>
     <certItem issuerName="MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==">
       <serialNumber>BQ==</serialNumber>
     </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>45KI4WIxyXfNrdtdj7C6</serialNumber>
     </certItem>
+    <certItem issuerName="MG0xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRswGQYDVQQLExJQcmltYXJ5IENsYXNzIDEgQ0ExJjAkBgNVBAMTHUdsb2JhbFNpZ24gUHJpbWFyeSBDbGFzcyAxIENB">
+      <serialNumber>BAAAAAABHkSl5ao=</serialNumber>
+    </certItem>
     <certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
       <serialNumber>L79XLVO2ZmtAu7FAG8Wmzw==</serialNumber>
     </certItem>
     <certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
       <serialNumber>bAOrKSMsmA0MLJyAJ5BRsUM=</serialNumber>
     </certItem>
     <certItem issuerName="MF8xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRQwEgYDVQQLEwtQYXJ0bmVycyBDQTEfMB0GA1UEAxMWR2xvYmFsU2lnbiBQYXJ0bmVycyBDQQ==">
       <serialNumber>BAAAAAABF2Tb8Bc=</serialNumber>
     </certItem>
+    <certItem issuerName="MFYxCzAJBgNVBAYTAkpQMQ8wDQYDVQQKEwZKSVBERUMxGjAYBgNVBAsTEUpDQU4gU3ViIFJvb3QgQ0EwMRowGAYDVQQDExFKQ0FOIFN1YiBSb290IENBMA==">
+      <serialNumber>BAAAAAABK84yjs8=</serialNumber>
+    </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>TurPPI6eivtNeGYdM0ZWXQ==</serialNumber>
     </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABHJRKNmk=</serialNumber>
     </certItem>
     <certItem issuerName="MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=">
       <serialNumber>Rvm2CEw2IC2Mu/ax0A46QQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MFwxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xLTArBgNVBAMMJFN0YWF0IGRlciBOZWRlcmxhbmRlbiBCdXJnZXIgQ0EgLSBHMg==">
+      <serialNumber>ATE3ew==</serialNumber>
+    </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESByYNtAIfizf2L3NMzCH8zZ</serialNumber>
+    </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>J2La+q+JOURNWkX60OP2lQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MGExCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xMjAwBgNVBAMMKVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBDQSAtIEcy">
+      <serialNumber>LTRcDHabRHU=</serialNumber>
+    </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABHkSHjz8=</serialNumber>
     </certItem>
     <certItem issuerName="MEQxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQDExRHZW9UcnVzdCBTU0wgQ0EgLSBHMw==">
       <serialNumber>RUT1Gehd1KKYPfqOlgspoQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESCC9oPNcRdPOox+SjWm9dTX</serialNumber>
+    </certItem>
+    <certItem issuerName="MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==">
+      <serialNumber>TrKEMhb2PKktH8lHg0AV5A==</serialNumber>
+    </certItem>
+    <certItem issuerName="MIGKMQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEmMCQGA1UECxMdQ29weXJpZ2h0IChjKSAyMDA1IFdJU2VLZXkgU0ExFjAUBgNVBAsTDUludGVybmF0aW9uYWwxKTAnBgNVBAMTIFdJU2VLZXkgQ2VydGlmeUlEIEFkdmFuY2VkIEcxIENB">
+      <serialNumber>WD1AyQAAAAAAJQ==</serialNumber>
+    </certItem>
+    <certItem issuerName="MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=">
+      <serialNumber>BAAAAAABFUtaxac=</serialNumber>
+    </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>NMpMcEnex3eXx4ohk9glcQ==</serialNumber>
     </certItem>
     <certItem issuerName="MIGQMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDE2MDQGA1UEAxMtQ09NT0RPIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB">
       <serialNumber>UoRGnb96CUDTxIqVry6LBg==</serialNumber>
     </certItem>
     <certItem issuerName="MEQxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQDExRHZW9UcnVzdCBTU0wgQ0EgLSBHMg==">
       <serialNumber>VfTSum25nb65YPlpuhJAvg==</serialNumber>
@@ -3632,28 +3880,37 @@
       <serialNumber>OnvXX72mvUI2Id/NMzegmg==</serialNumber>
     </certItem>
     <certItem issuerName="MHcxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEoMCYGA1UEAxMfU3ltYW50ZWMgQ2xhc3MgMyBFViBTU0wgQ0EgLSBHMw==">
       <serialNumber>acI1CFIgmwSFBoU5+ahDgg==</serialNumber>
     </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>GtXUVojhwOTkaQ4bTKblEQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA2IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHNQ==">
+      <serialNumber>buROL/l2GuXISv+/JVLkdA==</serialNumber>
+    </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABA/A35EU=</serialNumber>
     </certItem>
     <certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
       <serialNumber>ORFgmCj072NjcJnrxOMfQA==</serialNumber>
     </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>BYyEX2b5+K+myAIR7eXaRQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>Cfk9qg==</serialNumber>
+    </certItem>
     <certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
       <serialNumber>e/fIfg2Dj2tkYIWVu2r82Cc=</serialNumber>
     </certItem>
+    <certItem issuerName="MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu">
+      <serialNumber>BAAAAAABJ/v3ZwA=</serialNumber>
+    </certItem>
     <certItem issuerName="MEQxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQDExRHZW9UcnVzdCBTU0wgQ0EgLSBHMg==">
       <serialNumber>SdegFrLaFTCsoMAW5ED+zA==</serialNumber>
     </certItem>
     <certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzI=">
       <serialNumber>XhcFm2g619rt8Sro+a4rHA==</serialNumber>
     </certItem>
     <certItem issuerName="MHMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEkMCIGA1UEAxMbU3ltYW50ZWMgQ2xhc3MgMyBEU0EgU1NMIENB">
       <serialNumber>AuhvPsYZfVP6UDsuyjeZ4Q==</serialNumber>
@@ -3662,136 +3919,298 @@
       <serialNumber>bx/XHJqcwxDOptxJ2lh5vw==</serialNumber>
     </certItem>
     <certItem issuerName="MEQxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQDExRHZW9UcnVzdCBTU0wgQ0EgLSBHMg==">
       <serialNumber>WX89jn8yGZVvoKTD9jDfRQ==</serialNumber>
     </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABCUVQ9No=</serialNumber>
     </certItem>
+    <certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
+      <serialNumber>AQAAAAA=</serialNumber>
+    </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>fWK0j/Vi8vNWg3VAGjc02w==</serialNumber>
     </certItem>
+    <certItem issuerName="MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDI=">
+      <serialNumber>BXA=</serialNumber>
+    </certItem>
+    <certItem issuerName="MDIxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKEwVDTk5JQzETMBEGA1UEAxMKQ05OSUMgUk9PVA==">
+      <serialNumber>STMAeg==</serialNumber>
+    </certItem>
+    <certItem issuerName="MIGXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEfMB0GA1UEAxMWVVROLVVTRVJGaXJzdC1IYXJkd2FyZQ==">
+      <serialNumber>EEpERSryZFMagbsNw/WoWQ==</serialNumber>
+    </certItem>
     <certItem issuerName="MEYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR8wHQYDVQQDExZHZW9UcnVzdCBTSEEyNTYgU1NMIENB">
       <serialNumber>OUvvVscW0/NltofkmV9qmg==</serialNumber>
     </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESCLRVuhcUZaluIgIVlRJx+O</serialNumber>
+    </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABJQdAjik=</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>F6QlB/yX+A==</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
+      <serialNumber>Bydr0Q==</serialNumber>
+    </certItem>
     <certItem issuerName="MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA3IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHNA==">
       <serialNumber>cXXMzbWDHMIdCotb3h64yw==</serialNumber>
     </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESCis569omrbb20yySF39+aE</serialNumber>
+    </certItem>
     <certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
       <serialNumber>dItWlz2V62Philqj9m6Pbg==</serialNumber>
     </certItem>
     <certItem issuerName="MEQxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQDExRHZW9UcnVzdCBTU0wgQ0EgLSBHMw==">
       <serialNumber>cpqpXVWPk5AXzGw+zNIcBw==</serialNumber>
     </certItem>
     <certItem issuerName="MGcxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpGcmF1bmhvZmVyMSEwHwYDVQQLExhGcmF1bmhvZmVyIENvcnBvcmF0ZSBQS0kxIDAeBgNVBAMTF0ZyYXVuaG9mZXIgUm9vdCBDQSAyMDA3">
       <serialNumber>YR3YYQAAAAAABA==</serialNumber>
     </certItem>
+    <certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
+      <serialNumber>BYOGvG32ukb1Yxj2oKoFyw==</serialNumber>
+    </certItem>
     <certItem issuerName="MIG1MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMS8wLQYDVQQDEyZWZXJpU2lnbiBDbGFzcyAzIFNlY3VyZSBTZXJ2ZXIgQ0EgLSBHMw==">
       <serialNumber>NvEJoRYL2yvAZrAjbDIipQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
+      <serialNumber>GN2Hrh9LtnA=</serialNumber>
+    </certItem>
     <certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
       <serialNumber>DAk9hy8DhHSo+aQetvPB/fY=</serialNumber>
     </certItem>
+    <certItem issuerName="MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=">
+      <serialNumber>CSY=</serialNumber>
+    </certItem>
     <certItem issuerName="MIG1MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMS8wLQYDVQQDEyZWZXJpU2lnbiBDbGFzcyAzIFNlY3VyZSBTZXJ2ZXIgQ0EgLSBHMw==">
       <serialNumber>QZBvapTZFvmYktEPsBYLQQ==</serialNumber>
     </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>PAdKZPiaac2CvPxbOrsHOw==</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
+      <serialNumber>BydeGg==</serialNumber>
+    </certItem>
     <certItem issuerName="MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==">
       <serialNumber>Bg==</serialNumber>
     </certItem>
+    <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
+      <serialNumber>BAAAAAABM6d3Z0s=</serialNumber>
+    </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>JV/LVzSKI/wsDgg3UuZHlA==</serialNumber>
     </certItem>
     <certItem issuerName="MEExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xGzAZBgNVBAMTEnRoYXd0ZSBTU0wgQ0EgLSBHMg==">
       <serialNumber>FNISyWWTGi5Yco6fGh58/A==</serialNumber>
     </certItem>
+    <certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
+      <serialNumber>FJl6tXgNpSg=</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
+      <serialNumber>ByeQ9g==</serialNumber>
+    </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>VN2yeFexyXjPf34fHGmbhg==</serialNumber>
     </certItem>
+    <certItem issuerName="MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=">
+      <serialNumber>BAAAAAABLF5/Gog=</serialNumber>
+    </certItem>
+    <certItem issuerName="MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDI=">
+      <serialNumber>EM8bDLBnnoYe4LnWpLIhS4esr3I=</serialNumber>
+    </certItem>
+    <certItem issuerName="MFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
+      <serialNumber>IyIVazG4RE9AERkb+ekH8w==</serialNumber>
+    </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>E77H6yvyFQjO0PcN3x0H+Q==</serialNumber>
     </certItem>
+    <certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
+      <serialNumber>AQAAAAI=</serialNumber>
+    </certItem>
+    <certItem issuerName="MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dD">
+      <serialNumber>Ew1ee9Jq7Q/Dig3ACF4V6Q==</serialNumber>
+    </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>a9/VeyVWrzFD7rM2PEHwQA==</serialNumber>
     </certItem>
+    <certItem issuerName="MIGXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEfMB0GA1UEAxMWVVROLVVTRVJGaXJzdC1IYXJkd2FyZQ==">
+      <serialNumber>Xrr31RF0DoIzMKXS6XtD+g==</serialNumber>
+    </certItem>
     <certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
       <serialNumber>UV9aaDeNRNtQuXjRYk4Skhg=</serialNumber>
     </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESDItX4ruWiLnrlz0rk4/bmz</serialNumber>
+    </certItem>
+    <certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
+      <serialNumber>Aw1SPC56593ZCZ9vCNHKwQ==</serialNumber>
+    </certItem>
     <certItem issuerName="MHcxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEoMCYGA1UEAxMfU3ltYW50ZWMgQ2xhc3MgMyBFViBTU0wgQ0EgLSBHMg==">
       <serialNumber>UVKsEezpGWOVQ4W9esstng==</serialNumber>
     </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>UMUwXwT1Z4juyQ/CNTf4mw==</serialNumber>
     </certItem>
     <certItem issuerName="MDIxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKEwVDTk5JQzETMBEGA1UEAxMKQ05OSUMgUk9PVA==">
       <serialNumber>STMAjg==</serialNumber>
     </certItem>
     <certItem issuerName="MEMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAMTFHRoYXd0ZSBTSEEyNTYgU1NMIENB">
       <serialNumber>UKKK5ol/rKBZchAAOnZjaA==</serialNumber>
     </certItem>
+    <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
+      <serialNumber>BAAAAAABLF5/HXY=</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>CcHC/g==</serialNumber>
+    </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>COwoDFvz7GD8R2K7Lo0rYQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MEgxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlvbjEXMBUGA1UEAxMOU2VjdXJlVHJ1c3QgQ0E=">
+      <serialNumber>ANygrItIJ2rcKlyS3Lue07U=</serialNumber>
+    </certItem>
+    <certItem issuerName="MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjEXMBUGA1UEAxMORFNUIFJvb3QgQ0EgWDM=">
+      <serialNumber>CgFBQgAAAUFcf/EVAAAAAg==</serialNumber>
+    </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESD9YhzIEOwiOT7Nwip+E1KI</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>CeagHQ==</serialNumber>
+    </certItem>
     <certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
       <serialNumber>OYBKgxEHpW/8XGAGAlvJyMA=</serialNumber>
     </certItem>
+    <certItem issuerName="MIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls">
+      <serialNumber>D/wZ7+m1Mv8SONSEFcs73w==</serialNumber>
+    </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>LdbnCbsA9sOgI4mkUpWXPw==</serialNumber>
     </certItem>
+    <certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
+      <serialNumber>GN2Hrh9LtnM=</serialNumber>
+    </certItem>
+    <certItem issuerName="MG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3Q=">
+      <serialNumber>Os2rnHWYhryvdOXfgan06A==</serialNumber>
+    </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESDu2nhlLPzfx+LYgjlYFP/k</serialNumber>
+    </certItem>
     <certItem issuerName="MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==">
       <serialNumber>EQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=">
+      <serialNumber>BAAAAAABHkSl5AQ=</serialNumber>
+    </certItem>
+    <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
+      <serialNumber>BAAAAAABHkSHki0=</serialNumber>
+    </certItem>
     <certItem issuerName="MF8xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRQwEgYDVQQLEwtQYXJ0bmVycyBDQTEfMB0GA1UEAxMWR2xvYmFsU2lnbiBQYXJ0bmVycyBDQQ==">
       <serialNumber>BAAAAAABCfhiO+s=</serialNumber>
     </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>AygWP2Fgd2T+iLbmAlKT6g==</serialNumber>
     </certItem>
+    <certItem issuerName="MF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
+      <serialNumber>L7tgs/W85vnhV7I7qJ6N/g==</serialNumber>
+    </certItem>
     <certItem issuerName="MIGBMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTElMCMGA1UECxMcUHJpbWFyeSBPYmplY3QgUHVibGlzaGluZyBDQTEwMC4GA1UEAxMnR2xvYmFsU2lnbiBQcmltYXJ5IE9iamVjdCBQdWJsaXNoaW5nIENB">
       <serialNumber>BAAAAAABI54PryQ=</serialNumber>
     </certItem>
+    <certItem issuerName="MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=">
+      <serialNumber>BAAAAAABKUXDqA8=</serialNumber>
+    </certItem>
+    <certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
+      <serialNumber>AQAAAAM=</serialNumber>
+    </certItem>
+    <certItem issuerName="MEgxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlvbjEXMBUGA1UEAxMOU2VjdXJlVHJ1c3QgQ0E=">
+      <serialNumber>R4af5A==</serialNumber>
+    </certItem>
+    <certItem issuerName="MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIzMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu">
+      <serialNumber>BAAAAAABJQcQQN0=</serialNumber>
+    </certItem>
     <certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzI=">
       <serialNumber>EDQMI0tR4kSntv1O37N10g==</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>Cfk9oA==</serialNumber>
+    </certItem>
+    <certItem issuerName="MIGpMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYDVQQLEy8oYykgMjAwNiB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UEAxMWdGhhd3RlIFByaW1hcnkgUm9vdCBDQQ==">
+      <serialNumber>Ikdj3zYXXGsC/Afm9Tvx+g==</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>CeFU2w==</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>CskruA==</serialNumber>
+    </certItem>
     <certItem issuerName="MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=">
       <serialNumber>BUrYjru5px1ym4QUN33TOQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MEoxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlvbjEZMBcGA1UEAxMQU2VjdXJlIEdsb2JhbCBDQQ==">
+      <serialNumber>TXxtAQ==</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>Cyr1PA==</serialNumber>
+    </certItem>
+    <certItem issuerName="MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==">
+      <serialNumber>U4P1tUoxl/XkztlVHdtdgw==</serialNumber>
+    </certItem>
     <certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
       <serialNumber>sPNcCSE9Nkg3jy5IN1xe2Q==</serialNumber>
     </certItem>
     <certItem issuerName="MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=">
       <serialNumber>E5I2y6sIonl4a+TmlXc7fw==</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
+      <serialNumber>Byd5cg==</serialNumber>
+    </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
+      <serialNumber>CdWFNw==</serialNumber>
+    </certItem>
+    <certItem issuerName="MDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMCREU=">
+      <serialNumber>M0VSOewW3WI=</serialNumber>
+    </certItem>
     <certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
       <serialNumber>KjoVfZ3by6+pL8fssyfM6A==</serialNumber>
     </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABBHYoIFs=</serialNumber>
     </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABHJRKMpA=</serialNumber>
     </certItem>
+    <certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
+      <serialNumber>eR1nUEz8k+nDSBD+bb5uIQ==</serialNumber>
+    </certItem>
+    <certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
+      <serialNumber>Ai7cBJYqBE0I9NdyoZfRrw==</serialNumber>
+    </certItem>
+    <certItem issuerName="MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB">
+      <serialNumber>ESDYXNBhF+dePFjojs7u2vj1</serialNumber>
+    </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>ezdAeCxKH7BFs7vn3byYaw==</serialNumber>
     </certItem>
     <certItem issuerName="MGExCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xMjAwBgNVBAMMKVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBDQSAtIEcy">
       <serialNumber>ATE0vw==</serialNumber>
     </certItem>
     <certItem issuerName="MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==">
       <serialNumber>BAAAAAABAPpuVh0=</serialNumber>
     </certItem>
     <certItem issuerName="MGgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEiMCAGA1UEAxMZR2VvVHJ1c3QgRFYgU1NMIFNIQTI1NiBDQQ==">
       <serialNumber>OE4/d+p3YRzzcSl+kmZ8Mw==</serialNumber>
     </certItem>
     <certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=">
       <serialNumber>HNo1DR4XCe4mS1iUMsY6Wg==</serialNumber>
     </certItem>
+    <certItem issuerName="MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu">
+      <serialNumber>BAAAAAABEAuMoRs=</serialNumber>
+    </certItem>
     <certItem issuerName="MGExCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEbMBkGA1UEAxMSR2VvVHJ1c3QgRFYgU1NMIENB">
       <serialNumber>CWhp</serialNumber>
     </certItem>
   </certItems>
 </blocklist>
--- a/browser/base/content/browser-media.js
+++ b/browser/base/content/browser-media.js
@@ -351,14 +351,14 @@ let gDecoderDoctorHandler = {
       // first time we get this resolution -> Clear prefs and report telemetry.
       Services.prefs.clearUserPref(formatsPref);
       Services.prefs.clearUserPref(buttonClickedPref);
       histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_SOLVED);
     }
   },
 }
 
-window.messageManager.addMessageListener("DecoderDoctor:Notification", gDecoderDoctorHandler);
-window.messageManager.addMessageListener("EMEVideo:ContentMediaKeysRequest", gEMEHandler);
+window.getGroupMessageManager("browsers").addMessageListener("DecoderDoctor:Notification", gDecoderDoctorHandler);
+window.getGroupMessageManager("browsers").addMessageListener("EMEVideo:ContentMediaKeysRequest", gEMEHandler);
 window.addEventListener("unload", function() {
-  window.messageManager.removeMessageListener("EMEVideo:ContentMediaKeysRequest", gEMEHandler);
-  window.messageManager.removeMessageListener("DecoderDoctor:Notification", gDecoderDoctorHandler);
+  window.getGroupMessageManager("browsers").removeMessageListener("EMEVideo:ContentMediaKeysRequest", gEMEHandler);
+  window.getGroupMessageManager("browsers").removeMessageListener("DecoderDoctor:Notification", gDecoderDoctorHandler);
 }, false);
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -840,17 +840,17 @@ var BookmarksEventHandler = {
 
     if (aEvent.button == 2 || (aEvent.button == 0 && !modifKey))
       return;
 
     var target = aEvent.originalTarget;
     // If this event bubbled up from a menu or menuitem, close the menus.
     // Do this before opening tabs, to avoid hiding the open tabs confirm-dialog.
     if (target.localName == "menu" || target.localName == "menuitem") {
-      for (node = target.parentNode; node; node = node.parentNode) {
+      for (let node = target.parentNode; node; node = node.parentNode) {
         if (node.localName == "menupopup")
           node.hidePopup();
         else if (node.localName != "menu" &&
                  node.localName != "splitmenu" &&
                  node.localName != "hbox" &&
                  node.localName != "vbox" )
           break;
       }
@@ -1996,9 +1996,8 @@ var AutoShowBookmarksToolbar = {
     let placement = CustomizableUI.getPlacementOfWidget("personal-bookmarks");
     let area = placement && placement.area;
     if (area != CustomizableUI.AREA_BOOKMARKS)
       return;
 
     setToolbarVisibility(toolbar, true);
   }
 };
-
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1072,21 +1072,21 @@ var gBrowserInit = {
     }, false, true);
 
     gBrowser.addEventListener("InsecureLoginFormsStateChange", function() {
       gIdentityHandler.refreshForInsecureLoginForms();
     });
 
     let uriToLoad = this._getUriToLoad();
     if (uriToLoad && uriToLoad != "about:blank") {
-      if (uriToLoad instanceof Ci.nsISupportsArray) {
-        let count = uriToLoad.Count();
+      if (uriToLoad instanceof Ci.nsIArray) {
+        let count = uriToLoad.length;
         let specs = [];
         for (let i = 0; i < count; i++) {
-          let urisstring = uriToLoad.GetElementAt(i).QueryInterface(Ci.nsISupportsString);
+          let urisstring = uriToLoad.queryElementAt(i, Ci.nsISupportsString);
           specs.push(urisstring.data);
         }
 
         // This function throws for certain malformed URIs, so use exception handling
         // so that we don't disrupt startup
         try {
           gBrowser.loadTabs(specs, false, true);
         } catch (e) {}
@@ -1408,17 +1408,17 @@ var gBrowserInit = {
     this.delayedStartupFinished = true;
 
     Services.obs.notifyObservers(window, "browser-delayed-startup-finished", "");
     TelemetryTimestamps.add("delayedStartupFinished");
   },
 
   // Returns the URI(s) to load at startup.
   _getUriToLoad: function () {
-    // window.arguments[0]: URI to load (string), or an nsISupportsArray of
+    // window.arguments[0]: URI to load (string), or an nsIArray of
     //                      nsISupportsStrings to load, or a xul:tab of
     //                      a tabbrowser, which will be replaced by this
     //                      window (for this case, all other arguments are
     //                      ignored).
     if (!window.arguments || !window.arguments[0])
       return null;
 
     let uri = window.arguments[0];
@@ -4245,20 +4245,20 @@ var XULBrowserWindow = {
   },
 
   forceInitialBrowserRemote: function() {
     let initBrowser =
       document.getAnonymousElementByAttribute(gBrowser, "anonid", "initialBrowser");
     return initBrowser.frameLoader.tabParent;
   },
 
-  forceInitialBrowserNonRemote: function() {
+  forceInitialBrowserNonRemote: function(aOpener) {
     let initBrowser =
       document.getAnonymousElementByAttribute(gBrowser, "anonid", "initialBrowser");
-    gBrowser.updateBrowserRemoteness(initBrowser, false);
+    gBrowser.updateBrowserRemoteness(initBrowser, false, aOpener);
   },
 
   setDefaultStatus: function (status) {
     this.defaultStatus = status;
     this.updateStatusField();
   },
 
   setOverLink: function (url, anchorElt) {
@@ -4896,17 +4896,18 @@ var TabsProgressListener = {
 
 function nsBrowserAccess() { }
 
 nsBrowserAccess.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow, Ci.nsISupports]),
 
   _openURIInNewTab: function(aURI, aReferrer, aReferrerPolicy, aIsPrivate,
                              aIsExternal, aForceNotRemote=false,
-                             aUserContextId=Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID) {
+                             aUserContextId=Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID,
+                             aOpener=null) {
     let win, needToFocusWin;
 
     // try the current window.  if we're in a popup, fall back on the most recent browser window
     if (window.toolbar.visible)
       win = window;
     else {
       win = RecentWindow.getMostRecentBrowserWindow({private: aIsPrivate});
       needToFocusWin = true;
@@ -4926,36 +4927,38 @@ nsBrowserAccess.prototype = {
     let loadInBackground = gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground");
 
     let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", {
                                       referrerURI: aReferrer,
                                       referrerPolicy: aReferrerPolicy,
                                       userContextId: aUserContextId,
                                       fromExternal: aIsExternal,
                                       inBackground: loadInBackground,
-                                      forceNotRemote: aForceNotRemote});
+                                      forceNotRemote: aForceNotRemote,
+                                      opener: aOpener,
+                                      });
     let browser = win.gBrowser.getBrowserForTab(tab);
 
     if (needToFocusWin || (!loadInBackground && aIsExternal))
       win.focus();
 
     return browser;
   },
 
-  openURI: function (aURI, aOpener, aWhere, aContext) {
+  openURI: function (aURI, aOpener, aWhere, aFlags) {
     // This function should only ever be called if we're opening a URI
     // from a non-remote browser window (via nsContentTreeOwner).
     if (aOpener && Cu.isCrossProcessWrapper(aOpener)) {
       Cu.reportError("nsBrowserAccess.openURI was passed a CPOW for aOpener. " +
                      "openURI should only ever be called from non-remote browsers.");
       throw Cr.NS_ERROR_FAILURE;
     }
 
     var newWindow = null;
-    var isExternal = (aContext == Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
+    var isExternal = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
 
     if (aOpener && isExternal) {
       Cu.reportError("nsBrowserAccess.openURI did not expect an opener to be " +
                      "passed if the context is OPEN_EXTERNAL.");
       throw Cr.NS_ERROR_FAILURE;
     }
 
     if (isExternal && aURI && aURI.schemeIs("chrome")) {
@@ -4999,19 +5002,21 @@ nsBrowserAccess.prototype = {
         // this means forcing the newly opened browser to be non-remote so that
         // we can hand back the nsIDOMWindow. The XULBrowserWindow.shouldLoadURI
         // will do the job of shuttling off the newly opened browser to run in
         // the right process once it starts loading a URI.
         let forceNotRemote = !!aOpener;
         let userContextId = aOpener && aOpener.document
                               ? aOpener.document.nodePrincipal.originAttributes.userContextId
                               : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID;
+        let openerWindow = (aFlags & Ci.nsIBrowserDOMWindow.OPEN_NO_OPENER) ? null : aOpener;
         let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy,
                                             isPrivate, isExternal,
-                                            forceNotRemote, userContextId);
+                                            forceNotRemote, userContextId,
+                                            openerWindow);
         if (browser)
           newWindow = browser.contentWindow;
         break;
       default : // OPEN_CURRENTWINDOW or an illegal value
         newWindow = content;
         if (aURI) {
           let loadflags = isExternal ?
                             Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL :
@@ -5023,23 +5028,23 @@ nsBrowserAccess.prototype = {
                                     });
         }
         if (!gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground"))
           window.focus();
     }
     return newWindow;
   },
 
-  openURIInFrame: function browser_openURIInFrame(aURI, aParams, aWhere, aContext) {
+  openURIInFrame: function browser_openURIInFrame(aURI, aParams, aWhere, aFlags) {
     if (aWhere != Ci.nsIBrowserDOMWindow.OPEN_NEWTAB) {
       dump("Error: openURIInFrame can only open in new tabs");
       return null;
     }
 
-    var isExternal = (aContext == Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
+    var isExternal = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
 
     var userContextId = aParams.openerOriginAttributes &&
                         ("userContextId" in aParams.openerOriginAttributes)
                           ? aParams.openerOriginAttributes.userContextId
                           : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID
 
     let browser = this._openURIInNewTab(aURI, aParams.referrer,
                                         aParams.referrerPolicy,
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -1048,28 +1048,26 @@ function setItemValue(id, value)
 
 function formatNumber(number)
 {
   return (+number).toLocaleString();  // coerce number to a numeric value before calling toLocaleString()
 }
 
 function formatDate(datestr, unknown)
 {
-  // scriptable date formatter, for pretty printing dates
-  var dateService = Components.classes["@mozilla.org/intl/scriptabledateformat;1"]
-                              .getService(Components.interfaces.nsIScriptableDateFormat);
-
   var date = new Date(datestr);
   if (!date.valueOf())
     return unknown;
 
-  return dateService.FormatDateTime("", dateService.dateFormatLong,
-                                    dateService.timeFormatSeconds,
-                                    date.getFullYear(), date.getMonth()+1, date.getDate(),
-                                    date.getHours(), date.getMinutes(), date.getSeconds());
+  const locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
+                 .getService(Components.interfaces.nsIXULChromeRegistry)
+                 .getSelectedLocale("global", true);
+  const dtOptions = { year: 'numeric', month: 'long', day: 'numeric',
+                      hour: 'numeric', minute: 'numeric', second: 'numeric' };
+  return date.toLocaleString(locale, dtOptions);
 }
 
 function doCopy()
 {
   if (!gClipboardHelper)
     return;
 
   var elem = document.commandDispatcher.focusedElement;
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1498,16 +1498,17 @@
             var aRelatedToCurrent;
             var aAllowMixedContent;
             var aSkipAnimation;
             var aForceNotRemote;
             var aNoReferrer;
             var aUserContextId;
             var aRelatedBrowser;
             var aOriginPrincipal;
+            var aOpener;
             if (arguments.length == 2 &&
                 typeof arguments[1] == "object" &&
                 !(arguments[1] instanceof Ci.nsIURI)) {
               let params = arguments[1];
               aReferrerURI          = params.referrerURI;
               aReferrerPolicy       = params.referrerPolicy;
               aCharset              = params.charset;
               aPostData             = params.postData;
@@ -1517,16 +1518,17 @@
               aRelatedToCurrent     = params.relatedToCurrent;
               aAllowMixedContent    = params.allowMixedContent;
               aSkipAnimation        = params.skipAnimation;
               aForceNotRemote       = params.forceNotRemote;
               aNoReferrer           = params.noReferrer;
               aUserContextId        = params.userContextId;
               aRelatedBrowser       = params.relatedBrowser;
               aOriginPrincipal      = params.originPrincipal;
+              aOpener               = params.opener;
             }
 
             var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
                          Services.prefs.getBoolPref("browser.tabs.loadInBackground");
             var owner = bgLoad ? null : this.selectedTab;
             var tab = this.addTab(aURI, {
                                   referrerURI: aReferrerURI,
                                   referrerPolicy: aReferrerPolicy,
@@ -1537,17 +1539,18 @@
                                   fromExternal: aFromExternal,
                                   relatedToCurrent: aRelatedToCurrent,
                                   skipAnimation: aSkipAnimation,
                                   allowMixedContent: aAllowMixedContent,
                                   forceNotRemote: aForceNotRemote,
                                   noReferrer: aNoReferrer,
                                   userContextId: aUserContextId,
                                   originPrincipal: aOriginPrincipal,
-                                  relatedBrowser: aRelatedBrowser });
+                                  relatedBrowser: aRelatedBrowser,
+                                  opener: aOpener });
             if (!bgLoad)
               this.selectedTab = tab;
 
             return tab;
          ]]>
         </body>
       </method>
 
@@ -1650,21 +1653,37 @@
               this.selectedBrowser.focus();
           }
         ]]></body>
       </method>
 
       <method name="updateBrowserRemoteness">
         <parameter name="aBrowser"/>
         <parameter name="aShouldBeRemote"/>
+        <parameter name="aOpener"/>
         <body>
           <![CDATA[
             let isRemote = aBrowser.getAttribute("remote") == "true";
-            if (isRemote == aShouldBeRemote)
+
+            // If we are passed an opener, we must be making the browser non-remote, and
+            // if the browser is _currently_ non-remote, we need the openers to match,
+            // because it is already too late to change it.
+            if (aOpener) {
+              if (aShouldBeRemote) {
+                throw new Exception("Cannot set an opener on a browser which should be remote!");
+              }
+              if (!isRemote && aBrowser.contentWindow.opener != aOpener) {
+                throw new Exception("Cannot change opener on an already non-remote browser!");
+              }
+            }
+
+            // Abort if we're not going to change anything
+            if (isRemote == aShouldBeRemote) {
               return false;
+            }
 
             let tab = this.getTabForBrowser(aBrowser);
             let evt = document.createEvent("Events");
             evt.initEvent("BeforeTabRemotenessChange", true, false);
             tab.dispatchEvent(evt);
 
             let wasActive = document.activeElement == aBrowser;
 
@@ -1695,16 +1714,20 @@
             let parent = aBrowser.parentNode;
             parent.removeChild(aBrowser);
             aBrowser.setAttribute("remote", aShouldBeRemote ? "true" : "false");
 
             // NB: This works with the hack in the browser constructor that
             // turns this normal property into a field.
             aBrowser.relatedBrowser = relatedBrowser;
 
+            // Set the opener window on the browser, such that when the frame
+            // loader is created the opener is set correctly.
+            aBrowser.presetOpenerWindow(aOpener);
+
             parent.appendChild(aBrowser);
 
             aBrowser.userTypedValue = oldUserTypedValue;
             if (hadStartedLoad) {
               aBrowser.urlbarChangeTracker.startedLoad();
             }
 
             aBrowser.droppedLinkHandler = droppedLinkHandler;
@@ -1876,16 +1899,23 @@
             if (aParams.userContextId) {
               b.setAttribute("usercontextid", aParams.userContextId);
             }
 
             if (aParams.remote) {
               b.setAttribute("remote", "true");
             }
 
+            if (aParams.opener) {
+              if (aParams.remote) {
+                throw new Exception("Cannot set opener window on a remote browser!");
+              }
+              b.QueryInterface(Ci.nsIFrameLoaderOwner).presetOpenerWindow(aParams.opener);
+            }
+
             if (window.gShowPageResizers && window.windowState == window.STATE_NORMAL) {
               b.setAttribute("showresizer", "true");
             }
 
             if (!aParams.isPreloadBrowser && this.hasAttribute("autocompletepopup")) {
               b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
             }
 
@@ -1976,17 +2006,18 @@
             }
 
             if (!browser) {
               // No preloaded browser found, create one.
               browser = this._createBrowser({permanentKey: aTab.permanentKey,
                                              remote: remote,
                                              uriIsAboutBlank: uriIsAboutBlank,
                                              userContextId: aParams.userContextId,
-                                             relatedBrowser: aParams.relatedBrowser});
+                                             relatedBrowser: aParams.relatedBrowser,
+                                             opener: aParams.opener});
             }
 
             let notificationbox = this.getNotificationBox(browser);
             let uniqueId = this._generateUniquePanelID();
             notificationbox.id = uniqueId;
             aTab.linkedPanel = uniqueId;
             aTab.linkedBrowser = browser;
             aTab.hasBrowser = true;
@@ -2052,16 +2083,17 @@
             var aSkipAnimation;
             var aAllowMixedContent;
             var aForceNotRemote;
             var aNoReferrer;
             var aUserContextId;
             var aEventDetail;
             var aRelatedBrowser;
             var aOriginPrincipal;
+            var aOpener;
             if (arguments.length == 2 &&
                 typeof arguments[1] == "object" &&
                 !(arguments[1] instanceof Ci.nsIURI)) {
               let params = arguments[1];
               aReferrerURI          = params.referrerURI;
               aReferrerPolicy       = params.referrerPolicy;
               aCharset              = params.charset;
               aPostData             = params.postData;
@@ -2072,16 +2104,17 @@
               aSkipAnimation        = params.skipAnimation;
               aAllowMixedContent    = params.allowMixedContent;
               aForceNotRemote       = params.forceNotRemote;
               aNoReferrer           = params.noReferrer;
               aUserContextId        = params.userContextId;
               aEventDetail          = params.eventDetail;
               aRelatedBrowser       = params.relatedBrowser;
               aOriginPrincipal      = params.originPrincipal;
+              aOpener               = params.opener;
             }
 
             // if we're adding tabs, we're past interrupt mode, ditch the owner
             if (this.mCurrentTab.owner)
               this.mCurrentTab.owner = null;
 
             var t = document.createElementNS(NS_XUL, "tab");
 
@@ -2139,17 +2172,18 @@
             // bug this will be removed so we can leave the tab in its "lazy"
             // state to be exploited for startup optimization.  Note that for
             // now this must occur before "TabOpen" event is fired, as that will
             // trigger SessionStore.jsm to run code that expects the existence
             // of tab.linkedBrowser.
             let browserParams = {
               forceNotRemote: aForceNotRemote,
               userContextId:  aUserContextId,
-              relatedBrowser: aRelatedBrowser
+              relatedBrowser: aRelatedBrowser,
+              opener: aOpener,
             };
             let { usingPreloadedContent } = this._linkBrowserToTab(t, aURI, browserParams);
             let b = t.linkedBrowser;
 
             // Dispatch a new tab notification.  We do this once we're
             // entirely done, so that things are in a consistent state
             // even if the event listener opens or closes tabs.
             var detail = aEventDetail || {};
@@ -6568,16 +6602,25 @@
       Describes how the tab ended up in this mute state. May be any of:
 
        - undefined: The tabs mute state has never changed.
        - null: The mute state was last changed through the UI.
        - Any string: The ID was changed through an extension API. The string
                      must be the ID of the extension which changed it.
       -->
       <field name="muteReason">undefined</field>
+
+      <property name="userContextId" readonly="true">
+        <getter>
+          return this.hasAttribute("usercontextid")
+                   ? parseInt(this.getAttribute("usercontextid"))
+                   : 0;
+        </getter>
+      </property>
+
       <property name="soundPlaying" readonly="true">
         <getter>
           return this.getAttribute("soundplaying") == "true";
         </getter>
       </property>
 
       <property name="lastAccessed">
         <getter>
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -24,17 +24,16 @@ support-files =
   bug792517-2.html
   bug792517.html
   bug792517.sjs
   bug839103.css
   clipboard_pastefile.html
   contextmenu_common.js
   ctxmenu-image.png
   discovery.html
-  domplate_test.js
   download_page.html
   dummy_page.html
   feed_tab.html
   file_generic_favicon.ico
   file_with_favicon.html
   file_bug822367_1.html
   file_bug822367_1.js
   file_bug822367_2.html
--- a/browser/base/content/test/general/browser_bug409624.js
+++ b/browser/base/content/test/general/browser_bug409624.js
@@ -3,20 +3,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 XPCOMUtils.defineLazyModuleGetter(this, "FormHistory",
                                   "resource://gre/modules/FormHistory.jsm");
 
 add_task(function* test() {
   // This test relies on the form history being empty to start with delete
   // all the items first.
-  yield new Promise(resolve => {
+  yield new Promise((resolve, reject) => {
     FormHistory.update({ op: "remove" },
                        { handleError(error) {
-                           do_throw("Error occurred updating form history: " + error);
+                           reject(error);
                          },
                          handleCompletion(reason) {
                            if (!reason) {
                              resolve();
                            } else {
                              reject();
                            }
                          },
--- a/browser/base/content/test/general/browser_bug553455.js
+++ b/browser/base/content/test/general/browser_bug553455.js
@@ -143,32 +143,32 @@ function waitForInstallDialog() {
   return Task.spawn(function* () {
     if (Preferences.get("xpinstall.customConfirmationUI", false)) {
       yield waitForNotification("addon-install-confirmation");
       return;
     }
 
     info("Waiting for install dialog");
 
-    yield new Promise(resolve => {
+    let window = yield new Promise(resolve => {
       Services.wm.addListener({
         onOpenWindow: function(aXULWindow) {
           Services.wm.removeListener(this);
-          resolve();
+          resolve(aXULWindow);
         },
         onCloseWindow: function(aXULWindow) {
         },
         onWindowTitleChange: function(aXULWindow, aNewTitle) {
         }
       });
     });
     info("Install dialog opened, waiting for focus");
 
-    let domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                              .getInterface(Ci.nsIDOMWindow);
+    let domwindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
+                          .getInterface(Ci.nsIDOMWindow);
     yield new Promise(resolve => {
       waitForFocus(function() {
         resolve();
       }, domwindow);
     });
     info("Saw install dialog");
     is(domwindow.document.location.href, XPINSTALL_URL, "Should have seen the right window open");
 
@@ -743,17 +743,16 @@ function test_localFile() {
     let notification = PopupNotifications.panel.childNodes[0];
     is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
     is(notification.getAttribute("label"),
        "This add-on could not be installed because it appears to be corrupt.",
        "Should have seen the right message");
 
     yield removeTab();
   });
-    path = CHROMEROOT + "corrupt.xpi";
 },
 
 function test_tabClose() {
   return Task.spawn(function* () {
     if (!Preferences.get("xpinstall.customConfirmationUI", false)) {
       runNextTest();
       return;
     }
--- a/browser/base/content/test/general/browser_sanitize-timespans.js
+++ b/browser/base/content/test/general/browser_sanitize-timespans.js
@@ -54,17 +54,17 @@ function countEntries(name, message, che
 
   var obj = {};
   if (name !== null)
     obj.fieldname = name;
 
   let count;
   FormHistory.count(obj, { handleResult: result => count = result,
                            handleError: function (error) {
-                             do_throw("Error occurred searching form history: " + error);
+                             throw new Error("Error occurred searching form history: " + error);
                              deferred.reject(error)
                            },
                            handleCompletion: function (reason) {
                              if (!reason) {
                                check(count, message);
                                deferred.resolve();
                              }
                            },
@@ -489,29 +489,29 @@ function setupHistory() {
 function* setupFormHistory() {
 
   function searchEntries(terms, params) {
     let deferred = Promise.defer();
 
     let results = [];
     FormHistory.search(terms, params, { handleResult: result => results.push(result),
                                         handleError: function (error) {
-                                          do_throw("Error occurred searching form history: " + error);
+                                          throw new Error("Error occurred searching form history: " + error);
                                           deferred.reject(error);
                                         },
                                         handleCompletion: function (reason) { deferred.resolve(results); }
                                       });
     return deferred.promise;
   }
 
   function update(changes)
   {
     let deferred = Promise.defer();
     FormHistory.update(changes, { handleError: function (error) {
-                                    do_throw("Error occurred searching form history: " + error);
+                                    throw new Error("Error occurred searching form history: " + error);
                                     deferred.reject(error);
                                   },
                                   handleCompletion: function (reason) { deferred.resolve(); }
                                 });
     return deferred.promise;
   }
 
   // Make sure we've got a clean DB to start with, then add the entries we'll be testing.
--- a/browser/base/content/test/general/browser_sanitizeDialog.js
+++ b/browser/base/content/test/general/browser_sanitizeDialog.js
@@ -897,17 +897,17 @@ function promiseAddFormEntryWithMinutesA
   let name = aMinutesAgo + "-minutes-ago";
 
   // Artifically age the entry to the proper vintage.
   let timestamp = now_uSec - (aMinutesAgo * kUsecPerMin);
 
   return new Promise((resolve, reject) =>
     FormHistory.update({ op: "add", fieldname: name, value: "dummy", firstUsed: timestamp },
                        { handleError: function (error) {
-                           do_throw("Error occurred updating form history: " + error);
+                           throw new Error("Error occurred updating form history: " + error);
                            reject();
                          },
                          handleCompletion: function (reason) {
                            resolve(name);
                          }
                        })
    )
 }
@@ -917,17 +917,17 @@ function promiseAddFormEntryWithMinutesA
  */
 function formNameExists(name)
 {
   return new Promise((resolve, reject) => {
     let count = 0;
     FormHistory.count({ fieldname: name },
                       { handleResult: result => count = result,
                         handleError: function (error) {
-                          do_throw("Error occurred searching form history: " + error);
+                          throw new Error("Error occurred searching form history: " + error);
                           reject(error);
                         },
                         handleCompletion: function (reason) {
                           if (!reason) {
                             resolve(count);
                           }
                         }
                       });
@@ -948,17 +948,17 @@ function* blankSlate() {
   yield new Promise((resolve, reject) => {
     FormHistory.update({op: "remove"}, {
       handleCompletion(reason) {
         if (!reason) {
           resolve();
         }
       },
       handleError(error) {
-        do_throw("Error occurred updating form history: " + error);
+        throw new Error("Error occurred updating form history: " + error);
         reject(error);
       }
     });
   });
 
   yield PlacesTestUtils.clearHistory();
 }
 
deleted file mode 100644
--- a/browser/base/content/test/general/domplate_test.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var doc;
-var div;
-var plate;
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource:///modules/domplate.jsm");
-
-function createDocument()
-{
-  doc.body.innerHTML = '<div id="first">no</div>';
-  doc.title = "Domplate Test";
-  setupDomplateTests();
-}
-
-function setupDomplateTests()
-{
-  ok(domplate, "domplate is defined");
-  plate = domplate({tag: domplate.DIV("Hello!")});
-  ok(plate, "template is defined");
-  div = doc.getElementById("first");
-  ok(div, "we have our div");
-  plate.tag.replace({}, div, template);
-  is(div.innerText, "Hello!", "Is the div's innerText replaced?");
-  finishUp();
-}
-
-function finishUp()
-{
-  gBrowser.removeCurrentTab();
-  finish();
-}
-
-function test()
-{
-  waitForExplicitFinish();
-  gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.selectedBrowser.addEventListener("load", function() {
-    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
-    doc = content.document;
-    waitForFocus(createDocument, content);
-  }, true);
-
-  content.location = "data:text/html;charset=utf-8,domplate_test.js";
-}
-
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabPrompts/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc.js"
+  ]
+};
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabs/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc.js"
+  ]
+};
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/urlbar/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc.js"
+  ]
+};
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/webrtc/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc.js"
+  ]
+};
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -1362,16 +1362,29 @@ file, You can obtain one at http://mozil
 
       <field name="_oneOffSearchesEnabled">false</field>
 
       <field name="_overrideValue">null</field>
       <property name="overrideValue"
                 onget="return this._overrideValue;"
                 onset="this._overrideValue = val; return val;"/>
 
+      <method name="onPopupClick">
+        <parameter name="aEvent"/>
+        <body><![CDATA[
+          if (aEvent.button == 2) {
+            // Ignore right-clicks.
+            return;
+          }
+          // Otherwise "call super" -- do what autocomplete-base-popup does.
+          let controller = this.view.QueryInterface(Components.interfaces.nsIAutoCompleteController);
+          controller.handleEnter(true, aEvent);
+        ]]></body>
+      </method>
+
       <method name="enableOneOffSearches">
         <parameter name="enable"/>
         <body><![CDATA[
           this._oneOffSearchesEnabled = enable;
           if (enable) {
             this.oneOffSearchButtons.telemetryOrigin = "urlbar";
             this.oneOffSearchButtons.style.display = "-moz-box";
             this.oneOffSearchButtons.popup = this;
--- a/browser/components/contextualidentity/test/browser/browser_eme.js
+++ b/browser/components/contextualidentity/test/browser/browser_eme.js
@@ -86,16 +86,17 @@ function generateKeyInfo(aData) {
 add_task(function* setup() {
   // Make sure userContext is enabled.
   yield new Promise(resolve => {
     SpecialPowers.pushPrefEnv({"set": [
       [ "privacy.userContext.enabled", true ],
       [ "media.mediasource.enabled", true ],
       [ "media.eme.apiVisible", true ],
       [ "media.mediasource.webm.enabled", true ],
+      [ "media.clearkey.persistent-license.enabled", true ],
     ]}, resolve);
   });
 });
 
 add_task(function* test() {
   // Open a tab with the default container.
   let defaultContainer = yield openTabInUserContext(TEST_URL + "empty_file.html", USER_ID_DEFAULT);
 
--- a/browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js
+++ b/browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js
@@ -176,16 +176,17 @@ function* checkEMEKey(browser, emeSessio
 
 add_task(function* setup() {
   // Make sure userContext is enabled.
   yield SpecialPowers.pushPrefEnv({"set": [
       [ "privacy.userContext.enabled", true ],
       [ "media.mediasource.enabled", true ],
       [ "media.eme.apiVisible", true ],
       [ "media.mediasource.webm.enabled", true ],
+      [ "media.clearkey.persistent-license.enabled", true ],
   ]});
 });
 
 add_task(function* test_EME_forgetThisSite() {
   let tabs = [];
   let emeSessionIds = [];
 
   for (let userContextId of Object.keys(USER_CONTEXTS)) {
--- a/browser/components/extensions/ext-tabs.js
+++ b/browser/components/extensions/ext-tabs.js
@@ -3,16 +3,18 @@
 "use strict";
 
 XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
                                    "@mozilla.org/browser/aboutnewtab-service;1",
                                    "nsIAboutNewTabService");
 
 XPCOMUtils.defineLazyModuleGetter(this, "MatchPattern",
                                   "resource://gre/modules/MatchPattern.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
+                                  "resource://gre/modules/PrivateBrowsingUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
                                   "resource://gre/modules/PromiseUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
                                   "resource://gre/modules/Services.jsm");
 
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 
 var {
@@ -518,18 +520,47 @@ extensions.registerSchemaAPI("tabs", "ad
           if (createProperties.url !== null) {
             url = context.uri.resolve(createProperties.url);
 
             if (!context.checkLoadURL(url, {dontReportErrors: true})) {
               return Promise.reject({message: `Illegal URL: ${url}`});
             }
           }
 
+          if (createProperties.cookieStoreId && !extension.hasPermission("cookies")) {
+            return Promise.reject({message: `No permission for cookieStoreId: ${createProperties.cookieStoreId}`});
+          }
+
+          let options = {};
+          if (createProperties.cookieStoreId) {
+            if (!global.isValidCookieStoreId(createProperties.cookieStoreId)) {
+              return Promise.reject({message: `Illegal cookieStoreId: ${createProperties.cookieStoreId}`});
+            }
+
+            let privateWindow = PrivateBrowsingUtils.isBrowserPrivate(window.gBrowser);
+            if (privateWindow && !global.isPrivateCookieStoreId(createProperties.cookieStoreId)) {
+              return Promise.reject({message: `Illegal to set non-private cookieStorageId in a private window`});
+            }
+
+            if (!privateWindow && global.isPrivateCookieStoreId(createProperties.cookieStoreId)) {
+              return Promise.reject({message: `Illegal to set private cookieStorageId in a non-private window`});
+            }
+
+            if (global.isContainerCookieStoreId(createProperties.cookieStoreId)) {
+              let containerId = global.getContainerForCookieStoreId(createProperties.cookieStoreId);
+              if (!containerId) {
+                return Promise.reject({message: `No cookie store exists with ID ${createProperties.cookieStoreId}`});
+              }
+
+              options.userContextId = containerId;
+            }
+          }
+
           tabListener.initTabReady();
-          let tab = window.gBrowser.addTab(url || window.BROWSER_NEW_TAB_URL);
+          let tab = window.gBrowser.addTab(url || window.BROWSER_NEW_TAB_URL, options);
 
           let active = true;
           if (createProperties.active !== null) {
             active = createProperties.active;
           }
           if (active) {
             window.gBrowser.selectedTab = tab;
           }
@@ -688,16 +719,21 @@ extensions.registerSchemaAPI("tabs", "ad
 
           if (queryInfo.currentWindow !== null) {
             let eq = window == currentWindow(context);
             if (queryInfo.currentWindow != eq) {
               return false;
             }
           }
 
+          if (queryInfo.cookieStoreId !== null &&
+              tab.cookieStoreId != queryInfo.cookieStoreId) {
+            return false;
+          }
+
           if (pattern && !pattern.matches(Services.io.newURI(tab.url, null, null))) {
             return false;
           }
 
           return true;
         }
 
         let result = [];
--- a/browser/components/extensions/ext-utils.js
+++ b/browser/components/extensions/ext-utils.js
@@ -639,17 +639,17 @@ ExtensionTabManager.prototype = {
       status: TabManager.getStatus(tab),
       incognito: PrivateBrowsingUtils.isBrowserPrivate(browser),
       width: browser.frameLoader.lazyWidth || browser.clientWidth,
       height: browser.frameLoader.lazyHeight || browser.clientHeight,
       audible: tab.soundPlaying,
       mutedInfo,
     };
     if (this.extension.hasPermission("cookies")) {
-      result.cookieStoreId = getCookieStoreIdForTab(result);
+      result.cookieStoreId = getCookieStoreIdForTab(result, tab);
     }
 
     if (this.hasTabPermission(tab)) {
       result.url = browser.currentURI.spec;
       let title = browser.contentTitle || tab.label;
       if (title) {
         result.title = title;
       }
--- a/browser/components/extensions/ext-windows.js
+++ b/browser/components/extensions/ext-windows.js
@@ -115,19 +115,19 @@ extensions.registerSchemaAPI("windows", 
           if (createData.incognito !== null && createData.incognito != incognito) {
             return Promise.reject({message: "`incognito` property must match the incognito state of tab"});
           }
           createData.incognito = incognito;
 
           args.appendElement(tab, /* weak = */ false);
         } else if (createData.url !== null) {
           if (Array.isArray(createData.url)) {
-            let array = Cc["@mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
+            let array = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
             for (let url of createData.url) {
-              array.AppendElement(mkstr(url));
+              array.appendElement(mkstr(url), /* weak = */ false);
             }
             args.appendElement(array, /* weak = */ false);
           } else {
             args.appendElement(mkstr(createData.url), /* weak = */ false);
           }
         } else {
           args.appendElement(mkstr(aboutNewTabService.newTabURL), /* weak = */ false);
         }
--- a/browser/components/extensions/schemas/tabs.json
+++ b/browser/components/extensions/schemas/tabs.json
@@ -68,17 +68,18 @@
           "mutedInfo": {"$ref": "MutedInfo", "optional": true, "description": "Current tab muted state and the reason for the last state change."},
           "url": {"type": "string", "optional": true, "permissions": ["tabs"], "description": "The URL the tab is displaying. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission."},
           "title": {"type": "string", "optional": true, "permissions": ["tabs"], "description": "The title of the tab. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission."},
           "favIconUrl": {"type": "string", "optional": true, "permissions": ["tabs"], "description": "The URL of the tab's favicon. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission. It may also be an empty string if the tab is loading."},
           "status": {"type": "string", "optional": true, "description": "Either <em>loading</em> or <em>complete</em>."},
           "incognito": {"type": "boolean", "description": "Whether the tab is in an incognito window."},
           "width": {"type": "integer", "optional": true, "description": "The width of the tab in pixels."},
           "height": {"type": "integer", "optional": true, "description": "The height of the tab in pixels."},
-          "sessionId": {"unsupported": true, "type": "string", "optional": true, "description": "The session ID used to uniquely identify a Tab obtained from the $(ref:sessions) API."}
+          "sessionId": {"unsupported": true, "type": "string", "optional": true, "description": "The session ID used to uniquely identify a Tab obtained from the $(ref:sessions) API."},
+          "cookieStoreId": {"type": "string", "description": "The CookieStoreId used for the tab."}
         }
       },
       {
         "id": "ZoomSettingsMode",
         "type": "string",
         "description": "Defines how zoom changes are handled, i.e. which entity is responsible for the actual scaling of the page; defaults to <code>automatic</code>.",
         "enum": [
           {
@@ -386,16 +387,21 @@
                 "description": "Whether the tab should be pinned. Defaults to <var>false</var>"
               },
               "openerTabId": {
                 "unsupported": true,
                 "type": "integer",
                 "minimum": 0,
                 "optional": true,
                 "description": "The ID of the tab that opened this tab. If specified, the opener tab must be in the same window as the newly created tab."
+              },
+              "cookieStoreId": {
+                "type": "string",
+                "optional": true,
+                "description": "The CookieStoreId for the tab that opened this tab."
               }
             }
           },
           {
             "type": "function",
             "name": "callback",
             "optional": true,
             "parameters": [
@@ -509,16 +515,21 @@
                 "optional": true,
                 "description": "The type of window the tabs are in."
               },
               "index": {
                 "type": "integer",
                 "optional": true,
                 "minimum": 0,
                 "description": "The position of the tabs within their windows."
+              },
+              "cookieStoreId": {
+                "type": "string",
+                "optional": true,
+                "description": "The CookieStoreId used for the tab."
               }
             }
           },
           {
             "type": "function",
             "name": "callback",
             "parameters": [
               {
--- a/browser/components/extensions/test/browser/browser.ini
+++ b/browser/components/extensions/test/browser/browser.ini
@@ -78,16 +78,17 @@ tags = webextensions
 [browser_ext_tabs_move_window_multiple.js]
 [browser_ext_tabs_move_window_pinned.js]
 [browser_ext_tabs_onHighlighted.js]
 [browser_ext_tabs_onUpdated.js]
 [browser_ext_tabs_query.js]
 [browser_ext_tabs_reload.js]
 [browser_ext_tabs_reload_bypass_cache.js]
 [browser_ext_tabs_sendMessage.js]
+[browser_ext_tabs_cookieStoreId.js]
 [browser_ext_tabs_update.js]
 [browser_ext_tabs_zoom.js]
 [browser_ext_tabs_update_url.js]
 [browser_ext_topwindowid.js]
 [browser_ext_webNavigation_frameId0.js]
 [browser_ext_webNavigation_getFrames.js]
 [browser_ext_webNavigation_urlbar_transitions.js]
 [browser_ext_windows.js]
--- a/browser/components/extensions/test/browser/browser_ext_contentscript_connect.js
+++ b/browser/components/extensions/test/browser/browser_ext_contentscript_connect.js
@@ -15,31 +15,33 @@ add_task(function* () {
       let port_messages_received = 0;
 
       browser.runtime.onConnect.addListener((port) => {
         browser.test.assertTrue(!!port, "port1 received");
 
         ports_received++;
         browser.test.assertEq(1, ports_received, "1 port received");
 
-        port.onMessage.addListener((msg, sender) => {
+        port.onMessage.addListener((msg, msgPort) => {
           browser.test.assertEq("port message", msg, "listener1 port message received");
+          browser.test.assertEq(port, msgPort, "onMessage should receive port as second argument");
 
           port_messages_received++;
           browser.test.assertEq(1, port_messages_received, "1 port message received");
         });
       });
       browser.runtime.onConnect.addListener((port) => {
         browser.test.assertTrue(!!port, "port2 received");
 
         ports_received++;
         browser.test.assertEq(2, ports_received, "2 ports received");
 
-        port.onMessage.addListener((msg, sender) => {
+        port.onMessage.addListener((msg, msgPort) => {
           browser.test.assertEq("port message", msg, "listener2 port message received");
+          browser.test.assertEq(port, msgPort, "onMessage should receive port as second argument");
 
           port_messages_received++;
           browser.test.assertEq(2, port_messages_received, "2 port messages received");
 
           browser.test.notifyPass("contentscript_connect.pass");
         });
       });
 
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_cookieStoreId.js
@@ -0,0 +1,170 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+add_task(function* setup() {
+  // make sure userContext is enabled.
+  return SpecialPowers.pushPrefEnv({"set": [
+    ["privacy.userContext.enabled", true],
+  ]});
+});
+
+add_task(function* () {
+  info("Start testing tabs.create with cookieStoreId");
+
+  let testCases = [
+    // No private window
+    {privateTab: false, cookieStoreId: null, success: true, expectedCookieStoreId: "firefox-default"},
+    {privateTab: false, cookieStoreId: "firefox-default", success: true, expectedCookieStoreId: "firefox-default"},
+    {privateTab: false, cookieStoreId: "firefox-container-1", success: true, expectedCookieStoreId: "firefox-container-1"},
+    {privateTab: false, cookieStoreId: "firefox-container-2", success: true, expectedCookieStoreId: "firefox-container-2"},
+    {privateTab: false, cookieStoreId: "firefox-container-42", failure: "exist"},
+    {privateTab: false, cookieStoreId: "firefox-private", failure: "defaultToPrivate"},
+    {privateTab: false, cookieStoreId: "wow", failure: "illegal"},
+
+    // Private window
+    {privateTab: true, cookieStoreId: null, success: true, expectedCookieStoreId: "firefox-private"},
+    {privateTab: true, cookieStoreId: "firefox-private", success: true, expectedCookieStoreId: "firefox-private"},
+    {privateTab: true, cookieStoreId: "firefox-default", failure: "privateToDefault"},
+    {privateTab: true, cookieStoreId: "firefox-container-1", failure: "privateToDefault"},
+    {privateTab: true, cookieStoreId: "wow", failure: "illegal"},
+  ];
+
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["tabs", "cookies"],
+    },
+
+    background: function() {
+      function testTab(data, tab) {
+        browser.test.assertTrue(data.success, "we want a success");
+        browser.test.assertTrue(!!tab, "we have a tab");
+        browser.test.assertEq(data.expectedCookieStoreId, tab.cookieStoreId, "tab should have the correct cookieStoreId");
+      }
+
+      function runTest(data) {
+        // Tab Creation
+        browser.tabs.create({windowId: data.privateTab ? this.privateWindowId : this.defaultWindowId,
+                             cookieStoreId: data.cookieStoreId})
+
+        // Tests for tab creation
+        .then((tab) => {
+          testTab(data, tab);
+          return tab;
+        }, (error) => {
+          browser.test.assertTrue(!!data.failure, "we want a failure");
+          if (data.failure == "illegal") {
+            browser.test.assertTrue(/Illegal cookieStoreId/.test(error.message),
+                                    "runtime.lastError should report the expected error message");
+          } else if (data.failure == "defaultToPrivate") {
+            browser.test.assertTrue("Illegal to set private cookieStorageId in a non private window",
+                                    error.message,
+                                    "runtime.lastError should report the expected error message");
+          } else if (data.failure == "privateToDefault") {
+            browser.test.assertTrue("Illegal to set non private cookieStorageId in a private window",
+                                    error.message,
+                                    "runtime.lastError should report the expected error message");
+          } else if (data.failure == "exist") {
+            browser.test.assertTrue(/No cookie store exists/.test(error.message),
+                                    "runtime.lastError should report the expected error message");
+          } else {
+            browser.test.fail("The test is broken");
+          }
+
+          return null;
+        })
+
+        // Tests for tab querying
+        .then((tab) => {
+          if (tab) {
+            return browser.tabs.query({windowId: data.privateTab ? this.privateWindowId : this.defaultWindowId,
+                                       cookieStoreId: data.cookieStoreId})
+                   .then((tabs) => {
+                     browser.test.assertTrue(tabs.length >= 1, "Tab found!");
+                     testTab(data, tabs[0]);
+                     return tab;
+                   });
+          }
+        })
+
+        .then((tab) => {
+          if (tab) {
+            return browser.cookies.getAllCookieStores()
+                   .then(stores => {
+                     let store = stores.find(store => store.id === tab.cookieStoreId);
+                     browser.test.assertTrue(!!store, "We have a store for this tab.");
+                     return tab;
+                   });
+          }
+        })
+
+        .then((tab) => {
+          if (tab) {
+            return browser.tabs.remove(tab.id);
+          }
+        })
+
+        .then(() => {
+          browser.test.sendMessage("test-done");
+        }, () => {
+          browser.test.fail("An exception has ben thrown");
+        });
+      }
+
+      function initialize() {
+        browser.windows.create({incognito: true})
+        .then((win) => {
+          this.privateWindowId = win.id;
+          return browser.windows.create({incognito: false});
+        })
+        .then((win) => {
+          this.defaultWindowId = win.id;
+        })
+        .then(() => {
+          browser.test.sendMessage("ready");
+        });
+      }
+
+      function shutdown() {
+        browser.windows.remove(this.privateWindowId)
+        .then(() => {
+          browser.windows.remove(this.defaultWindowId);
+        })
+        .then(() => {
+          browser.test.sendMessage("gone");
+        });
+      }
+
+      // Waiting for messages
+      browser.test.onMessage.addListener((msg, data) => {
+        if (msg == "be-ready") {
+          initialize();
+        } else if (msg == "test") {
+          runTest(data);
+        } else {
+          browser.test.assertTrue("finish", msg, "Shutting down");
+          shutdown();
+        }
+      });
+    },
+  });
+
+  yield extension.startup();
+
+  info("Tests must be ready...");
+  extension.sendMessage("be-ready");
+  yield extension.awaitMessage("ready");
+  info("Tests are ready to run!");
+
+  for (let test of testCases) {
+    info(`test tab.create with cookieStoreId: "${test.cookieStoreId}"`);
+    extension.sendMessage("test", test);
+    yield extension.awaitMessage("test-done");
+  }
+
+  info("Waiting for shutting down...");
+  extension.sendMessage("finish");
+  yield extension.awaitMessage("gone");
+
+  yield extension.unload();
+});
--- a/browser/components/feeds/FeedWriter.js
+++ b/browser/components/feeds/FeedWriter.js
@@ -257,21 +257,30 @@ FeedWriter.prototype = {
   _parseDate(dateString) {
     // Convert the date into the user's local time zone
     let dateObj = new Date(dateString);
 
     // Make sure the date we're given is valid.
     if (!dateObj.getTime())
       return false;
 
-    let dateService = Cc["@mozilla.org/intl/scriptabledateformat;1"].
-                      getService(Ci.nsIScriptableDateFormat);
-    return dateService.FormatDateTime("", dateService.dateFormatLong, dateService.timeFormatNoSeconds,
-                                      dateObj.getFullYear(), dateObj.getMonth()+1, dateObj.getDate(),
-                                      dateObj.getHours(), dateObj.getMinutes(), dateObj.getSeconds());
+    return this._dateFormatter.format(dateObj);
+  },
+
+  __dateFormatter: null,
+  get _dateFormatter() {
+    if (!this.__dateFormatter) {
+      const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
+                     .getService(Ci.nsIXULChromeRegistry)
+                     .getSelectedLocale("global", true);
+      const dtOptions = { year: 'numeric', month: 'long', day: 'numeric',
+                          hour: 'numeric', minute: 'numeric' };
+      this.__dateFormatter = new Intl.DateTimeFormat(locale, dtOptions);
+    }
+    return this.__dateFormatter;
   },
 
   /**
    * Returns the feed type.
    */
   __feedType: null,
   _getFeedType() {
     if (this.__feedType != null)
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -196,23 +196,23 @@ function openWindow(parent, url, target,
   var stringArgs = null;
   if (args instanceof Array) // array
     stringArgs = args;
   else if (args) // string
     stringArgs = [args];
 
   if (stringArgs) {
     // put the URIs into argArray
-    var uriArray = Components.classes["@mozilla.org/supports-array;1"]
-                       .createInstance(Components.interfaces.nsISupportsArray);
+    var uriArray = Components.classes["@mozilla.org/array;1"]
+                       .createInstance(Components.interfaces.nsIMutableArray);
     stringArgs.forEach(function (uri) {
       var sstring = Components.classes["@mozilla.org/supports-string;1"]
                               .createInstance(nsISupportsString);
       sstring.data = uri;
-      uriArray.AppendElement(sstring);
+      uriArray.appendElement(sstring, /* weak = */ false);
     });
     argArray.appendElement(uriArray, /*weak =*/ false);
   } else {
     argArray.appendElement(null, /*weak =*/ false);
   }
 
   // Pass these as null to ensure that we always trigger the "single URL"
   // behavior in browser.js's gBrowserInit.onLoad (which handles the window
--- a/browser/components/places/PlacesUIUtils.jsm
+++ b/browser/components/places/PlacesUIUtils.jsm
@@ -975,17 +975,17 @@ this.PlacesUIUtils = {
   },
 
   openLiveMarkNodesInTabs:
   function PUIU_openLiveMarkNodesInTabs(aNode, aEvent, aView) {
     let window = aView.ownerWindow;
 
     PlacesUtils.livemarks.getLivemark({id: aNode.itemId})
       .then(aLivemark => {
-        urlsToOpen = [];
+        let urlsToOpen = [];
 
         let nodes = aLivemark.getNodesForContainer(aNode);
         for (let node of nodes) {
           urlsToOpen.push({uri: node.uri, isBookmark: false});
         }
 
         if (this.confirmOpenInTabs(urlsToOpen.length, window)) {
           this._openTabset(urlsToOpen, aEvent, window);
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -406,18 +406,21 @@ var PlacesOrganizer = {
   },
 
   /**
    * Populates the restore menu with the dates of the backups available.
    */
   populateRestoreMenu: function PO_populateRestoreMenu() {
     let restorePopup = document.getElementById("fileRestorePopup");
 
-    let dateSvc = Cc["@mozilla.org/intl/scriptabledateformat;1"].
-                  getService(Ci.nsIScriptableDateFormat);
+    const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
+                   .getService(Ci.nsIXULChromeRegistry)
+                   .getSelectedLocale("global", true);
+    const dtOptions = { year: 'numeric', month: 'long', day: 'numeric' };
+    let dateFormatter = new Intl.DateTimeFormat(locale, dtOptions);
 
     // Remove existing menu items.  Last item is the restoreFromFile item.
     while (restorePopup.childNodes.length > 1)
       restorePopup.removeChild(restorePopup.firstChild);
 
     Task.spawn(function* () {
       let backupFiles = yield PlacesBackups.getBackupFiles();
       if (backupFiles.length == 0)
@@ -439,23 +442,17 @@ var PlacesOrganizer = {
                      ")";
         } else {
           sizeInfo = " (" + sizeString + ")";
         }
 
         let backupDate = PlacesBackups.getDateForFile(backupFiles[i]);
         let m = restorePopup.insertBefore(document.createElement("menuitem"),
                                           document.getElementById("restoreFromFile"));
-        m.setAttribute("label",
-                       dateSvc.FormatDate("",
-                                          Ci.nsIScriptableDateFormat.dateFormatLong,
-                                          backupDate.getFullYear(),
-                                          backupDate.getMonth() + 1,
-                                          backupDate.getDate()) +
-                                          sizeInfo);
+        m.setAttribute("label", dateFormatter.format(backupDate) + sizeInfo);
         m.setAttribute("value", OS.Path.basename(backupFiles[i]));
         m.setAttribute("oncommand",
                        "PlacesOrganizer.onRestoreMenuItemClick(this);");
       }
 
       // Add the restoreFromFile item.
       restorePopup.insertBefore(document.createElement("menuseparator"),
                                 document.getElementById("restoreFromFile"));
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -28,25 +28,16 @@ PlacesTreeView.prototype = {
   __xulStore: null,
   get _xulStore() {
     if (!this.__xulStore) {
       this.__xulStore = Cc["@mozilla.org/xul/xulstore;1"].getService(Ci.nsIXULStore);
     }
     return this.__xulStore;
   },
 
-  __dateService: null,
-  get _dateService() {
-    if (!this.__dateService) {
-      this.__dateService = Cc["@mozilla.org/intl/scriptabledateformat;1"].
-                           getService(Ci.nsIScriptableDateFormat);
-    }
-    return this.__dateService;
-  },
-
   QueryInterface: XPCOMUtils.generateQI(PTV_interfaces),
 
   // Bug 761494:
   // ----------
   // Some addons use methods from nsINavHistoryResultObserver and
   // nsINavHistoryResultTreeViewer, without QIing to these interfaces first.
   // That's not a problem when the view is retrieved through the
   // <tree>.view getter (which returns the wrappedJSObject of this object),
@@ -499,26 +490,46 @@ PlacesTreeView.prototype = {
     // milliseconds from today's midnight.
     // getTimezoneOffset corrects that based on local time, notice midnight
     // can have a different offset during DST-change days.
     let dateObj = new Date();
     let now = dateObj.getTime() - dateObj.getTimezoneOffset() * MS_PER_MINUTE;
     let midnight = now - (now % MS_PER_DAY);
     midnight += new Date(midnight).getTimezoneOffset() * MS_PER_MINUTE;
 
-    let dateFormat = timeMs >= midnight ?
-                      Ci.nsIScriptableDateFormat.dateFormatNone :
-                      Ci.nsIScriptableDateFormat.dateFormatShort;
+    let timeObj = new Date(timeMs);
+    return timeMs >= midnight ? this._todayFormatter.format(timeObj)
+                              : this._dateFormatter.format(timeObj);
+  },
 
-    let timeObj = new Date(timeMs);
-    return (this._dateService.FormatDateTime("", dateFormat,
-      Ci.nsIScriptableDateFormat.timeFormatNoSeconds,
-      timeObj.getFullYear(), timeObj.getMonth() + 1,
-      timeObj.getDate(), timeObj.getHours(),
-      timeObj.getMinutes(), timeObj.getSeconds()));
+  // We use a different formatter for times within the current day,
+  // so we cache both a "today" formatter and a general date formatter.
+  __todayFormatter: null,
+  get _todayFormatter() {
+    if (!this.__todayFormatter) {
+      const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
+                     .getService(Ci.nsIXULChromeRegistry)
+                     .getSelectedLocale("global", true);
+      const dtOptions = { hour: 'numeric', minute: 'numeric' };
+      this.__todayFormatter = new Intl.DateTimeFormat(locale, dtOptions);
+    }
+    return this.__todayFormatter;
+  },
+
+  __dateFormatter: null,
+  get _dateFormatter() {
+    if (!this.__dateFormatter) {
+      const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
+                     .getService(Ci.nsIXULChromeRegistry)
+                     .getSelectedLocale("global", true);
+      const dtOptions = { year: '2-digit', month: 'numeric', day: 'numeric',
+                          hour: 'numeric', minute: 'numeric' };
+      this.__dateFormatter = new Intl.DateTimeFormat(locale, dtOptions);
+    }
+    return this.__dateFormatter;
   },
 
   COLUMN_TYPE_UNKNOWN: 0,
   COLUMN_TYPE_TITLE: 1,
   COLUMN_TYPE_URI: 2,
   COLUMN_TYPE_DATE: 3,
   COLUMN_TYPE_VISITCOUNT: 4,
   COLUMN_TYPE_DESCRIPTION: 5,
--- a/browser/components/places/tests/chrome/test_treeview_date.xul
+++ b/browser/components/places/tests/chrome/test_treeview_date.xul
@@ -48,19 +48,16 @@
      * https://bugzilla.mozilla.org/show_bug.cgi?id=435322
      *
      * Ensures that date in places treeviews is correctly formatted.
      */
 
     function runTest() {
       SimpleTest.waitForExplicitFinish();
 
-      let ds = Cc["@mozilla.org/intl/scriptabledateformat;1"].
-               getService(Ci.nsIScriptableDateFormat);
-
       function uri(spec) {
         return Services.io.newURI(spec, null, null);
       }
 
       Task.spawn(function* () {
         yield PlacesTestUtils.clearHistory();
 
         let midnight = new Date();
@@ -102,16 +99,19 @@
         tree.place = queryURI;
 
         // loop through the rows and check formatting
         let treeView = tree.view;
         let rc = treeView.rowCount;
         ok(rc >= 3, "Rows found");
         let columns = tree.columns;
         ok(columns.count > 0, "Columns found");
+        const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
+                       .getService(Ci.nsIXULChromeRegistry)
+                       .getSelectedLocale("global", true);
         for (let r = 0; r < rc; r++) {
           let node = treeView.nodeForTreeIndex(r);
           ok(node, "Places node found");
           for (let ci = 0; ci < columns.count; ci++) {
             let c = columns.getColumnAt(ci);
             let text = treeView.getCellText(r, c);
             switch (c.element.getAttribute("anonid")) {
               case "title":
@@ -122,33 +122,28 @@
                   is(text, node.title, "Title is correct");
                 break;
               case "url":
                 is(text, node.uri, "Uri is correct");
                 break;
               case "date":
                 let timeObj = new Date(node.time / 1000);
                 // Default is short date format.
-                let dateFormat = Ci.nsIScriptableDateFormat.dateFormatShort;
+                let dtOptions = { year: '2-digit', month: 'numeric', day: 'numeric',
+                                  hour: 'numeric', minute: 'numeric' };
                 // For today's visits we don't show date portion.
                 if (node.uri == "http://at.midnight.com/" ||
-                    node.uri == "http://after.midnight.com/")
-                  dateFormat = Ci.nsIScriptableDateFormat.dateFormatNone;
-                else if (node.uri == "http://before.midnight.com/")
-                  dateFormat = Ci.nsIScriptableDateFormat.dateFormatShort;
-                else {
+                    node.uri == "http://after.midnight.com/") {
+                  dtOptions = { hour: 'numeric', minute: 'numeric' };
+                } else if (node.uri != "http://before.midnight.com/") {
                   // Avoid to test spurious uris, due to how the test works
                   // a redirecting uri could be put in the tree while we test.
                   break;
                 }
-                let timeStr = ds.FormatDateTime("", dateFormat,
-                      Ci.nsIScriptableDateFormat.timeFormatNoSeconds,
-                      timeObj.getFullYear(), timeObj.getMonth() + 1,
-                      timeObj.getDate(), timeObj.getHours(),
-                      timeObj.getMinutes(), timeObj.getSeconds())
+                let timeStr = timeObj.toLocaleString(locale, dtOptions);
 
                 is(text, timeStr, "Date format is correct");
                 break;
               case "visitCount":
                 is(text, 1, "Visit count is correct");
                 break;
             }
           }
--- a/browser/components/preferences/cookies.js
+++ b/browser/components/preferences/cookies.js
@@ -11,18 +11,16 @@ Components.utils.import("resource://gre/
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService",
                                   "resource://gre/modules/ContextualIdentityService.jsm");
 
 var gCookiesWindow = {
   _cm               : Components.classes["@mozilla.org/cookiemanager;1"]
                                 .getService(Components.interfaces.nsICookieManager),
-  _ds               : Components.classes["@mozilla.org/intl/scriptabledateformat;1"]
-                                .getService(Components.interfaces.nsIScriptableDateFormat),
   _hosts            : {},
   _hostOrder        : [],
   _tree             : null,
   _bundle           : null,
 
   init: function () {
     var os = Components.classes["@mozilla.org/observer-service;1"]
                        .getService(Components.interfaces.nsIObserverService);
@@ -508,24 +506,22 @@ var gCookiesWindow = {
         break;
     }
     this._view._rowCount = hostCount.value;
   },
 
   formatExpiresString: function (aExpires) {
     if (aExpires) {
       var date = new Date(1000 * aExpires);
-      return this._ds.FormatDateTime("", this._ds.dateFormatLong,
-                                     this._ds.timeFormatSeconds,
-                                     date.getFullYear(),
-                                     date.getMonth() + 1,
-                                     date.getDate(),
-                                     date.getHours(),
-                                     date.getMinutes(),
-                                     date.getSeconds());
+      const locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
+                     .getService(Components.interfaces.nsIXULChromeRegistry)
+                     .getSelectedLocale("global", true);
+      const dtOptions = { year: 'numeric', month: 'long', day: 'numeric',
+                          hour: 'numeric', minute: 'numeric', second: 'numeric' };
+      return date.toLocaleString(locale, dtOptions);
     }
     return this._bundle.getString("expireAtEndOfSession");
   },
 
   _getUserContextString: function(aUserContextId) {
     if (parseInt(aUserContextId) == 0) {
       return this._bundle.getString("defaultUserContextLabel");
     }
--- a/browser/components/preferences/in-content/tests/browser_advanced_update.js
+++ b/browser/components/preferences/in-content/tests/browser_advanced_update.js
@@ -3,18 +3,16 @@
 
 "use strict";
 
 const { classes: Cc, interfaces: Ci, manager: Cm, utils: Cu, results: Cr } = Components;
 
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 
 const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
-const dateFormat = Cc["@mozilla.org/intl/scriptabledateformat;1"]
-                      .getService(Components.interfaces.nsIScriptableDateFormat);
 
 const mockUpdateManager = {
   contractId: "@mozilla.org/updates/update-manager;1",
 
   _mockClassId: uuidGenerator.generateUUID(),
 
   _originalClassId: "",
 
@@ -82,25 +80,22 @@ const mockUpdateManager = {
 };
 
 function resetPreferences() {
   Services.prefs.clearUserPref("browser.search.update");
 }
 
 function formatInstallDate(sec) {
   var date = new Date(sec);
-  return dateFormat.FormatDateTime("",
-    dateFormat.dateFormatLong,
-    dateFormat.timeFormatSeconds,
-    date.getFullYear(),
-    date.getMonth() + 1,
-    date.getDate(),
-    date.getHours(),
-    date.getMinutes(),
-    date.getSeconds());
+  const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
+                 .getService(Ci.nsIXULChromeRegistry)
+                 .getSelectedLocale("global", true);
+  const dtOptions = { year: 'numeric', month: 'long', day: 'numeric',
+                      hour: 'numeric', minute: 'numeric', second: 'numeric' };
+  return date.toLocaleString(locale, dtOptions);
 }
 
 registerCleanupFunction(resetPreferences);
 
 add_task(function*() {
   yield openPreferencesViaOpenPreferencesAPI("advanced", "updateTab", { leaveOpen: true });
   resetPreferences();
   Services.prefs.setBoolPref("browser.search.update", false);
--- a/browser/components/preferences/translation.js
+++ b/browser/components/preferences/translation.js
@@ -233,17 +233,17 @@ var gTranslationExceptions = {
     this.onSiteSelected();
   },
 
   onSiteKeyPress: function(aEvent) {
     if (aEvent.keyCode == KeyEvent.DOM_VK_DELETE)
       this.onSiteDeleted();
   },
 
-  onLanguageKeyPress: function() {
+  onLanguageKeyPress: function(aEvent) {
     if (aEvent.keyCode == KeyEvent.DOM_VK_DELETE)
       this.onLanguageDeleted();
   },
 
   onWindowKeyPress: function(aEvent) {
     if (aEvent.keyCode == KeyEvent.DOM_VK_ESCAPE)
       window.close();
   },
--- a/browser/components/syncedtabs/test/browser/head.js
+++ b/browser/components/syncedtabs/test/browser/head.js
@@ -2,16 +2,17 @@ const {classes: Cc, interfaces: Ci, util
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
 
 
 // Load mocking/stubbing library, sinon
 // docs: http://sinonjs.org/docs/
+/* global sinon */
 let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
 loader.loadSubScript("resource://testing-common/sinon-1.16.1.js");
 
 registerCleanupFunction(function*() {
   // Cleanup window or the test runner will throw an error
   delete window.sinon;
   delete window.setImmediate;
   delete window.clearImmediate;
--- a/browser/components/syncedtabs/test/xpcshell/head.js
+++ b/browser/components/syncedtabs/test/xpcshell/head.js
@@ -19,11 +19,11 @@ let window = {
     setInterval: setInterval,
     clearTimeout: clearTimeout,
     clearinterval: clearInterval
 };
 let self = window;
 
 // Load mocking/stubbing library, sinon
 // docs: http://sinonjs.org/docs/
+/* global sinon */
 let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
 loader.loadSubScript("resource://testing-common/sinon-1.16.1.js");
-
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/linux32/debug-artifact
@@ -0,0 +1,12 @@
+MOZ_AUTOMATION_BUILD_SYMBOLS=0
+MOZ_AUTOMATION_L10N_CHECK=0
+
+. "$topsrcdir/build/unix/mozconfig.linux32"
+. "$topsrcdir/build/mozconfig.common.override"
+
+ac_add_options --enable-artifact-builds
+ac_add_options --enable-artifact-build-symbols
+unset CC
+unset CXX
+
+ac_add_options --enable-debug
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/linux64/debug-artifact
@@ -0,0 +1,13 @@
+MOZ_AUTOMATION_BUILD_SYMBOLS=0
+MOZ_AUTOMATION_L10N_CHECK=0
+
+. "$topsrcdir/build/unix/mozconfig.linux"
+. "$topsrcdir/build/mozconfig.common.override"
+
+ac_add_options --enable-artifact-builds
+ac_add_options --enable-artifact-build-symbols
+unset CC
+unset CXX
+
+ac_add_options --enable-debug
+
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/macosx64/debug-artifact
@@ -0,0 +1,12 @@
+MOZ_AUTOMATION_BUILD_SYMBOLS=0
+MOZ_AUTOMATION_L10N_CHECK=0
+
+. "$topsrcdir/build/macosx/mozconfig.common"
+. "$topsrcdir/build/mozconfig.common.override"
+
+ac_add_options --enable-artifact-builds
+ac_add_options --enable-artifact-build-symbols
+unset CC
+unset CXX
+
+ac_add_options --enable-debug
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/win32/debug-artifact
@@ -0,0 +1,12 @@
+MOZ_AUTOMATION_BUILD_SYMBOLS=0
+MOZ_AUTOMATION_L10N_CHECK=0
+
+. "$topsrcdir/browser/config/mozconfigs/common"
+. "$topsrcdir/build/mozconfig.win-common"
+. "$topsrcdir/build/win32/mozconfig.vs-latest"
+. "$topsrcdir/build/mozconfig.common.override"
+
+ac_add_options --enable-artifact-builds
+ac_add_options --enable-artifact-build-symbols
+
+ac_add_options --enable-debug
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/win64/debug-artifact
@@ -0,0 +1,13 @@
+MOZ_AUTOMATION_BUILD_SYMBOLS=0
+MOZ_AUTOMATION_L10N_CHECK=0
+
+. "$topsrcdir/browser/config/mozconfigs/win64/common-win64"
+. "$topsrcdir/browser/config/mozconfigs/common"
+. "$topsrcdir/build/mozconfig.win-common"
+. "$topsrcdir/build/win64/mozconfig.vs-latest"
+. "$topsrcdir/build/mozconfig.common.override"
+
+ac_add_options --enable-artifact-builds
+ac_add_options --enable-artifact-build-symbols
+
+ac_add_options --enable-debug
--- a/browser/confvars.sh
+++ b/browser/confvars.sh
@@ -50,14 +50,15 @@ MOZ_APP_ID={ec8030f7-c20a-464f-9b0e-13a3
 ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-central
 # The MAR_CHANNEL_ID must not contain the following 3 characters: ",\t "
 MAR_CHANNEL_ID=firefox-mozilla-central
 MOZ_PROFILE_MIGRATOR=1
 MOZ_APP_STATIC_INI=1
 MOZ_WEBGL_CONFORMANT=1
 MOZ_JSDOWNLOADS=1
 MOZ_RUST_MP4PARSE=1
+MOZ_RUST_URLPARSE=1
 
 # Enable checking that add-ons are signed by the trusted root
 MOZ_ADDON_SIGNING=1
 
 # Include the DevTools client, not just the server (which is the default)
 MOZ_DEVTOOLS=all
new file mode 100644
--- /dev/null
+++ b/browser/extensions/aushelper/bootstrap.js
@@ -0,0 +1,129 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+
+const APP_UPDATE_URL_PREF = "app.update.url";
+const REPLACE_KEY = "%OS_VERSION%";
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/TelemetryLog.jsm");
+
+function startup() {
+  if (Services.appinfo.OS != "WINNT") {
+    return;
+  }
+
+  const regCPUPath = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
+  let wrk;
+  try {
+    wrk = Cc["@mozilla.org/windows-registry-key;1"].createInstance(Ci.nsIWindowsRegKey);
+    wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE, regCPUPath, wrk.ACCESS_READ);
+  } catch (e) {
+    Cu.reportError("Unable to open registry. Exception: " + e);
+    TelemetryLog.log("AUSHELPER_FATAL_ERROR", [e]);
+  }
+
+  // If any of the following values are successfully retrieved and they don't
+  // match the condition for that value then it is safe to update. Hence why the
+  // following checks are somewhat convoluted. The possible values for the
+  // variable set by each check is as follows:
+  //
+  //          | Match | No Match | Error |
+  // variable |  true |   false  |  null |
+
+  let cpuVendorIDMatch = false;
+  try {
+    let cpuVendorID = wrk.readStringValue("VendorIdentifier");
+    if (cpuVendorID.toLowerCase() == "genuineintel") {
+      cpuVendorIDMatch = true;
+    }
+  } catch (e) {
+    cpuVendorIDMatch = null;
+    Cu.reportError("Error getting CPU vendor indentifier. Exception: " + e);
+    TelemetryLog.log("AUSHELPER_CPU_VENDOR_ID_ERROR", [e]);
+  }
+
+  let cpuIDMatch = false;
+  try {
+    let cpuID = wrk.readStringValue("Identifier");
+    if (cpuID.toLowerCase().indexOf("family 6 model 61 stepping 4") != -1) {
+      cpuIDMatch = true;
+    }
+  } catch (e) {
+    cpuIDMatch = null;
+    Cu.reportError("Error getting CPU indentifier. Exception: " + e);
+    TelemetryLog.log("AUSHELPER_CPU_ID_ERROR", [e]);
+  }
+
+  let microCodeVersions = [0xe, 0x11, 0x12, 0x13, 0x16, 0x18, 0x19];
+  let cpuRevMatch = false;
+  try {
+    let keyNames = ["Update Revision", "Update Signature"];
+    for (let i = 0; i < keyNames.length; ++i) {
+      try {
+        let regVal = wrk.readBinaryValue(keyNames[i]);
+        if (regVal.length == 8) {
+          let hexVal = [];
+          // We are only inyterested in the highest byte and return the little
+          // endian value for it.
+          for (let j = 4; j < 8; j++) {
+            let c = regVal.charCodeAt(j).toString(16);
+            if (c.length == 1) {
+              c = "0" + c;
+            }
+            hexVal.unshift(c);
+          }
+          if (microCodeVersions.indexOf(parseInt(hexVal.join(''))) != -1) {
+            cpuRevMatch = true;
+          }
+          break;
+        }
+      } catch (e) {
+        if (i == keyNames.length - 1) {
+          // The registry key name's value was not successfully queried.
+          cpuRevMatch = null;
+          Cu.reportError("Error getting CPU revision. Exception: " + e);
+          TelemetryLog.log("AUSHELPER_CPU_REV_ERROR", [e]);
+        }
+      }
+    }
+  } catch (ex) {
+    cpuRevMatch = null;
+    Cu.reportError("Error getting CPU revision. Exception: " + ex);
+    TelemetryLog.log("AUSHELPER_CPU_REV_ERROR", [ex]);
+  }
+
+  let resultCode = 3;
+  let newValue = "(unkBug1296630v1)";
+  // The following uses strict equality checks since the values can be true,
+  // false, or null.
+  if (cpuVendorIDMatch === false || cpuIDMatch === false || cpuRevMatch === false) {
+    // Since one of the values is false then the system won't be affected by
+    // bug 1296630 according to the conditions set out in bug 1311515.
+    newValue = "(noBug1296630v1)";
+    resultCode = 0;
+  } else if (cpuVendorIDMatch === null || cpuIDMatch === null || cpuRevMatch === null) {
+    // Since one of the values is null we can't say for sure if the system will
+    // be affected by bug 1296630.
+    newValue = "(errBug1296630v1)";
+    resultCode = 2;
+  } else if (cpuVendorIDMatch === true && cpuIDMatch === true && cpuRevMatch === true) {
+    // Since all of the values are true we can say that the system will be
+    // affected by bug 1296630.
+    newValue = "(yesBug1296630v1)";
+    resultCode = 1;
+  }
+
+  let defaultBranch = Services.prefs.getDefaultBranch("");
+  let curPrefValue = defaultBranch.getCharPref(APP_UPDATE_URL_PREF);
+  let newPrefValue = curPrefValue.replace(REPLACE_KEY + "/", REPLACE_KEY + newValue + "/");
+  defaultBranch.setCharPref(APP_UPDATE_URL_PREF, newPrefValue);
+  TelemetryLog.log("AUSHELPER_RESULT", [resultCode]);
+}
+
+function shutdown() {}
+function install() {}
+function uninstall() {}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/aushelper/install.rdf.in
@@ -0,0 +1,32 @@
+<?xml version="1.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/. -->
+
+#filter substitution
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>aushelper@mozilla.org</em:id>
+    <em:version>1.0</em:version>
+    <em:type>2</em:type>
+    <em:bootstrap>true</em:bootstrap>
+    <em:multiprocessCompatible>true</em:multiprocessCompatible>
+
+    <!-- Target Application this extension can install into,
+        with minimum and maximum supported versions. -->
+    <em:targetApplication>
+      <Description>
+        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+        <em:minVersion>@MOZ_APP_VERSION@</em:minVersion>
+        <em:maxVersion>@MOZ_APP_MAXVERSION@</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+
+    <!-- Front End MetaData -->
+    <em:name>Application Update Service Helper</em:name>
+    <em:description>Sets value(s) in the update url based on custom checks.</em:description>
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/browser/extensions/aushelper/moz.build
@@ -0,0 +1,16 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
+DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']
+
+FINAL_TARGET_FILES.features['aushelper@mozilla.org'] += [
+  'bootstrap.js'
+]
+
+FINAL_TARGET_PP_FILES.features['aushelper@mozilla.org'] += [
+  'install.rdf.in'
+]
--- a/browser/extensions/moz.build
+++ b/browser/extensions/moz.build
@@ -1,15 +1,16 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 DIRS += [
+    'aushelper',
     'e10srollout',
     'pdfjs',
     'pocket',
     'webcompat',
 ]
 
 # Only include the following system add-ons if building Aurora or Nightly
 if 'a' in CONFIG['GRE_MILESTONE']:
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,3 +1,3 @@
 This is the pdf.js project output, https://github.com/mozilla/pdf.js
 
-Current extension version is: 1.6.263
+Current extension version is: 1.6.274
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -19,18 +19,18 @@
   } else if (typeof exports !== 'undefined') {
     factory(exports);
   } else {
     factory(root['pdfjsDistBuildPdf'] = {});
   }
 }(this, function (exports) {
   // Use strict in our context only - users might not want it
   'use strict';
-  var pdfjsVersion = '1.6.263';
-  var pdfjsBuild = '7e392c0';
+  var pdfjsVersion = '1.6.274';
+  var pdfjsBuild = '1c3fb17';
   var pdfjsFilePath = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : null;
   var pdfjsLibs = {};
   (function pdfjsWrapper() {
     (function (root, factory) {
       factory(root.pdfjsSharedUtil = {});
     }(this, function (exports) {
       var globalScope = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : this;
       var FONT_IDENTITY_MATRIX = [
@@ -2226,17 +2226,17 @@
             addLinkAttributes(link, {
               url: this.data.url,
               target: this.data.newWindow ? LinkTarget.BLANK : undefined
             });
             if (!this.data.url) {
               if (this.data.action) {
                 this._bindNamedAction(link, this.data.action);
               } else {
-                this._bindLink(link, this.data.dest || null);
+                this._bindLink(link, this.data.dest);
               }
             }
             this.container.appendChild(link);
             return this.container;
           },
           /**
            * Bind internal links to the link element.
            *
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -19,18 +19,18 @@
   } else if (typeof exports !== 'undefined') {
     factory(exports);
   } else {
     factory(root['pdfjsDistBuildPdfWorker'] = {});
   }
 }(this, function (exports) {
   // Use strict in our context only - users might not want it
   'use strict';
-  var pdfjsVersion = '1.6.263';
-  var pdfjsBuild = '7e392c0';
+  var pdfjsVersion = '1.6.274';
+  var pdfjsBuild = '1c3fb17';
   var pdfjsFilePath = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : null;
   var pdfjsLibs = {};
   (function pdfjsWrapper() {
     (function (root, factory) {
       factory(root.pdfjsCoreArithmeticDecoder = {});
     }(this, function (exports) {
       /* This class implements the QM Coder decoding as defined in
        *   JPEG 2000 Part I Final Committee Draft Version 1.0
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -954,20 +954,22 @@ var pdfjsWebLibs;
           _bindLink: function PDFOutlineViewer_bindLink(element, item) {
             if (item.url) {
               pdfjsLib.addLinkAttributes(element, {
                 url: item.url,
                 target: item.newWindow ? PDFJS.LinkTarget.BLANK : undefined
               });
               return;
             }
-            var linkService = this.linkService;
-            element.href = linkService.getDestinationHash(item.dest);
-            element.onclick = function goToDestination(e) {
-              linkService.navigateTo(item.dest);
+            var self = this, destination = item.dest;
+            element.href = self.linkService.getDestinationHash(destination);
+            element.onclick = function () {
+              if (destination) {
+                self.linkService.navigateTo(destination);
+              }
               return false;
             };
           },
           /**
            * @private
            */
           _setStyles: function PDFOutlineViewer_setStyles(element, item) {
             var styleStr = '';
@@ -4179,56 +4181,66 @@ var pdfjsWebLibs;
           /**
            * @param dest - The PDF destination object.
            */
           navigateTo: function PDFLinkService_navigateTo(dest) {
             var destString = '';
             var self = this;
             var goToDestination = function (destRef) {
               // dest array looks like that: <page-ref> </XYZ|/FitXXX> <args..>
-              var pageNumber = destRef instanceof Object ? self._pagesRefCache[destRef.num + ' ' + destRef.gen + ' R'] : destRef + 1;
+              var pageNumber;
+              if (destRef instanceof Object) {
+                pageNumber = self._cachedPageNumber(destRef);
+              } else if ((destRef | 0) === destRef) {
+                // Integer
+                pageNumber = destRef + 1;
+              } else {
+                console.error('PDFLinkService_navigateTo: "' + destRef + '" is not a valid destination reference.');
+                return;
+              }
               if (pageNumber) {
-                if (pageNumber > self.pagesCount) {
-                  console.error('PDFLinkService_navigateTo: ' + 'Trying to navigate to a non-existent page.');
+                if (pageNumber < 1 || pageNumber > self.pagesCount) {
+                  console.error('PDFLinkService_navigateTo: "' + pageNumber + '" is a non-existent page number.');
                   return;
                 }
                 self.pdfViewer.scrollPageIntoView({
                   pageNumber: pageNumber,
                   destArray: dest
                 });
                 if (self.pdfHistory) {
                   // Update the browsing history.
                   self.pdfHistory.push({
                     dest: dest,
                     hash: destString,
                     page: pageNumber
                   });
                 }
               } else {
                 self.pdfDocument.getPageIndex(destRef).then(function (pageIndex) {
-                  var pageNum = pageIndex + 1;
-                  var cacheKey = destRef.num + ' ' + destRef.gen + ' R';
-                  self._pagesRefCache[cacheKey] = pageNum;
+                  self.cachePageRef(pageIndex + 1, destRef);
                   goToDestination(destRef);
+                }).catch(function () {
+                  console.error('PDFLinkService_navigateTo: "' + destRef + '" is not a valid page reference.');
+                  return;
                 });
               }
             };
             var destinationPromise;
             if (typeof dest === 'string') {
               destString = dest;
               destinationPromise = this.pdfDocument.getDestination(dest);
             } else {
               destinationPromise = Promise.resolve(dest);
             }
             destinationPromise.then(function (destination) {
               dest = destination;
               if (!(destination instanceof Array)) {
+                console.error('PDFLinkService_navigateTo: "' + destination + '" is not a valid destination array.');
                 return;
               }
-              // invalid destination
               goToDestination(destination[0]);
             });
           },
           /**
            * @param dest - The PDF destination object.
            * @returns {string} The hyperlink to the PDF object.
            */
           getDestinationHash: function PDFLinkService_getDestinationHash(dest) {
@@ -4335,24 +4347,25 @@ var pdfjsWebLibs;
               }
               // simple page
               if ('pagemode' in params) {
                 this.eventBus.dispatch('pagemode', {
                   source: this,
                   mode: params.pagemode
                 });
               }
-            } else if (isPageNumber(hash)) {
-              // Page number.
-              this.page = hash | 0;
             } else {
-              // Named (or explicit) destination.
               dest = unescape(hash);
               try {
                 dest = JSON.parse(dest);
+                if (!(dest instanceof Array)) {
+                  // Avoid incorrectly rejecting a valid named destination, such as
+                  // e.g. "4.3" or "true", because `JSON.parse` converted its type.
+                  dest = dest.toString();
+                }
               } catch (ex) {
               }
               if (typeof dest === 'string' || isValidExplicitDestination(dest)) {
                 if (this.pdfHistory) {
                   this.pdfHistory.updateNextHashParam(dest);
                 }
                 this.navigateTo(dest);
                 return;
@@ -4403,16 +4416,20 @@ var pdfjsWebLibs;
           },
           /**
            * @param {number} pageNum - page number.
            * @param {Object} pageRef - reference to the page.
            */
           cachePageRef: function PDFLinkService_cachePageRef(pageNum, pageRef) {
             var refStr = pageRef.num + ' ' + pageRef.gen + ' R';
             this._pagesRefCache[refStr] = pageNum;
+          },
+          _cachedPageNumber: function PDFLinkService_cachedPageNumber(pageRef) {
+            var refStr = pageRef.num + ' ' + pageRef.gen + ' R';
+            return this._pagesRefCache && this._pagesRefCache[refStr] || null;
           }
         };
         function isValidExplicitDestination(dest) {
           if (!(dest instanceof Array)) {
             return false;
           }
           var destLength = dest.length, allowNull = true;
           if (destLength < 2) {
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -809,17 +809,17 @@ bin/libfreebl_32int64_3.so
 
 #if defined(CLANG_CXX)
 #if defined(MOZ_ASAN) || defined(MOZ_TSAN)
 @BINPATH@/llvm-symbolizer
 #endif
 #endif
 
 #if defined(MOZ_ASAN) && defined(CLANG_CL)
-@BINPATH@/clang_rt.asan_dynamic-i386.dll
+@BINPATH@/clang_rt.asan_dynamic-*.dll
 #endif
 
 
 ; media
 @RESPATH@/gmp-clearkey/0.1/@DLL_PREFIX@clearkey@DLL_SUFFIX@
 @RESPATH@/gmp-clearkey/0.1/clearkey.info
 
 ; gfx
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -732,16 +732,25 @@ decoder.noCodecs.message = To play video, you may need to install Microsoft’s Media Feature Pack.
 decoder.noCodecsVista.message = To play video, you may need to install Microsoft’s Platform Update Supplement for Windows Vista.
 decoder.noCodecsXP.message = To play video, you may need to enable Adobe’s Primetime Content Decryption Module.
 decoder.noCodecsLinux.message = To play video, you may need to install the required video codecs.
 decoder.noHWAcceleration.message = To improve video quality, you may need to install Microsoft’s Media Feature Pack.
 decoder.noHWAccelerationVista.message = To improve video quality, you may need to install Microsoft’s Platform Update Supplement for Windows Vista.
 decoder.noPulseAudio.message = To play audio, you may need to install the required PulseAudio software.
 decoder.unsupportedLibavcodec.message = libavcodec may be vulnerable or is not supported, and should be updated to play video.
 
+# LOCALIZATION NOTE (captivePortal.infoMessage):
+# This string is shown in a notification bar when we detect a captive portal is blocking network access
+# and requires the user to log in before browsing. %1$S is replaced with brandShortName.
+captivePortal.infoMessage=This network may require you to login to use the internet. %1$S has opened the login page for you.
+# LOCALIZATION NOTE (captivePortal.showLoginPage):
+# The label for a button shown in the info bar in all tabs except the login page tab.
+# The button shows the portal login page tab when clicked.
+captivePortal.showLoginPage=Show Login Page
+
 permissions.remove.tooltip = Clear this permission and ask again
 
 # LOCALIZATION NOTE (aboutDialog.architecture.*):
 # The sixtyFourBit and thirtyTwoBit strings describe the architecture of the
 # current Firefox build: 32-bit or 64-bit. These strings are used in parentheses
 # between the Firefox version and the "What's new" link in the About dialog,
 # e.g.: "48.0.2 (32-bit) <What's new>" or "51.0a1 (2016-09-05) (64-bit)".
 aboutDialog.architecture.sixtyFourBit = 64-bit
--- a/browser/modules/CaptivePortalWatcher.jsm
+++ b/browser/modules/CaptivePortalWatcher.jsm
@@ -7,32 +7,38 @@
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 /**
  * This constant is chosen to be large enough for a portal recheck to complete,
  * and small enough that the delay in opening a tab isn't too noticeable.
  * Please see comments for _delayedAddCaptivePortalTab for more details.
  */
 const PORTAL_RECHECK_DELAY_MS = 150;
 
+// This is the value used to identify the captive portal notification.
+const PORTAL_NOTIFICATION_VALUE = "captive-portal-detected";
+
 this.EXPORTED_SYMBOLS = [ "CaptivePortalWatcher" ];
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource:///modules/RecentWindow.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "cps",
                                    "@mozilla.org/network/captive-portal-service;1",
                                    "nsICaptivePortalService");
 
 this.CaptivePortalWatcher = {
   // This holds a weak reference to the captive portal tab so that we
   // don't leak it if the user closes it.
   _captivePortalTab: null,
 
+  // This holds a weak reference to the captive portal notification.
+  _captivePortalNotification: null,
+
   _initialized: false,
 
   /**
    * If a portal is detected when we don't have focus, we first wait for focus
    * and then add the tab after a small delay. This is set to true while we wait
    * so that in the unlikely event that we receive another notification while
    * waiting, we can avoid adding a second tab.
    */
@@ -45,17 +51,17 @@ this.CaptivePortalWatcher = {
   init() {
     Services.obs.addObserver(this, "captive-portal-login", false);
     Services.obs.addObserver(this, "captive-portal-login-abort", false);
     Services.obs.addObserver(this, "captive-portal-login-success", false);
     this._initialized = true;
 
     if (cps.state == cps.LOCKED_PORTAL) {
       // A captive portal has already been detected.
-      this._addCaptivePortalTab();
+      this._captivePortalDetected();
       return;
     }
 
     cps.recheckCaptivePortal();
   },
 
   uninit() {
     if (!this._initialized) {
@@ -64,48 +70,63 @@ this.CaptivePortalWatcher = {
     Services.obs.removeObserver(this, "captive-portal-login");
     Services.obs.removeObserver(this, "captive-portal-login-abort");
     Services.obs.removeObserver(this, "captive-portal-login-success");
   },
 
   observe(subject, topic, data) {
     switch (topic) {
       case "captive-portal-login":
-        this._addCaptivePortalTab();
+        this._captivePortalDetected();
         break;
       case "captive-portal-login-abort":
       case "captive-portal-login-success":
         this._captivePortalGone();
         break;
       case "xul-window-visible":
         this._delayedAddCaptivePortalTab();
         break;
     }
   },
 
-  _addCaptivePortalTab() {
+  _captivePortalDetected() {
     if (this._waitingToAddTab) {
       return;
     }
 
     let win = RecentWindow.getMostRecentBrowserWindow();
     // If there's no browser window or none have focus, open and show the
     // tab when we regain focus. This is so that if a different application was
     // focused, when the user (re-)focuses a browser window, we open the tab
     // immediately in that window so they can login before continuing to browse.
-    if (!win || !win.document.hasFocus()) {
+    if (!win || win != Services.ww.activeWindow) {
       this._waitingToAddTab = true;
       Services.obs.addObserver(this, "xul-window-visible", false);
       return;
     }
 
-    // The browser is in use - add the tab without selecting it.
-    let tab = win.gBrowser.addTab(this.canonicalURL);
+    // The browser is in use - show a notification and add the tab without
+    // selecting it, unless the caller specifically requested selection.
+    this._ensureCaptivePortalTab(win);
+    this._showNotification(win);
+  },
+
+  _ensureCaptivePortalTab(win) {
+    let tab;
+    if (this._captivePortalTab) {
+      tab = this._captivePortalTab.get();
+    }
+
+    // If the tab is gone or going, we need to open a new one.
+    if (!tab || tab.closing || !tab.parentNode) {
+      tab = win.gBrowser.addTab(this.canonicalURL);
+    }
+
     this._captivePortalTab = Cu.getWeakReference(tab);
-    return;
+    return tab;
   },
 
   /**
    * Called after we regain focus if we detect a portal while a browser window
    * doesn't have focus. Triggers a portal recheck to reaffirm state, and adds
    * the tab if needed after a short delay to allow the recheck to complete.
    */
   _delayedAddCaptivePortalTab() {
@@ -130,35 +151,37 @@ this.CaptivePortalWatcher = {
     // - If it is, the delay is chosen to not be extremely noticeable.
     setTimeout(() => {
       this._waitingToAddTab = false;
       if (cps.state != cps.LOCKED_PORTAL) {
         // We're free of the portal!
         return;
       }
 
-      let tab = win.gBrowser.addTab(this.canonicalURL);
+      this._showNotification(win);
+      let tab = this._ensureCaptivePortalTab(win);
+
       // Focus the tab only if the recheck has completed, i.e. we're sure
       // that the portal is still locked. This way, if the recheck completes
       // after we add the tab and we're free of the portal, the tab contents
       // won't flicker.
       if (cps.lastChecked != lastChecked) {
         win.gBrowser.selectedTab = tab;
       }
-
-      this._captivePortalTab = Cu.getWeakReference(tab);
     }, PORTAL_RECHECK_DELAY_MS);
   },
 
   _captivePortalGone() {
     if (this._waitingToAddTab) {
       Services.obs.removeObserver(this, "xul-window-visible");
       this._waitingToAddTab = false;
     }
 
+    this._removeNotification();
+
     if (!this._captivePortalTab) {
       return;
     }
 
     let tab = this._captivePortalTab.get();
     // In all the cases below, we want to stop treating the tab as a
     // captive portal tab.
     this._captivePortalTab = null;
@@ -176,9 +199,86 @@ this.CaptivePortalWatcher = {
     if (tab.linkedBrowser.currentURI.spec != this.canonicalURL &&
         tabbrowser.selectedTab == tab) {
       return;
     }
 
     // Remove the tab.
     tabbrowser.removeTab(tab);
   },
+
+  get _productName() {
+    delete this._productName;
+    return this._productName =
+      Services.strings.createBundle("chrome://branding/locale/brand.properties")
+                      .GetStringFromName("brandShortName");
+  },
+
+  get _browserBundle() {
+    delete this._browserBundle;
+    return this._browserBundle =
+      Services.strings.createBundle("chrome://browser/locale/browser.properties");
+  },
+
+  handleEvent(aEvent) {
+    if (aEvent.type != "TabSelect" || !this._captivePortalTab || !this._captivePortalNotification) {
+      return;
+    }
+
+    let tab = this._captivePortalTab.get();
+    let n = this._captivePortalNotification.get();
+    if (!tab || !n) {
+      return;
+    }
+
+    let doc = tab.ownerDocument;
+    let button = n.querySelector("button.notification-button");
+    if (doc.defaultView.gBrowser.selectedTab == tab) {
+      button.style.visibility = "hidden";
+    } else {
+      button.style.visibility = "visible";
+    }
+  },
+
+  _showNotification(win) {
+    let buttons = [
+      {
+        label: this._browserBundle.GetStringFromName("captivePortal.showLoginPage"),
+        callback: () => {
+          win.gBrowser.selectedTab = this._ensureCaptivePortalTab(win);
+
+          // Returning true prevents the notification from closing.
+          return true;
+        },
+        isDefault: true,
+      },
+    ];
+
+    let message = this._browserBundle.formatStringFromName("captivePortal.infoMessage",
+                                                           [this._productName], 1);
+
+    let closeHandler = (aEventName) => {
+      if (aEventName != "removed") {
+        return;
+      }
+      win.gBrowser.tabContainer.removeEventListener("TabSelect", this);
+    };
+
+    let nb = win.document.getElementById("high-priority-global-notificationbox");
+    let n = nb.appendNotification(message, PORTAL_NOTIFICATION_VALUE, "",
+                                  nb.PRIORITY_INFO_MEDIUM, buttons, closeHandler);
+
+    this._captivePortalNotification = Cu.getWeakReference(n);
+
+    win.gBrowser.tabContainer.addEventListener("TabSelect", this);
+  },
+
+  _removeNotification() {
+    if (!this._captivePortalNotification)
+      return;
+    let n = this._captivePortalNotification.get();
+    this._captivePortalNotification = null;
+    if (!n || !n.parentNode) {
+      return;
+    }
+    n.close();
+  },
 };
--- a/browser/modules/SocialService.jsm
+++ b/browser/modules/SocialService.jsm
@@ -505,17 +505,17 @@ this.SocialService = {
       if (!data['origin']) {
         Cu.reportError("SocialService.manifestFromData directory service provided manifest without origin.");
         return null;
       }
       installOrigin = data.origin;
     }
     // force/fixup origin
     let URI = Services.io.newURI(installOrigin, null, null);
-    principal = Services.scriptSecurityManager.createCodebasePrincipal(URI, {});
+    let principal = Services.scriptSecurityManager.createCodebasePrincipal(URI, {});
     data.origin = principal.origin;
 
     // iconURL and name are required
     let providerHasFeatures = featureURLs.some(url => data[url]);
     if (!providerHasFeatures) {
       Cu.reportError("SocialService.manifestFromData manifest missing required urls.");
       return null;
     }
--- a/browser/modules/test/browser.ini
+++ b/browser/modules/test/browser.ini
@@ -2,17 +2,16 @@
 support-files =
   head.js
 
 [browser_BrowserUITelemetry_buckets.js]
 [browser_BrowserUITelemetry_defaults.js]
 [browser_BrowserUITelemetry_sidebar.js]
 [browser_BrowserUITelemetry_syncedtabs.js]
 [browser_CaptivePortalWatcher.js]
-skip-if = os == "linux" || os == "win" || (os == "mac" && debug && e10s) # Bug 1279491, Bug 1287714 for OS X debug e10s
 [browser_ContentSearch.js]
 support-files =
   contentSearch.js
   contentSearchBadImage.xml
   contentSearchSuggestions.sjs
   contentSearchSuggestions.xml
 [browser_NetworkPrioritizer.js]
 [browser_PermissionUI.js]
--- a/browser/modules/test/browser_CaptivePortalWatcher.js
+++ b/browser/modules/test/browser_CaptivePortalWatcher.js
@@ -1,15 +1,16 @@
 "use strict";
 
 Components.utils.import("resource:///modules/RecentWindow.jsm");
 
 const CANONICAL_CONTENT = "success";
 const CANONICAL_URL = "data:text/plain;charset=utf-8," + CANONICAL_CONTENT;
 const CANONICAL_URL_REDIRECTED = "data:text/plain;charset=utf-8,redirected";
+const PORTAL_NOTIFICATION_VALUE = "captive-portal-detected";
 
 add_task(function* setup() {
   yield SpecialPowers.pushPrefEnv({
     set: [["captivedetect.canonicalURL", CANONICAL_URL],
           ["captivedetect.canonicalContent", CANONICAL_CONTENT]],
   });
 });
 
@@ -20,170 +21,306 @@ add_task(function* setup() {
  */
 function* portalDetectedNoBrowserWindow() {
   let getMostRecentBrowserWindow = RecentWindow.getMostRecentBrowserWindow;
   RecentWindow.getMostRecentBrowserWindow = () => {};
   Services.obs.notifyObservers(null, "captive-portal-login", null);
   RecentWindow.getMostRecentBrowserWindow = getMostRecentBrowserWindow;
 }
 
-function* openWindowAndWaitForPortalTab() {
+function* openWindowAndWaitForPortalTabAndNotification() {
   let win = yield BrowserTestUtils.openNewBrowserWindow();
-  let tab = yield BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
+  // Thanks to things being async, at this point we now have a new browser window
+  // but the portal notification and tab may or may not have opened. So first we
+  // check if there's already a portal notification, and if not, wait.
+  let notification = win.document.getElementById("high-priority-global-notificationbox")
+                        .getNotificationWithValue(PORTAL_NOTIFICATION_VALUE);
+  if (!notification) {
+    notification =
+      yield BrowserTestUtils.waitForGlobalNotificationBar(win, PORTAL_NOTIFICATION_VALUE);
+  }
+  // Then we see if there's already a portal tab. If it's open, it'll be the second one.
+  let tab = win.gBrowser.tabs[1];
+  if (!tab || tab.linkedBrowser.currentURI.spec != CANONICAL_URL) {
+    // The tab either hasn't been opened yet or it hasn't loaded the portal URL.
+    // Waiting for a location change in the tabbrowser covers both cases.
+    yield BrowserTestUtils.waitForLocationChange(win.gBrowser, CANONICAL_URL);
+    // At this point the portal tab should be the second tab. If there is still
+    // no second tab, something is wrong, and the selectedTab test below will fail.
+    tab = win.gBrowser.tabs[1];
+  }
   is(win.gBrowser.selectedTab, tab,
     "The captive portal tab should be open and selected in the new window.");
+  testShowLoginPageButtonVisibility(notification, "hidden");
   return win;
 }
 
 function freePortal(aSuccess) {
   Services.obs.notifyObservers(null,
     "captive-portal-login-" + (aSuccess ? "success" : "abort"), null);
 }
 
+function ensurePortalTab(win) {
+  // For the tests that call this function, it's enough to ensure there
+  // are two tabs in the window - the default tab and the portal tab.
+  is(win.gBrowser.tabs.length, 2,
+    "There should be a captive portal tab in the window.");
+}
+
+function ensurePortalNotification(win) {
+  let notificationBox =
+    win.document.getElementById("high-priority-global-notificationbox");
+  let notification = notificationBox.getNotificationWithValue(PORTAL_NOTIFICATION_VALUE)
+  isnot(notification, null,
+    "There should be a captive portal notification in the window.");
+  return notification;
+}
+
+// Helper to test whether the "Show Login Page" is visible in the captive portal
+// notification (it should be hidden when the portal tab is selected).
+function testShowLoginPageButtonVisibility(notification, visibility) {
+  let showLoginPageButton = notification.querySelector("button.notification-button");
+  // If the visibility property was never changed from default, it will be
+  // an empty string, so we pretend it's "visible" (effectively the same).
+  is(showLoginPageButton.style.visibility || "visible", visibility,
+    "The \"Show Login Page\" button should be " + visibility + ".");
+}
+
+function ensureNoPortalTab(win) {
+  is(win.gBrowser.tabs.length, 1,
+    "There should be no captive portal tab in the window.");
+}
+
+function ensureNoPortalNotification(win) {
+  let notificationBox =
+    win.document.getElementById("high-priority-global-notificationbox");
+  is(notificationBox.getNotificationWithValue(PORTAL_NOTIFICATION_VALUE), null,
+    "There should be no captive portal notification in the window.");
+}
+
 // Each of the test cases below is run twice: once for login-success and once
 // for login-abort (aSuccess set to true and false respectively).
 let testCasesForBothSuccessAndAbort = [
   /**
    * A portal is detected when there's no browser window,
    * then a browser window is opened, then the portal is freed.
    * The portal tab should be added and focused when the window is
    * opened, and closed automatically when the success event is fired.
    */
   function* test_detectedWithNoBrowserWindow_Open(aSuccess) {
     yield portalDetectedNoBrowserWindow();
-    let win = yield openWindowAndWaitForPortalTab();
+    let win = yield openWindowAndWaitForPortalTabAndNotification();
     freePortal(aSuccess);
-    is(win.gBrowser.tabs.length, 1,
-      "The captive portal tab should have been closed.");
+    ensureNoPortalTab(win);
+    ensureNoPortalNotification(win);
     yield BrowserTestUtils.closeWindow(win);
   },
 
   /**
    * A portal is detected when there's no browser window, and the
    * portal is freed before a browser window is opened. No portal
    * tab should be added when a browser window is opened.
    */
   function* test_detectedWithNoBrowserWindow_GoneBeforeOpen(aSuccess) {
     yield portalDetectedNoBrowserWindow();
     freePortal(aSuccess);
     let win = yield BrowserTestUtils.openNewBrowserWindow();
     // Wait for a while to make sure no tab is opened.
     yield new Promise(resolve => {
       setTimeout(resolve, 1000);
     });
-    is(win.gBrowser.tabs.length, 1,
-      "No captive portal tab should have been opened.");
+    ensureNoPortalTab(win);
+    ensureNoPortalNotification(win);
     yield BrowserTestUtils.closeWindow(win);
   },
 
   /**
    * A portal is detected when a browser window has focus. A portal tab should be
    * opened in the background in the focused browser window. If the portal is
    * freed when the tab isn't focused, the tab should be closed automatically.
    */
   function* test_detectedWithFocus(aSuccess) {
     let win = RecentWindow.getMostRecentBrowserWindow();
     let p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
     Services.obs.notifyObservers(null, "captive-portal-login", null);
     let tab = yield p;
+    ensurePortalTab(win);
+    ensurePortalNotification(win);
     isnot(win.gBrowser.selectedTab, tab,
       "The captive portal tab should be open in the background in the current window.");
     freePortal(aSuccess);
-    is(win.gBrowser.tabs.length, 1,
-      "The portal tab should have been closed.");
+    ensureNoPortalTab(win);
+    ensureNoPortalNotification(win);
   },
 
   /**
    * A portal is detected when a browser window has focus. A portal tab should be
    * opened in the background in the focused browser window. If the portal is
    * freed when the tab has focus, the tab should be closed automatically.
    */
   function* test_detectedWithFocus_selectedTab(aSuccess) {
     let win = RecentWindow.getMostRecentBrowserWindow();
     let p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
     Services.obs.notifyObservers(null, "captive-portal-login", null);
     let tab = yield p;
+    ensurePortalTab(win);
+    ensurePortalNotification(win);
     isnot(win.gBrowser.selectedTab, tab,
       "The captive portal tab should be open in the background in the current window.");
     win.gBrowser.selectedTab = tab;
     freePortal(aSuccess);
-    is(win.gBrowser.tabs.length, 1,
-      "The portal tab should have been closed.");
+    ensureNoPortalTab(win);
+    ensureNoPortalNotification(win);
   },
 ];
 
 let singleRunTestCases = [
   /**
    * A portal is detected when there's no browser window,
    * then a browser window is opened, and the portal is logged into
    * and redirects to a different page. The portal tab should be added
    * and focused when the window is opened, and left open after login
    * since it redirected.
    */
   function* test_detectedWithNoBrowserWindow_Redirect() {
     yield portalDetectedNoBrowserWindow();
-    let win = yield openWindowAndWaitForPortalTab();
+    let win = yield openWindowAndWaitForPortalTabAndNotification();
     let browser = win.gBrowser.selectedTab.linkedBrowser;
     let loadPromise =
       BrowserTestUtils.browserLoaded(browser, false, CANONICAL_URL_REDIRECTED);
     BrowserTestUtils.loadURI(browser, CANONICAL_URL_REDIRECTED);
     yield loadPromise;
     freePortal(true);
-    is(win.gBrowser.tabs.length, 2,
-      "The captive portal tab should not have been closed.");
+    ensurePortalTab(win);
+    ensureNoPortalNotification(win);
     yield BrowserTestUtils.closeWindow(win);
   },
 
   /**
    * A portal is detected when a browser window has focus. A portal tab should be
    * opened in the background in the focused browser window. If the portal is
    * freed when the tab isn't focused, the tab should be closed automatically,
    * even if the portal has redirected to a URL other than CANONICAL_URL.
    */
   function* test_detectedWithFocus_redirectUnselectedTab() {
     let win = RecentWindow.getMostRecentBrowserWindow();
     let p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
     Services.obs.notifyObservers(null, "captive-portal-login", null);
     let tab = yield p;
+    ensurePortalTab(win);
+    ensurePortalNotification(win);
     isnot(win.gBrowser.selectedTab, tab,
       "The captive portal tab should be open in the background in the current window.");
     let browser = tab.linkedBrowser;
     let loadPromise =
       BrowserTestUtils.browserLoaded(browser, false, CANONICAL_URL_REDIRECTED);
     BrowserTestUtils.loadURI(browser, CANONICAL_URL_REDIRECTED);
     yield loadPromise;
     freePortal(true);
-    is(win.gBrowser.tabs.length, 1,
-      "The portal tab should have been closed.");
+    ensureNoPortalTab(win);
+    ensureNoPortalNotification(win);
   },
 
   /**
    * A portal is detected when a browser window has focus. A portal tab should be
    * opened in the background in the focused browser window. If the portal is
    * freed when the tab has focus, and it has redirected to another page, the
    * tab should be kept open.
    */
   function* test_detectedWithFocus_redirectSelectedTab() {
     let win = RecentWindow.getMostRecentBrowserWindow();
     let p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
     Services.obs.notifyObservers(null, "captive-portal-login", null);
     let tab = yield p;
+    ensurePortalNotification(win);
     isnot(win.gBrowser.selectedTab, tab,
       "The captive portal tab should be open in the background in the current window.");
     win.gBrowser.selectedTab = tab;
     let browser = tab.linkedBrowser;
     let loadPromise =
       BrowserTestUtils.browserLoaded(browser, false, CANONICAL_URL_REDIRECTED);
     BrowserTestUtils.loadURI(browser, CANONICAL_URL_REDIRECTED);
     yield loadPromise;
     freePortal(true);
-    is(win.gBrowser.tabs.length, 2,
-      "The portal tab should not have been closed.");
+    ensurePortalTab(win);
+    ensureNoPortalNotification(win);
     yield BrowserTestUtils.removeTab(tab);
   },
+
+  /**
+   * Test the various expected behaviors of the "Show Login Page" button
+   * in the captive portal notification. The button should be visible for
+   * all tabs except the captive portal tab, and when clicked, should
+   * ensure a captive portal tab is open and select it.
+   */
+  function* test_showLoginPageButton() {
+    let win = RecentWindow.getMostRecentBrowserWindow();
+    let p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
+    Services.obs.notifyObservers(null, "captive-portal-login", null);
+    let tab = yield p;
+    let notification = ensurePortalNotification(win);
+    isnot(win.gBrowser.selectedTab, tab,
+      "The captive portal tab should be open in the background in the current window.");
+    testShowLoginPageButtonVisibility(notification, "visible");
+
+    function testPortalTabSelectedAndButtonNotVisible() {
+      is(win.gBrowser.selectedTab, tab, "The captive portal tab should be selected.");
+      testShowLoginPageButtonVisibility(notification, "hidden");
+    }
+
+    // Select the captive portal tab. The button should hide.
+    let otherTab = win.gBrowser.selectedTab;
+    win.gBrowser.selectedTab = tab;
+    testShowLoginPageButtonVisibility(notification, "hidden");
+
+    // Select the other tab. The button should become visible.
+    win.gBrowser.selectedTab = otherTab;
+    testShowLoginPageButtonVisibility(notification, "visible");
+
+    // Simulate clicking the button. The portal tab should be selected and
+    // the button should hide.
+    let button = notification.querySelector("button.notification-button");
+    button.click();
+    testPortalTabSelectedAndButtonNotVisible();
+
+    // Close the tab. The button should become visible.
+    yield BrowserTestUtils.removeTab(tab);
+    ensureNoPortalTab(win);
+    testShowLoginPageButtonVisibility(notification, "visible");
+
+    function* clickButtonAndExpectNewPortalTab() {
+      p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
+      button.click();
+      tab = yield p;
+      is(win.gBrowser.selectedTab, tab, "The captive portal tab should be selected.");
+    }
+
+    // When the button is clicked, a new portal tab should be opened and
+    // selected.
+    yield clickButtonAndExpectNewPortalTab();
+
+    // Open another arbitrary tab. The button should become visible. When it's clicked,
+    // the portal tab should be selected.
+    let anotherTab = yield BrowserTestUtils.openNewForegroundTab(win.gBrowser);
+    testShowLoginPageButtonVisibility(notification, "visible");
+    button.click();
+    is(win.gBrowser.selectedTab, tab, "The captive portal tab should be selected.");
+
+    // Close the portal tab and select the arbitrary tab. The button should become
+    // visible and when it's clicked, a new portal tab should be opened.
+    yield BrowserTestUtils.removeTab(tab);
+    win.gBrowser.selectedTab = anotherTab;
+    testShowLoginPageButtonVisibility(notification, "visible");
+    yield clickButtonAndExpectNewPortalTab();
+
+    yield BrowserTestUtils.removeTab(anotherTab);
+    freePortal(true);
+    ensureNoPortalTab(win);
+    ensureNoPortalNotification(win);
+  },
 ];
 
 for (let testcase of testCasesForBothSuccessAndAbort) {
   add_task(testcase.bind(null, true));
   add_task(testcase.bind(null, false));
 }
 
 for (let testcase of singleRunTestCases) {
--- a/browser/themes/osx/places/organizer.css
+++ b/browser/themes/osx/places/organizer.css
@@ -56,16 +56,32 @@
 #placesList > treechildren::-moz-tree-twisty(open) {
   list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded");
 }
 
 #placesList > treechildren::-moz-tree-twisty(open, selected) {
   list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted");
 }
 
+#placesList > treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty {
+  list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-rtl");
+}
+
+#placesList > treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(selected) {
+  list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-inverted-rtl");
+}
+
+#placesList > treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(open) {
+  list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded");
+}
+
+#placesList > treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(open, selected) {
+  list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted");
+}
+
 @media (-moz-mac-yosemite-theme) {
   #placesList > treechildren::-moz-tree-cell-text(selected) {
     color: -moz-dialogtext;
     font-weight: 500;
   }
 
   #placesList > treechildren::-moz-tree-cell-text(selected, focus) {
     color: #fff;
@@ -81,16 +97,32 @@
 
   #placesList > treechildren::-moz-tree-twisty(open, selected) {
     list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded");
   }
 
   #placesList > treechildren::-moz-tree-twisty(open, selected, focus) {
     list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted");
   }
+
+  #placesList > treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(selected) {
+    list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-rtl");
+  }
+
+  #placesList > treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(selected, focus) {
+    list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-inverted-rtl");
+  }
+
+  #placesList > treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(open, selected) {
+    list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded");
+  }
+
+  #placesList > treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(open, selected, focus) {
+    list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted");
+  }
 }
 
 #placesToolbar {
   padding: 0 4px 3px;
 }
 
 #placesView {
   border-top: none !important;
--- a/browser/themes/osx/places/places.css
+++ b/browser/themes/osx/places/places.css
@@ -74,16 +74,32 @@
 .sidebar-placesTreechildren::-moz-tree-twisty(open) {
   list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded");
 }
 
 .sidebar-placesTreechildren::-moz-tree-twisty(open, selected) {
   list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted");
 }
 
+.sidebar-placesTreechildren:-moz-locale-dir(rtl)::-moz-tree-twisty {
+  list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-rtl");
+}
+
+.sidebar-placesTreechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(selected) {
+  list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-inverted-rtl");
+}
+
+.sidebar-placesTreechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(open) {
+  list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded");
+}
+
+.sidebar-placesTreechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(open, selected) {
+  list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted");
+}
+
 @media (-moz-mac-yosemite-theme) {
   .sidebar-placesTreechildren::-moz-tree-cell-text(selected) {
     color: -moz-dialogtext;
     font-weight: 500;
   }
 
   .sidebar-placesTreechildren::-moz-tree-cell-text(selected, focus) {
     color: #fff;
@@ -99,16 +115,32 @@
 
   .sidebar-placesTreechildren::-moz-tree-twisty(open, selected) {
     list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded");
   }
 
   .sidebar-placesTreechildren::-moz-tree-twisty(open, selected, focus) {
     list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted");
   }
+
+  .sidebar-placesTreechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(selected) {
+    list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-rtl");
+  }
+
+  .sidebar-placesTreechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(selected, focus) {
+    list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-inverted-rtl")
+  }
+
+  .sidebar-placesTreechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(open, selected) {
+    list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded");
+  }
+
+  .sidebar-placesTreechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(open, selected, focus) {
+    list-style-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted");
+  }
 }
 
 #viewButton {
   -moz-appearance: none;
   padding-bottom: 1px;
   padding-inline-start: 5px;
   padding-inline-end: 0px;
   margin: 0;
--- a/browser/themes/osx/syncedtabs/sidebar.css
+++ b/browser/themes/osx/syncedtabs/sidebar.css
@@ -47,16 +47,32 @@
 .item.client.selected:focus .item-twisty-container {
   background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted");
 }
 
 .item.client.selected.closed:focus .item-twisty-container {
   background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-inverted");
 }
 
+.item.client .item-twisty-container:dir(rtl) {
+  background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded");
+}
+
+.item.client.closed .item-twisty-container:dir(rtl) {
+  background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-rtl");
+}
+
+.item.client.selected:focus .item-twisty-container:dir(rtl) {
+  background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted");
+}
+
+.item.client.selected.closed:focus .item-twisty-container:dir(rtl) {
+  background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-inverted-rtl");
+}
+
 @media (-moz-mac-yosemite-theme) {
   .item.selected > .item-title-container {
     color: -moz-dialogtext;
     font-weight: 500;
   }
 
   .item.selected:focus > .item-title-container {
     color: #fff;
--- a/build/autoconf/sanitize.m4
+++ b/build/autoconf/sanitize.m4
@@ -9,18 +9,22 @@ dnl = Use Address Sanitizer
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(address-sanitizer,
 [  --enable-address-sanitizer       Enable Address Sanitizer (default=no)],
     MOZ_ASAN=1,
     MOZ_ASAN= )
 if test -n "$MOZ_ASAN"; then
     MOZ_LLVM_HACKS=1
     if test -n "$CLANG_CL"; then
-        # Look for clang_rt.asan_dynamic-i386.dll
-        MOZ_CLANG_RT_ASAN_LIB=clang_rt.asan_dynamic-i386.dll
+        # Look for the ASan runtime binary
+        if test "$CPU_ARCH" = "x86_64"; then
+          MOZ_CLANG_RT_ASAN_LIB=clang_rt.asan_dynamic-x86_64.dll
+        else
+          MOZ_CLANG_RT_ASAN_LIB=clang_rt.asan_dynamic-i386.dll
+        fi
         # We use MOZ_PATH_PROG in order to get a Windows style path.
         MOZ_PATH_PROG(MOZ_CLANG_RT_ASAN_LIB_PATH, $MOZ_CLANG_RT_ASAN_LIB)
         if test -z "$MOZ_CLANG_RT_ASAN_LIB_PATH"; then
             AC_MSG_ERROR([Couldn't find $MOZ_CLANG_RT_ASAN_LIB.  It should be available in the same location as clang-cl.])
         fi
         AC_SUBST(MOZ_CLANG_RT_ASAN_LIB_PATH)
     fi
     CFLAGS="-fsanitize=address $CFLAGS"
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -239,17 +239,17 @@ class Automation(object):
     # enable non-local connections for the purposes of local testing.  Don't
     # override the user's choice here.  See bug 1049688.
     env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1')
 
     env['GNOME_DISABLE_CRASH_DIALOG'] = '1'
     env['XRE_NO_WINDOWS_CRASH_DIALOG'] = '1'
 
     # Set WebRTC logging in case it is not set yet
-    env.setdefault('MOZ_LOG', 'signaling:3,mtransport:4,datachannel:4,jsep:4,MediaPipelineFactory:4')
+    env.setdefault('MOZ_LOG', 'signaling:3,mtransport:4,DataChannel:4,jsep:4,MediaPipelineFactory:4')
     env.setdefault('R_LOG_LEVEL', '6')
     env.setdefault('R_LOG_DESTINATION', 'stderr')
     env.setdefault('R_LOG_VERBOSE', '1')
 
     # ASan specific environment stuff
     if self.IS_ASAN and (self.IS_LINUX or self.IS_MAC):
       # Symbolizer support
       llvmsym = os.path.join(xrePath, "llvm-symbolizer")
--- a/build/docs/index.rst
+++ b/build/docs/index.rst
@@ -21,16 +21,17 @@ Important Concepts
    python
    test_manifests
    mozinfo
    preprocessor
    jar-manifests
    defining-binaries
    toolchains
    locales
+   rust
 
 integrated development environment (IDE)
 ========================================
 .. toctree::
    :maxdepth: 1
 
    androideclipse
    cppeclipse
new file mode 100644
--- /dev/null
+++ b/build/docs/rust.rst
@@ -0,0 +1,78 @@
+.. _rust:
+
+==============================
+Including Rust Code in Firefox
+==============================
+
+The build system has support for building and linking Rust crates.
+Rust code is built using ``cargo`` in the typical way, so it is
+straightforward to take an existing Rust crate and integrate it
+into Firefox.
+
+.. important::
+
+   Rust code is not currently enabled by default in Firefox builds.
+   This should change soon (`bug 1283898 <https://bugzilla.mozilla.org/show_bug.cgi?id=1283898>`_),
+   but the option to build without Rust code will likely last a little longer
+   (`bug 1284816 <https://bugzilla.mozilla.org/show_bug.cgi?id=1284816>`_),
+   so Rust code cannot currently be used for required components.
+
+
+Linking Rust Crates into libxul
+===============================
+
+Rust crates that you want to link into libxul should be listed in the
+``dependencies`` section of `toolkit/library/rust/shared/Cargo.toml <https://dxr.mozilla.org/mozilla-central/source/toolkit/library/rust/shared/Cargo.toml>`_.
+This ensures that the Rust code will be linked properly into libxul as well
+as the copy of libxul used for gtests.
+
+Linking Rust Crates into something else
+=======================================
+
+There currently is not any Rust code being linked into binaries other than
+libxul. If you would like to do so, you'll need to create a directory with
+a ``Cargo.toml`` file for your crate, and a ``moz.build`` file that contains:
+
+.. code-block:: python
+
+    RustLibrary('crate_name')
+
+Where *crate_name* matches the name from the ``[package]`` section of your
+``Cargo.toml``. You can refer to `the moz.build file <https://dxr.mozilla.org/mozilla-central/rev/3f4c3a3cabaf94958834d3a8935adfb4a887942d/toolkit/library/rust/moz.build#7>`_ and `the Cargo.toml file <https://dxr.mozilla.org/mozilla-central/rev/3f4c3a3cabaf94958834d3a8935adfb4a887942d/toolkit/library/rust/Cargo.toml>`_ that are used for libxul.
+
+You can then add ``USE_LIBS += ['crate_name']`` to the ``moz.build`` file
+that defines the binary as you would with any other library in the tree.
+
+.. important::
+
+    You cannot link a Rust crate into an intermediate library that will wind
+    up being linked into libxul. The build system enforces that only a single
+    ``RustLibrary`` may be linked into a binary. If you need to do this, you
+    will have to add a ``RustLibrary`` to link to any standalone binaries that
+    link the intermediate library, and also add the Rust crate to the libxul
+    dependencies as in `linking Rust Crates into libxul`_.
+
+Where Should I put my Crate?
+============================
+
+If your crate's canonical home is mozilla-central, you can put it next to the
+other code in the module it belongs to.
+
+If your crate is mirrored into mozilla-central from another repository, and
+will not be actively developed in mozilla-central, you can simply list it
+as a ``crates.io``-style dependency with a version number, and let it be
+vendored into the ``third_party/rust`` directory.
+
+If your crate is mirrored into mozilla-central from another repository, but
+will be actively developed in both locations, you should send mail to the
+dev-builds mailing list to start a discussion on how to meet your needs.
+
+
+Crate dependencies
+==================
+
+All dependencies for in-tree Rust crates are vendored into the
+``third_party/rust`` directory. Currently if you add a dependency on a new
+crate you must run ``mach vendor rust`` to vendor the dependencies into
+that directory. In the future we hope to make it so that you only need to
+vendor the dependencies in order to build your changes in a CI push.
--- a/chrome/nsChromeRegistry.cpp
+++ b/chrome/nsChromeRegistry.cpp
@@ -27,16 +27,20 @@
 #include "nsIObserverService.h"
 #include "nsIPresShell.h"
 #include "nsIScriptError.h"
 #include "nsIWindowMediator.h"
 #include "nsIPrefService.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/StyleSheetInlines.h"
 
+#ifdef ENABLE_INTL_API
+#include "unicode/uloc.h"
+#endif
+
 nsChromeRegistry* nsChromeRegistry::gChromeRegistry;
 
 // DO NOT use namespace mozilla; it'll break due to a naming conflict between
 // mozilla::TextRange and a TextRange in OSX headers.
 using mozilla::StyleSheet;
 using mozilla::dom::IsChromeURI;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -641,16 +645,21 @@ nsChromeRegistry::MustLoadURLRemotely(ns
     *aResult = !!(flags & REMOTE_REQUIRED);
   }
   return NS_OK;
 }
 
 bool
 nsChromeRegistry::GetDirectionForLocale(const nsACString& aLocale)
 {
+#ifdef ENABLE_INTL_API
+  nsAutoCString locale(aLocale);
+  SanitizeForBCP47(locale);
+  return uloc_isRightToLeft(locale.get());
+#else
   // first check the intl.uidirection.<locale> preference, and if that is not
   // set, check the same preference but with just the first two characters of
   // the locale. If that isn't set, default to left-to-right.
   nsAutoCString prefString = NS_LITERAL_CSTRING("intl.uidirection.") + aLocale;
   nsCOMPtr<nsIPrefBranch> prefBranch (do_GetService(NS_PREFSERVICE_CONTRACTID));
   if (!prefBranch) {
     return false;
   }
@@ -661,16 +670,17 @@ nsChromeRegistry::GetDirectionForLocale(
     int32_t hyphen = prefString.FindChar('-');
     if (hyphen >= 1) {
       nsAutoCString shortPref(Substring(prefString, 0, hyphen));
       prefBranch->GetCharPref(shortPref.get(), getter_Copies(dir));
     }
   }
 
   return dir.EqualsLiteral("rtl");
+#endif
 }
 
 NS_IMETHODIMP_(bool)
 nsChromeRegistry::WrappersEnabled(nsIURI *aURI)
 {
   nsCOMPtr<nsIURL> chromeURL (do_QueryInterface(aURI));
   if (!chromeURL)
     return false;
@@ -704,8 +714,37 @@ nsChromeRegistry::GetSingleton()
   else
     cr = new nsChromeRegistryChrome();
 
   if (NS_FAILED(cr->Init()))
     return nullptr;
 
   return cr.forget();
 }
+
+void
+nsChromeRegistry::SanitizeForBCP47(nsACString& aLocale)
+{
+#ifdef ENABLE_INTL_API
+  // Currently, the only locale code we use that's not BCP47-conformant is
+  // "ja-JP-mac" on OS X, but let's try to be more general than just
+  // hard-coding that here.
+  const int32_t LANG_TAG_CAPACITY = 128;
+  char langTag[LANG_TAG_CAPACITY];
+  nsAutoCString locale(aLocale);
+  UErrorCode err = U_ZERO_ERROR;
+  // This is a fail-safe method that will set langTag to "und" if it cannot
+  // match any part of the input locale code.
+  int32_t len = uloc_toLanguageTag(locale.get(), langTag, LANG_TAG_CAPACITY,
+                                   false, &err);
+  if (U_SUCCESS(err) && len > 0) {
+    aLocale.Assign(langTag, len);
+  }
+#else
+  // This is only really needed for Intl API purposes, AFAIK,
+  // so probably won't be used in a non-ENABLE_INTL_API build.
+  // But let's fix up the single anomalous code we actually ship,
+  // just in case:
+  if (aLocale.EqualsLiteral("ja-JP-mac")) {
+    aLocale.AssignLiteral("ja-JP");
+  }
+#endif
+}
--- a/chrome/nsChromeRegistry.h
+++ b/chrome/nsChromeRegistry.h
@@ -96,16 +96,18 @@ protected:
   nsresult SelectLocaleFromPref(nsIPrefBranch* prefs);
 
   static nsresult RefreshWindow(nsPIDOMWindowOuter* aWindow);
   static nsresult GetProviderAndPath(nsIURL* aChromeURL,
                                      nsACString& aProvider, nsACString& aPath);
 
   bool GetDirectionForLocale(const nsACString& aLocale);
 
+  void SanitizeForBCP47(nsACString& aLocale);
+
 public:
   static already_AddRefed<nsChromeRegistry> GetSingleton();
 
   struct ManifestProcessingContext
   {
     ManifestProcessingContext(NSLocationType aType, mozilla::FileLocation &aFile)
       : mType(aType)
       , mFile(aFile)
--- a/chrome/nsChromeRegistryChrome.cpp
+++ b/chrome/nsChromeRegistryChrome.cpp
@@ -219,40 +219,45 @@ getUILangCountry(nsACString& aUILang)
 }
 
 NS_IMETHODIMP
 nsChromeRegistryChrome::IsLocaleRTL(const nsACString& package, bool *aResult)
 {
   *aResult = false;
 
   nsAutoCString locale;
-  GetSelectedLocale(package, locale);
+  GetSelectedLocale(package, false, locale);
   if (locale.Length() < 2)
     return NS_OK;
 
   *aResult = GetDirectionForLocale(locale);
   return NS_OK;
 }
 
 nsresult
 nsChromeRegistryChrome::GetSelectedLocale(const nsACString& aPackage,
+                                          bool aAsBCP47,
                                           nsACString& aLocale)
 {
   nsCString realpackage;
   nsresult rv = OverrideLocalePackage(aPackage, realpackage);
   if (NS_FAILED(rv))
     return rv;
   PackageEntry* entry;
   if (!mPackagesHash.Get(realpackage, &entry))
     return NS_ERROR_FILE_NOT_FOUND;
 
   aLocale = entry->locales.GetSelected(mSelectedLocale, nsProviderArray::LOCALE);
   if (aLocale.IsEmpty())
     return NS_ERROR_FAILURE;
 
+  if (aAsBCP47) {
+    SanitizeForBCP47(aLocale);
+  }
+
   return NS_OK;
 }
 
 nsresult
 nsChromeRegistryChrome::OverrideLocalePackage(const nsACString& aPackage,
                                               nsACString& aOverride)
 {
   const nsACString& pref = NS_LITERAL_CSTRING(PACKAGE_OVERRIDE_BRANCH) + aPackage;
--- a/chrome/nsChromeRegistryChrome.h
+++ b/chrome/nsChromeRegistryChrome.h
@@ -31,16 +31,17 @@ class nsChromeRegistryChrome : public ns
 
   NS_IMETHOD CheckForNewChrome() override;
   NS_IMETHOD CheckForOSAccessibility() override;
   NS_IMETHOD GetLocalesForPackage(const nsACString& aPackage,
                                   nsIUTF8StringEnumerator* *aResult) override;
   NS_IMETHOD IsLocaleRTL(const nsACString& package,
                          bool *aResult) override;
   NS_IMETHOD GetSelectedLocale(const nsACString& aPackage,
+                               bool aAsBCP47,
                                nsACString& aLocale) override;
   NS_IMETHOD Observe(nsISupports *aSubject, const char *aTopic,
                      const char16_t *someData) override;
 
 #ifdef MOZ_XUL
   NS_IMETHOD GetXULOverlays(nsIURI *aURI,
                             nsISimpleEnumerator **_retval) override;
   NS_IMETHOD GetStyleOverlays(nsIURI *aURI,
--- a/chrome/nsChromeRegistryContent.cpp
+++ b/chrome/nsChromeRegistryContent.cpp
@@ -217,23 +217,27 @@ nsChromeRegistryContent::IsLocaleRTL(con
     return NS_ERROR_NOT_AVAILABLE;
   }
   *aResult = GetDirectionForLocale(mLocale);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsChromeRegistryContent::GetSelectedLocale(const nsACString& aPackage,
+                                           bool aAsBCP47,
                                            nsACString& aLocale)
 {
   if (aPackage != nsDependentCString("global")) {
     NS_ERROR("Uh-oh, caller wanted something other than 'some local'");
     return NS_ERROR_NOT_AVAILABLE;
   }
   aLocale = mLocale;
+  if (aAsBCP47) {
+    SanitizeForBCP47(aLocale);
+  }
   return NS_OK;
 }
   
 NS_IMETHODIMP
 nsChromeRegistryContent::Observe(nsISupports* aSubject, const char* aTopic,
                                  const char16_t* aData)
 {
   CONTENT_NOT_IMPLEMENTED();
--- a/chrome/nsChromeRegistryContent.h
+++ b/chrome/nsChromeRegistryContent.h
@@ -28,16 +28,17 @@ class nsChromeRegistryContent : public n
                                   nsIUTF8StringEnumerator* *aResult) override;
   NS_IMETHOD CheckForNewChrome() override;
   NS_IMETHOD CheckForOSAccessibility() override;
   NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic,
                      const char16_t* aData) override;
   NS_IMETHOD IsLocaleRTL(const nsACString& package,
                          bool *aResult) override;
   NS_IMETHOD GetSelectedLocale(const nsACString& aPackage,
+                               bool aAsBCP47,
                                nsACString& aLocale) override;
   NS_IMETHOD GetStyleOverlays(nsIURI *aChromeURL,
                               nsISimpleEnumerator **aResult) override;
   NS_IMETHOD GetXULOverlays(nsIURI *aChromeURL,
                             nsISimpleEnumerator **aResult) override;
 
   void RegisterPackage(const ChromePackage& aPackage);
   void RegisterOverride(const OverrideMapping& aOverride);
--- a/chrome/nsIChromeRegistry.idl
+++ b/chrome/nsIChromeRegistry.idl
@@ -45,18 +45,23 @@ interface nsIChromeRegistry : nsISupport
   [notxpcom] boolean wrappersEnabled(in nsIURI aURI);
 };
 
 [scriptable, uuid(93251ddf-5e85-4172-ac2a-31780562974f)]
 interface nsIXULChromeRegistry : nsIChromeRegistry
 {
   /* Should be called when locales change to reload all chrome (including XUL). */
   void reloadChrome();
-  
-  ACString getSelectedLocale(in ACString packageName);
+
+  // If the optional asBCP47 parameter is true, the locale code will be
+  // converted to a BCP47 language tag; in particular, this means that
+  // "ja-JP-mac" will be returned as "ja-JP-x-lvariant-mac", which can be
+  // passed to ECMA402 Intl API methods without throwing a RangeError.
+  ACString getSelectedLocale(in ACString packageName,
+                             [optional] in boolean asBCP47);
   
   // Get the direction of the locale via the intl.uidirection.<locale> pref
   boolean isLocaleRTL(in ACString package);
 
   /* Should be called when skins change. Reloads only stylesheets. */
   void refreshSkins();
 
   /**
--- a/devtools/client/netmonitor/moz.build
+++ b/devtools/client/netmonitor/moz.build
@@ -13,16 +13,17 @@ DIRS += [
 
 DevToolsModules(
     'constants.js',
     'custom-request-view.js',
     'events.js',
     'filter-predicates.js',
     'l10n.js',
     'panel.js',
+    'performance-statistics-view.js',
     'prefs.js',
     'request-utils.js',
     'requests-menu-view.js',
     'sort-predicates.js',
     'store.js',
     'toolbar-view.js',
 )
 
--- a/devtools/client/netmonitor/netmonitor-controller.js
+++ b/devtools/client/netmonitor/netmonitor-controller.js
@@ -38,16 +38,17 @@ const Services = require("Services");
 /* eslint-disable mozilla/reject-some-requires */
 const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
 const EventEmitter = require("devtools/shared/event-emitter");
 const Editor = require("devtools/client/sourceeditor/editor");
 const {TimelineFront} = require("devtools/shared/fronts/timeline");
 const {Task} = require("devtools/shared/task");
 const {Prefs} = require("./prefs");
 const {EVENTS} = require("./events");
+const Actions = require("./actions/index");
 
 XPCOMUtils.defineConstant(this, "EVENTS", EVENTS);
 XPCOMUtils.defineConstant(this, "ACTIVITY_TYPE", ACTIVITY_TYPE);
 XPCOMUtils.defineConstant(this, "Editor", Editor);
 XPCOMUtils.defineConstant(this, "Prefs", Prefs);
 
 XPCOMUtils.defineLazyModuleGetter(this, "Chart",
   "resource://devtools/client/shared/widgets/Chart.jsm");
--- a/devtools/client/netmonitor/netmonitor-view.js
+++ b/devtools/client/netmonitor/netmonitor-view.js
@@ -14,46 +14,43 @@ XPCOMUtils.defineLazyGetter(this, "Netwo
 
 /* eslint-disable mozilla/reject-some-requires */
 const {VariablesView} = require("resource://devtools/client/shared/widgets/VariablesView.jsm");
 /* eslint-disable mozilla/reject-some-requires */
 const {VariablesViewController} = require("resource://devtools/client/shared/widgets/VariablesViewController.jsm");
 const {ToolSidebar} = require("devtools/client/framework/sidebar");
 const {testing: isTesting} = require("devtools/shared/flags");
 const {ViewHelpers, Heritage} = require("devtools/client/shared/widgets/view-helpers");
-const {PluralForm} = require("devtools/shared/plural-form");
 const {Filters} = require("./filter-predicates");
 const {getFormDataSections,
        formDataURI,
        getUriHostPort} = require("./request-utils");
 const {L10N} = require("./l10n");
 const {RequestsMenuView} = require("./requests-menu-view");
 const {CustomRequestView} = require("./custom-request-view");
 const {ToolbarView} = require("./toolbar-view");
 const {configureStore} = require("./store");
-const Actions = require("./actions/index");
+const {PerformanceStatisticsView} = require("./performance-statistics-view");
 
 // Initialize the global redux variables
 var gStore = configureStore();
 
 // ms
 const WDA_DEFAULT_VERIFY_INTERVAL = 50;
 
 // Use longer timeout during testing as the tests need this process to succeed
 // and two seconds is quite short on slow debug builds. The timeout here should
 // be at least equal to the general mochitest timeout of 45 seconds so that this
 // never gets hit during testing.
 // ms
 const WDA_DEFAULT_GIVE_UP_TIMEOUT = isTesting ? 45000 : 2000;
 
 // 100 KB in bytes
 const SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE = 102400;
-const REQUEST_TIME_DECIMALS = 2;
 const HEADERS_SIZE_DECIMALS = 3;
-const CONTENT_SIZE_DECIMALS = 2;
 const CONTENT_MIME_TYPE_MAPPINGS = {
   "/ecmascript": Editor.modes.js,
   "/javascript": Editor.modes.js,
   "/x-javascript": Editor.modes.js,
   "/html": Editor.modes.html,
   "/xhtml": Editor.modes.html,
   "/xml": Editor.modes.html,
   "/atom": Editor.modes.html,
@@ -75,33 +72,32 @@ const GENERIC_VARIABLES_VIEW_SETTINGS = 
   lazyEmptyDelay: 10,
   searchEnabled: true,
   editableValueTooltip: "",
   editableNameTooltip: "",
   preventDisableOnChange: true,
   preventDescriptorModifiers: true,
   eval: () => {}
 };
-// px
-const NETWORK_ANALYSIS_PIE_CHART_DIAMETER = 200;
 
 /**
  * Object defining the network monitor view components.
  */
 var NetMonitorView = {
   /**
    * Initializes the network monitor view.
    */
   initialize: function () {
     this._initializePanes();
 
     this.Toolbar.initialize(gStore);
     this.RequestsMenu.initialize(gStore);
     this.NetworkDetails.initialize();
     this.CustomRequest.initialize();
+    this.PerformanceStatistics.initialize(gStore);
   },
 
   /**
    * Destroys the network monitor view.
    */
   destroy: function () {
     this._isDestroyed = true;
     this.Toolbar.destroy();
@@ -1192,259 +1188,23 @@ NetworkDetailsView.prototype = {
   _paramsPostPayload: "",
   _requestHeaders: "",
   _responseHeaders: "",
   _requestCookies: "",
   _responseCookies: ""
 };
 
 /**
- * Functions handling the performance statistics view.
- */
-function PerformanceStatisticsView() {
-}
-
-PerformanceStatisticsView.prototype = {
-  /**
-   * Initializes and displays empty charts in this container.
-   */
-  displayPlaceholderCharts: function () {
-    this._createChart({
-      id: "#primed-cache-chart",
-      title: "charts.cacheEnabled"
-    });
-    this._createChart({
-      id: "#empty-cache-chart",
-      title: "charts.cacheDisabled"
-    });
-    window.emit(EVENTS.PLACEHOLDER_CHARTS_DISPLAYED);
-  },
-
-  /**
-   * Populates and displays the primed cache chart in this container.
-   *
-   * @param array items
-   *        @see this._sanitizeChartDataSource
-   */
-  createPrimedCacheChart: function (items) {
-    this._createChart({
-      id: "#primed-cache-chart",
-      title: "charts.cacheEnabled",
-      data: this._sanitizeChartDataSource(items),
-      strings: this._commonChartStrings,
-      totals: this._commonChartTotals,
-      sorted: true
-    });
-    window.emit(EVENTS.PRIMED_CACHE_CHART_DISPLAYED);
-  },
-
-  /**
-   * Populates and displays the empty cache chart in this container.
-   *
-   * @param array items
-   *        @see this._sanitizeChartDataSource
-   */
-  createEmptyCacheChart: function (items) {
-    this._createChart({
-      id: "#empty-cache-chart",
-      title: "charts.cacheDisabled",
-      data: this._sanitizeChartDataSource(items, true),
-      strings: this._commonChartStrings,
-      totals: this._commonChartTotals,
-      sorted: true
-    });
-    window.emit(EVENTS.EMPTY_CACHE_CHART_DISPLAYED);
-  },
-
-  /**
-   * Common stringifier predicates used for items and totals in both the
-   * "primed" and "empty" cache charts.
-   */
-  _commonChartStrings: {
-    size: value => {
-      let string = L10N.numberWithDecimals(value / 1024, CONTENT_SIZE_DECIMALS);
-      return L10N.getFormatStr("charts.sizeKB", string);
-    },
-    time: value => {
-      let string = L10N.numberWithDecimals(value / 1000, REQUEST_TIME_DECIMALS);
-      return L10N.getFormatStr("charts.totalS", string);
-    }
-  },
-  _commonChartTotals: {
-    size: total => {
-      let string = L10N.numberWithDecimals(total / 1024, CONTENT_SIZE_DECIMALS);
-      return L10N.getFormatStr("charts.totalSize", string);
-    },
-    time: total => {
-      let seconds = total / 1000;
-      let string = L10N.numberWithDecimals(seconds, REQUEST_TIME_DECIMALS);
-      return PluralForm.get(seconds,
-        L10N.getStr("charts.totalSeconds")).replace("#1", string);
-    },
-    cached: total => {
-      return L10N.getFormatStr("charts.totalCached", total);
-    },
-    count: total => {
-      return L10N.getFormatStr("charts.totalCount", total);
-    }
-  },
-
-  /**
-   * Adds a specific chart to this container.
-   *
-   * @param object
-   *        An object containing all or some the following properties:
-   *          - id: either "#primed-cache-chart" or "#empty-cache-chart"
-   *          - title/data/strings/totals/sorted: @see Chart.jsm for details
-   */
-  _createChart: function ({ id, title, data, strings, totals, sorted }) {
-    let container = $(id);
-
-    // Nuke all existing charts of the specified type.
-    while (container.hasChildNodes()) {
-      container.firstChild.remove();
-    }
-
-    // Create a new chart.
-    let chart = Chart.PieTable(document, {
-      diameter: NETWORK_ANALYSIS_PIE_CHART_DIAMETER,
-      title: L10N.getStr(title),
-      data: data,
-      strings: strings,
-      totals: totals,
-      sorted: sorted
-    });
-
-    chart.on("click", (_, item) => {
-      // Reset FilterButtons and enable one filter exclusively
-      gStore.dispatch(Actions.enableFilterOnly(item.label));
-      NetMonitorView.showNetworkInspectorView();
-    });
-
-    container.appendChild(chart.node);
-  },
-
-  /**
-   * Sanitizes the data source used for creating charts, to follow the
-   * data format spec defined in Chart.jsm.
-   *
-   * @param array items
-   *        A collection of request items used as the data source for the chart.
-   * @param boolean emptyCache
-   *        True if the cache is considered enabled, false for disabled.
-   */
-  _sanitizeChartDataSource: function (items, emptyCache) {
-    let data = [
-      "html", "css", "js", "xhr", "fonts", "images", "media", "flash", "ws", "other"
-    ].map(e => ({
-      cached: 0,
-      count: 0,
-      label: e,
-      size: 0,
-      time: 0
-    }));
-
-    for (let requestItem of items) {
-      let details = requestItem.attachment;
-      let type;
-
-      if (Filters.html(details)) {
-        // "html"
-        type = 0;
-      } else if (Filters.css(details)) {
-        // "css"
-        type = 1;
-      } else if (Filters.js(details)) {
-        // "js"
-        type = 2;
-      } else if (Filters.fonts(details)) {
-        // "fonts"
-        type = 4;
-      } else if (Filters.images(details)) {
-        // "images"
-        type = 5;
-      } else if (Filters.media(details)) {
-        // "media"
-        type = 6;
-      } else if (Filters.flash(details)) {
-        // "flash"
-        type = 7;
-      } else if (Filters.ws(details)) {
-        // "ws"
-        type = 8;
-      } else if (Filters.xhr(details)) {
-        // Verify XHR last, to categorize other mime types in their own blobs.
-        // "xhr"
-        type = 3;
-      } else {
-        // "other"
-        type = 9;
-      }
-
-      if (emptyCache || !responseIsFresh(details)) {
-        data[type].time += details.totalTime || 0;
-        data[type].size += details.contentSize || 0;
-      } else {
-        data[type].cached++;
-      }
-      data[type].count++;
-    }
-
-    return data.filter(e => e.count > 0);
-  },
-};
-
-/**
  * DOM query helper.
+ * TODO: Move it into "dom-utils.js" module and "require" it when needed.
  */
 var $ = (selector, target = document) => target.querySelector(selector);
 var $all = (selector, target = document) => target.querySelectorAll(selector);
 
 /**
- * Checks if the "Expiration Calculations" defined in section 13.2.4 of the
- * "HTTP/1.1: Caching in HTTP" spec holds true for a collection of headers.
- *
- * @param object
- *        An object containing the { responseHeaders, status } properties.
- * @return boolean
- *         True if the response is fresh and loaded from cache.
- */
-function responseIsFresh({ responseHeaders, status }) {
-  // Check for a "304 Not Modified" status and response headers availability.
-  if (status != 304 || !responseHeaders) {
-    return false;
-  }
-
-  let list = responseHeaders.headers;
-  let cacheControl = list.filter(e => {
-    return e.name.toLowerCase() == "cache-control";
-  })[0];
-
-  let expires = list.filter(e => e.name.toLowerCase() == "expires")[0];
-
-  // Check the "Cache-Control" header for a maximum age value.
-  if (cacheControl) {
-    let maxAgeMatch =
-      cacheControl.value.match(/s-maxage\s*=\s*(\d+)/) ||
-      cacheControl.value.match(/max-age\s*=\s*(\d+)/);
-
-    if (maxAgeMatch && maxAgeMatch.pop() > 0) {
-      return true;
-    }
-  }
-
-  // Check the "Expires" header for a valid date.
-  if (expires && Date.parse(expires.value)) {
-    return true;
-  }
-
-  return false;
-}
-
-/**
  * Makes sure certain properties are available on all objects in a data store.
  *
  * @param array dataStore
  *        A list of objects for which to check the availability of properties.
  * @param array mandatoryFields
  *        A list of strings representing properties of objects in dataStore.
  * @return object
  *         A promise resolved when all objects in dataStore contain the
copy from devtools/client/netmonitor/netmonitor-view.js
copy to devtools/client/netmonitor/performance-statistics-view.js
--- a/devtools/client/netmonitor/netmonitor-view.js
+++ b/devtools/client/netmonitor/performance-statistics-view.js
@@ -1,1214 +1,43 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 /* import-globals-from ./netmonitor-controller.js */
-/* globals Prefs, gNetwork, setInterval, setTimeout, clearInterval, clearTimeout, btoa */
-/* exported $, $all */
+/* globals $ */
 "use strict";
 
-XPCOMUtils.defineLazyGetter(this, "NetworkHelper", function () {
-  return require("devtools/shared/webconsole/network-helper");
-});
-
-/* eslint-disable mozilla/reject-some-requires */
-const {VariablesView} = require("resource://devtools/client/shared/widgets/VariablesView.jsm");
-/* eslint-disable mozilla/reject-some-requires */
-const {VariablesViewController} = require("resource://devtools/client/shared/widgets/VariablesViewController.jsm");
-const {ToolSidebar} = require("devtools/client/framework/sidebar");
-const {testing: isTesting} = require("devtools/shared/flags");
-const {ViewHelpers, Heritage} = require("devtools/client/shared/widgets/view-helpers");
 const {PluralForm} = require("devtools/shared/plural-form");
 const {Filters} = require("./filter-predicates");
-const {getFormDataSections,
-       formDataURI,
-       getUriHostPort} = require("./request-utils");
 const {L10N} = require("./l10n");
-const {RequestsMenuView} = require("./requests-menu-view");
-const {CustomRequestView} = require("./custom-request-view");
-const {ToolbarView} = require("./toolbar-view");
-const {configureStore} = require("./store");
 const Actions = require("./actions/index");
 
-// Initialize the global redux variables
-var gStore = configureStore();
-
-// ms
-const WDA_DEFAULT_VERIFY_INTERVAL = 50;
-
-// Use longer timeout during testing as the tests need this process to succeed
-// and two seconds is quite short on slow debug builds. The timeout here should
-// be at least equal to the general mochitest timeout of 45 seconds so that this
-// never gets hit during testing.
-// ms
-const WDA_DEFAULT_GIVE_UP_TIMEOUT = isTesting ? 45000 : 2000;
-
-// 100 KB in bytes
-const SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE = 102400;
 const REQUEST_TIME_DECIMALS = 2;
-const HEADERS_SIZE_DECIMALS = 3;
 const CONTENT_SIZE_DECIMALS = 2;
-const CONTENT_MIME_TYPE_MAPPINGS = {
-  "/ecmascript": Editor.modes.js,
-  "/javascript": Editor.modes.js,
-  "/x-javascript": Editor.modes.js,
-  "/html": Editor.modes.html,
-  "/xhtml": Editor.modes.html,
-  "/xml": Editor.modes.html,
-  "/atom": Editor.modes.html,
-  "/soap": Editor.modes.html,
-  "/vnd.mpeg.dash.mpd": Editor.modes.html,
-  "/rdf": Editor.modes.css,
-  "/rss": Editor.modes.css,
-  "/css": Editor.modes.css
-};
 
-const DEFAULT_EDITOR_CONFIG = {
-  mode: Editor.modes.text,
-  readOnly: true,
-  lineNumbers: true
-};
-const GENERIC_VARIABLES_VIEW_SETTINGS = {
-  lazyEmpty: true,
-  // ms
-  lazyEmptyDelay: 10,
-  searchEnabled: true,
-  editableValueTooltip: "",
-  editableNameTooltip: "",
-  preventDisableOnChange: true,
-  preventDescriptorModifiers: true,
-  eval: () => {}
-};
 // px
 const NETWORK_ANALYSIS_PIE_CHART_DIAMETER = 200;
 
 /**
- * Object defining the network monitor view components.
- */
-var NetMonitorView = {
-  /**
-   * Initializes the network monitor view.
-   */
-  initialize: function () {
-    this._initializePanes();
-
-    this.Toolbar.initialize(gStore);
-    this.RequestsMenu.initialize(gStore);
-    this.NetworkDetails.initialize();
-    this.CustomRequest.initialize();
-  },
-
-  /**
-   * Destroys the network monitor view.
-   */
-  destroy: function () {
-    this._isDestroyed = true;
-    this.Toolbar.destroy();
-    this.RequestsMenu.destroy();
-    this.NetworkDetails.destroy();
-    this.CustomRequest.destroy();
-
-    this._destroyPanes();
-  },
-
-  /**
-   * Initializes the UI for all the displayed panes.
-   */
-  _initializePanes: function () {
-    dumpn("Initializing the NetMonitorView panes");
-
-    this._body = $("#body");
-    this._detailsPane = $("#details-pane");
-    this._detailsPaneToggleButton = $("#details-pane-toggle");
-
-    this._collapsePaneString = L10N.getStr("collapseDetailsPane");
-    this._expandPaneString = L10N.getStr("expandDetailsPane");
-
-    this._detailsPane.setAttribute("width", Prefs.networkDetailsWidth);
-    this._detailsPane.setAttribute("height", Prefs.networkDetailsHeight);
-    this.toggleDetailsPane({ visible: false });
-
-    // Disable the performance statistics mode.
-    if (!Prefs.statistics) {
-      $("#request-menu-context-perf").hidden = true;
-      $("#notice-perf-message").hidden = true;
-      $("#requests-menu-network-summary-button").hidden = true;
-    }
-  },
-
-  /**
-   * Destroys the UI for all the displayed panes.
-   */
-  _destroyPanes: Task.async(function* () {
-    dumpn("Destroying the NetMonitorView panes");
-
-    Prefs.networkDetailsWidth = this._detailsPane.getAttribute("width");
-    Prefs.networkDetailsHeight = this._detailsPane.getAttribute("height");
-
-    this._detailsPane = null;
-    this._detailsPaneToggleButton = null;
-
-    for (let p of this._editorPromises.values()) {
-      let editor = yield p;
-      editor.destroy();
-    }
-  }),
-
-  /**
-   * Gets the visibility state of the network details pane.
-   * @return boolean
-   */
-  get detailsPaneHidden() {
-    return this._detailsPane.classList.contains("pane-collapsed");
-  },
-
-  /**
-   * Sets the network details pane hidden or visible.
-   *
-   * @param object flags
-   *        An object containing some of the following properties:
-   *        - visible: true if the pane should be shown, false to hide
-   *        - animated: true to display an animation on toggle
-   *        - delayed: true to wait a few cycles before toggle
-   *        - callback: a function to invoke when the toggle finishes
-   * @param number tabIndex [optional]
-   *        The index of the intended selected tab in the details pane.
-   */
-  toggleDetailsPane: function (flags, tabIndex) {
-    let pane = this._detailsPane;
-    let button = this._detailsPaneToggleButton;
-
-    ViewHelpers.togglePane(flags, pane);
-
-    if (flags.visible) {
-      this._body.classList.remove("pane-collapsed");
-      button.classList.remove("pane-collapsed");
-      button.setAttribute("tooltiptext", this._collapsePaneString);
-    } else {
-      this._body.classList.add("pane-collapsed");
-      button.classList.add("pane-collapsed");
-      button.setAttribute("tooltiptext", this._expandPaneString);
-    }
-
-    if (tabIndex !== undefined) {
-      $("#event-details-pane").selectedIndex = tabIndex;
-    }
-  },
-
-  /**
-   * Gets the current mode for this tool.
-   * @return string (e.g, "network-inspector-view" or "network-statistics-view")
-   */
-  get currentFrontendMode() {
-    // The getter may be called from a timeout after the panel is destroyed.
-    if (!this._body.selectedPanel) {
-      return null;
-    }
-    return this._body.selectedPanel.id;
-  },
-
-  /**
-   * Toggles between the frontend view modes ("Inspector" vs. "Statistics").
-   */
-  toggleFrontendMode: function () {
-    if (this.currentFrontendMode != "network-inspector-view") {
-      this.showNetworkInspectorView();
-    } else {
-      this.showNetworkStatisticsView();
-    }
-  },
-
-  /**
-   * Switches to the "Inspector" frontend view mode.
-   */
-  showNetworkInspectorView: function () {
-    this._body.selectedPanel = $("#network-inspector-view");
-    this.RequestsMenu._flushWaterfallViews(true);
-  },
-
-  /**
-   * Switches to the "Statistics" frontend view mode.
-   */
-  showNetworkStatisticsView: function () {
-    this._body.selectedPanel = $("#network-statistics-view");
-
-    let controller = NetMonitorController;
-    let requestsView = this.RequestsMenu;
-    let statisticsView = this.PerformanceStatistics;
-
-    Task.spawn(function* () {
-      statisticsView.displayPlaceholderCharts();
-      yield controller.triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_ENABLED);
-
-      try {
-        // • The response headers and status code are required for determining
-        // whether a response is "fresh" (cacheable).
-        // • The response content size and request total time are necessary for
-        // populating the statistics view.
-        // • The response mime type is used for categorization.
-        yield whenDataAvailable(requestsView.attachments, [
-          "responseHeaders", "status", "contentSize", "mimeType", "totalTime"
-        ]);
-      } catch (ex) {
-        // Timed out while waiting for data. Continue with what we have.
-        console.error(ex);
-      }
-
-      statisticsView.createPrimedCacheChart(requestsView.items);
-      statisticsView.createEmptyCacheChart(requestsView.items);
-    });
-  },
-
-  reloadPage: function () {
-    NetMonitorController.triggerActivity(
-      ACTIVITY_TYPE.RELOAD.WITH_CACHE_DEFAULT);
-  },
-
-  /**
-   * Lazily initializes and returns a promise for a Editor instance.
-   *
-   * @param string id
-   *        The id of the editor placeholder node.
-   * @return object
-   *         A promise that is resolved when the editor is available.
-   */
-  editor: function (id) {
-    dumpn("Getting a NetMonitorView editor: " + id);
-
-    if (this._editorPromises.has(id)) {
-      return this._editorPromises.get(id);
-    }
-
-    let deferred = promise.defer();
-    this._editorPromises.set(id, deferred.promise);
-
-    // Initialize the source editor and store the newly created instance
-    // in the ether of a resolved promise's value.
-    let editor = new Editor(DEFAULT_EDITOR_CONFIG);
-    editor.appendTo($(id)).then(() => deferred.resolve(editor));
-
-    return deferred.promise;
-  },
-
-  _body: null,
-  _detailsPane: null,
-  _detailsPaneToggleButton: null,
-  _collapsePaneString: "",
-  _expandPaneString: "",
-  _editorPromises: new Map()
-};
-
-/**
- * Functions handling the sidebar details view.
- */
-function SidebarView() {
-  dumpn("SidebarView was instantiated");
-}
-
-SidebarView.prototype = {
-  /**
-   * Sets this view hidden or visible. It's visible by default.
-   *
-   * @param boolean visibleFlag
-   *        Specifies the intended visibility.
-   */
-  toggle: function (visibleFlag) {
-    NetMonitorView.toggleDetailsPane({ visible: visibleFlag });
-    NetMonitorView.RequestsMenu._flushWaterfallViews(true);
-  },
-
-  /**
-   * Populates this view with the specified data.
-   *
-   * @param object data
-   *        The data source (this should be the attachment of a request item).
-   * @return object
-   *        Returns a promise that resolves upon population of the subview.
-   */
-  populate: Task.async(function* (data) {
-    let isCustom = data.isCustom;
-    let view = isCustom ?
-      NetMonitorView.CustomRequest :
-      NetMonitorView.NetworkDetails;
-
-    yield view.populate(data);
-    $("#details-pane").selectedIndex = isCustom ? 0 : 1;
-
-    window.emit(EVENTS.SIDEBAR_POPULATED);
-  })
-};
-
-/**
- * Functions handling the requests details view.
- */
-function NetworkDetailsView() {
-  dumpn("NetworkDetailsView was instantiated");
-
-  // The ToolSidebar requires the panel object to be able to emit events.
-  EventEmitter.decorate(this);
-
-  this._onTabSelect = this._onTabSelect.bind(this);
-}
-
-NetworkDetailsView.prototype = {
-  /**
-   * An object containing the state of tabs.
-   */
-  _viewState: {
-    // if updating[tab] is true a task is currently updating the given tab.
-    updating: [],
-    // if dirty[tab] is true, the tab needs to be repopulated once current
-    // update task finishes
-    dirty: [],
-    // the most recently received attachment data for the request
-    latestData: null,
-  },
-
-  /**
-   * Initialization function, called when the network monitor is started.
-   */
-  initialize: function () {
-    dumpn("Initializing the NetworkDetailsView");
-
-    this.widget = $("#event-details-pane");
-    this.sidebar = new ToolSidebar(this.widget, this, "netmonitor", {
-      disableTelemetry: true,
-      showAllTabsMenu: true
-    });
-
-    this._headers = new VariablesView($("#all-headers"),
-      Heritage.extend(GENERIC_VARIABLES_VIEW_SETTINGS, {
-        emptyText: L10N.getStr("headersEmptyText"),
-        searchPlaceholder: L10N.getStr("headersFilterText")
-      }));
-    this._cookies = new VariablesView($("#all-cookies"),
-      Heritage.extend(GENERIC_VARIABLES_VIEW_SETTINGS, {
-        emptyText: L10N.getStr("cookiesEmptyText"),
-        searchPlaceholder: L10N.getStr("cookiesFilterText")
-      }));
-    this._params = new VariablesView($("#request-params"),
-      Heritage.extend(GENERIC_VARIABLES_VIEW_SETTINGS, {
-        emptyText: L10N.getStr("paramsEmptyText"),
-        searchPlaceholder: L10N.getStr("paramsFilterText")
-      }));
-    this._json = new VariablesView($("#response-content-json"),
-      Heritage.extend(GENERIC_VARIABLES_VIEW_SETTINGS, {
-        onlyEnumVisible: true,
-        searchPlaceholder: L10N.getStr("jsonFilterText")
-      }));
-    VariablesViewController.attach(this._json);
-
-    this._paramsQueryString = L10N.getStr("paramsQueryString");
-    this._paramsFormData = L10N.getStr("paramsFormData");
-    this._paramsPostPayload = L10N.getStr("paramsPostPayload");
-    this._requestHeaders = L10N.getStr("requestHeaders");
-    this._requestHeadersFromUpload = L10N.getStr("requestHeadersFromUpload");
-    this._responseHeaders = L10N.getStr("responseHeaders");
-    this._requestCookies = L10N.getStr("requestCookies");
-    this._responseCookies = L10N.getStr("responseCookies");
-
-    $("tabpanels", this.widget).addEventListener("select", this._onTabSelect);
-  },
-
-  /**
-   * Destruction function, called when the network monitor is closed.
-   */
-  destroy: function () {
-    dumpn("Destroying the NetworkDetailsView");
-    this.sidebar.destroy();
-    $("tabpanels", this.widget).removeEventListener("select",
-      this._onTabSelect);
-  },
-
-  /**
-   * Populates this view with the specified data.
-   *
-   * @param object data
-   *        The data source (this should be the attachment of a request item).
-   * @return object
-   *        Returns a promise that resolves upon population the view.
-   */
-  populate: function (data) {
-    $("#request-params-box").setAttribute("flex", "1");
-    $("#request-params-box").hidden = false;
-    $("#request-post-data-textarea-box").hidden = true;
-    $("#response-content-info-header").hidden = true;
-    $("#response-content-json-box").hidden = true;
-    $("#response-content-textarea-box").hidden = true;
-    $("#raw-headers").hidden = true;
-    $("#response-content-image-box").hidden = true;
-
-    let isHtml = Filters.html(data);
-
-    // Show the "Preview" tabpanel only for plain HTML responses.
-    this.sidebar.toggleTab(isHtml, "preview-tab");
-
-    // Show the "Security" tab only for requests that
-    //   1) are https (state != insecure)
-    //   2) come from a target that provides security information.
-    let hasSecurityInfo = data.securityState &&
-                          data.securityState !== "insecure";
-    this.sidebar.toggleTab(hasSecurityInfo, "security-tab");
-
-    // Switch to the "Headers" tabpanel if the "Preview" previously selected
-    // and this is not an HTML response or "Security" was selected but this
-    // request has no security information.
-
-    if (!isHtml && this.widget.selectedPanel === $("#preview-tabpanel") ||
-        !hasSecurityInfo && this.widget.selectedPanel ===
-          $("#security-tabpanel")) {
-      this.widget.selectedIndex = 0;
-    }
-
-    this._headers.empty();
-    this._cookies.empty();
-    this._params.empty();
-    this._json.empty();
-
-    this._dataSrc = { src: data, populated: [] };
-    this._onTabSelect();
-    window.emit(EVENTS.NETWORKDETAILSVIEW_POPULATED);
-
-    return promise.resolve();
-  },
-
-  /**
-   * Listener handling the tab selection event.
-   */
-  _onTabSelect: function () {
-    let { src, populated } = this._dataSrc || {};
-    let tab = this.widget.selectedIndex;
-    let view = this;
-
-    // Make sure the data source is valid and don't populate the same tab twice.
-    if (!src || populated[tab]) {
-      return;
-    }
-
-    let viewState = this._viewState;
-    if (viewState.updating[tab]) {
-      // A task is currently updating this tab. If we started another update
-      // task now it would result in a duplicated content as described in bugs
-      // 997065 and 984687. As there's no way to stop the current task mark the
-      // tab dirty and refresh the panel once the current task finishes.
-      viewState.dirty[tab] = true;
-      viewState.latestData = src;
-      return;
-    }
-
-    Task.spawn(function* () {
-      viewState.updating[tab] = true;
-      switch (tab) {
-        // "Headers"
-        case 0:
-          yield view._setSummary(src);
-          yield view._setResponseHeaders(src.responseHeaders);
-          yield view._setRequestHeaders(
-            src.requestHeaders,
-            src.requestHeadersFromUploadStream);
-          break;
-        // "Cookies"
-        case 1:
-          yield view._setResponseCookies(src.responseCookies);
-          yield view._setRequestCookies(src.requestCookies);
-          break;
-        // "Params"
-        case 2:
-          yield view._setRequestGetParams(src.url);
-          yield view._setRequestPostParams(
-            src.requestHeaders,
-            src.requestHeadersFromUploadStream,
-            src.requestPostData);
-          break;
-        // "Response"
-        case 3:
-          yield view._setResponseBody(src.url, src.responseContent);
-          break;
-        // "Timings"
-        case 4:
-          yield view._setTimingsInformation(src.eventTimings);
-          break;
-        // "Security"
-        case 5:
-          yield view._setSecurityInfo(src.securityInfo, src.url);
-          break;
-        // "Preview"
-        case 6:
-          yield view._setHtmlPreview(src.responseContent);
-          break;
-      }
-      viewState.updating[tab] = false;
-    }).then(() => {
-      if (tab == this.widget.selectedIndex) {
-        if (viewState.dirty[tab]) {
-          // The request information was updated while the task was running.
-          viewState.dirty[tab] = false;
-          view.populate(viewState.latestData);
-        } else {
-          // Tab is selected but not dirty. We're done here.
-          populated[tab] = true;
-          window.emit(EVENTS.TAB_UPDATED);
-
-          if (NetMonitorController.isConnected()) {
-            NetMonitorView.RequestsMenu.ensureSelectedItemIsVisible();
-          }
-        }
-      } else if (viewState.dirty[tab]) {
-        // Tab is dirty but no longer selected. Don't refresh it now, it'll be
-        // done if the tab is shown again.
-        viewState.dirty[tab] = false;
-      }
-    }, e => console.error(e));
-  },
-
-  /**
-   * Sets the network request summary shown in this view.
-   *
-   * @param object data
-   *        The data source (this should be the attachment of a request item).
-   */
-  _setSummary: function (data) {
-    if (data.url) {
-      let unicodeUrl = NetworkHelper.convertToUnicode(unescape(data.url));
-      $("#headers-summary-url-value").setAttribute("value", unicodeUrl);
-      $("#headers-summary-url-value").setAttribute("tooltiptext", unicodeUrl);
-      $("#headers-summary-url").removeAttribute("hidden");
-    } else {
-      $("#headers-summary-url").setAttribute("hidden", "true");
-    }
-
-    if (data.method) {
-      $("#headers-summary-method-value").setAttribute("value", data.method);
-      $("#headers-summary-method").removeAttribute("hidden");
-    } else {
-      $("#headers-summary-method").setAttribute("hidden", "true");
-    }
-
-    if (data.remoteAddress) {
-      let address = data.remoteAddress;
-      if (address.indexOf(":") != -1) {
-        address = `[${address}]`;
-      }
-      if (data.remotePort) {
-        address += `:${data.remotePort}`;
-      }
-      $("#headers-summary-address-value").setAttribute("value", address);
-      $("#headers-summary-address-value").setAttribute("tooltiptext", address);
-      $("#headers-summary-address").removeAttribute("hidden");
-    } else {
-      $("#headers-summary-address").setAttribute("hidden", "true");
-    }
-
-    if (data.status) {
-      // "code" attribute is only used by css to determine the icon color
-      let code;
-      if (data.fromCache) {
-        code = "cached";
-      } else if (data.fromServiceWorker) {
-        code = "service worker";
-      } else {
-        code = data.status;
-      }
-      $("#headers-summary-status-circle").setAttribute("code", code);
-      $("#headers-summary-status-value").setAttribute("value",
-        data.status + " " + data.statusText);
-      $("#headers-summary-status").removeAttribute("hidden");
-    } else {
-      $("#headers-summary-status").setAttribute("hidden", "true");
-    }
-
-    if (data.httpVersion) {
-      $("#headers-summary-version-value").setAttribute("value",
-        data.httpVersion);
-      $("#headers-summary-version").removeAttribute("hidden");
-    } else {
-      $("#headers-summary-version").setAttribute("hidden", "true");
-    }
-  },
-
-  /**
-   * Sets the network request headers shown in this view.
-   *
-   * @param object headers
-   *        The "requestHeaders" message received from the server.
-   * @param object uploadHeaders
-   *        The "requestHeadersFromUploadStream" inferred from the POST payload.
-   * @return object
-   *        A promise that resolves when request headers are set.
-   */
-  _setRequestHeaders: Task.async(function* (headers, uploadHeaders) {
-    if (headers && headers.headers.length) {
-      yield this._addHeaders(this._requestHeaders, headers);
-    }
-    if (uploadHeaders && uploadHeaders.headers.length) {
-      yield this._addHeaders(this._requestHeadersFromUpload, uploadHeaders);
-    }
-  }),
-
-  /**
-   * Sets the network response headers shown in this view.
-   *
-   * @param object response
-   *        The message received from the server.
-   * @return object
-   *        A promise that resolves when response headers are set.
-   */
-  _setResponseHeaders: Task.async(function* (response) {
-    if (response && response.headers.length) {
-      response.headers.sort((a, b) => a.name > b.name);
-      yield this._addHeaders(this._responseHeaders, response);
-    }
-  }),
-
-  /**
-   * Populates the headers container in this view with the specified data.
-   *
-   * @param string name
-   *        The type of headers to populate (request or response).
-   * @param object response
-   *        The message received from the server.
-   * @return object
-   *        A promise that resolves when headers are added.
-   */
-  _addHeaders: Task.async(function* (name, response) {
-    let kb = response.headersSize / 1024;
-    let size = L10N.numberWithDecimals(kb, HEADERS_SIZE_DECIMALS);
-    let text = L10N.getFormatStr("networkMenu.sizeKB", size);
-
-    let headersScope = this._headers.addScope(name + " (" + text + ")");
-    headersScope.expanded = true;
-
-    for (let header of response.headers) {
-      let headerVar = headersScope.addItem(header.name, {}, {relaxed: true});
-      let headerValue = yield gNetwork.getString(header.value);
-      headerVar.setGrip(headerValue);
-    }
-  }),
-
-  /**
-   * Sets the network request cookies shown in this view.
-   *
-   * @param object response
-   *        The message received from the server.
-   * @return object
-   *        A promise that is resolved when the request cookies are set.
-   */
-  _setRequestCookies: Task.async(function* (response) {
-    if (response && response.cookies.length) {
-      response.cookies.sort((a, b) => a.name > b.name);
-      yield this._addCookies(this._requestCookies, response);
-    }
-  }),
-
-  /**
-   * Sets the network response cookies shown in this view.
-   *
-   * @param object response
-   *        The message received from the server.
-   * @return object
-   *        A promise that is resolved when the response cookies are set.
-   */
-  _setResponseCookies: Task.async(function* (response) {
-    if (response && response.cookies.length) {
-      yield this._addCookies(this._responseCookies, response);
-    }
-  }),
-
-  /**
-   * Populates the cookies container in this view with the specified data.
-   *
-   * @param string name
-   *        The type of cookies to populate (request or response).
-   * @param object response
-   *        The message received from the server.
-   * @return object
-   *        Returns a promise that resolves upon the adding of cookies.
-   */
-  _addCookies: Task.async(function* (name, response) {
-    let cookiesScope = this._cookies.addScope(name);
-    cookiesScope.expanded = true;
-
-    for (let cookie of response.cookies) {
-      let cookieVar = cookiesScope.addItem(cookie.name, {}, {relaxed: true});
-      let cookieValue = yield gNetwork.getString(cookie.value);
-      cookieVar.setGrip(cookieValue);
-
-      // By default the cookie name and value are shown. If this is the only
-      // information available, then nothing else is to be displayed.
-      let cookieProps = Object.keys(cookie);
-      if (cookieProps.length == 2) {
-        continue;
-      }
-
-      // Display any other information other than the cookie name and value
-      // which may be available.
-      let rawObject = Object.create(null);
-      let otherProps = cookieProps.filter(e => e != "name" && e != "value");
-      for (let prop of otherProps) {
-        rawObject[prop] = cookie[prop];
-      }
-      cookieVar.populate(rawObject);
-      cookieVar.twisty = true;
-      cookieVar.expanded = true;
-    }
-  }),
-
-  /**
-   * Sets the network request get params shown in this view.
-   *
-   * @param string url
-   *        The request's url.
-   */
-  _setRequestGetParams: function (url) {
-    let query = NetworkHelper.nsIURL(url).query;
-    if (query) {
-      this._addParams(this._paramsQueryString, query);
-    }
-  },
-
-  /**
-   * Sets the network request post params shown in this view.
-   *
-   * @param object headers
-   *        The "requestHeaders" message received from the server.
-   * @param object uploadHeaders
-   *        The "requestHeadersFromUploadStream" inferred from the POST payload.
-   * @param object postData
-   *        The "requestPostData" message received from the server.
-   * @return object
-   *        A promise that is resolved when the request post params are set.
-   */
-  _setRequestPostParams: Task.async(function* (headers, uploadHeaders,
-    postData) {
-    if (!headers || !uploadHeaders || !postData) {
-      return;
-    }
-
-    let formDataSections = yield getFormDataSections(
-      headers,
-      uploadHeaders,
-      postData,
-      gNetwork.getString.bind(gNetwork));
-
-    this._params.onlyEnumVisible = false;
-
-    // Handle urlencoded form data sections (e.g. "?foo=bar&baz=42").
-    if (formDataSections.length > 0) {
-      formDataSections.forEach(section => {
-        this._addParams(this._paramsFormData, section);
-      });
-    } else {
-      // Handle JSON and actual forms ("multipart/form-data" content type).
-      let postDataLongString = postData.postData.text;
-      let text = yield gNetwork.getString(postDataLongString);
-      let jsonVal = null;
-      try {
-        jsonVal = JSON.parse(text);
-      } catch (ex) { // eslint-disable-line
-      }
-
-      if (jsonVal) {
-        this._params.onlyEnumVisible = true;
-        let jsonScopeName = L10N.getStr("jsonScopeName");
-        let jsonScope = this._params.addScope(jsonScopeName);
-        jsonScope.expanded = true;
-        let jsonItem = jsonScope.addItem(undefined, { enumerable: true });
-        jsonItem.populate(jsonVal, { sorted: true });
-      } else {
-        // This is really awkward, but hey, it works. Let's show an empty
-        // scope in the params view and place the source editor containing
-        // the raw post data directly underneath.
-        $("#request-params-box").removeAttribute("flex");
-        let paramsScope = this._params.addScope(this._paramsPostPayload);
-        paramsScope.expanded = true;
-        paramsScope.locked = true;
-
-        $("#request-post-data-textarea-box").hidden = false;
-        let editor = yield NetMonitorView.editor("#request-post-data-textarea");
-        editor.setMode(Editor.modes.text);
-        editor.setText(text);
-      }
-    }
-
-    window.emit(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
-  }),
-
-  /**
-   * Populates the params container in this view with the specified data.
-   *
-   * @param string name
-   *        The type of params to populate (get or post).
-   * @param string queryString
-   *        A query string of params (e.g. "?foo=bar&baz=42").
-   */
-  _addParams: function (name, queryString) {
-    let paramsArray = NetworkHelper.parseQueryString(queryString);
-    if (!paramsArray) {
-      return;
-    }
-    let paramsScope = this._params.addScope(name);
-    paramsScope.expanded = true;
-
-    for (let param of paramsArray) {
-      let paramVar = paramsScope.addItem(param.name, {}, {relaxed: true});
-      paramVar.setGrip(param.value);
-    }
-  },
-
-  /**
-   * Sets the network response body shown in this view.
-   *
-   * @param string url
-   *        The request's url.
-   * @param object response
-   *        The message received from the server.
-   * @return object
-   *         A promise that is resolved when the response body is set.
-   */
-  _setResponseBody: Task.async(function* (url, response) {
-    if (!response) {
-      return;
-    }
-    let { mimeType, text, encoding } = response.content;
-    let responseBody = yield gNetwork.getString(text);
-
-    // Handle json, which we tentatively identify by checking the MIME type
-    // for "json" after any word boundary. This works for the standard
-    // "application/json", and also for custom types like "x-bigcorp-json".
-    // Additionally, we also directly parse the response text content to
-    // verify whether it's json or not, to handle responses incorrectly
-    // labeled as text/plain instead.
-    let jsonMimeType, jsonObject, jsonObjectParseError;
-    try {
-      jsonMimeType = /\bjson/.test(mimeType);
-      jsonObject = JSON.parse(responseBody);
-    } catch (e) {
-      jsonObjectParseError = e;
-    }
-    if (jsonMimeType || jsonObject) {
-      // Extract the actual json substring in case this might be a "JSONP".
-      // This regex basically parses a function call and captures the
-      // function name and arguments in two separate groups.
-      let jsonpRegex = /^\s*([\w$]+)\s*\(\s*([^]*)\s*\)\s*;?\s*$/;
-      let [_, callbackPadding, jsonpString] = // eslint-disable-line
-        responseBody.match(jsonpRegex) || [];
-
-      // Make sure this is a valid JSON object first. If so, nicely display
-      // the parsing results in a variables view. Otherwise, simply show
-      // the contents as plain text.
-      if (callbackPadding && jsonpString) {
-        try {
-          jsonObject = JSON.parse(jsonpString);
-        } catch (e) {
-          jsonObjectParseError = e;
-        }
-      }
-
-      // Valid JSON or JSONP.
-      if (jsonObject) {
-        $("#response-content-json-box").hidden = false;
-        let jsonScopeName = callbackPadding
-          ? L10N.getFormatStr("jsonpScopeName", callbackPadding)
-          : L10N.getStr("jsonScopeName");
-
-        let jsonVar = { label: jsonScopeName, rawObject: jsonObject };
-        yield this._json.controller.setSingleVariable(jsonVar).expanded;
-      } else {
-        // Malformed JSON.
-        $("#response-content-textarea-box").hidden = false;
-        let infoHeader = $("#response-content-info-header");
-        infoHeader.setAttribute("value", jsonObjectParseError);
-        infoHeader.setAttribute("tooltiptext", jsonObjectParseError);
-        infoHeader.hidden = false;
-
-        let editor = yield NetMonitorView.editor("#response-content-textarea");
-        editor.setMode(Editor.modes.js);
-        editor.setText(responseBody);
-      }
-    } else if (mimeType.includes("image/")) {
-      // Handle images.
-      $("#response-content-image-box").setAttribute("align", "center");
-      $("#response-content-image-box").setAttribute("pack", "center");
-      $("#response-content-image-box").hidden = false;
-      $("#response-content-image").src = formDataURI(mimeType, encoding, responseBody);
-
-      // Immediately display additional information about the image:
-      // file name, mime type and encoding.
-      $("#response-content-image-name-value").setAttribute("value",
-        NetworkHelper.nsIURL(url).fileName);
-      $("#response-content-image-mime-value").setAttribute("value", mimeType);
-
-      // Wait for the image to load in order to display the width and height.
-      $("#response-content-image").onload = e => {
-        // XUL images are majestic so they don't bother storing their dimensions
-        // in width and height attributes like the rest of the folk. Hack around
-        // this by getting the bounding client rect and subtracting the margins.
-        let { width, height } = e.target.getBoundingClientRect();
-        let dimensions = (width - 2) + " \u00D7 " + (height - 2);
-        $("#response-content-image-dimensions-value").setAttribute("value",
-          dimensions);
-      };
-    } else {
-      $("#response-content-textarea-box").hidden = false;
-      let editor = yield NetMonitorView.editor("#response-content-textarea");
-      editor.setMode(Editor.modes.text);
-      editor.setText(responseBody);
-
-      // Maybe set a more appropriate mode in the Source Editor if possible,
-      // but avoid doing this for very large files.
-      if (responseBody.length < SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE) {
-        let mapping = Object.keys(CONTENT_MIME_TYPE_MAPPINGS).find(key => {
-          return mimeType.includes(key);
-        });
-
-        if (mapping) {
-          editor.setMode(CONTENT_MIME_TYPE_MAPPINGS[mapping]);
-        }
-      }
-    }
-
-    window.emit(EVENTS.RESPONSE_BODY_DISPLAYED);
-  }),
-
-  /**
-   * Sets the timings information shown in this view.
-   *
-   * @param object response
-   *        The message received from the server.
-   */
-  _setTimingsInformation: function (response) {
-    if (!response) {
-      return;
-    }
-    let { blocked, dns, connect, send, wait, receive } = response.timings;
-
-    let tabboxWidth = $("#details-pane").getAttribute("width");
-
-    // Other nodes also take some space.
-    let availableWidth = tabboxWidth / 2;
-    let scale = (response.totalTime > 0 ?
-                 Math.max(availableWidth / response.totalTime, 0) :
-                 0);
-
-    $("#timings-summary-blocked .requests-menu-timings-box")
-      .setAttribute("width", blocked * scale);
-    $("#timings-summary-blocked .requests-menu-timings-total")
-      .setAttribute("value", L10N.getFormatStr("networkMenu.totalMS", blocked));
-
-    $("#timings-summary-dns .requests-menu-timings-box")
-      .setAttribute("width", dns * scale);
-    $("#timings-summary-dns .requests-menu-timings-total")
-      .setAttribute("value", L10N.getFormatStr("networkMenu.totalMS", dns));
-
-    $("#timings-summary-connect .requests-menu-timings-box")
-      .setAttribute("width", connect * scale);
-    $("#timings-summary-connect .requests-menu-timings-total")
-      .setAttribute("value", L10N.getFormatStr("networkMenu.totalMS", connect));
-
-    $("#timings-summary-send .requests-menu-timings-box")
-      .setAttribute("width", send * scale);
-    $("#timings-summary-send .requests-menu-timings-total")
-      .setAttribute("value", L10N.getFormatStr("networkMenu.totalMS", send));
-
-    $("#timings-summary-wait .requests-menu-timings-box")
-      .setAttribute("width", wait * scale);
-    $("#timings-summary-wait .requests-menu-timings-total")
-      .setAttribute("value", L10N.getFormatStr("networkMenu.totalMS", wait));
-
-    $("#timings-summary-receive .requests-menu-timings-box")
-      .setAttribute("width", receive * scale);
-    $("#timings-summary-receive .requests-menu-timings-total")
-      .setAttribute("value", L10N.getFormatStr("networkMenu.totalMS", receive));
-
-    $("#timings-summary-dns .requests-menu-timings-box")
-      .style.transform = "translateX(" + (scale * blocked) + "px)";
-    $("#timings-summary-connect .requests-menu-timings-box")
-      .style.transform = "translateX(" + (scale * (blocked + dns)) + "px)";
-    $("#timings-summary-send .requests-menu-timings-box")
-      .style.transform =
-        "translateX(" + (scale * (blocked + dns + connect)) + "px)";
-    $("#timings-summary-wait .requests-menu-timings-box")
-      .style.transform =
-        "translateX(" + (scale * (blocked + dns + connect + send)) + "px)";
-    $("#timings-summary-receive .requests-menu-timings-box")
-      .style.transform =
-        "translateX(" + (scale * (blocked + dns + connect + send + wait)) +
-          "px)";
-
-    $("#timings-summary-dns .requests-menu-timings-total")
-      .style.transform = "translateX(" + (scale * blocked) + "px)";
-    $("#timings-summary-connect .requests-menu-timings-total")
-      .style.transform = "translateX(" + (scale * (blocked + dns)) + "px)";
-    $("#timings-summary-send .requests-menu-timings-total")
-      .style.transform =
-        "translateX(" + (scale * (blocked + dns + connect)) + "px)";
-    $("#timings-summary-wait .requests-menu-timings-total")
-      .style.transform =
-        "translateX(" + (scale * (blocked + dns + connect + send)) + "px)";
-    $("#timings-summary-receive .requests-menu-timings-total")
-      .style.transform =
-        "translateX(" + (scale * (blocked + dns + connect + send + wait)) +
-         "px)";
-  },
-
-  /**
-   * Sets the preview for HTML responses shown in this view.
-   *
-   * @param object response
-   *        The message received from the server.
-   * @return object
-   *        A promise that is resolved when the html preview is rendered.
-   */
-  _setHtmlPreview: Task.async(function* (response) {
-    if (!response) {
-      return promise.resolve();
-    }
-    let { text } = response.content;
-    let responseBody = yield gNetwork.getString(text);
-
-    // Always disable JS when previewing HTML responses.
-    let iframe = $("#response-preview");
-    iframe.contentDocument.docShell.allowJavascript = false;
-    iframe.contentDocument.documentElement.innerHTML = responseBody;
-
-    window.emit(EVENTS.RESPONSE_HTML_PREVIEW_DISPLAYED);
-    return undefined;
-  }),
-
-  /**
-   * Sets the security information shown in this view.
-   *
-   * @param object securityInfo
-   *        The data received from server
-   * @param string url
-   *        The URL of this request
-   * @return object
-   *        A promise that is resolved when the security info is rendered.
-   */
-  _setSecurityInfo: Task.async(function* (securityInfo, url) {
-    if (!securityInfo) {
-      // We don't have security info. This could mean one of two things:
-      // 1) This connection is not secure and this tab is not visible and thus
-      //    we shouldn't be here.
-      // 2) We have already received securityState and the tab is visible BUT
-      //    the rest of the information is still on its way. Once it arrives
-      //    this method is called again.
-      return;
-    }
-
-    /**
-     * A helper that sets value and tooltiptext attributes of an element to
-     * specified value.
-     *
-     * @param string selector
-     *        A selector for the element.
-     * @param string value
-     *        The value to set. If this evaluates to false a placeholder string
-     *        <Not Available> is used instead.
-     */
-    function setValue(selector, value) {
-      let label = $(selector);
-      if (!value) {
-        label.setAttribute("value", L10N.getStr(
-          "netmonitor.security.notAvailable"));
-        label.setAttribute("tooltiptext", label.getAttribute("value"));
-      } else {
-        label.setAttribute("value", value);
-        label.setAttribute("tooltiptext", value);
-      }
-    }
-
-    let errorbox = $("#security-error");
-    let infobox = $("#security-information");
-
-    if (securityInfo.state === "secure" || securityInfo.state === "weak") {
-      infobox.hidden = false;
-      errorbox.hidden = true;
-
-      // Warning icons
-      let cipher = $("#security-warning-cipher");
-
-      if (securityInfo.state === "weak") {
-        cipher.hidden = securityInfo.weaknessReasons.indexOf("cipher") === -1;
-      } else {
-        cipher.hidden = true;
-      }
-
-      let enabledLabel = L10N.getStr("netmonitor.security.enabled");
-      let disabledLabel = L10N.getStr("netmonitor.security.disabled");
-
-      // Connection parameters
-      setValue("#security-protocol-version-value",
-        securityInfo.protocolVersion);
-      setValue("#security-ciphersuite-value", securityInfo.cipherSuite);
-
-      // Host header
-      let domain = getUriHostPort(url);
-      let hostHeader = L10N.getFormatStr("netmonitor.security.hostHeader",
-        domain);
-      setValue("#security-info-host-header", hostHeader);
-
-      // Parameters related to the domain
-      setValue("#security-http-strict-transport-security-value",
-                securityInfo.hsts ? enabledLabel : disabledLabel);
-
-      setValue("#security-public-key-pinning-value",
-                securityInfo.hpkp ? enabledLabel : disabledLabel);
-
-      // Certificate parameters
-      let cert = securityInfo.cert;
-      setValue("#security-cert-subject-cn", cert.subject.commonName);
-      setValue("#security-cert-subject-o", cert.subject.organization);
-      setValue("#security-cert-subject-ou", cert.subject.organizationalUnit);
-
-      setValue("#security-cert-issuer-cn", cert.issuer.commonName);
-      setValue("#security-cert-issuer-o", cert.issuer.organization);
-      setValue("#security-cert-issuer-ou", cert.issuer.organizationalUnit);
-
-      setValue("#security-cert-validity-begins", cert.validity.start);
-      setValue("#security-cert-validity-expires", cert.validity.end);
-
-      setValue("#security-cert-sha1-fingerprint", cert.fingerprint.sha1);
-      setValue("#security-cert-sha256-fingerprint", cert.fingerprint.sha256);
-    } else {
-      infobox.hidden = true;
-      errorbox.hidden = false;
-
-      // Strip any HTML from the message.
-      let plain = new DOMParser().parseFromString(securityInfo.errorMessage,
-        "text/html");
-      setValue("#security-error-message", plain.body.textContent);
-    }
-  }),
-
-  _dataSrc: null,
-  _headers: null,
-  _cookies: null,
-  _params: null,
-  _json: null,
-  _paramsQueryString: "",
-  _paramsFormData: "",
-  _paramsPostPayload: "",
-  _requestHeaders: "",
-  _responseHeaders: "",
-  _requestCookies: "",
-  _responseCookies: ""
-};
-
-/**
  * Functions handling the performance statistics view.
  */
 function PerformanceStatisticsView() {
 }
 
 PerformanceStatisticsView.prototype = {
   /**
+   * Initialization function, called when the debugger is started.
+   */
+  initialize: function (store) {
+    this.store = store;
+  },
+
+  /**
    * Initializes and displays empty charts in this container.
    */
   displayPlaceholderCharts: function () {
     this._createChart({
       id: "#primed-cache-chart",
       title: "charts.cacheEnabled"
     });
     this._createChart({
@@ -1310,17 +139,17 @@ PerformanceStatisticsView.prototype = {
       data: data,
       strings: strings,
       totals: totals,
       sorted: sorted
     });
 
     chart.on("click", (_, item) => {
       // Reset FilterButtons and enable one filter exclusively
-      gStore.dispatch(Actions.enableFilterOnly(item.label));
+      this.store.dispatch(Actions.enableFilterOnly(item.label));
       NetMonitorView.showNetworkInspectorView();
     });
 
     container.appendChild(chart.node);
   },
 
   /**
    * Sanitizes the data source used for creating charts, to follow the
@@ -1388,22 +217,16 @@ PerformanceStatisticsView.prototype = {
       data[type].count++;
     }
 
     return data.filter(e => e.count > 0);
   },
 };
 
 /**
- * DOM query helper.
- */
-var $ = (selector, target = document) => target.querySelector(selector);
-var $all = (selector, target = document) => target.querySelectorAll(selector);
-
-/**
  * Checks if the "Expiration Calculations" defined in section 13.2.4 of the
  * "HTTP/1.1: Caching in HTTP" spec holds true for a collection of headers.
  *
  * @param object
  *        An object containing the { responseHeaders, status } properties.
  * @return boolean
  *         True if the response is fresh and loaded from cache.
  */
@@ -1434,49 +257,9 @@ function responseIsFresh({ responseHeade
   // Check the "Expires" header for a valid date.
   if (expires && Date.parse(expires.value)) {
     return true;
   }
 
   return false;
 }
 
-/**
- * Makes sure certain properties are available on all objects in a data store.
- *
- * @param array dataStore
- *        A list of objects for which to check the availability of properties.
- * @param array mandatoryFields
- *        A list of strings representing properties of objects in dataStore.
- * @return object
- *         A promise resolved when all objects in dataStore contain the
- *         properties defined in mandatoryFields.
- */
-function whenDataAvailable(dataStore, mandatoryFields) {
-  let deferred = promise.defer();
-
-  let interval = setInterval(() => {
-    if (dataStore.every(item => {
-      return mandatoryFields.every(field => field in item);
-    })) {
-      clearInterval(interval);
-      clearTimeout(timer);
-      deferred.resolve();
-    }
-  }, WDA_DEFAULT_VERIFY_INTERVAL);
-
-  let timer = setTimeout(() => {
-    clearInterval(interval);
-    deferred.reject(new Error("Timed out while waiting for data"));
-  }, WDA_DEFAULT_GIVE_UP_TIMEOUT);
-
-  return deferred.promise;
-}
-
-/**
- * Preliminary setup for the NetMonitorView object.
- */
-NetMonitorView.Toolbar = new ToolbarView();
-NetMonitorView.RequestsMenu = new RequestsMenuView();
-NetMonitorView.Sidebar = new SidebarView();
-NetMonitorView.CustomRequest = new CustomRequestView();
-NetMonitorView.NetworkDetails = new NetworkDetailsView();
-NetMonitorView.PerformanceStatistics = new PerformanceStatisticsView();
+exports.PerformanceStatisticsView = PerformanceStatisticsView;
--- a/devtools/client/responsive.html/browser/tunnel.js
+++ b/devtools/client/responsive.html/browser/tunnel.js
@@ -237,18 +237,18 @@ function tunnelToInnerBrowser(outer, inn
       let { detail } = event;
       event.preventDefault();
       let uri = Services.io.newURI(detail.url, null, null);
       // This API is used mainly because it's near the path used for <a target/> with
       // regular browser tabs (which calls `openURIInFrame`).  The more elaborate APIs
       // that support openers, window features, etc. didn't seem callable from JS and / or
       // this event doesn't give enough info to use them.
       browserWindow.browserDOMWindow
-                   .openURI(uri, null, Ci.nsIBrowserDOMWindow.OPEN_NEWTAB,
-                            Ci.nsIBrowserDOMWindow.OPEN_NEWTAB);
+        .openURI(uri, null, Ci.nsIBrowserDOMWindow.OPEN_NEWTAB,
+                 Ci.nsIBrowserDOMWindow.OPEN_NEW);
     },
 
     stop() {
       let tab = gBrowser.getTabForBrowser(outer);
       let filteredProgressListener = gBrowser._tabFilters.get(tab);
 
       // The browser's state has changed over time while the tunnel was active.  Push the
       // the current state down to the inner browser, so that it follows the content in
--- a/devtools/client/shared/components/reps/grip.js
+++ b/devtools/client/shared/components/reps/grip.js
@@ -45,16 +45,26 @@ define(function (require, exports, modul
         return this.propIterator(object, max);
       } catch (err) {
         console.error(err);
       }
       return [];
     },
 
     propIterator: function (object, max) {
+      if (Object.keys(object.preview).includes("wrappedValue")) {
+        const { Rep } = createFactories(require("./rep"));
+
+        return [Rep({
+          object: object.preview.wrappedValue,
+          mode: this.props.mode || "tiny",
+          defaultRep: Grip,
+        })];
+      }
+
       // Property filter. Show only interesting properties to the user.
       let isInterestingProp = this.props.isInterestingProp || ((type, value) => {
         return (
           type == "boolean" ||
           type == "number" ||
           (type == "string" && value.length != 0)
         );
       });
--- a/devtools/client/shared/components/reps/moz.build
+++ b/devtools/client/shared/components/reps/moz.build
@@ -18,16 +18,17 @@ DevToolsModules(
     'grip.js',
     'infinity.js',
     'nan.js',
     'null.js',
     'number.js',
     'object-with-text.js',
     'object-with-url.js',
     'object.js',
+    'promise.js',
     'prop-rep.js',
     'regexp.js',
     'rep-utils.js',
     'rep.js',
     'reps.css',
     'string.js',
     'stylesheet.js',
     'symbol.js',
new file mode 100644
--- /dev/null
+++ b/devtools/client/shared/components/reps/promise.js
@@ -0,0 +1,111 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+// Make this available to both AMD and CJS environments
+define(function (require, exports, module) {
+  // ReactJS
+  const React = require("devtools/client/shared/vendor/react");
+  // Dependencies
+  const { createFactories, isGrip } = require("./rep-utils");
+  const { PropRep } = createFactories(require("./prop-rep"));
+  // Shortcuts
+  const { span } = React.DOM;
+
+  /**
+   * Renders a DOM Promise object.
+   */
+  const PromiseRep = React.createClass({
+    displayName: "Promise",
+
+    propTypes: {
+      object: React.PropTypes.object.isRequired,
+      mode: React.PropTypes.string,
+    },
+
+    getTitle: function (object) {
+      const title = object.class;
+      if (this.props.objectLink) {
+        return this.props.objectLink({
+          object: object
+        }, title);
+      }
+      return title;
+    },
+
+    getProps: function (promiseState) {
+      const keys = ["state"];
+      if (Object.keys(promiseState).includes("value")) {
+        keys.push("value");
+      }
+
+      return keys.map((key, i) => {
+        return PropRep(Object.assign({}, this.props, {
+          mode: "tiny",
+          name: `<${key}>`,
+          object: promiseState[key],
+          equal: ": ",
+          delim: i < keys.length - 1 ? ", " : ""
+        }));
+      });
+    },
+
+    render: function () {
+      const object = this.props.object;
+      const {promiseState} = object;
+      let objectLink = this.props.objectLink || span;
+
+      if (this.props.mode == "tiny") {
+        let { Rep } = createFactories(require("./rep"));
+
+        return (
+          span({className: "objectBox objectBox-object"},
+            this.getTitle(object),
+            objectLink({
+              className: "objectLeftBrace",
+              object: object
+            }, " { "),
+            Rep({object: promiseState.state}),
+            objectLink({
+              className: "objectRightBrace",
+              object: object
+            }, " }")
+          )
+        );
+      }
+
+      const props = this.getProps(promiseState);
+      return (
+        span({className: "objectBox objectBox-object"},
+          this.getTitle(object),
+          objectLink({
+            className: "objectLeftBrace",
+            object: object
+          }, " { "),
+          ...props,
+          objectLink({
+            className: "objectRightBrace",
+            object: object
+          }, " }")
+        )
+      );
+    },
+  });
+
+  // Registration
+  function supportsObject(object, type) {
+    if (!isGrip(object)) {
+      return false;
+    }
+    return type === "Promise";
+  }
+
+  // Exports from this module
+  exports.PromiseRep = {
+    rep: PromiseRep,
+    supportsObject: supportsObject
+  };
+});
--- a/devtools/client/shared/components/reps/rep-utils.js
+++ b/devtools/client/shared/components/reps/rep-utils.js
@@ -43,16 +43,23 @@ define(function (require, exports, modul
   function cropString(text, limit, alternativeText) {
     if (!alternativeText) {
       alternativeText = "\u2026";
     }
 
     // Make sure it's a string.
     text = text + "";
 
+    // Replace all non-printable characters, except of
+    // (horizontal) tab (HT: \x09) and newline (LF: \x0A, CR: \x0D),
+    // with unicode replacement character (u+fffd).
+    // eslint-disable-next-line no-control-regex
+    let re = new RegExp("[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\x9F]", "g");
+    text = text.replace(re, "\ufffd");
+
     // Crop the string only if a limit is actually specified.
     if (!limit || limit <= 0) {
       return text;
     }
 
     // Set the limit at least to the length of the alternative text
     // plus one character of the original text.
     if (limit <= alternativeText.length) {
--- a/devtools/client/shared/components/reps/rep.js
+++ b/devtools/client/shared/components/reps/rep.js
@@ -25,16 +25,17 @@ define(function (require, exports, modul
   const { NaNRep } = require("./nan");
 
   // DOM types (grips)
   const { Attribute } = require("./attribute");
   const { DateTime } = require("./date-time");
   const { Document } = require("./document");
   const { Event } = require("./event");
   const { Func } = require("./function");
+  const { PromiseRep } = require("./promise");
   const { RegExp } = require("./regexp");
   const { StyleSheet } = require("./stylesheet");
   const { CommentNode } = require("./comment-node");
   const { TextNode } = require("./text-node");
   const { Window } = require("./window");
   const { ObjectWithText } = require("./object-with-text");
   const { ObjectWithURL } = require("./object-with-url");
   const { GripArray } = require("./grip-array");
@@ -48,16 +49,17 @@ define(function (require, exports, modul
     RegExp,
     StyleSheet,
     Event,
     DateTime,
     CommentNode,
     TextNode,
     Attribute,
     Func,
+    PromiseRep,
     ArrayRep,
     Document,
     Window,
     ObjectWithText,
     ObjectWithURL,
     GripArray,
     GripMap,
     Grip,
--- a/devtools/client/shared/components/tabs/tabs.css
+++ b/devtools/client/shared/components/tabs/tabs.css
@@ -37,34 +37,26 @@
 
 .tabs .tab-panel {
   height: 100%;
 }
 
 .tabs .all-tabs-menu  {
   position: absolute;
   top: 0;
-  right: 0;
+  offset-inline-end: 0;
   width: 15px;
   height: 100%;
-  border-style: solid;
-  border-width: 0;
-  border-inline-start-width: 1px;
-  border-color: var(--theme-splitter-color);
+  border-inline-start: 1px solid var(--theme-splitter-color);
   background: url("chrome://devtools/skin/images/dropmarker.svg");
   background-repeat: no-repeat;
   background-position: center;
   background-color: var(--theme-tab-toolbar-background);
 }
 
-.tabs .all-tabs-menu:-moz-locale-dir(rtl) {
-  right: unset;
-  left: 0;
-}
-
 /* Light Theme */
 
 .theme-dark .tabs,
 .theme-light .tabs {
   background: var(--theme-body-background);
 }
 
 .theme-dark .tabs .tabs-navigation,
--- a/devtools/client/shared/components/test/mochitest/chrome.ini
+++ b/devtools/client/shared/components/test/mochitest/chrome.ini
@@ -19,16 +19,17 @@ support-files =
 [test_reps_grip-map.html]
 [test_reps_infinity.html]
 [test_reps_nan.html]
 [test_reps_null.html]
 [test_reps_number.html]
 [test_reps_object.html]
 [test_reps_object-with-text.html]
 [test_reps_object-with-url.html]
+[test_reps_promise.html]
 [test_reps_regexp.html]
 [test_reps_string.html]
 [test_reps_stylesheet.html]
 [test_reps_symbol.html]
 [test_reps_text-node.html]
 [test_reps_undefined.html]
 [test_reps_window.html]
 [test_sidebar_toggle.html]
--- a/devtools/client/shared/components/test/mochitest/test_reps_grip.html
+++ b/devtools/client/shared/components/test/mochitest/test_reps_grip.html
@@ -17,16 +17,19 @@ Test grip rep
 window.onload = Task.async(function* () {
   let { Rep } = browserRequire("devtools/client/shared/components/reps/rep");
   let { Grip } = browserRequire("devtools/client/shared/components/reps/grip");
 
   const componentUnderTest = Grip;
 
   try {
     yield testBasic();
+    yield testBooleanObject();
+    yield testNumberObject();
+    yield testStringObject();
 
     // Test property iterator
     yield testMaxProps();
     yield testMoreThanMaxProps();
     yield testUninterestingProps();
     yield testNonEnumerableProps();
 
     // Test that properties are rendered as expected by PropRep
@@ -70,16 +73,118 @@ window.onload = Task.async(function* () 
         mode: "long",
         expectedOutput: defaultOutput,
       }
     ];
 
     testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
   }
 
+  function testBooleanObject() {
+    // Test object: `new Boolean(true)`
+    const testName = "testBooleanObject";
+
+    // Test that correct rep is chosen
+    const gripStub = getGripStub(testName);
+    const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
+    is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
+
+    // Test rendering
+    const defaultOutput = `Boolean { true }`;
+
+    const modeTests = [
+      {
+        mode: undefined,
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "tiny",
+        expectedOutput: `Boolean`,
+      },
+      {
+        mode: "short",
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "long",
+        expectedOutput: defaultOutput,
+      }
+    ];
+
+    testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
+  }
+
+  function testNumberObject() {
+    // Test object: `new Number(42)`
+    const testName = "testNumberObject";
+
+    // Test that correct rep is chosen
+    const gripStub = getGripStub(testName);
+    const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
+    is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
+
+    // Test rendering
+    const defaultOutput = `Number { 42 }`;
+
+    const modeTests = [
+      {
+        mode: undefined,
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "tiny",
+        expectedOutput: `Number`,
+      },
+      {
+        mode: "short",
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "long",
+        expectedOutput: defaultOutput,
+      }
+    ];
+
+    testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
+  }
+
+  function testStringObject() {
+    // Test object: `new String("foo")`
+    const testName = "testStringObject";
+
+    // Test that correct rep is chosen
+    const gripStub = getGripStub(testName);
+    const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
+    is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
+
+    // Test rendering
+    const defaultOutput = `String { "foo" }`;
+
+    const modeTests = [
+      {
+        mode: undefined,
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "tiny",
+        expectedOutput: `String`,
+      },
+      {
+        mode: "short",
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "long",
+        expectedOutput: defaultOutput,
+      }
+    ];
+
+    testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
+  }
+
   function testMaxProps() {
     // Test object: `{a: "a", b: "b", c: "c"}`;
     const testName = "testMaxProps";
 
     const defaultOutput = `Object { a: "a", b: "b", c: "c" }`;
 
     const modeTests = [
       {
@@ -525,16 +630,57 @@ window.onload = Task.async(function* () 
                 "writable": true,
                 "value": 3
               }
             },
             "ownPropertiesLength": 4,
             "safeGetterValues": {}
           }
         };
-
+      case "testBooleanObject":
+        return {
+          "type": "object",
+          "actor": "server1.conn1.child1/obj57",
+          "class": "Boolean",
+          "ownPropertyLength": 0,
+          "preview": {
+            "kind": "Object",
+            "ownProperties": {},
+            "ownPropertiesLength": 0,
+            "safeGetterValues": {},
+            "wrappedValue": true
+          }
+        };
+      case "testNumberObject":
+        return {
+          "type": "object",
+          "actor": "server1.conn1.child1/obj59",
+          "class": "Number",
+          "ownPropertyLength": 0,
+          "preview": {
+            "kind": "Object",
+            "ownProperties": {},
+            "ownPropertiesLength": 0,
+            "safeGetterValues": {},
+            "wrappedValue": 42
+          }
+        };
+      case "testStringObject":
+        return {
+          "type": "object",
+          "actor": "server1.conn1.child1/obj61",
+          "class": "String",
+          "ownPropertyLength": 4,
+          "preview": {
+            "kind": "Object",
+            "ownProperties": {},
+            "ownPropertiesLength": 4,
+            "safeGetterValues": {},
+            "wrappedValue": "foo"
+          }
+        };
     }
   }
 });
 </script>
 </pre>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/devtools/client/shared/components/test/mochitest/test_reps_promise.html
@@ -0,0 +1,331 @@
+
+<!DOCTYPE HTML>
+<html>
+<!--
+Test Promise rep
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Rep test - Promise</title>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+</head>
+<body>
+<pre id="test">
+<script src="head.js" type="application/javascript;version=1.8"></script>
+<script type="application/javascript;version=1.8">
+"use strict";
+
+window.onload = Task.async(function* () {
+  let { Rep } = browserRequire("devtools/client/shared/components/reps/rep");
+  let { PromiseRep } = browserRequire("devtools/client/shared/components/reps/promise");
+
+  const componentUnderTest = PromiseRep;
+
+  try {
+    yield testPending();
+    yield testFulfilledWithNumber();
+    yield testFulfilledWithString();
+    yield testFulfilledWithObject();
+    yield testFulfilledWithArray();
+  } catch (e) {
+    ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
+  } finally {
+    SimpleTest.finish();
+  }
+
+  function testPending() {
+    // Test object = `new Promise((resolve, reject) => true)`
+    const stub = getGripStub("testPending");
+
+    // Test that correct rep is chosen.
+    const renderedRep = shallowRenderComponent(Rep, { object: stub });
+    is(renderedRep.type, PromiseRep.rep,
+      `Rep correctly selects ${PromiseRep.rep.displayName} for pending Promise`);
+
+    // Test rendering
+    const defaultOutput = `Promise { <state>: "pending" }`;
+
+    const modeTests = [
+      {
+        mode: undefined,
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "tiny",
+        expectedOutput: `Promise { "pending" }`,
+      },
+      {
+        mode: "short",
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "long",
+        expectedOutput: defaultOutput,
+      }
+    ];
+
+    testRepRenderModes(modeTests, "testPending", componentUnderTest, stub);
+  }
+  function testFulfilledWithNumber() {
+    // Test object = `Promise.resolve(42)`
+    const stub = getGripStub("testFulfilledWithNumber");
+
+    // Test that correct rep is chosen.
+    const renderedRep = shallowRenderComponent(Rep, { object: stub });
+    const {displayName} = PromiseRep.rep;
+    is(renderedRep.type, PromiseRep.rep,
+      `Rep correctly selects ${displayName} for Promise fulfilled with a number`);
+
+    // Test rendering
+    const defaultOutput = `Promise { <state>: "fulfilled", <value>: 42 }`;
+
+    const modeTests = [
+      {
+        mode: undefined,
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "tiny",
+        expectedOutput: `Promise { "fulfilled" }`,
+      },
+      {
+        mode: "short",
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "long",
+        expectedOutput: defaultOutput,
+      }
+    ];
+
+    testRepRenderModes(modeTests, "testFulfilledWithNumber", componentUnderTest, stub);
+  }
+  function testFulfilledWithString() {
+    // Test object = `Promise.resolve("foo")`
+    const stub = getGripStub("testFulfilledWithString");
+
+    // Test that correct rep is chosen.
+    const renderedRep = shallowRenderComponent(Rep, { object: stub });
+    const {displayName} = PromiseRep.rep;
+    is(renderedRep.type, PromiseRep.rep,
+      `Rep correctly selects ${displayName} for Promise fulfilled with a string`);
+
+    // Test rendering
+    const defaultOutput = `Promise { <state>: "fulfilled", <value>: "foo" }`;
+
+    const modeTests = [
+      {
+        mode: undefined,
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "tiny",
+        expectedOutput: `Promise { "fulfilled" }`,
+      },
+      {
+        mode: "short",
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "long",
+        expectedOutput: defaultOutput,
+      }
+    ];
+
+    testRepRenderModes(modeTests, "testFulfilledWithString", componentUnderTest, stub);
+  }
+
+  function testFulfilledWithObject() {
+    // Test object = `Promise.resolve({foo: "bar", baz: "boo"})`
+    const stub = getGripStub("testFulfilledWithObject");
+
+    // Test that correct rep is chosen.
+    const renderedRep = shallowRenderComponent(Rep, { object: stub });
+    const {displayName} = PromiseRep.rep;
+    is(renderedRep.type, PromiseRep.rep,
+      `Rep correctly selects ${displayName} for Promise fulfilled with an object`);
+
+    // Test rendering
+    const defaultOutput = `Promise { <state>: "fulfilled", <value>: Object }`;
+
+    const modeTests = [
+      {
+        mode: undefined,
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "tiny",
+        expectedOutput: `Promise { "fulfilled" }`,
+      },
+      {
+        mode: "short",
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "long",
+        expectedOutput: defaultOutput,
+      }
+    ];
+
+    testRepRenderModes(modeTests, "testFulfilledWithObject", componentUnderTest, stub);
+  }
+
+  function testFulfilledWithArray() {
+    // Test object = `Promise.resolve([1,2,3])`
+    const stub = getGripStub("testFulfilledWithArray");
+
+    // Test that correct rep is chosen.
+    const renderedRep = shallowRenderComponent(Rep, { object: stub });
+    const {displayName} = PromiseRep.rep;
+    is(renderedRep.type, PromiseRep.rep,
+      `Rep correctly selects ${displayName} for Promise fulfilled with an array`);
+
+    // Test rendering
+    const defaultOutput = `Promise { <state>: "fulfilled", <value>: [3] }`;
+
+    const modeTests = [
+      {
+        mode: undefined,
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "tiny",
+        expectedOutput: `Promise { "fulfilled" }`,
+      },
+      {
+        mode: "short",
+        expectedOutput: defaultOutput,
+      },
+      {
+        mode: "long",
+        expectedOutput: defaultOutput,
+      }
+    ];
+
+    testRepRenderModes(modeTests, "testFulfilledWithArray", componentUnderTest, stub);
+  }
+
+  function getGripStub(name) {
+    switch (name) {
+      case "testPending":
+        return {
+          "type": "object",
+          "actor": "server1.conn1.child1/obj54",
+          "class": "Promise",
+          "promiseState": {
+            "state": "pending",
+            "creationTimestamp": 1477327760242.5752
+          },
+          "ownPropertyLength": 0,
+          "preview": {
+            "kind": "Object",
+            "ownProperties": {},
+            "ownPropertiesLength": 0,
+            "safeGetterValues": {}
+          }
+        };
+      case "testFulfilledWithNumber":
+        return {
+          "type": "object",
+          "actor": "server1.conn1.child1/obj55",
+          "class": "Promise",
+          "promiseState": {
+            "state": "fulfilled",
+            "value": 42,
+            "creationTimestamp": 1477327760242.721,
+            "timeToSettle": 0.018497000000479602
+          },
+          "ownPropertyLength": 0,
+          "preview": {
+            "kind": "Object",
+            "ownProperties": {},
+            "ownPropertiesLength": 0,
+            "safeGetterValues": {}
+          }
+        };
+      case "testFulfilledWithString":
+        return {
+          "type": "object",
+          "actor": "server1.conn1.child1/obj56",
+          "class": "Promise",
+          "promiseState": {
+            "state": "fulfilled",
+            "value": "foo",
+            "creationTimestamp": 1477327760243.2483,
+            "timeToSettle": 0.0019969999998465937
+          },
+          "ownPropertyLength": 0,
+          "preview": {
+            "kind": "Object",
+            "ownProperties": {},
+            "ownPropertiesLength": 0,
+            "safeGetterValues": {}
+          }
+        };
+      case "testFulfilledWithObject":
+        return {
+          "type": "object",
+          "actor": "server1.conn1.child1/obj59",
+          "class": "Promise",
+          "promiseState": {
+            "state": "fulfilled",
+            "value": {
+              "type": "object",
+              "actor": "server1.conn1.child1/obj60",
+              "class": "Object",
+              "extensible": true,
+              "frozen": false,
+              "sealed": false,
+              "ownPropertyLength": 2
+            },
+            "creationTimestamp": 1477327760243.2214,
+            "timeToSettle": 0.002035999999861815
+          },
+          "ownPropertyLength": 0,
+          "preview": {
+            "kind": "Object",
+            "ownProperties": {},
+            "ownPropertiesLength": 0,
+            "safeGetterValues": {}
+          }
+        };
+      case "testFulfilledWithArray":
+        return {
+          "type": "object",
+          "actor": "server1.conn1.child1/obj57",
+          "class": "Promise",
+          "promiseState": {
+            "state": "fulfilled",
+            "value": {
+              "type": "object",
+              "actor": "server1.conn1.child1/obj58",
+              "class": "Array",
+              "extensible": true,
+              "frozen": false,
+              "sealed": false,
+              "ownPropertyLength": 4,
+              "preview": {
+                "kind": "ArrayLike",
+                "length": 3
+              }
+            },
+            "creationTimestamp": 1477327760242.9597,
+            "timeToSettle": 0.006158000000141328
+          },
+          "ownPropertyLength": 0,
+          "preview": {
+            "kind": "Object",
+            "ownProperties": {},
+            "ownPropertiesLength": 0,
+            "safeGetterValues": {}
+          }
+        };
+    }
+    return null;
+  }
+});
+</script>
+</pre>
+</body>
+</html>
--- a/devtools/client/shared/components/test/mochitest/test_reps_string.html
+++ b/devtools/client/shared/components/test/mochitest/test_reps_string.html
@@ -23,16 +23,17 @@ window.onload = Task.async(function* () 
     const renderedRep = shallowRenderComponent(Rep, { object: getGripStub("testMultiline") });
     is(renderedRep.type, StringRep.rep, `Rep correctly selects ${StringRep.rep.displayName}`);
 
     // Test rendering
     yield testMultiline();
     yield testMultilineOpen();
     yield testMultilineLimit();
     yield testUseQuotes();
+    yield testNonPritableCharacters();
   } catch(e) {
     ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
   } finally {
     SimpleTest.finish();
   }
 
   function testMultiline() {
     const renderedComponent = renderComponent(StringRep.rep, { object: getGripStub("testMultiline") });
@@ -46,25 +47,31 @@ window.onload = Task.async(function* () 
 
   function testMultilineOpen() {
     const renderedComponent = renderComponent(StringRep.rep, { object: getGripStub("testMultiline"), member: {open: true} });
     is(renderedComponent.textContent, "\"aaaaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbb\ncccccccccccccccc\n\"", "String rep has expected text content for multiline string when open");
   }
 
   function testUseQuotes(){
      const renderedComponent = renderComponent(StringRep.rep, { object: getGripStub("testUseQuotes"), useQuotes: false });
-     is(renderedComponent.textContent, "abc","String rep was expected to omit quotes");
+     is(renderedComponent.textContent, "abc", "String rep was expected to omit quotes");
+  }
+
+  function testNonPritableCharacters(){
+     const renderedComponent = renderComponent(StringRep.rep, { object: getGripStub("testNonPritableCharacters"), useQuotes: false });
+     is(renderedComponent.textContent, "a\ufffdb", "String rep was expected to omit non printable characters");
   }
 
   function getGripStub(name) {
     switch (name) {
       case "testMultiline":
-      	 return "aaaaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbb\ncccccccccccccccc\n";
-	 break;
+        return "aaaaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbb\ncccccccccccccccc\n";
       case "testUseQuotes":
-	 return "abc";
+        return "abc";
+      case "testNonPritableCharacters":
+        return "a\x01b";
     }
   }
 });
 </script>
 </pre>
 </body>
 </html>
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -26,16 +26,17 @@
 #include "mozilla/LoadInfo.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/StartupTimeline.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 #include "Navigator.h"
 #include "URIUtils.h"
+#include "mozilla/dom/DocGroup.h"
 
 #include "nsIContent.h"
 #include "nsIContentInlines.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMElement.h"
 
 #include "nsArray.h"
@@ -1537,17 +1538,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
   return InternalLoad(aURI,
                       originalURI,
                       loadReplace,
                       referrer,
                       referrerPolicy,
                       triggeringPrincipal,
                       principalToInherit,
                       flags,
-                      target.get(),
+                      target,
                       nullptr,      // No type hint
                       NullString(), // No forced download
                       postStream,
                       headersStream,
                       loadType,
                       nullptr, // No SHEntry
                       aFirstParty,
                       srcdoc,
@@ -3143,19 +3144,18 @@ nsDocShell::GetName(nsAString& aName)
 NS_IMETHODIMP
 nsDocShell::SetName(const nsAString& aName)
 {
   mName = aName;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocShell::NameEquals(const char16_t* aName, bool* aResult)
-{
-  NS_ENSURE_ARG_POINTER(aName);
+nsDocShell::NameEquals(const nsAString& aName, bool* aResult)
+{
   NS_ENSURE_ARG_POINTER(aResult);
   *aResult = mName.Equals(aName);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetCustomUserAgent(nsAString& aCustomUserAgent)
 {
@@ -3644,83 +3644,54 @@ ItemIsActive(nsIDocShellTreeItem* aItem)
       return true;
     }
   }
 
   return false;
 }
 
 NS_IMETHODIMP
-nsDocShell::FindItemWithName(const char16_t* aName,
+nsDocShell::FindItemWithName(const nsAString& aName,
                              nsISupports* aRequestor,
                              nsIDocShellTreeItem* aOriginalRequestor,
                              nsIDocShellTreeItem** aResult)
 {
-  NS_ENSURE_ARG(aName);
   NS_ENSURE_ARG_POINTER(aResult);
 
   // If we don't find one, we return NS_OK and a null result
   *aResult = nullptr;
 
-  if (!*aName) {
+  if (aName.IsEmpty()) {
     return NS_OK;
   }
 
   if (aRequestor) {
     // If aRequestor is not null we don't need to check special names, so
     // just hand straight off to the search by actual name function.
     return DoFindItemWithName(aName, aRequestor, aOriginalRequestor, aResult);
   } else {
     // This is the entry point into the target-finding algorithm.  Check
     // for special names.  This should only be done once, hence the check
     // for a null aRequestor.
 
     nsCOMPtr<nsIDocShellTreeItem> foundItem;
-    nsDependentString name(aName);
-    if (name.LowerCaseEqualsLiteral("_self")) {
+    if (aName.LowerCaseEqualsLiteral("_self")) {
       foundItem = this;
-    } else if (name.LowerCaseEqualsLiteral("_blank")) {
+    } else if (aName.LowerCaseEqualsLiteral("_blank")) {
       // Just return null.  Caller must handle creating a new window with
       // a blank name himself.
       return NS_OK;
-    } else if (name.LowerCaseEqualsLiteral("_parent")) {
+    } else if (aName.LowerCaseEqualsLiteral("_parent")) {
       GetSameTypeParent(getter_AddRefs(foundItem));
       if (!foundItem) {
         foundItem = this;
       }
-    } else if (name.LowerCaseEqualsLiteral("_top")) {
+    } else if (aName.LowerCaseEqualsLiteral("_top")) {
       GetSameTypeRootTreeItem(getter_AddRefs(foundItem));
       NS_ASSERTION(foundItem, "Must have this; worst case it's us!");
-    }
-    // _main is an IE target which should be case-insensitive but isn't
-    // see bug 217886 for details
-    else if (name.LowerCaseEqualsLiteral("_content") ||
-             name.EqualsLiteral("_main")) {
-      // Must pass our same type root as requestor to the
-      // treeowner to make sure things work right.
-      nsCOMPtr<nsIDocShellTreeItem> root;
-      GetSameTypeRootTreeItem(getter_AddRefs(root));
-      if (mTreeOwner) {
-        NS_ASSERTION(root, "Must have this; worst case it's us!");
-        mTreeOwner->FindItemWithName(aName, root, aOriginalRequestor,
-                                     getter_AddRefs(foundItem));
-      }
-#ifdef DEBUG
-      else {
-        NS_ERROR("Someone isn't setting up the tree owner.  "
-                 "You might like to try that.  "
-                 "Things will.....you know, work.");
-        // Note: _content should always exist.  If we don't have one
-        // hanging off the treeowner, just create a named window....
-        // so don't return here, in case we did that and can now find
-        // it.
-        // XXXbz should we be using |root| instead of creating
-        // a new window?
-      }
-#endif
     } else {
       // Do the search for item by an actual name.
       DoFindItemWithName(aName, aRequestor, aOriginalRequestor,
                          getter_AddRefs(foundItem));
     }
 
     if (foundItem && !CanAccessItem(foundItem, aOriginalRequestor)) {
       foundItem = nullptr;
@@ -3743,17 +3714,17 @@ nsDocShell::AssertOriginAttributesMatchP
   if (mItemType == typeChrome) {
     MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0);
   } else {
     MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId == mPrivateBrowsingId);
   }
 }
 
 nsresult
-nsDocShell::DoFindItemWithName(const char16_t* aName,
+nsDocShell::DoFindItemWithName(const nsAString& aName,
                                nsISupports* aRequestor,
                                nsIDocShellTreeItem* aOriginalRequestor,
                                nsIDocShellTreeItem** aResult)
 {
   // First we check our name.
   if (mName.Equals(aName) && ItemIsActive(this) &&
       CanAccessItem(this, aOriginalRequestor)) {
     NS_ADDREF(*aResult = this);
@@ -3784,33 +3755,37 @@ nsDocShell::DoFindItemWithName(const cha
   // docShellTreeOwner to do the search.
   nsCOMPtr<nsIDocShellTreeItem> parentAsTreeItem =
     do_QueryInterface(GetAsSupports(mParent));
   if (parentAsTreeItem) {
     if (parentAsTreeItem == reqAsTreeItem) {
       return NS_OK;
     }
 
-    if (parentAsTreeItem->ItemType() == mItemType) {
+    // If we have a same-type parent, respecting browser and app boundaries.
+    // NOTE: Could use GetSameTypeParent if the issues described in bug 1310344 are fixed.
+    if (!GetIsMozBrowserOrApp() && parentAsTreeItem->ItemType() == mItemType) {
       return parentAsTreeItem->FindItemWithName(
         aName,
         static_cast<nsIDocShellTreeItem*>(this),
         aOriginalRequestor,
         aResult);
     }
   }
 
-  // If the parent is null or not of the same type fall through and ask tree
-  // owner.
-
-  // This may fail, but comparing against null serves the same purpose
-  nsCOMPtr<nsIDocShellTreeOwner> reqAsTreeOwner(do_QueryInterface(aRequestor));
-  if (mTreeOwner && mTreeOwner != reqAsTreeOwner) {
-    return mTreeOwner->FindItemWithName(aName, this, aOriginalRequestor,
-                                        aResult);
+  // If we have a null parent or the parent is not of the same type, we need to
+  // give up on finding it in our tree, and start looking in our TabGroup.
+  nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
+  if (window) {
+    RefPtr<mozilla::dom::TabGroup> tabGroup = window->TabGroup();
+    // We don't want to make the request to our TabGroup if they are the ones
+    // which made a request to us.
+    if (tabGroup != aRequestor) {
+      tabGroup->FindItemWithName(aName, this, aOriginalRequestor, aResult);
+    }
   }
 
   return NS_OK;
 }
 
 bool
 nsDocShell::IsSandboxedFrom(nsIDocShell* aTargetDocShell)
 {
@@ -4185,29 +4160,28 @@ nsDocShell::GetChildAt(int32_t aIndex, n
 
   nsIDocumentLoader* child = ChildAt(aIndex);
   NS_ENSURE_TRUE(child, NS_ERROR_UNEXPECTED);
 
   return CallQueryInterface(child, aChild);
 }
 
 NS_IMETHODIMP
-nsDocShell::FindChildWithName(const char16_t* aName,
+nsDocShell::FindChildWithName(const nsAString& aName,
                               bool aRecurse, bool aSameType,
                               nsIDocShellTreeItem* aRequestor,