Merge inbound to m-c a=merge
authorWes Kocher <wkocher@mozilla.com>
Wed, 07 Oct 2015 10:29:41 -0700
changeset 266598 49d87bbe0122d894c8e45f0b409c42dfe1c36737
parent 266597 1831ba1be747218569761f3f57e986f78f349b09 (current diff)
parent 266588 d6793bb3e45b2853d33c653b14f5a909ee46a9e4 (diff)
child 266599 1e1fa696e2b626ead6817b7c5bd871fec5d5ab5a
push id15565
push userkwierso@gmail.com
push dateWed, 07 Oct 2015 18:35:05 +0000
treeherderfx-team@eb3424a2e285 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone44.0a1
Merge inbound to m-c a=merge
accessible/windows/ia2/ia2Accessible.cpp
browser/base/content/social-content.js
devtools/client/animationinspector/animation-controller.js
devtools/client/layoutview/view.js
devtools/client/styleinspector/test/head.js
devtools/client/webide/content/webide.js
devtools/client/webide/test/head.js
devtools/server/tests/browser/head.js
docshell/base/nsDocShell.cpp
dom/animation/Animation.cpp
dom/animation/Animation.h
dom/animation/KeyframeEffect.cpp
dom/animation/KeyframeEffect.h
dom/audiochannel/AudioChannelAgent.cpp
dom/base/Navigator.cpp
dom/base/WebSocket.cpp
dom/base/nsContentUtils.cpp
dom/base/nsDOMWindowUtils.cpp
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsIDocument.h
dom/base/nsObjectLoadingContent.cpp
dom/base/nsPIDOMWindow.h
dom/canvas/CanvasRenderingContext2D.cpp
dom/canvas/nsICanvasRenderingContextInternal.h
dom/crypto/WebCryptoTask.cpp
dom/crypto/WebCryptoTask.h
dom/fetch/FetchDriver.cpp
dom/filesystem/GetDirectoryListingTask.cpp
dom/html/nsHTMLDocument.cpp
dom/html/test/file_fullscreen-ancestor-stacking-context.html
dom/ipc/ContentChild.cpp
dom/media/MP3Decoder.cpp
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaFormatReader.cpp
dom/media/MediaFormatReader.h
dom/media/MediaManager.cpp
dom/media/MediaManager.h
dom/media/fmp4/MP4Decoder.cpp
dom/media/gmp/GMPServiceParent.cpp
dom/media/omx/MediaCodecProxy.h
dom/media/omx/MediaOmxCommonDecoder.cpp
dom/media/omx/MediaOmxReader.cpp
dom/media/platforms/PlatformDecoderModule.cpp
dom/media/platforms/PlatformDecoderModule.h
dom/media/platforms/agnostic/BlankDecoderModule.cpp
dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
dom/media/platforms/agnostic/eme/EMEDecoderModule.h
dom/media/platforms/apple/AppleDecoderModule.cpp
dom/media/platforms/ffmpeg/FFmpegDataDecoder.h
dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
dom/media/platforms/gonk/GonkAudioDecoderManager.cpp
dom/media/platforms/gonk/GonkAudioDecoderManager.h
dom/media/platforms/gonk/GonkMediaDataDecoder.cpp
dom/media/platforms/gonk/GonkMediaDataDecoder.h
dom/media/platforms/gonk/GonkVideoDecoderManager.cpp
dom/media/platforms/gonk/GonkVideoDecoderManager.h
dom/media/systemservices/MediaUtils.h
dom/media/webaudio/AudioContext.cpp
dom/media/webaudio/AudioContext.h
dom/media/webaudio/AudioDestinationNode.cpp
dom/media/webaudio/AudioDestinationNode.h
dom/media/webm/AudioDecoder.cpp
dom/media/webm/IntelWebMVideoDecoder.cpp
dom/media/webm/IntelWebMVideoDecoder.h
dom/media/webm/SoftwareWebMVideoDecoder.cpp
dom/media/webm/SoftwareWebMVideoDecoder.h
dom/media/webm/WebMReader.cpp
dom/media/webm/WebMReader.h
dom/media/webrtc/RTCCertificate.cpp
dom/svg/SVGFEImageElement.cpp
dom/workers/RuntimeService.cpp
dom/workers/ScriptLoader.cpp
dom/workers/ServiceWorkerScriptCache.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
dom/workers/Workers.h
gfx/2d/PathHelpers.h
gfx/gl/GLTextureImage.cpp
gfx/gl/GLTextureImage.h
gfx/layers/ImageLayers.h
gfx/layers/LayerTreeInvalidation.cpp
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/YCbCrImageDataSerializer.cpp
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZCTreeManager.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/basic/BasicCanvasLayer.cpp
gfx/layers/basic/BasicImageLayer.cpp
gfx/layers/composite/AsyncCompositionManager.h
gfx/layers/composite/CanvasLayerComposite.cpp
gfx/layers/composite/ImageLayerComposite.cpp
gfx/layers/ipc/CompositorChild.cpp
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/CompositorParent.h
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/CompositorOGLVR.cpp
gfx/thebes/GraphicsFilter.h
gfx/thebes/gfxDrawable.cpp
gfx/thebes/gfxDrawable.h
gfx/thebes/gfxPattern.h
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxUtils.h
gfx/thebes/gfxWindowsNativeDrawing.cpp
image/ClippedImage.cpp
image/ClippedImage.h
image/DynamicImage.cpp
image/FrozenImage.h
image/ImageWrapper.cpp
image/OrientedImage.cpp
image/OrientedImage.h
image/RasterImage.cpp
image/RasterImage.h
image/VectorImage.cpp
image/imgFrame.cpp
image/imgFrame.h
image/imgIContainer.idl
js/src/devtools/rootAnalysis/build.b2g
js/src/devtools/rootAnalysis/build.browser
js/src/devtools/rootAnalysis/build.shell
js/src/jit-test/tests/basic/bug778268.js
js/src/jit/AtomicOperations-inl.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/tests/js1_7/regress/regress-406477.js
js/src/vm/Interpreter.cpp
js/src/vm/Runtime.h
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/src/XPCShellImpl.cpp
layout/base/AccessibleCaretManager.cpp
layout/base/AccessibleCaretManager.h
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSRendering.cpp
layout/base/nsDisplayList.h
layout/base/nsDocumentViewer.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/generic/nsBlockFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsImageFrame.cpp
layout/generic/nsPluginFrame.cpp
layout/generic/nsPluginFrame.h
layout/mathml/nsMathMLFrame.cpp
layout/style/AnimationCommon.h
layout/style/full-screen-override.css
layout/style/nsAnimationManager.cpp
layout/style/nsAnimationManager.h
layout/style/nsCSSParser.cpp
layout/style/nsCSSProps.h
layout/style/nsCSSRuleProcessor.cpp
layout/style/nsLayoutStylesheetCache.cpp
layout/style/nsLayoutStylesheetCache.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.h
layout/style/nsTransitionManager.cpp
layout/style/nsTransitionManager.h
layout/svg/nsSVGIntegrationUtils.cpp
layout/xul/tree/nsTreeBodyFrame.cpp
media/libstagefright/frameworks/av/media/libstagefright/id3/ID3.cpp
media/libstagefright/frameworks/av/media/libstagefright/include/ID3.h
modules/libjar/nsJARChannel.cpp
modules/libjar/nsJARChannel.h
modules/libpref/init/all.js
netwerk/base/nsIOService.cpp
netwerk/base/nsNetUtil.cpp
netwerk/protocol/app/AppProtocolHandler.cpp
netwerk/protocol/http/Http2Session.cpp
netwerk/protocol/http/Http2Stream.cpp
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/nsCORSListenerProxy.cpp
netwerk/protocol/http/nsHttpChannel.cpp
security/manager/ssl/nsNSSCallbacks.cpp
testing/profiles/prefs_general.js
toolkit/components/alerts/resources/content/alert.js
toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
toolkit/components/url-classifier/nsUrlClassifierProxies.h
toolkit/mozapps/extensions/internal/XPIProvider.jsm
toolkit/mozapps/extensions/test/xpcshell/test_system_update.js
widget/PuppetWidget.cpp
widget/cocoa/nsCocoaUtils.mm
widget/nsBaseDragService.cpp
xpcom/base/nsMemoryReporterManager.cpp
xpcom/base/nsMemoryReporterManager.h
--- a/accessible/atk/AccessibleWrap.cpp
+++ b/accessible/atk/AccessibleWrap.cpp
@@ -9,16 +9,18 @@
 #include "Accessible-inl.h"
 #include "ApplicationAccessibleWrap.h"
 #include "InterfaceInitFuncs.h"
 #include "nsAccUtils.h"
 #include "mozilla/a11y/PDocAccessible.h"
 #include "OuterDocAccessible.h"
 #include "ProxyAccessible.h"
 #include "RootAccessible.h"
+#include "TableAccessible.h"
+#include "TableCellAccessible.h"
 #include "nsMai.h"
 #include "nsMaiHyperlink.h"
 #include "nsString.h"
 #include "nsAutoPtr.h"
 #include "prprf.h"
 #include "nsStateMap.h"
 #include "mozilla/a11y/Platform.h"
 #include "Relation.h"
@@ -1565,8 +1567,123 @@ AccessibleWrap::FireAtkShowHideEvent(Acc
     NS_ENSURE_STATE(parentObject);
 
     bool isFromUserInput = aEvent->IsFromUserInput();
     const char *signal_name = kMutationStrings[isFromUserInput][aIsAdded];
     g_signal_emit_by_name(parentObject, signal_name, indexInParent, aObject, nullptr);
 
     return NS_OK;
 }
+
+// static
+void
+AccessibleWrap::GetKeyBinding(Accessible* aAccessible, nsAString& aResult)
+{
+  // Return all key bindings including access key and keyboard shortcut.
+
+  // Get access key.
+  nsAutoString keyBindingsStr;
+  KeyBinding keyBinding = aAccessible->AccessKey();
+  if (!keyBinding.IsEmpty()) {
+    keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
+
+    Accessible* parent = aAccessible->Parent();
+    roles::Role role = parent ? parent->Role() : roles::NOTHING;
+    if (role == roles::PARENT_MENUITEM || role == roles::MENUITEM ||
+        role == roles::RADIO_MENU_ITEM || role == roles::CHECK_MENU_ITEM) {
+      // It is submenu, expose keyboard shortcuts from menu hierarchy like
+      // "s;<Alt>f:s"
+      nsAutoString keysInHierarchyStr = keyBindingsStr;
+      do {
+        KeyBinding parentKeyBinding = parent->AccessKey();
+        if (!parentKeyBinding.IsEmpty()) {
+          nsAutoString str;
+          parentKeyBinding.ToString(str, KeyBinding::eAtkFormat);
+          str.Append(':');
+
+          keysInHierarchyStr.Insert(str, 0);
+        }
+      } while ((parent = parent->Parent()) && parent->Role() != roles::MENUBAR);
+
+      keyBindingsStr.Append(';');
+      keyBindingsStr.Append(keysInHierarchyStr);
+    }
+  } else {
+    // No access key, add ';' to point this.
+    keyBindingsStr.Append(';');
+  }
+
+  // Get keyboard shortcut.
+  keyBindingsStr.Append(';');
+  keyBinding = aAccessible->KeyboardShortcut();
+  if (!keyBinding.IsEmpty()) {
+    keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
+  }
+  aResult = keyBindingsStr;
+}
+
+// static
+Accessible*
+AccessibleWrap::GetColumnHeader(TableAccessible* aAccessible, int32_t aColIdx)
+{
+  if (!aAccessible) {
+    return nullptr;
+  }
+
+  Accessible* cell = aAccessible->CellAt(0, aColIdx);
+  if (!cell) {
+    return nullptr;
+  }
+
+  // If the cell at the first row is column header then assume it is column
+  // header for all rows,
+  if (cell->Role() == roles::COLUMNHEADER) {
+    return cell;
+  }
+
+  // otherwise get column header for the data cell at the first row.
+  TableCellAccessible* tableCell = cell->AsTableCell();
+  if (!tableCell) {
+    return nullptr;
+  }
+
+  nsAutoTArray<Accessible*, 10> headerCells;
+  tableCell->ColHeaderCells(&headerCells);
+  if (headerCells.IsEmpty()) {
+    return nullptr;
+  }
+
+  return headerCells[0];
+}
+
+// static
+Accessible*
+AccessibleWrap::GetRowHeader(TableAccessible* aAccessible, int32_t aRowIdx)
+{
+  if (!aAccessible) {
+    return nullptr;
+  }
+
+  Accessible* cell = aAccessible->CellAt(aRowIdx, 0);
+  if (!cell) {
+    return nullptr;
+  }
+
+  // If the cell at the first column is row header then assume it is row
+  // header for all columns,
+  if (cell->Role() == roles::ROWHEADER) {
+    return cell;
+  }
+
+  // otherwise get row header for the data cell at the first column.
+  TableCellAccessible* tableCell = cell->AsTableCell();
+  if (!tableCell) {
+    return nullptr;
+  }
+
+  nsAutoTArray<Accessible*, 10> headerCells;
+  tableCell->RowHeaderCells(&headerCells);
+  if (headerCells.IsEmpty()) {
+    return nullptr;
+  }
+
+  return headerCells[0];
+}
--- a/accessible/atk/AccessibleWrap.h
+++ b/accessible/atk/AccessibleWrap.h
@@ -64,16 +64,22 @@ public:
   bool IsValidObject();
 
   static const char * ReturnString(nsAString &aString) {
     static nsCString returnedString;
     returnedString = NS_ConvertUTF16toUTF8(aString);
     return returnedString.get();
   }
 
+  static void GetKeyBinding(Accessible* aAccessible, nsAString& aResult);
+
+  static Accessible* GetColumnHeader(TableAccessible* aAccessible,
+                                     int32_t aColIdx);
+  static Accessible* GetRowHeader(TableAccessible* aAccessible,
+                                  int32_t aRowIdx);
 protected:
 
   nsresult FireAtkStateChangeEvent(AccEvent* aEvent, AtkObject *aObject);
   nsresult FireAtkTextChangedEvent(AccEvent* aEvent, AtkObject *aObject);
   nsresult FireAtkShowHideEvent(AccEvent* aEvent, AtkObject *aObject,
                                 bool aIsAdded);
 
   AtkObject *mAtkObject;
--- a/accessible/atk/nsMaiInterfaceAction.cpp
+++ b/accessible/atk/nsMaiInterfaceAction.cpp
@@ -5,107 +5,90 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "InterfaceInitFuncs.h"
 
 #include "Accessible-inl.h"
 #include "nsMai.h"
 #include "Role.h"
 #include "mozilla/Likely.h"
-
+#include "ProxyAccessible.h"
 #include "nsString.h"
 
 using namespace mozilla::a11y;
 
 extern "C" {
 
 static gboolean
 doActionCB(AtkAction *aAction, gint aActionIndex)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
-  return accWrap && accWrap->DoAction(aActionIndex);
+  if (accWrap) {
+    return accWrap->DoAction(aActionIndex);
+  }
+
+  ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction));
+  return proxy && proxy->DoAction(aActionIndex);
 }
 
 static gint
 getActionCountCB(AtkAction *aAction)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
-  return accWrap ? accWrap->ActionCount() : 0;
+  if (accWrap) {
+    return accWrap->ActionCount();
+  }
+
+  ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction));
+  return proxy ? proxy->ActionCount() : 0;
 }
 
 static const gchar*
 getActionDescriptionCB(AtkAction *aAction, gint aActionIndex)
 {
+  nsAutoString description;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
-  if (!accWrap)
+  if (accWrap) {
+    accWrap->ActionDescriptionAt(aActionIndex, description);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction))) {
+    proxy->ActionDescriptionAt(aActionIndex, description);
+  } else {
     return nullptr;
+  }
 
-  nsAutoString description;
-  accWrap->ActionDescriptionAt(aActionIndex, description);
   return AccessibleWrap::ReturnString(description);
 }
 
 static const gchar*
 getActionNameCB(AtkAction *aAction, gint aActionIndex)
 {
+  nsAutoString autoStr;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
-  if (!accWrap)
+  if (accWrap) {
+    accWrap->ActionNameAt(aActionIndex, autoStr);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction))) {
+    proxy->ActionNameAt(aActionIndex, autoStr);
+  } else {
     return nullptr;
+  }
 
-  nsAutoString autoStr;
-  accWrap->ActionNameAt(aActionIndex, autoStr);
   return AccessibleWrap::ReturnString(autoStr);
 }
 
 static const gchar*
 getKeyBindingCB(AtkAction *aAction, gint aActionIndex)
 {
+  nsAutoString keyBindingsStr;
   AccessibleWrap* acc = GetAccessibleWrap(ATK_OBJECT(aAction));
-  if (!acc)
+  if (acc) {
+    AccessibleWrap::GetKeyBinding(acc, keyBindingsStr);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction))) {
+    proxy->AtkKeyBinding(keyBindingsStr);
+  } else {
     return nullptr;
-
-  // Return all key bindings including access key and keyboard shortcut.
-  nsAutoString keyBindingsStr;
-
-  // Get access key.
-  KeyBinding keyBinding = acc->AccessKey();
-  if (!keyBinding.IsEmpty()) {
-    keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
-
-    Accessible* parent = acc->Parent();
-    roles::Role role = parent ? parent->Role() : roles::NOTHING;
-    if (role == roles::PARENT_MENUITEM || role == roles::MENUITEM ||
-        role == roles::RADIO_MENU_ITEM || role == roles::CHECK_MENU_ITEM) {
-      // It is submenu, expose keyboard shortcuts from menu hierarchy like
-      // "s;<Alt>f:s"
-      nsAutoString keysInHierarchyStr = keyBindingsStr;
-      do {
-        KeyBinding parentKeyBinding = parent->AccessKey();
-        if (!parentKeyBinding.IsEmpty()) {
-          nsAutoString str;
-          parentKeyBinding.ToString(str, KeyBinding::eAtkFormat);
-          str.Append(':');
-
-          keysInHierarchyStr.Insert(str, 0);
-        }
-      } while ((parent = parent->Parent()) && parent->Role() != roles::MENUBAR);
-
-      keyBindingsStr.Append(';');
-      keyBindingsStr.Append(keysInHierarchyStr);
-    }
-  } else {
-    // No access key, add ';' to point this.
-    keyBindingsStr.Append(';');
-  }
-
-  // Get keyboard shortcut.
-  keyBindingsStr.Append(';');
-  keyBinding = acc->KeyboardShortcut();
-  if (!keyBinding.IsEmpty()) {
-    keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
   }
 
   return AccessibleWrap::ReturnString(keyBindingsStr);
 }
 }
 
 void
 actionInterfaceInitCB(AtkActionIface* aIface)
--- a/accessible/atk/nsMaiInterfaceTable.cpp
+++ b/accessible/atk/nsMaiInterfaceTable.cpp
@@ -7,205 +7,260 @@
 #include "InterfaceInitFuncs.h"
 
 #include "Accessible-inl.h"
 #include "AccessibleWrap.h"
 #include "nsAccUtils.h"
 #include "TableAccessible.h"
 #include "TableCellAccessible.h"
 #include "nsMai.h"
-
+#include "ProxyAccessible.h"
 #include "nsArrayUtils.h"
 
 #include "mozilla/Likely.h"
 
 using namespace mozilla::a11y;
 
 extern "C" {
 static AtkObject*
 refAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
 {
+  if (aRowIdx < 0 || aColIdx < 0) {
+    return nullptr;
+  }
+
+  AtkObject* cellAtkObj = nullptr;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap || aRowIdx < 0 || aColIdx < 0)
-    return nullptr;
+  if (accWrap) {
+    Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, aColIdx);
+    if (!cell) {
+      return nullptr;
+    }
 
-  Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, aColIdx);
-  if (!cell)
-    return nullptr;
+    cellAtkObj = AccessibleWrap::GetAtkObject(cell);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    ProxyAccessible* cell = proxy->TableCellAt(aRowIdx, aColIdx);
+    if (!cell) {
+      return nullptr;
+    }
 
-  AtkObject* cellAtkObj = AccessibleWrap::GetAtkObject(cell);
-  if (cellAtkObj)
+    cellAtkObj = GetWrapperFor(cell);
+  }
+
+  if (cellAtkObj) {
     g_object_ref(cellAtkObj);
+  }
 
   return cellAtkObj;
 }
 
 static gint
 getIndexAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
 {
-  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap || aRowIdx < 0 || aColIdx < 0)
+  if (aRowIdx < 0 || aColIdx < 0) {
     return -1;
+  }
 
-  return static_cast<gint>(accWrap->AsTable()->CellIndexAt(aRowIdx, aColIdx));
+  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
+  if (accWrap) {
+    return static_cast<gint>(accWrap->AsTable()->CellIndexAt(aRowIdx, aColIdx));
+  }
+
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableCellIndexAt(aRowIdx, aColIdx));
+  }
+
+  return -1;
 }
 
 static gint
 getColumnAtIndexCB(AtkTable *aTable, gint aIdx)
 {
-  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap || aIdx < 0)
+  if (aIdx < 0) {
     return -1;
+  }
 
+  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
+  if (accWrap) {
     return static_cast<gint>(accWrap->AsTable()->ColIndexAt(aIdx));
+  }
+
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableColumnIndexAt(aIdx));
+  }
+
+  return -1;
 }
 
 static gint
 getRowAtIndexCB(AtkTable *aTable, gint aIdx)
 {
-  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap || aIdx < 0)
+  if (aIdx < 0) {
     return -1;
+  }
 
+  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
+  if (accWrap) {
     return static_cast<gint>(accWrap->AsTable()->RowIndexAt(aIdx));
+  }
+
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableRowIndexAt(aIdx));
+  }
+
+  return -1;
 }
 
 static gint
 getColumnCountCB(AtkTable *aTable)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return -1;
+  if (accWrap) {
+    return static_cast<gint>(accWrap->AsTable()->ColCount());
+  }
 
-    return static_cast<gint>(accWrap->AsTable()->ColCount());
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableColumnCount());
+  }
+
+  return -1;
 }
 
 static gint
 getRowCountCB(AtkTable *aTable)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return -1;
+  if (accWrap) {
+    return static_cast<gint>(accWrap->AsTable()->RowCount());
+  }
 
-    return static_cast<gint>(accWrap->AsTable()->RowCount());
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableRowCount());
+  }
+
+  return -1;
 }
 
 static gint
 getColumnExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
 {
-  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap || aRowIdx < 0 || aColIdx < 0)
+  if (aRowIdx < 0 || aColIdx < 0) {
     return -1;
+  }
 
+  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
+  if (accWrap) {
     return static_cast<gint>(accWrap->AsTable()->ColExtentAt(aRowIdx, aColIdx));
+  }
+
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableColumnExtentAt(aRowIdx, aColIdx));
+  }
+
+  return -1;
 }
 
 static gint
 getRowExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return -1;
+  if (accWrap) {
+    return static_cast<gint>(accWrap->AsTable()->RowExtentAt(aRowIdx, aColIdx));
+  }
 
-  return static_cast<gint>(accWrap->AsTable()->RowExtentAt(aRowIdx, aColIdx));
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableRowExtentAt(aRowIdx, aColIdx));
+  }
+
+  return -1;
 }
 
 static AtkObject*
 getCaptionCB(AtkTable* aTable)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return nullptr;
+  if (accWrap) {
+    Accessible* caption = accWrap->AsTable()->Caption();
+    return caption ? AccessibleWrap::GetAtkObject(caption) : nullptr;
+  }
 
-  Accessible* caption = accWrap->AsTable()->Caption();
-  return caption ? AccessibleWrap::GetAtkObject(caption) : nullptr;
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    ProxyAccessible* caption = proxy->TableCaption();
+    return caption ? GetWrapperFor(caption) : nullptr;
+  }
+
+  return nullptr;
 }
 
 static const gchar*
 getColumnDescriptionCB(AtkTable *aTable, gint aColumn)
 {
+  nsAutoString autoStr;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
+  if (accWrap) {
+    accWrap->AsTable()->ColDescription(aColumn, autoStr);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    proxy->TableColumnDescription(aColumn, autoStr);
+  } else {
     return nullptr;
-
-  nsAutoString autoStr;
-  accWrap->AsTable()->ColDescription(aColumn, autoStr);
+  }
 
   return AccessibleWrap::ReturnString(autoStr);
 }
 
 static AtkObject*
 getColumnHeaderCB(AtkTable *aTable, gint aColIdx)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return nullptr;
-
-  Accessible* cell = accWrap->AsTable()->CellAt(0, aColIdx);
-  if (!cell)
-    return nullptr;
-
-  // If the cell at the first row is column header then assume it is column
-  // header for all rows,
-  if (cell->Role() == roles::COLUMNHEADER)
-    return AccessibleWrap::GetAtkObject(cell);
+  if (accWrap) {
+    Accessible* header =
+      AccessibleWrap::GetColumnHeader(accWrap->AsTable(), aColIdx);
+    return header ? AccessibleWrap::GetAtkObject(header) : nullptr;
+  }
 
-  // otherwise get column header for the data cell at the first row.
-  TableCellAccessible* tableCell = cell->AsTableCell();
-  if (!tableCell)
-    return nullptr;
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    ProxyAccessible* header = proxy->AtkTableColumnHeader(aColIdx);
+    return header ? GetWrapperFor(header) : nullptr;
+  }
 
-  nsAutoTArray<Accessible*, 10> headerCells;
-  tableCell->ColHeaderCells(&headerCells);
-  if (headerCells.IsEmpty())
-    return nullptr;
-
-  return AccessibleWrap::GetAtkObject(headerCells[0]);
+  return nullptr;
 }
 
 static const gchar*
 getRowDescriptionCB(AtkTable *aTable, gint aRow)
 {
+  nsAutoString autoStr;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
+  if (accWrap) {
+    accWrap->AsTable()->RowDescription(aRow, autoStr);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    proxy->TableRowDescription(aRow, autoStr);
+  } else {
     return nullptr;
-
-  nsAutoString autoStr;
-  accWrap->AsTable()->RowDescription(aRow, autoStr);
+  }
 
   return AccessibleWrap::ReturnString(autoStr);
 }
 
 static AtkObject*
 getRowHeaderCB(AtkTable *aTable, gint aRowIdx)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return nullptr;
-
-  Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, 0);
-  if (!cell)
-    return nullptr;
-
-  // If the cell at the first column is row header then assume it is row
-  // header for all columns,
-  if (cell->Role() == roles::ROWHEADER)
-    return AccessibleWrap::GetAtkObject(cell);
+  if (accWrap) {
+    Accessible* header =
+      AccessibleWrap::GetRowHeader(accWrap->AsTable(), aRowIdx);
+    return header ? AccessibleWrap::GetAtkObject(header) : nullptr;
+  }
 
-  // otherwise get row header for the data cell at the first column.
-  TableCellAccessible* tableCell = cell->AsTableCell();
-  if (!tableCell)
-    return nullptr;
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    ProxyAccessible* header = proxy->AtkTableRowHeader(aRowIdx);
+    return header ? GetWrapperFor(header) : nullptr;
+  }
 
-  nsAutoTArray<Accessible*, 10> headerCells;
-  tableCell->RowHeaderCells(&headerCells);
-  if (headerCells.IsEmpty())
-    return nullptr;
-
-  return AccessibleWrap::GetAtkObject(headerCells[0]);
+  return nullptr;
 }
 
 static AtkObject*
 getSummaryCB(AtkTable *aTable)
 {
   // Neither html:table nor xul:tree nor ARIA grid/tree have an ability to
   // link an accessible object to specify a summary. There is closes method
   // in TableAccessible::summary to get a summary as a string which is not
@@ -213,22 +268,26 @@ getSummaryCB(AtkTable *aTable)
   return nullptr;
 }
 
 static gint
 getSelectedColumnsCB(AtkTable *aTable, gint** aSelected)
 {
   *aSelected = nullptr;
 
+  nsAutoTArray<uint32_t, 10> cols;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
+  if (accWrap) {
+    accWrap->AsTable()->SelectedColIndices(&cols);
+   } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    proxy->TableSelectedColumnIndices(&cols);
+  } else {
     return 0;
+  }
 
-  nsAutoTArray<uint32_t, 10> cols;
-  accWrap->AsTable()->SelectedColIndices(&cols);
   if (cols.IsEmpty())
     return 0;
 
   gint* atkColumns = g_new(gint, cols.Length());
   if (!atkColumns) {
     NS_WARNING("OUT OF MEMORY");
     return 0;
   }
@@ -236,63 +295,75 @@ getSelectedColumnsCB(AtkTable *aTable, g
   memcpy(atkColumns, cols.Elements(), cols.Length() * sizeof(uint32_t));
   *aSelected = atkColumns;
   return cols.Length();
 }
 
 static gint
 getSelectedRowsCB(AtkTable *aTable, gint **aSelected)
 {
+  nsAutoTArray<uint32_t, 10> rows;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
+  if (accWrap) {
+    accWrap->AsTable()->SelectedRowIndices(&rows);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    proxy->TableSelectedRowIndices(&rows);
+  } else {
     return 0;
-
-  nsAutoTArray<uint32_t, 10> rows;
-  accWrap->AsTable()->SelectedRowIndices(&rows);
+  }
 
   gint* atkRows = g_new(gint, rows.Length());
   if (!atkRows) {
     NS_WARNING("OUT OF MEMORY");
     return 0;
   }
 
   memcpy(atkRows, rows.Elements(), rows.Length() * sizeof(uint32_t));
   *aSelected = atkRows;
   return rows.Length();
 }
 
 static gboolean
 isColumnSelectedCB(AtkTable *aTable, gint aColIdx)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return FALSE;
+  if (accWrap) {
+    return static_cast<gboolean>(accWrap->AsTable()->IsColSelected(aColIdx));
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gboolean>(proxy->TableColumnSelected(aColIdx));
+  }
 
-  return static_cast<gboolean>(accWrap->AsTable()->IsColSelected(aColIdx));
+  return FALSE;
 }
 
 static gboolean
 isRowSelectedCB(AtkTable *aTable, gint aRowIdx)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return FALSE;
+  if (accWrap) {
+    return static_cast<gboolean>(accWrap->AsTable()->IsRowSelected(aRowIdx));
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gboolean>(proxy->TableRowSelected(aRowIdx));
+  }
 
-  return static_cast<gboolean>(accWrap->AsTable()->IsRowSelected(aRowIdx));
+  return FALSE;
 }
 
 static gboolean
 isCellSelectedCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return FALSE;
-
+  if (accWrap) {
     return static_cast<gboolean>(accWrap->AsTable()->
       IsCellSelected(aRowIdx, aColIdx));
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gboolean>(proxy->TableCellSelected(aRowIdx, aColIdx));
+  }
+
+  return FALSE;
 }
 }
 
 void
 tableInterfaceInitCB(AtkTableIface* aIface)
 {
   NS_ASSERTION(aIface, "no interface!");
   if (MOZ_UNLIKELY(!aIface))
--- a/accessible/ipc/DocAccessibleChild.cpp
+++ b/accessible/ipc/DocAccessibleChild.cpp
@@ -12,16 +12,19 @@
 #include "HyperTextAccessible-inl.h"
 #include "TextLeafAccessible.h"
 #include "ImageAccessible.h"
 #include "TableAccessible.h"
 #include "TableCellAccessible.h"
 #include "nsIPersistentProperties2.h"
 #include "nsISimpleEnumerator.h"
 #include "nsAccUtils.h"
+#ifdef MOZ_ACCESSIBILITY_ATK
+#include "AccessibleWrap.h"
+#endif
 
 namespace mozilla {
 namespace a11y {
 
 static uint32_t
 InterfacesFor(Accessible* aAcc)
 {
   uint32_t interfaces = 0;
@@ -1445,16 +1448,62 @@ DocAccessibleChild::RecvTableIsProbablyF
   if (acc) {
     *aForLayout = acc->IsProbablyLayoutTable();
   }
 
   return true;
 }
 
 bool
+DocAccessibleChild::RecvAtkTableColumnHeader(const uint64_t& aID,
+                                             const int32_t& aCol,
+                                             uint64_t* aHeader,
+                                             bool* aOk)
+{
+  *aHeader = 0;
+  *aOk = false;
+
+#ifdef MOZ_ACCESSIBILITY_ATK
+  TableAccessible* acc = IdToTableAccessible(aID);
+  if (acc) {
+    Accessible* header = AccessibleWrap::GetColumnHeader(acc, aCol);
+    if (header) {
+      *aHeader = reinterpret_cast<uint64_t>(header->UniqueID());
+      *aOk = true;
+    }
+  }
+#endif
+
+  return true;
+}
+
+bool
+DocAccessibleChild::RecvAtkTableRowHeader(const uint64_t& aID,
+                                          const int32_t& aRow,
+                                          uint64_t* aHeader,
+                                          bool* aOk)
+{
+  *aHeader = 0;
+  *aOk = false;
+
+#ifdef MOZ_ACCESSIBILITY_ATK
+  TableAccessible* acc = IdToTableAccessible(aID);
+  if (acc) {
+    Accessible* header = AccessibleWrap::GetRowHeader(acc, aRow);
+    if (header) {
+      *aHeader = reinterpret_cast<uint64_t>(header->UniqueID());
+      *aOk = true;
+    }
+  }
+#endif
+
+  return true;
+}
+
+bool
 DocAccessibleChild::RecvSelectedItems(const uint64_t& aID,
                                       nsTArray<uint64_t>* aSelectedItemIDs)
 {
   Accessible* acc = IdToAccessibleSelect(aID);
   if (acc) {
     nsAutoTArray<Accessible*, 10> selectedItems;
     acc->SelectedItems(&selectedItems);
     aSelectedItemIDs->SetCapacity(selectedItems.Length());
@@ -1651,16 +1700,29 @@ DocAccessibleChild::RecvKeyboardShortcut
     *aKey = kb.Key();
     *aModifierMask = kb.ModifierMask();
   }
 
   return true;
 }
 
 bool
+DocAccessibleChild::RecvAtkKeyBinding(const uint64_t& aID,
+                                      nsString* aResult)
+{
+#ifdef MOZ_ACCESSIBILITY_ATK
+  Accessible* acc = IdToAccessible(aID);
+  if (acc) {
+    AccessibleWrap::GetKeyBinding(acc, *aResult);
+  }
+#endif
+  return true;
+}
+
+bool
 DocAccessibleChild::RecvCurValue(const uint64_t& aID,
                                  double* aValue)
 {
   *aValue = UnspecifiedNaN<double>();
   Accessible* acc = IdToAccessible(aID);
   if (acc) {
     *aValue = acc->CurValue();
   }
--- a/accessible/ipc/DocAccessibleChild.h
+++ b/accessible/ipc/DocAccessibleChild.h
@@ -358,16 +358,24 @@ public:
   virtual bool RecvTableSelectRow(const uint64_t& aID,
                                   const uint32_t& aRow) override;
   virtual bool RecvTableUnselectColumn(const uint64_t& aID,
                                        const uint32_t& aCol) override;
   virtual bool RecvTableUnselectRow(const uint64_t& aID,
                                     const uint32_t& aRow) override;
   virtual bool RecvTableIsProbablyForLayout(const uint64_t& aID,
                                             bool* aForLayout) override;
+  virtual bool RecvAtkTableColumnHeader(const uint64_t& aID,
+                                        const int32_t& aCol,
+                                        uint64_t* aHeader,
+                                        bool* aOk) override;
+  virtual bool RecvAtkTableRowHeader(const uint64_t& aID,
+                                     const int32_t& aRow,
+                                     uint64_t* aHeader,
+                                     bool* aOk) override;
 
   virtual bool RecvSelectedItems(const uint64_t& aID,
                                  nsTArray<uint64_t>* aSelectedItemIDs) override;
 
   virtual bool RecvSelectedItemCount(const uint64_t& aID,
                                      uint32_t* aCount) override;
 
   virtual bool RecvGetSelectedItem(const uint64_t& aID,
@@ -411,16 +419,19 @@ public:
   virtual bool RecvAccessKey(const uint64_t& aID,
                              uint32_t* aKey,
                              uint32_t* aModifierMask) override;
 
   virtual bool RecvKeyboardShortcut(const uint64_t& aID,
                                     uint32_t* aKey,
                                     uint32_t* aModifierMask) override;
 
+  virtual bool RecvAtkKeyBinding(const uint64_t& aID,
+                                 nsString* aResult) override;
+
   virtual bool RecvCurValue(const uint64_t& aID,
                             double* aValue) override;
 
   virtual bool RecvSetCurValue(const uint64_t& aID,
                                const double& aValue,
                                bool* aRetVal) override;
 
   virtual bool RecvMinValue(const uint64_t& aID,
--- a/accessible/ipc/PDocAccessible.ipdl
+++ b/accessible/ipc/PDocAccessible.ipdl
@@ -197,32 +197,37 @@ child:
   prio(high) sync TableSelectedCellIndices(uint64_t aID) returns(uint32_t[] aCellIndeces);
   prio(high) sync TableSelectedColumnIndices(uint64_t aID) returns(uint32_t[] aColumnIndeces);
   prio(high) sync TableSelectedRowIndices(uint64_t aID) returns(uint32_t[] aRowIndeces);
   prio(high) sync TableSelectColumn(uint64_t aID, uint32_t aCol);
   prio(high) sync TableSelectRow(uint64_t aID, uint32_t aRow);
   prio(high) sync TableUnselectColumn(uint64_t aID, uint32_t aCol);
   prio(high) sync TableUnselectRow(uint64_t aID, uint32_t aRow);
   prio(high) sync TableIsProbablyForLayout(uint64_t aID) returns(bool aForLayout);
+  prio(high) sync AtkTableColumnHeader(uint64_t aID, int32_t aCol)
+    returns(uint64_t aHeaderID, bool aOk);
+  prio(high) sync AtkTableRowHeader(uint64_t aID, int32_t aRow)
+    returns(uint64_t aHeaderID, bool aOk);
 
   prio(high) sync SelectedItems(uint64_t aID) returns(uint64_t[] aSelectedItemIDs);
   prio(high) sync SelectedItemCount(uint64_t aID) returns(uint32_t aCount);
   prio(high) sync GetSelectedItem(uint64_t aID, uint32_t aIndex) returns(uint64_t aSelected, bool aOk);
   prio(high) sync IsItemSelected(uint64_t aID, uint32_t aIndex) returns(bool aSelected);
   prio(high) sync AddItemToSelection(uint64_t aID, uint32_t aIndex) returns(bool aSuccess);
   prio(high) sync RemoveItemFromSelection(uint64_t aID, uint32_t aIndex) returns(bool aSuccess);
   prio(high) sync SelectAll(uint64_t aID) returns(bool aSuccess);
   prio(high) sync UnselectAll(uint64_t aID) returns(bool aSuccess);
 
   prio(high) sync DoAction(uint64_t aID, uint8_t aIndex) returns(bool aSuccess);
   prio(high) sync ActionCount(uint64_t aID) returns(uint8_t aCount);
   prio(high) sync ActionDescriptionAt(uint64_t aID, uint8_t aIndex) returns(nsString aDescription);
   prio(high) sync ActionNameAt(uint64_t aID, uint8_t aIndex) returns(nsString aName);
   prio(high) sync AccessKey(uint64_t aID) returns(uint32_t aKey, uint32_t aModifierMask);
   prio(high) sync KeyboardShortcut(uint64_t aID) returns(uint32_t aKey, uint32_t aModifierMask);
+  prio(high) sync AtkKeyBinding(uint64_t aID) returns(nsString aResult);
 
   prio(high) sync CurValue(uint64_t aID) returns(double aValue);
   prio(high) sync SetCurValue(uint64_t aID, double aValue) returns(bool aRetVal);
   prio(high) sync MinValue(uint64_t aID) returns(double aValue);
   prio(high) sync MaxValue(uint64_t aID) returns(double aValue);
   prio(high) sync Step(uint64_t aID) returns(double aStep);
 
   async TakeFocus(uint64_t aID);
--- a/accessible/ipc/ProxyAccessible.cpp
+++ b/accessible/ipc/ProxyAccessible.cpp
@@ -815,16 +815,34 @@ ProxyAccessible::TableUnselectRow(uint32
 bool
 ProxyAccessible::TableIsProbablyForLayout()
 {
   bool forLayout = false;
   unused << mDoc->SendTableIsProbablyForLayout(mID, &forLayout);
   return forLayout;
 }
 
+ProxyAccessible*
+ProxyAccessible::AtkTableColumnHeader(int32_t aCol)
+{
+  uint64_t headerID = 0;
+  bool ok = false;
+  unused << mDoc->SendAtkTableColumnHeader(mID, aCol, &headerID, &ok);
+  return ok ? mDoc->GetAccessible(headerID) : nullptr;
+}
+
+ProxyAccessible*
+ProxyAccessible::AtkTableRowHeader(int32_t aRow)
+{
+  uint64_t headerID = 0;
+  bool ok = false;
+  unused << mDoc->SendAtkTableRowHeader(mID, aRow, &headerID, &ok);
+  return ok ? mDoc->GetAccessible(headerID) : nullptr;
+}
+
 void
 ProxyAccessible::SelectedItems(nsTArray<ProxyAccessible*>* aSelectedItems)
 {
   nsAutoTArray<uint64_t, 10> itemIDs;
   unused << mDoc->SendSelectedItems(mID, &itemIDs);
   aSelectedItems->SetCapacity(itemIDs.Length());
   for (size_t i = 0; i < itemIDs.Length(); ++i) {
     aSelectedItems->AppendElement(mDoc->GetAccessible(itemIDs[i]));
@@ -929,16 +947,22 @@ KeyBinding
 ProxyAccessible::KeyboardShortcut()
 {
   uint32_t key = 0;
   uint32_t modifierMask = 0;
   unused << mDoc->SendKeyboardShortcut(mID, &key, &modifierMask);
   return KeyBinding(key, modifierMask);
 }
 
+void
+ProxyAccessible::AtkKeyBinding(nsString& aBinding)
+{
+  unused << mDoc->SendAtkKeyBinding(mID, &aBinding);
+}
+
 double
 ProxyAccessible::CurValue()
 {
   double val = UnspecifiedNaN<double>();
   unused << mDoc->SendCurValue(mID, &val);
   return val;
 }
 
--- a/accessible/ipc/ProxyAccessible.h
+++ b/accessible/ipc/ProxyAccessible.h
@@ -292,32 +292,35 @@ public:
   void TableSelectedCellIndices(nsTArray<uint32_t>* aCellIndices);
   void TableSelectedColumnIndices(nsTArray<uint32_t>* aColumnIndices);
   void TableSelectedRowIndices(nsTArray<uint32_t>* aRowIndices);
   void TableSelectColumn(uint32_t aCol);
   void TableSelectRow(uint32_t aRow);
   void TableUnselectColumn(uint32_t aCol);
   void TableUnselectRow(uint32_t aRow);
   bool TableIsProbablyForLayout();
+  ProxyAccessible* AtkTableColumnHeader(int32_t aCol);
+  ProxyAccessible* AtkTableRowHeader(int32_t aRow);
 
   void SelectedItems(nsTArray<ProxyAccessible*>* aSelectedItems);
   uint32_t SelectedItemCount();
   ProxyAccessible* GetSelectedItem(uint32_t aIndex);
   bool IsItemSelected(uint32_t aIndex);
   bool AddItemToSelection(uint32_t aIndex);
   bool RemoveItemFromSelection(uint32_t aIndex);
   bool SelectAll();
   bool UnselectAll();
 
   bool DoAction(uint8_t aIndex);
   uint8_t ActionCount();
   void ActionDescriptionAt(uint8_t aIndex, nsString& aDescription);
   void ActionNameAt(uint8_t aIndex, nsString& aName);
   KeyBinding AccessKey();
   KeyBinding KeyboardShortcut();
+  void AtkKeyBinding(nsString& aBinding);
 
   double CurValue();
   bool SetCurValue(double aValue);
   double MinValue();
   double MaxValue();
   double Step();
 
   void TakeFocus();
--- a/accessible/tests/mochitest/jsat/dom_helper.js
+++ b/accessible/tests/mochitest/jsat/dom_helper.js
@@ -1,16 +1,16 @@
 'use strict';
 
 /* global getMainChromeWindow, AccessFuTest, GestureSettings, GestureTracker,
    SimpleTest, getBoundsForDOMElm, Point, Utils */
 /* exported loadJSON, eventMap */
 
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 Cu.import('resource://gre/modules/accessibility/Utils.jsm');
 Cu.import('resource://gre/modules/Geometry.jsm');
 Cu.import("resource://gre/modules/accessibility/Gestures.jsm");
 
 var win = getMainChromeWindow(window);
 
 /**
--- a/accessible/tests/mochitest/jsat/output.js
+++ b/accessible/tests/mochitest/jsat/output.js
@@ -1,9 +1,9 @@
-const Cu = Components.utils;
+var Cu = Components.utils;
 const PREF_UTTERANCE_ORDER = "accessibility.accessfu.utterance";
 
 Cu.import('resource://gre/modules/accessibility/Utils.jsm');
 Cu.import("resource://gre/modules/accessibility/OutputGenerator.jsm", this);
 
 /**
  * Test context output generation.
  *
--- a/accessible/tests/mochitest/relations.js
+++ b/accessible/tests/mochitest/relations.js
@@ -1,31 +1,31 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Constants
 
-const RELATION_CONTROLLED_BY = nsIAccessibleRelation.RELATION_CONTROLLED_BY;
-const RELATION_CONTROLLER_FOR = nsIAccessibleRelation.RELATION_CONTROLLER_FOR;
-const RELATION_DEFAULT_BUTTON = nsIAccessibleRelation.RELATION_DEFAULT_BUTTON;
-const RELATION_DESCRIBED_BY = nsIAccessibleRelation.RELATION_DESCRIBED_BY;
-const RELATION_DESCRIPTION_FOR = nsIAccessibleRelation.RELATION_DESCRIPTION_FOR;
-const RELATION_EMBEDDED_BY = nsIAccessibleRelation.RELATION_EMBEDDED_BY;
-const RELATION_EMBEDS = nsIAccessibleRelation.RELATION_EMBEDS;
-const RELATION_FLOWS_FROM = nsIAccessibleRelation.RELATION_FLOWS_FROM;
-const RELATION_FLOWS_TO = nsIAccessibleRelation.RELATION_FLOWS_TO;
-const RELATION_LABEL_FOR = nsIAccessibleRelation.RELATION_LABEL_FOR;
-const RELATION_LABELLED_BY = nsIAccessibleRelation.RELATION_LABELLED_BY;
-const RELATION_MEMBER_OF = nsIAccessibleRelation.RELATION_MEMBER_OF;
-const RELATION_NODE_CHILD_OF = nsIAccessibleRelation.RELATION_NODE_CHILD_OF;
-const RELATION_NODE_PARENT_OF = nsIAccessibleRelation.RELATION_NODE_PARENT_OF;
-const RELATION_PARENT_WINDOW_OF = nsIAccessibleRelation.RELATION_PARENT_WINDOW_OF;
-const RELATION_POPUP_FOR = nsIAccessibleRelation.RELATION_POPUP_FOR;
-const RELATION_SUBWINDOW_OF = nsIAccessibleRelation.RELATION_SUBWINDOW_OF;
-const RELATION_CONTAINING_DOCUMENT = nsIAccessibleRelation.RELATION_CONTAINING_DOCUMENT;
-const RELATION_CONTAINING_TAB_PANE = nsIAccessibleRelation.RELATION_CONTAINING_TAB_PANE;
-const RELATION_CONTAINING_APPLICATION = nsIAccessibleRelation.RELATION_CONTAINING_APPLICATION;
+var RELATION_CONTROLLED_BY = nsIAccessibleRelation.RELATION_CONTROLLED_BY;
+var RELATION_CONTROLLER_FOR = nsIAccessibleRelation.RELATION_CONTROLLER_FOR;
+var RELATION_DEFAULT_BUTTON = nsIAccessibleRelation.RELATION_DEFAULT_BUTTON;
+var RELATION_DESCRIBED_BY = nsIAccessibleRelation.RELATION_DESCRIBED_BY;
+var RELATION_DESCRIPTION_FOR = nsIAccessibleRelation.RELATION_DESCRIPTION_FOR;
+var RELATION_EMBEDDED_BY = nsIAccessibleRelation.RELATION_EMBEDDED_BY;
+var RELATION_EMBEDS = nsIAccessibleRelation.RELATION_EMBEDS;
+var RELATION_FLOWS_FROM = nsIAccessibleRelation.RELATION_FLOWS_FROM;
+var RELATION_FLOWS_TO = nsIAccessibleRelation.RELATION_FLOWS_TO;
+var RELATION_LABEL_FOR = nsIAccessibleRelation.RELATION_LABEL_FOR;
+var RELATION_LABELLED_BY = nsIAccessibleRelation.RELATION_LABELLED_BY;
+var RELATION_MEMBER_OF = nsIAccessibleRelation.RELATION_MEMBER_OF;
+var RELATION_NODE_CHILD_OF = nsIAccessibleRelation.RELATION_NODE_CHILD_OF;
+var RELATION_NODE_PARENT_OF = nsIAccessibleRelation.RELATION_NODE_PARENT_OF;
+var RELATION_PARENT_WINDOW_OF = nsIAccessibleRelation.RELATION_PARENT_WINDOW_OF;
+var RELATION_POPUP_FOR = nsIAccessibleRelation.RELATION_POPUP_FOR;
+var RELATION_SUBWINDOW_OF = nsIAccessibleRelation.RELATION_SUBWINDOW_OF;
+var RELATION_CONTAINING_DOCUMENT = nsIAccessibleRelation.RELATION_CONTAINING_DOCUMENT;
+var RELATION_CONTAINING_TAB_PANE = nsIAccessibleRelation.RELATION_CONTAINING_TAB_PANE;
+var RELATION_CONTAINING_APPLICATION = nsIAccessibleRelation.RELATION_CONTAINING_APPLICATION;
 
 ////////////////////////////////////////////////////////////////////////////////
 // General
 
 /**
  * Test the accessible relation.
  *
  * @param aIdentifier          [in] identifier to get an accessible, may be ID
--- a/accessible/windows/ia2/ia2Accessible.cpp
+++ b/accessible/windows/ia2/ia2Accessible.cpp
@@ -13,16 +13,17 @@
 
 #include "Compatibility.h"
 #include "ia2AccessibleRelation.h"
 #include "IUnknownImpl.h"
 #include "nsCoreUtils.h"
 #include "nsIAccessibleTypes.h"
 #include "mozilla/a11y/PDocAccessible.h"
 #include "Relation.h"
+#include "nsAccessibilityService.h"
 
 #include "nsIPersistentProperties2.h"
 #include "nsISimpleEnumerator.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 template<typename String> static void EscapeAttributeChars(String& aStr);
@@ -646,17 +647,37 @@ ia2Accessible::get_accessibleWithCaret(I
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aAccessible || !aCaretOffset)
     return E_INVALIDARG;
 
   *aAccessible = nullptr;
   *aCaretOffset = -1;
-  return E_NOTIMPL;
+
+  AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
+  if (acc->IsDefunct())
+    return CO_E_OBJNOTCONNECTED;
+
+  int32_t caretOffset = -1;
+  Accessible* accWithCaret = SelectionMgr()->AccessibleWithCaret(&caretOffset);
+  if (acc->Document() != accWithCaret->Document())
+    return S_FALSE;
+
+  Accessible* child = accWithCaret;
+  while (child != acc)
+    child = child->Parent();
+
+  if (!child)
+    return S_FALSE;
+
+  *aAccessible =  static_cast<IAccessible2*>(
+    static_cast<AccessibleWrap*>(accWithCaret));
+  *aCaretOffset = caretOffset;
+  return S_OK;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_relationTargetsOfType(BSTR aType,
                                          long aMaxTargets,
                                          IUnknown*** aTargets,
--- a/addon-sdk/source/modules/system/Startup.js
+++ b/addon-sdk/source/modules/system/Startup.js
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 var EXPORTED_SYMBOLS = ["Startup"];
 
-const { utils: Cu, interfaces: Ci, classes: Cc } = Components;
+var { utils: Cu, interfaces: Ci, classes: Cc } = Components;
 const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 const { defer } = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
 
 const { XulApp } = Cu.import("resource://gre/modules/commonjs/sdk/system/xul-app.jsm", {});
 
 const appStartupSrv = Cc["@mozilla.org/toolkit/app-startup;1"]
                        .getService(Ci.nsIAppStartup);
 
--- a/addon-sdk/source/python-lib/cuddlefish/mobile-utils/bootstrap.js
+++ b/addon-sdk/source/python-lib/cuddlefish/mobile-utils/bootstrap.js
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 
 var { log } = console;
 
 function startup(data, reason) {
   // This code allow to make all stdIO work
   try {
--- a/addon-sdk/source/test/fixtures/addon/bootstrap.js
+++ b/addon-sdk/source/test/fixtures/addon/bootstrap.js
@@ -1,9 +1,9 @@
 /* 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";
 
 const { utils: Cu } = Components;
 const {require} = Cu.import(`${ROOT}/toolkit/require.js`, {});
 const {Bootstrap} = require(`${ROOT}/sdk/addon/bootstrap.js`);
-const {startup, shutdown, install, uninstall} = new Bootstrap();
+var {startup, shutdown, install, uninstall} = new Bootstrap();
--- a/addon-sdk/source/test/test-content-script.js
+++ b/addon-sdk/source/test/test-content-script.js
@@ -722,17 +722,17 @@ exports["test requestAnimationFrame"] = 
     }
   );
 
 });
 
 exports["testGlobalScope"] = createProxyTest("", function (helper) {
 
   helper.createWorker(
-    'let toplevelScope = true;' +
+    'var toplevelScope = true;' +
     'assert(window.toplevelScope, "variables in toplevel scope are set to `window` object");' +
     'assert(this.toplevelScope, "variables in toplevel scope are set to `this` object");' +
     'done();'
   );
 
 });
 
 // Bug 715755: proxy code throw an exception on COW
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -3,20 +3,20 @@
 /* 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";
 
 window.performance.mark('gecko-settings-loadstart');
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 // The load order is important here SettingsRequestManager _must_ be loaded
 // prior to using SettingsListener otherwise there is a race in acquiring the
 // lock and fulfilling it. If we ever move SettingsListener or this file down in
 // the load order of shell.html things will likely break.
 Cu.import('resource://gre/modules/SettingsRequestManager.jsm');
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.import('resource://gre/modules/Services.jsm');
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -1497,17 +1497,17 @@ const saveWindowGeometry = () => {
   window.removeEventListener("unload", saveWindowGeometry);
   Services.prefs.setIntPref("b2g.nativeWindowGeometry.screenX", screenX);
   Services.prefs.setIntPref("b2g.nativeWindowGeometry.screenY", screenY);
   Services.prefs.setIntPref("b2g.nativeWindowGeometry.width", outerWidth);
   Services.prefs.setIntPref("b2g.nativeWindowGeometry.height", outerHeight);
 }
 window.addEventListener("unload", saveWindowGeometry);
 
-let baseWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
+var baseWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIWebNavigation)
                        .QueryInterface(Ci.nsIDocShellTreeItem)
                        .treeOwner
                        .QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIBaseWindow);
 
 const showNativeWindow = () => baseWindow.visibility = true;
 const hideNativeWindow = () => baseWindow.visibility = false;
--- a/b2g/chrome/content/shell_remote.js
+++ b/b2g/chrome/content/shell_remote.js
@@ -1,25 +1,25 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
 /* 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";
 
-const {utils: Cu} = Components;
+var {utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 
 function debug(aStr) {
   // dump(" -*- ShellRemote.js: " + aStr + "\n");
 }
 
-let remoteShell = {
+var remoteShell = {
 
   get homeURL() {
     let systemAppManifestURL = Services.io.newURI(this.systemAppManifestURL, null, null);
     let shellRemoteURL = Services.prefs.getCharPref("b2g.multiscreen.system_remote_url");
     shellRemoteURL = Services.io.newURI(shellRemoteURL, null, systemAppManifestURL);
     return shellRemoteURL.spec;
   },
 
--- a/b2g/chrome/content/test/mochitest/RecordingStatusChromeScript.js
+++ b/b2g/chrome/content/test/mochitest/RecordingStatusChromeScript.js
@@ -1,12 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
 const { Services } = Cu.import('resource://gre/modules/Services.jsm');
 const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
 
 var processId;
 
 function peekChildId(aSubject, aTopic, aData) {
   Services.obs.removeObserver(peekChildId, 'recording-device-events');
   Services.obs.removeObserver(peekChildId, 'recording-device-ipc-events');
--- a/b2g/components/MultiscreenHandler.jsm
+++ b/b2g/components/MultiscreenHandler.jsm
@@ -10,21 +10,21 @@ const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 
 function debug(aStr) {
   // dump("MultiscreenHandler: " + aStr + "\n");
 }
 
-let window = Services.wm.getMostRecentWindow("navigator:browser");
+var window = Services.wm.getMostRecentWindow("navigator:browser");
 
 // Multi-screen support on b2g. The following implementation will open a new
 // top-level window once we receive a display connected event.
-let MultiscreenHandler = {
+var MultiscreenHandler = {
 
   topLevelWindows: new Map(),
 
   init: function init() {
     Services.obs.addObserver(this, "display-changed", false);
     Services.obs.addObserver(this, "xpcom-shutdown", false);
   },
 
--- a/b2g/components/test/mochitest/filepicker_path_handler_chrome.js
+++ b/b2g/components/test/mochitest/filepicker_path_handler_chrome.js
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 'use strict';
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 // use ppmm to handle file-picker message.
 var ppmm = Cc['@mozilla.org/parentprocessmessagemanager;1']
              .getService(Ci.nsIMessageListenerManager);
 
 var pickResult = null;
 
 function processPickMessage(message) {
--- a/b2g/components/test/mochitest/permission_handler_chrome.js
+++ b/b2g/components/test/mochitest/permission_handler_chrome.js
@@ -3,19 +3,19 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 function debug(str) {
   dump("CHROME PERMISSON HANDLER -- " + str + "\n");
 }
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
 const { SystemAppProxy } = Cu.import("resource://gre/modules/SystemAppProxy.jsm");
 
 var eventHandler = function(evt) {
   if (!evt.detail || evt.detail.type !== "permission-prompt") {
     return;
   }
--- a/b2g/components/test/mochitest/presentation_prompt_handler_chrome.js
+++ b/b2g/components/test/mochitest/presentation_prompt_handler_chrome.js
@@ -3,17 +3,17 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 'use strict';
 
  function debug(str) {
    dump('presentation_prompt_handler_chrome: ' + str + '\n');
  }
 
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
 
 const manager = Cc["@mozilla.org/presentation-device/manager;1"]
                   .getService(Ci.nsIPresentationDeviceManager);
 
 const prompt = Cc['@mozilla.org/presentation-device/prompt;1']
                  .getService(Ci.nsIPresentationDevicePrompt);
--- a/b2g/components/test/mochitest/presentation_ui_glue_handler_chrome.js
+++ b/b2g/components/test/mochitest/presentation_ui_glue_handler_chrome.js
@@ -1,15 +1,15 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 'use strict';
 
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
 
 const glue = Cc["@mozilla.org/presentation/requestuiglue;1"]
              .createInstance(Ci.nsIPresentationRequestUIGlue);
 
 SystemAppProxy.addEventListener('mozPresentationChromeEvent', function(aEvent) {
   if (!aEvent.detail || aEvent.detail.type !== 'presentation-launch-receiver') {
--- a/b2g/components/test/mochitest/screenshot_helper.js
+++ b/b2g/components/test/mochitest/screenshot_helper.js
@@ -1,10 +1,10 @@
-const Cu = Components.utils;
-const Ci = Components.interfaces;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
 
 Cu.importGlobalProperties(['File']);
 
 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
 
 // Load a duplicated copy of the jsm to prevent messing with the currently running one
 var scope = {};
 Services.scriptloader.loadSubScript("resource://gre/modules/Screenshot.jsm", scope);
--- a/b2g/components/test/mochitest/systemapp_helper.js
+++ b/b2g/components/test/mochitest/systemapp_helper.js
@@ -1,9 +1,9 @@
-const Cu = Components.utils;
+var Cu = Components.utils;
 
 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
 
 // Load a duplicated copy of the jsm to prevent messing with the currently running one
 var scope = {};
 Services.scriptloader.loadSubScript("resource://gre/modules/SystemAppProxy.jsm", scope);
 const { SystemAppProxy } = scope;
 
--- a/b2g/components/test/unit/file_killswitch.js
+++ b/b2g/components/test/unit/file_killswitch.js
@@ -1,15 +1,15 @@
 /* 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";
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/NetUtil.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
 
 var kUserValues;
--- a/b2g/components/test/unit/head_identity.js
+++ b/b2g/components/test/unit/head_identity.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 // The following boilerplate makes sure that XPCOM calls
 // that use the profile directory work.
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "MinimalIDService",
--- a/b2g/components/test/unit/head_logshake_gonk.js
+++ b/b2g/components/test/unit/head_logshake_gonk.js
@@ -9,19 +9,19 @@
    do_get_profile, OS, volumeService, equal, XPCOMUtils */
 /* exported setup_logshake_mocks */
 
 /* disable use strict warning */
 /* jshint -W097 */
 
 "use strict";
 
-const Cu = Components.utils;
-const Ci = Components.interfaces;
-const Cc = Components.classes;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "volumeService",
                                    "@mozilla.org/telephony/volume-service;1",
                                    "nsIVolumeService");
 
--- a/b2g/components/test/unit/test_aboutserviceworkers.js
+++ b/b2g/components/test/unit/test_aboutserviceworkers.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {utils: Cu} = Components;
+var {utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "AboutServiceWorkers",
   "resource://gre/modules/AboutServiceWorkers.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gServiceWorkerManager",
--- a/b2g/components/test/unit/test_fxaccounts.js
+++ b/b2g/components/test/unit/test_fxaccounts.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {utils: Cu} = Components;
+var {utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://testing-common/httpd.js");
 
 XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsMgmtService",
   "resource://gre/modules/FxAccountsMgmtService.jsm",
--- a/b2g/components/test/unit/test_killswitch.js
+++ b/b2g/components/test/unit/test_killswitch.js
@@ -1,15 +1,15 @@
 /* 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";
 
-const {results: Cr} = Components;
+var {results: Cr} = Components;
 
 // Trivial test just to make sure we have no syntax error
 add_test(function test_ksm_ok() {
   ok(KillSwitchMain, "KillSwitchMain object exists");
 
   run_next_test();
 });
 
--- a/b2g/components/test/unit/test_logparser.js
+++ b/b2g/components/test/unit/test_logparser.js
@@ -1,11 +1,11 @@
 /* jshint moz: true */
 
-const {utils: Cu, classes: Cc, interfaces: Ci} = Components;
+var {utils: Cu, classes: Cc, interfaces: Ci} = Components;
 
 function debug(msg) {
   var timestamp = Date.now();
   dump("LogParser: " + timestamp + ": " + msg + "\n");
 }
 
 function run_test() {
   Cu.import("resource:///modules/LogParser.jsm");
--- a/b2g/components/test/unit/test_logshake.js
+++ b/b2g/components/test/unit/test_logshake.js
@@ -5,17 +5,17 @@
 /* jshint moz: true */
 /* global Components, LogCapture, LogShake, ok, add_test, run_next_test, dump */
 /* exported run_test */
 
 /* disable use strict warning */
 /* jshint -W097 */
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/LogCapture.jsm");
 Cu.import("resource://gre/modules/LogShake.jsm");
 
 const EVENTS_PER_SECOND = 6.25;
 const GRAVITY = 9.8;
 
 /**
--- a/b2g/simulator/bootstrap.js
+++ b/b2g/simulator/bootstrap.js
@@ -1,10 +1,10 @@
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 
 // Useful piece of code from :bent
 // http://mxr.mozilla.org/mozilla-central/source/dom/workers/test/extensions/bootstrap/bootstrap.js
 function registerAddonResourceHandler(data) {
   let file = data.installPath;
   let fileuri = file.isDirectory() ?
--- a/browser/base/content/aboutaccounts/aboutaccounts.js
+++ b/browser/base/content/aboutaccounts/aboutaccounts.js
@@ -1,15 +1,15 @@
 /* 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";
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/FxAccounts.jsm");
 
 var fxAccountsCommon = {};
 Cu.import("resource://gre/modules/FxAccountsCommon.js", fxAccountsCommon);
 
 // for master-password utilities
--- a/browser/base/content/abouthealthreport/abouthealth.js
+++ b/browser/base/content/abouthealthreport/abouthealth.js
@@ -1,15 +1,15 @@
 /* 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";
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 const prefs = new Preferences("datareporting.healthreport.");
 
 const PREF_UNIFIED = "toolkit.telemetry.unified";
 const PREF_UNIFIED_OPTIN = "toolkit.telemetry.unifiedIsOptIn";
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3717,16 +3717,18 @@ const BrowserSearch = {
   },
 
   recordOneoffSearchInTelemetry: function (engine, source, type, where) {
     let id = this._getSearchEngineId(engine) + "." + source;
     BrowserUITelemetry.countOneoffSearchEvent(id, type, where);
   }
 };
 
+XPCOMUtils.defineConstant(this, "BrowserSearch", BrowserSearch);
+
 function FillHistoryMenu(aParent) {
   // Lazily add the hover listeners on first showing and never remove them
   if (!aParent.hasStatusListener) {
     // Show history item's uri in the status bar when hovering, and clear on exit
     aParent.addEventListener("DOMMenuItemActive", function(aEvent) {
       // Only the current page should have the checked attribute, so skip it
       if (!aEvent.target.hasAttribute("checked"))
         XULBrowserWindow.setOverLink(aEvent.target.getAttribute("uri"));
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource://gre/modules/LoadContextInfo.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 //******** define a js object to implement nsITreeView
 function pageInfoTreeView(treeid, copycol)
 {
   // copycol is the index number for the column that we want to add to
   // the copy-n-paste buffer when the user hits accel-c
--- a/browser/base/content/sanitizeDialog.js
+++ b/browser/base/content/sanitizeDialog.js
@@ -1,18 +1,18 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
-let {Sanitizer} = Cu.import("resource:///modules/Sanitizer.jsm", {});
+var {Sanitizer} = Cu.import("resource:///modules/Sanitizer.jsm", {});
 
 var gSanitizePromptDialog = {
 
   get bundleBrowser()
   {
     if (!this._bundleBrowser)
       this._bundleBrowser = document.getElementById("bundleBrowser");
     return this._bundleBrowser;
--- a/browser/base/content/social-content.js
+++ b/browser/base/content/social-content.js
@@ -1,17 +1,17 @@
 /* -*- 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/. */
 
 /* This content script should work in any browser or iframe and should not
  * depend on the frame being contained in tabbrowser. */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 // social frames are always treated as app tabs
 docShell.isAppTab = true;
 
 // Error handling class used to listen for network errors in the social frames
--- a/browser/base/content/sync/aboutSyncTabs.js
+++ b/browser/base/content/sync/aboutSyncTabs.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://services-sync/main.js");
 Cu.import("resource:///modules/PlacesUIUtils.jsm");
 Cu.import("resource://gre/modules/PlacesUtils.jsm", this);
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
--- a/browser/base/content/sync/addDevice.js
+++ b/browser/base/content/sync/addDevice.js
@@ -1,15 +1,15 @@
 /* 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 Ci = Components.interfaces;
-const Cc = Components.classes;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cu = Components.utils;
 
 Cu.import("resource://services-sync/main.js");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const PIN_PART_LENGTH = 4;
 
 const ADD_DEVICE_PAGE       = 0;
 const SYNC_KEY_PAGE         = 1;
--- a/browser/base/content/sync/genericChange.js
+++ b/browser/base/content/sync/genericChange.js
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Ci = Components.interfaces;
-const Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
 
 Components.utils.import("resource://services-sync/main.js");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 var Change = {
   _dialog: null,
   _dialogType: null,
   _status: null,
--- a/browser/base/content/sync/setup.js
+++ b/browser/base/content/sync/setup.js
@@ -1,17 +1,17 @@
 // -*- 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 Ci = Components.interfaces;
-const Cc = Components.classes;
-const Cr = Components.results;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cr = Components.results;
+var Cu = Components.utils;
 
 // page consts
 
 const PAIR_PAGE                     = 0;
 const INTRO_PAGE                    = 1;
 const NEW_ACCOUNT_START_PAGE        = 2;
 const EXISTING_ACCOUNT_CONNECT_PAGE = 3;
 const EXISTING_ACCOUNT_LOGIN_PAGE   = 4;
--- a/browser/base/content/test/general/browser_aboutTabCrashed.js
+++ b/browser/base/content/test/general/browser_aboutTabCrashed.js
@@ -1,11 +1,11 @@
 "use strict";
 
-let { TabCrashReporter } =
+var { TabCrashReporter } =
   Cu.import("resource:///modules/ContentCrashReporters.jsm");
 
 const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
 const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
 const COMMENTS = "Here's my test comment!";
 const EMAIL = "foo@privacy.com";
 
 /**
--- a/browser/base/content/test/general/browser_alltabslistener.js
+++ b/browser/base/content/test/general/browser_alltabslistener.js
@@ -1,9 +1,9 @@
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 
 const gCompleteState = Ci.nsIWebProgressListener.STATE_STOP +
                        Ci.nsIWebProgressListener.STATE_IS_NETWORK;
 
 var gFrontProgressListener = {
   onProgressChange: function (aWebProgress, aRequest,
                               aCurSelfProgress, aMaxSelfProgress,
                               aCurTotalProgress, aMaxTotalProgress) {
--- a/browser/base/content/test/general/browser_bug356571.js
+++ b/browser/base/content/test/general/browser_bug356571.js
@@ -1,12 +1,12 @@
 // Bug 356571 - loadOneOrMoreURIs gives up if one of the URLs has an unknown protocol
 
-const Cr = Components.results;
-const Cm = Components.manager;
+var Cr = Components.results;
+var Cm = Components.manager;
 
 // Set to true when docShell alerts for unknown protocol error
 var didFail = false;
 
 // Override Alert to avoid blocking the test due to unknown protocol error
 const kPromptServiceUUID = "{6cc9c9fe-bc0b-432b-a410-253ef8bcc699}";
 const kPromptServiceContractID = "@mozilla.org/embedcomp/prompt-service;1";
 
--- a/browser/base/content/test/general/browser_bug567306.js
+++ b/browser/base/content/test/general/browser_bug567306.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-const {Ci: interfaces, Cc: classes} = Components;
+var {Ci: interfaces, Cc: classes} = Components;
 
 var Clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
 var HasFindClipboard = Clipboard.supportsFindClipboard();
 
 add_task(function* () {
   let newwindow = yield BrowserTestUtils.openNewBrowserWindow();
 
   let selectedBrowser = newwindow.gBrowser.selectedBrowser;
--- a/browser/base/content/test/general/browser_minimize.js
+++ b/browser/base/content/test/general/browser_minimize.js
@@ -1,37 +1,18 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
-function waitForActive() {
-    if (!gBrowser.docShell.isActive) {
-        executeSoon(waitForActive);
-        return;
-    }
-    is(gBrowser.docShell.isActive, true, "Docshell should be active again");
-    finish();
-}
 
-function waitForInactive() {
-    if (gBrowser.docShell.isActive) {
-        executeSoon(waitForInactive);
-        return;
-    }
-    is(gBrowser.docShell.isActive, false, "Docshell should be inactive");
-    window.restore();
-    waitForActive();
-}
-
-function test() {
+add_task(function *() {
     registerCleanupFunction(function() {
       window.restore();
     });
-
-    waitForExplicitFinish();
-    is(gBrowser.docShell.isActive, true, "Docshell should be active");
+    function waitForActive() { return gBrowser.selectedTab.linkedBrowser.docShellIsActive; }
+    function waitForInactive() { return !gBrowser.selectedTab.linkedBrowser.docShellIsActive; }
+    yield promiseWaitForCondition(waitForActive);
+    is(gBrowser.selectedTab.linkedBrowser.docShellIsActive, true, "Docshell should be active");
     window.minimize();
-    // XXX On Linux minimize/restore seem to be very very async, but
-    // our window.windowState changes sync.... so we can't rely on the
-    // latter correctly reflecting the state of the former.  In
-    // particular, a restore() call before minimizing is done will not
-    // actually restore the window, but change the window state.  As a
-    // result, just poll waiting for our expected isActive values.
-    waitForInactive();
-}
+    yield promiseWaitForCondition(waitForInactive);
+    is(gBrowser.selectedTab.linkedBrowser.docShellIsActive, false, "Docshell should be Inactive");
+    window.restore();
+    yield promiseWaitForCondition(waitForActive);
+    is(gBrowser.selectedTab.linkedBrowser.docShellIsActive, true, "Docshell should be active again");
+});
\ No newline at end of file
--- a/browser/base/content/test/general/browser_mixedContentFramesOnHttp.js
+++ b/browser/base/content/test/general/browser_mixedContentFramesOnHttp.js
@@ -5,49 +5,30 @@
  * Test for Bug 1182551 -
  *
  * This test has a top level HTTP page with an HTTPS iframe.  The HTTPS iframe
  * includes an HTTP image.  We check that the top level security state is
  * STATE_IS_INSECURE.  The mixed content from the iframe shouldn't "upgrade"
  * the HTTP top level page to broken HTTPS.
  */
 
-const gHttpTestRoot = "http://example.com/browser/browser/base/content/test/general/";
+const gHttpTestUrl = "http://example.com/browser/browser/base/content/test/general/file_mixedContentFramesOnHttp.html";
 
 var gTestBrowser = null;
 
-function SecStateTestsCompleted() {
-  gBrowser.removeCurrentTab();
-  window.focus();
-  finish();
-}
-
-function test() {
-  waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [
-    ["security.mixed_content.block_active_content", true],
-    ["security.mixed_content.block_display_content", false]
-  ]}, SecStateTests);
-}
+add_task(function *() {
+  yield new Promise(resolve => {
+    SpecialPowers.pushPrefEnv({
+      "set": [
+        ["security.mixed_content.block_active_content", true],
+        ["security.mixed_content.block_display_content", false]
+      ]
+    }, resolve);
+  });
+  let url = gHttpTestUrl
+  yield BrowserTestUtils.withNewTab({gBrowser, url}, function*(){
+    gTestBrowser = gBrowser.selectedBrowser;
+    // check security state is insecure
+    isSecurityState("insecure");
+    assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: true});
+  });
+});
 
-function SecStateTests() {
-  let url = gHttpTestRoot + "file_mixedContentFramesOnHttp.html";
-  gBrowser.selectedTab = gBrowser.addTab();
-  gTestBrowser = gBrowser.selectedBrowser;
-  whenLoaded(gTestBrowser, SecStateTest1);
-  gTestBrowser.contentWindow.location = url;
-}
-
-// The http page loads an https frame with an http image.
-function SecStateTest1() {
-  // check security state is insecure
-  isSecurityState("insecure");
-  assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: true});
-
-  SecStateTestsCompleted();
-}
-
-function whenLoaded(aElement, aCallback) {
-  aElement.addEventListener("load", function onLoad() {
-    aElement.removeEventListener("load", onLoad, true);
-    executeSoon(aCallback);
-  }, true);
-}
--- a/browser/base/content/test/general/browser_mixedContentFromOnunload.js
+++ b/browser/base/content/test/general/browser_mixedContentFromOnunload.js
@@ -9,72 +9,41 @@
 
 // We use different domains for each test and for navigation within each test
 const gHttpTestRoot1 = "http://example.com/browser/browser/base/content/test/general/";
 const gHttpsTestRoot1 = "https://test1.example.com/browser/browser/base/content/test/general/";
 const gHttpTestRoot2 = "http://example.net/browser/browser/base/content/test/general/";
 const gHttpsTestRoot2 = "https://test2.example.com/browser/browser/base/content/test/general/";
 
 var gTestBrowser = null;
-
-function SecStateTestsCompleted() {
-  gBrowser.removeCurrentTab();
-  window.focus();
-  finish();
-}
-
-function test() {
-  waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["security.mixed_content.block_active_content", true],
-                            ["security.mixed_content.block_display_content", false]]}, SecStateTests);
-}
-
-function SecStateTests() {
-  gBrowser.selectedTab = gBrowser.addTab();
+add_task(function *() {
+  let url = gHttpTestRoot1 + "file_mixedContentFromOnunload.html";
+  yield BrowserTestUtils.withNewTab({gBrowser, url}, function*(){
+    yield new Promise(resolve => {
+      SpecialPowers.pushPrefEnv({
+        "set": [
+          ["security.mixed_content.block_active_content", true],
+          ["security.mixed_content.block_display_content", false]
+        ]
+      }, resolve);
+    });
   gTestBrowser = gBrowser.selectedBrowser;
-
-  whenLoaded(gTestBrowser, SecStateTest1A);
-  let url = gHttpTestRoot1 + "file_mixedContentFromOnunload.html";
-  gTestBrowser.contentWindow.location = url;
-}
-
-// Navigation from an http page to a https page with no mixed content
-// The http page loads an http image on unload
-function SecStateTest1A() {
-  whenLoaded(gTestBrowser, SecStateTest1B);
-  let url = gHttpsTestRoot1 + "file_mixedContentFromOnunload_test1.html";
-  gTestBrowser.contentWindow.location = url;
-}
-
-function SecStateTest1B() {
+  // Navigation from an http page to a https page with no mixed content
+  // The http page loads an http image on unload
+  url = gHttpsTestRoot1 + "file_mixedContentFromOnunload_test1.html";
+  yield BrowserTestUtils.loadURI(gTestBrowser, url);
+  yield BrowserTestUtils.browserLoaded(gTestBrowser);
   // check security state.  Since current url is https and doesn't have any
   // mixed content resources, we expect it to be secure.
   isSecurityState("secure");
   assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: false});
-
-  whenLoaded(gTestBrowser, SecStateTest2A);
-
-  // change locations and proceed with the second test
-  let url = gHttpTestRoot2 + "file_mixedContentFromOnunload.html";
-  gTestBrowser.contentWindow.location = url;
-}
-
-// Navigation from an http page to a https page that has mixed display content
-// The https page loads an http image on unload
-function SecStateTest2A() {
-  whenLoaded(gTestBrowser, SecStateTest2B);
-  let url = gHttpsTestRoot2 + "file_mixedContentFromOnunload_test2.html";
-  gTestBrowser.contentWindow.location = url;
-}
-
-function SecStateTest2B() {
+  // Navigation from an http page to a https page that has mixed display content
+  // The https page loads an http image on unload
+  url = gHttpTestRoot2 + "file_mixedContentFromOnunload.html";
+  yield BrowserTestUtils.loadURI(gTestBrowser, url);
+  yield BrowserTestUtils.browserLoaded(gTestBrowser);
+  url = gHttpsTestRoot2 + "file_mixedContentFromOnunload_test2.html";
+  yield BrowserTestUtils.loadURI(gTestBrowser, url);
+  yield BrowserTestUtils.browserLoaded(gTestBrowser);
   isSecurityState("broken");
   assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: true});
-
-  SecStateTestsCompleted();
-}
-
-function whenLoaded(aElement, aCallback) {
-  aElement.addEventListener("load", function onLoad() {
-    aElement.removeEventListener("load", onLoad, true);
-    executeSoon(aCallback);
-  }, true);
-}
+  });
+});
--- a/browser/base/content/test/general/browser_overflowScroll.js
+++ b/browser/base/content/test/general/browser_overflowScroll.js
@@ -1,23 +1,23 @@
 var tabstrip = gBrowser.tabContainer.mTabstrip;
 var scrollbox = tabstrip._scrollbox;
 var originalSmoothScroll = tabstrip.smoothScroll;
 var tabs = gBrowser.tabs;
 
-let rect = ele => ele.getBoundingClientRect();
-let width = ele => rect(ele).width;
-let left = ele => rect(ele).left;
-let right = ele => rect(ele).right;
-let isLeft = (ele, msg) => is(left(ele) + tabstrip._tabMarginLeft, left(scrollbox), msg);
-let isRight = (ele, msg) => is(right(ele) - tabstrip._tabMarginRight, right(scrollbox), msg);
-let elementFromPoint = x => tabstrip._elementFromPoint(x);
-let nextLeftElement = () => elementFromPoint(left(scrollbox) - 1);
-let nextRightElement = () => elementFromPoint(right(scrollbox) + 1);
-let firstScrollable = () => tabs[gBrowser._numPinnedTabs];
+var rect = ele => ele.getBoundingClientRect();
+var width = ele => rect(ele).width;
+var left = ele => rect(ele).left;
+var right = ele => rect(ele).right;
+var isLeft = (ele, msg) => is(left(ele) + tabstrip._tabMarginLeft, left(scrollbox), msg);
+var isRight = (ele, msg) => is(right(ele) - tabstrip._tabMarginRight, right(scrollbox), msg);
+var elementFromPoint = x => tabstrip._elementFromPoint(x);
+var nextLeftElement = () => elementFromPoint(left(scrollbox) - 1);
+var nextRightElement = () => elementFromPoint(right(scrollbox) + 1);
+var firstScrollable = () => tabs[gBrowser._numPinnedTabs];
 
 function test() {
   requestLongerTimeout(2);
   waitForExplicitFinish();
 
   // If the previous (or more) test finished with cleaning up the tabs,
   // there may be some pending animations. That can cause a failure of
   // this tests, so, we should test this in another stack.
--- a/browser/base/content/test/general/browser_permissions.js
+++ b/browser/base/content/test/general/browser_permissions.js
@@ -1,13 +1,13 @@
 /*
  * Test the Permissions section in the Control Center.
  */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const PERMISSIONS_PAGE = "http://example.com/browser/browser/base/content/test/general/permissions.html";
 var {SitePermissions} = Cu.import("resource:///modules/SitePermissions.jsm", {});
 
 registerCleanupFunction(function() {
   SitePermissions.remove(gBrowser.currentURI, "install");
   while (gBrowser.tabs.length > 1) {
     gBrowser.removeCurrentTab();
   }
--- a/browser/base/content/test/general/browser_sanitizeDialog.js
+++ b/browser/base/content/test/general/browser_sanitizeDialog.js
@@ -13,31 +13,31 @@
  * test checks the UI of the dialog and makes sure it's correctly connected to
  * the sanitize timespan code.
  *
  * Some of this code, especially the history creation parts, was taken from
  * browser/base/content/test/general/browser_sanitize-timespans.js.
  */
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-let {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", {});
+var {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", {});
 
 XPCOMUtils.defineLazyModuleGetter(this, "FormHistory",
                                   "resource://gre/modules/FormHistory.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
                                   "resource://gre/modules/Downloads.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Timer",
                                   "resource://gre/modules/Timer.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
                                   "resource://testing-common/PlacesTestUtils.jsm");
 
-let tempScope = {};
+var tempScope = {};
 Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
                                            .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
-let Sanitizer = tempScope.Sanitizer;
+var Sanitizer = tempScope.Sanitizer;
 
 const kMsecPerMin = 60 * 1000;
 const kUsecPerMin = 60 * 1000000;
 
 add_task(function* init() {
   requestLongerTimeout(2);
   blankSlate();
   registerCleanupFunction(() => {
@@ -670,18 +670,18 @@ add_task(function* test_offline_apps_per
     var pm = Cc["@mozilla.org/permissionmanager;1"]
              .getService(Ci.nsIPermissionManager);
     is(pm.testPermissionFromPrincipal(principal, "offline-app"), 0, "offline-app permissions removed");
   };
   wh.open();
   return wh.promiseClosed;
 });
 
-let now_mSec = Date.now();
-let now_uSec = now_mSec * 1000;
+var now_mSec = Date.now();
+var now_uSec = now_mSec * 1000;
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /**
  * This wraps the dialog and provides some convenience methods for interacting
  * with it.
  *
  * @param aWin
--- a/browser/base/content/test/general/browser_trackingUI_1.js
+++ b/browser/base/content/test/general/browser_trackingUI_1.js
@@ -2,17 +2,17 @@
  * Test that the Tracking Protection section is visible in the Control Center
  * and has the correct state for the cases when:
  *   1) A page with no tracking elements is loaded.
  *   2) A page with tracking elements is loaded and they are blocked.
  *   3) A page with tracking elements is loaded and they are not blocked.
  * See also Bugs 1175327, 1043801, 1178985
  */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const PREF = "privacy.trackingprotection.enabled";
 const PB_PREF = "privacy.trackingprotection.pbmode.enabled";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
 var TrackingProtection = null;
 var tabbrowser = null;
 
 var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
--- a/browser/base/content/test/general/browser_trackingUI_2.js
+++ b/browser/base/content/test/general/browser_trackingUI_2.js
@@ -1,15 +1,15 @@
 /*
  * Test that the Tracking Protection section is never visible in the
  * Control Center when the feature is off.
  * See also Bugs 1175327, 1043801, 1178985.
  */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const PREF = "privacy.trackingprotection.enabled";
 const PB_PREF = "privacy.trackingprotection.pbmode.enabled";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
 var TrackingProtection = null;
 var tabbrowser = null;
 
 var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
--- a/browser/base/content/test/general/browser_trackingUI_4.js
+++ b/browser/base/content/test/general/browser_trackingUI_4.js
@@ -1,15 +1,15 @@
 /*
  * Test that the Tracking Protection icon is properly animated in the identity
  * block when loading tabs and switching between tabs.
  * See also Bug 1175858.
  */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const PREF = "privacy.trackingprotection.enabled";
 const PB_PREF = "privacy.trackingprotection.pbmode.enabled";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
 var TrackingProtection = null;
 var tabbrowser = null;
 
 var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
--- a/browser/base/content/test/general/browser_trackingUI_telemetry.js
+++ b/browser/base/content/test/general/browser_trackingUI_telemetry.js
@@ -1,13 +1,13 @@
 /*
  * Test telemetry for Tracking Protection
  */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const PREF = "privacy.trackingprotection.enabled";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
 const {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
 
 /**
  * Enable local telemetry recording for the duration of the tests.
  */
--- a/browser/base/content/test/general/content_aboutAccounts.js
+++ b/browser/base/content/test/general/content_aboutAccounts.js
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This file is loaded as a "content script" for browser_aboutAccounts tests
 "use strict";
 
-const {interfaces: Ci, utils: Cu} = Components;
+var {interfaces: Ci, utils: Cu} = Components;
 
 addEventListener("load", function load(event) {
   if (event.target != content.document) {
     return;
   }
 //  content.document.removeEventListener("load", load, true);
   sendAsyncMessage("test:document:load");
   // Opening Sync prefs in tests is a pain as leaks are reported due to the
--- a/browser/base/content/test/general/healthreport_pingData.js
+++ b/browser/base/content/test/general/healthreport_pingData.js
@@ -1,9 +1,9 @@
-const TEST_PINGS = [
+var TEST_PINGS = [
   {
     type: "test-telemetryArchive-1",
     payload: { foo: "bar" },
     date: new Date(2010, 1, 1, 10, 0, 0),
   },
   {
     type: "test-telemetryArchive-2",
     payload: { x: { y: "z"} },
--- a/browser/base/content/test/plugins/blocklist_proxy.js
+++ b/browser/base/content/test/plugins/blocklist_proxy.js
@@ -1,12 +1,12 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cm = Components.manager;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cm = Components.manager;
 
 const kBlocklistServiceUUID = "{66354bc9-7ed1-4692-ae1d-8da97d6b205e}";
 const kBlocklistServiceContractID = "@mozilla.org/extensions/blocklist;1";
 const kBlocklistServiceFactory = Cm.getClassObject(Cc[kBlocklistServiceContractID], Ci.nsIFactory);
 
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 
 /*
--- a/browser/base/content/test/plugins/browser_bug797677.js
+++ b/browser/base/content/test/plugins/browser_bug797677.js
@@ -1,14 +1,14 @@
 var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
 var gTestBrowser = null;
 var gConsoleErrors = 0;
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 add_task(function* () {
   registerCleanupFunction(function () {
     clearAllPluginPermissions();
     setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
     setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
     consoleService.unregisterListener(errorListener);
     gBrowser.removeCurrentTab();
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -1589,19 +1589,21 @@ file, You can obtain one at http://mozil
 
       <field name="progressmeter" readonly="true">
         document.getElementById("addon-progress-notification-progressmeter"); 
       </field>
       <field name="progresstext" readonly="true">
         document.getElementById("addon-progress-notification-progresstext");
       </field>
       <field name="DownloadUtils" readonly="true">
-        let utils = {};
-        Components.utils.import("resource://gre/modules/DownloadUtils.jsm", utils);
-        utils.DownloadUtils;
+        {
+          let utils = {};
+          Components.utils.import("resource://gre/modules/DownloadUtils.jsm", utils);
+          utils.DownloadUtils;
+        }
       </field>
 
       <method name="destroy">
         <body><![CDATA[
           if (!this.notification)
             return;
 
           this.notification.options.installs.forEach(function(aInstall) {
@@ -2671,21 +2673,23 @@ file, You can obtain one at http://mozil
         this._panel.addEventListener("popupshowing", this, false);
       ]]></constructor>
 
       <destructor><![CDATA[
         this._panel.removeEventListener("popupshowing", this, false);
       ]]></destructor>
 
       <field name="_panel" readonly="true"><![CDATA[
-        let node = this.parentNode;
-        while(node && node.localName != "panel") {
-          node = node.parentNode;
+        {
+          let node = this.parentNode;
+          while(node && node.localName != "panel") {
+            node = node.parentNode;
+          }
+          node;
         }
-        node;
       ]]></field>
       <field name="_promomessage" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "promo-message");
       </field>
       <field name="_promolink" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "promo-link");
       </field>
       <field name="_brandBundle" readonly="true">
--- a/browser/base/content/webrtcIndicator.js
+++ b/browser/base/content/webrtcIndicator.js
@@ -1,13 +1,13 @@
 /* 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;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource:///modules/webrtcUI.jsm");
 
 const BUNDLE_URL = "chrome://browser/locale/webrtcIndicator.properties";
 var gStringBundle;
 
 function init(event) {
   gStringBundle = Services.strings.createBundle(BUNDLE_URL);
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -505,16 +505,18 @@ const PanelUI = {
 
   _overlayScrollListenerBoundFn: null,
   _overlayScrollListener: function(aMQL) {
     ScrollbarSampler.resetSystemScrollbarWidth();
     this._scrollWidth = null;
   },
 };
 
+XPCOMUtils.defineConstant(this, "PanelUI", PanelUI);
+
 /**
  * Gets the currently selected locale for display.
  * @return  the selected locale or "en-US" if none is selected
  */
 function getLocale() {
   try {
     let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"]
                            .getService(Ci.nsIXULChromeRegistry);
--- a/browser/components/customizableui/test/browser_1096763_seen_widgets_post_reset.js
+++ b/browser/components/customizableui/test/browser_1096763_seen_widgets_post_reset.js
@@ -4,27 +4,28 @@ const BUTTONID = "test-seenwidget-post-r
 
 add_task(function*() {
   let widget = CustomizableUI.createWidget({
     id: BUTTONID,
     label: "Test widget seen post reset",
     defaultArea: CustomizableUI.AREA_NAVBAR
   });
 
+  const kPrefCustomizationState = "browser.uiCustomization.state";
   let bsPass = Cu.import("resource:///modules/CustomizableUI.jsm", {});
   ok(bsPass.gSeenWidgets.has(BUTTONID), "Widget should be seen after createWidget is called.");
   CustomizableUI.reset();
   ok(bsPass.gSeenWidgets.has(BUTTONID), "Widget should still be seen after reset.");
-  ok(!Services.prefs.prefHasUserValue(bsPass.kPrefCustomizationState), "Pref shouldn't be set right now, because that'd break undo.");
+  ok(!Services.prefs.prefHasUserValue(kPrefCustomizationState), "Pref shouldn't be set right now, because that'd break undo.");
   CustomizableUI.addWidgetToArea(BUTTONID, CustomizableUI.AREA_NAVBAR);
   gCustomizeMode.removeFromArea(document.getElementById(BUTTONID));
-  let hasUserValue = Services.prefs.prefHasUserValue(bsPass.kPrefCustomizationState);
+  let hasUserValue = Services.prefs.prefHasUserValue(kPrefCustomizationState);
   ok(hasUserValue, "Pref should be set right now.");
   if (hasUserValue) {
-    let seenArray = JSON.parse(Services.prefs.getCharPref(bsPass.kPrefCustomizationState)).seen;
+    let seenArray = JSON.parse(Services.prefs.getCharPref(kPrefCustomizationState)).seen;
     isnot(seenArray.indexOf(BUTTONID), -1, "Widget should be in saved 'seen' list.");
   }
 });
 
 registerCleanupFunction(function() {
   CustomizableUI.destroyWidget(BUTTONID);
   CustomizableUI.reset();
 });
--- a/browser/components/dirprovider/tests/unit/head_dirprovider.js
+++ b/browser/components/dirprovider/tests/unit/head_dirprovider.js
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 var gProfD = do_get_profile();
 var gDirSvc = Cc["@mozilla.org/file/directory_service;1"].
               getService(Ci.nsIProperties);
 var gPrefSvc = Cc["@mozilla.org/preferences-service;1"].
                getService(Ci.nsIPrefBranch);
 
 function writeTestFile(aParent, aName) {
--- a/browser/components/distribution.js
+++ b/browser/components/distribution.js
@@ -1,18 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 this.EXPORTED_SYMBOLS = [ "DistributionCustomizer" ];
 
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-const Cr = Components.results;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cr = Components.results;
+var Cu = Components.utils;
 
 const DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC =
   "distribution-customization-complete";
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
--- a/browser/components/downloads/content/downloads.js
+++ b/browser/components/downloads/content/downloads.js
@@ -575,16 +575,18 @@ const DownloadsPanel = {
       }
 
       DownloadsCommon.log("Opening downloads panel popup.");
       this.panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, null);
     });
   },
 };
 
+XPCOMUtils.defineConstant(this, "DownloadsPanel", DownloadsPanel);
+
 ////////////////////////////////////////////////////////////////////////////////
 //// DownloadsOverlayLoader
 
 /**
  * Allows loading the downloads panel and the status indicator interfaces on
  * demand, to improve startup performance.
  */
 const DownloadsOverlayLoader = {
@@ -653,16 +655,18 @@ const DownloadsOverlayLoader = {
       // We must call ensureOverlayLoaded again for each request, to check if
       // the associated callback can be invoked now, or if we must still wait
       // for the associated overlay to load.
       this.ensureOverlayLoaded(request.overlay, request.callback);
     }
   },
 };
 
+XPCOMUtils.defineConstant(this, "DownloadsOverlayLoader", DownloadsOverlayLoader);
+
 ////////////////////////////////////////////////////////////////////////////////
 //// DownloadsView
 
 /**
  * Builds and updates the downloads list widget, responding to changes in the
  * download state and real-time data.  In addition, handles part of the user
  * interaction events raised by the downloads list widget.
  */
@@ -999,16 +1003,18 @@ const DownloadsView = {
     dataTransfer.setData("text/uri-list", spec);
     dataTransfer.setData("text/plain", spec);
     dataTransfer.addElement(element);
 
     aEvent.stopPropagation();
   },
 }
 
+XPCOMUtils.defineConstant(this, "DownloadsView", DownloadsView);
+
 ////////////////////////////////////////////////////////////////////////////////
 //// DownloadsViewItem
 
 /**
  * Builds and updates a single item in the downloads list widget, responding to
  * changes in the download state and real-time data.
  *
  * @param download
@@ -1137,16 +1143,18 @@ const DownloadsViewController = {
    */
   commands: {
     downloadsCmd_clearList() {
       DownloadsCommon.getData(window).removeFinished();
     }
   }
 };
 
+XPCOMUtils.defineConstant(this, "DownloadsViewController", DownloadsViewController);
+
 ////////////////////////////////////////////////////////////////////////////////
 //// DownloadsViewItemController
 
 /**
  * Handles all the user interaction events, in particular the "commands",
  * related to a single item in the downloads list widgets.
  */
 function DownloadsViewItemController(download) {
@@ -1483,17 +1491,19 @@ const DownloadsSummary = {
   get _detailsNode() {
     let node = document.getElementById("downloadsSummaryDetails");
     if (!node) {
       return null;
     }
     delete this._detailsNode;
     return this._detailsNode = node;
   }
-}
+};
+
+XPCOMUtils.defineConstant(this, "DownloadsSummary", DownloadsSummary);
 
 ////////////////////////////////////////////////////////////////////////////////
 //// DownloadsFooter
 
 /**
  * Manages events sent to to the footer vbox, which contains both the
  * DownloadsSummary as well as the "Show All Downloads" button.
  */
@@ -1537,8 +1547,10 @@ const DownloadsFooter = {
     let node = document.getElementById("downloadsFooter");
     if (!node) {
       return null;
     }
     delete this._footerNode;
     return this._footerNode = node;
   }
 };
+
+XPCOMUtils.defineConstant(this, "DownloadsFooter", DownloadsFooter);
--- a/browser/components/downloads/content/indicator.js
+++ b/browser/components/downloads/content/indicator.js
@@ -572,8 +572,13 @@ const DownloadsIndicatorView = {
       this._onCustomizedAway();
       this._operational = false;
       this.ensureTerminated();
       this.ensureInitialized();
     }
   },
 };
 
+Object.defineProperty(this, "DownloadsIndicatorView", {
+  value: DownloadsIndicatorView,
+  enumerable: true,
+  writable: false
+});
--- a/browser/components/downloads/test/unit/head.js
+++ b/browser/components/downloads/test/unit/head.js
@@ -5,14 +5,14 @@
 
 /**
  * Provides infrastructure for automated download components tests.
  */
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Globals
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 Cu.import("resource:///modules/DownloadsCommon.jsm");
--- a/browser/components/extensions/ext-browserAction.js
+++ b/browser/components/extensions/ext-browserAction.js
@@ -12,17 +12,17 @@ var {
 } = ExtensionUtils;
 
 // WeakMap[Extension -> BrowserAction]
 var browserActionMap = new WeakMap();
 
 // WeakMap[Extension -> docshell]
 // This map is a cache of the windowless browser that's used to render ImageData
 // for the browser_action icon.
-let imageRendererMap = new WeakMap();
+var imageRendererMap = new WeakMap();
 
 function browserActionOf(extension)
 {
   return browserActionMap.get(extension);
 }
 
 function makeWidgetId(id)
 {
--- a/browser/components/extensions/ext-contextMenus.js
+++ b/browser/components/extensions/ext-contextMenus.js
@@ -1,45 +1,45 @@
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 Cu.import("resource://gre/modules/MatchPattern.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-let {
+var {
   EventManager,
   contextMenuItems,
   runSafe
 } = ExtensionUtils;
 
 
 // Map[Extension -> Map[ID -> MenuItem]]
 // Note: we want to enumerate all the menu items so
 // this cannot be a weak map.
-let contextMenuMap = new Map();
+var contextMenuMap = new Map();
 
 // Not really used yet, will be used for event pages.
-let onClickedCallbacksMap = new WeakMap();
+var onClickedCallbacksMap = new WeakMap();
 
 // If id is not specified for an item we use an integer.
-let nextID = 0;
+var nextID = 0;
 
 function contextMenuObserver(subject, topic, data) {
   subject = subject.wrappedJSObject;
   menuBuilder.build(subject);
 }
 
 // When a new contextMenu is opened, this function is called and
 // we populate the |xulMenu| with all the items from extensions
 // to be displayed. We always clear all the items again when
 // popuphidden fires. Since most of the info we need is already
 // calculated in nsContextMenu.jsm we simple reuse its flags here.
 // For remote processes there is a gContextMenuContentData where all
 // the important info is stored from the child process. We get
 // this data in |contentData|.
-let menuBuilder = {
+var menuBuilder = {
   build: function(contextData) {
     // TODO: icons should be set for items
     let xulMenu = contextData.menu;
     xulMenu.addEventListener("popuphidden", this);
     let doc = xulMenu.ownerDocument;
     for (let [ext, menuItemMap] of contextMenuMap) {
       let parentMap = new Map();
       let topLevelItems = new Set();
@@ -333,17 +333,17 @@ MenuItem.prototype = {
       // TODO: double check if mediaURL is always set when we need it
       return false;
     }
 
     return true;
   },
 };
 
-let extCount = 0;
+var extCount = 0;
 extensions.on("startup", (type, extension) => {
   contextMenuMap.set(extension, new Map());
   if (++extCount == 1) {
     Services.obs.addObserver(contextMenuObserver,
                              "on-build-contextmenu",
                              false);
   }
 });
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -1,7 +1,7 @@
-let {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm");
+var {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm");
 
 function makeWidgetId(id)
 {
   id = id.toLowerCase();
   return id.replace(/[^a-z0-9_-]/g, "_");
 }
--- a/browser/components/feeds/test/unit/head_feeds.js
+++ b/browser/components/feeds/test/unit/head_feeds.js
@@ -1,5 +1,5 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
 
 var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
--- a/browser/components/feeds/test/unit/test_355473.js
+++ b/browser/components/feeds/test/unit/test_355473.js
@@ -1,9 +1,9 @@
-const Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource://gre/modules/Services.jsm");
 
 function run_test() {
   var feedFeedURI = ios.newURI("feed://example.com/feed.xml", null, null);
   var httpFeedURI = ios.newURI("feed:http://example.com/feed.xml", null, null);
   var httpURI = ios.newURI("http://example.com/feed.xml", null, null);
 
   var httpsFeedURI =
--- a/browser/components/loop/modules/LoopRoomsCache.jsm
+++ b/browser/components/loop/modules/LoopRoomsCache.jsm
@@ -12,16 +12,17 @@ const {MozLoopService, LOOP_SESSION_TYPE
   Cu.import("resource:///modules/loop/MozLoopService.jsm", {});
 XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils",
                                   "resource://services-common/utils.js");
 XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
 
 this.EXPORTED_SYMBOLS = ["LoopRoomsCache"];
 
 const LOOP_ROOMS_CACHE_FILENAME = "loopRoomsCache.json";
+XPCOMUtils.defineConstant(this, "LOOP_ROOMS_CACHE_FILENAME", LOOP_ROOMS_CACHE_FILENAME);
 
 /**
  * RoomsCache is a cache for saving simple rooms data to the disk in case we
  * need it for back-up purposes, e.g. recording room keys for FxA if the user
  * changes their password.
  *
  * The format of the data is:
  *
--- a/browser/components/loop/modules/MozLoopService.jsm
+++ b/browser/components/loop/modules/MozLoopService.jsm
@@ -107,16 +107,24 @@ Cu.import("resource://gre/modules/Timer.
 Cu.import("resource://gre/modules/FxAccountsOAuthClient.jsm");
 
 Cu.importGlobalProperties(["URL"]);
 
 this.EXPORTED_SYMBOLS = ["MozLoopService", "LOOP_SESSION_TYPE",
   "TWO_WAY_MEDIA_CONN_LENGTH", "SHARING_STATE_CHANGE", "SHARING_ROOM_URL",
   "ROOM_CREATE", "ROOM_DELETE", "ROOM_CONTEXT_ADD"];
 
+XPCOMUtils.defineConstant(this, "LOOP_SESSION_TYPE", LOOP_SESSION_TYPE);
+XPCOMUtils.defineConstant(this, "TWO_WAY_MEDIA_CONN_LENGTH", TWO_WAY_MEDIA_CONN_LENGTH);
+XPCOMUtils.defineConstant(this, "SHARING_STATE_CHANGE", SHARING_STATE_CHANGE);
+XPCOMUtils.defineConstant(this, "SHARING_ROOM_URL", SHARING_ROOM_URL);
+XPCOMUtils.defineConstant(this, "ROOM_CREATE", ROOM_CREATE);
+XPCOMUtils.defineConstant(this, "ROOM_DELETE", ROOM_DELETE);
+XPCOMUtils.defineConstant(this, "ROOM_CONTEXT_ADD", ROOM_CONTEXT_ADD);
+
 XPCOMUtils.defineLazyModuleGetter(this, "injectLoopAPI",
   "resource:///modules/loop/MozLoopAPI.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "convertToRTCStatsReport",
   "resource://gre/modules/media/RTCStatsReport.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "loopUtils",
   "resource:///modules/loop/utils.js", "utils");
 XPCOMUtils.defineLazyModuleGetter(this, "loopCrypto",
--- a/browser/components/loop/test/xpcshell/head.js
+++ b/browser/components/loop/test/xpcshell/head.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 // Initialize this before the imports, as some of them need it.
 do_get_profile();
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Http.jsm");
 Cu.import("resource://testing-common/httpd.js");
--- a/browser/components/migration/IEProfileMigrator.js
+++ b/browser/components/migration/IEProfileMigrator.js
@@ -27,17 +27,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/PlacesUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OSCrypto",
                                   "resource://gre/modules/OSCrypto.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "WindowsRegistry",
                                   "resource://gre/modules/WindowsRegistry.jsm");
 
 Cu.importGlobalProperties(["URL"]);
 
-let CtypesKernelHelpers = MSMigrationUtils.CtypesKernelHelpers;
+var CtypesKernelHelpers = MSMigrationUtils.CtypesKernelHelpers;
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Resources
 
 
 function History() {
 }
 
--- a/browser/components/migration/content/migration.js
+++ b/browser/components/migration/content/migration.js
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 const kIMig = Ci.nsIBrowserProfileMigrator;
 const kIPStartup = Ci.nsIProfileStartup;
 
 Cu.import("resource:///modules/MigrationUtils.jsm");
 
 var MigrationWizard = {
   _source: "",                  // Source Profile Migrator ContractID suffix
--- a/browser/components/migration/tests/unit/head_migration.js
+++ b/browser/components/migration/tests/unit/head_migration.js
@@ -1,9 +1,9 @@
-const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
 
 Cu.importGlobalProperties([ "URL" ]);
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
--- a/browser/components/places/tests/unit/head_bookmarks.js
+++ b/browser/components/places/tests/unit/head_bookmarks.js
@@ -1,17 +1,17 @@
 /* -*- 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 Ci = Components.interfaces;
-const Cc = Components.classes;
-const Cr = Components.results;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cr = Components.results;
+var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/LoadContextInfo.jsm");
 
 // Import common head.
 var commonFile = do_get_file("../../../../../toolkit/components/places/tests/head_common.js", false);
 if (commonFile) {
   let uri = Services.io.newFileURI(commonFile);
--- a/browser/components/preferences/blocklists.js
+++ b/browser/components/preferences/blocklists.js
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 const TEST_LIST = "test-track-simple";
 const TRACK_SUFFIX = "-track-digest256";
 const TRACKING_TABLE_PREF = "urlclassifier.trackingTable";
 const LISTS_PREF_BRANCH = "browser.safebrowsing.provider.mozilla.lists.";
 
-let gBlocklistManager = {
+var gBlocklistManager = {
   _type: "",
   _blockLists: [],
   _brandShortName : null,
   _bundle: null,
   _tree: null,
 
   _view: {
     _rowCount: 0,
--- a/browser/components/preferences/in-content/preferences.js
+++ b/browser/components/preferences/in-content/preferences.js
@@ -1,18 +1,18 @@
 /* - This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this file,
    - You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 var gLastHash = "";
 
 var gCategoryInits = new Map();
 function init_category_if_required(category) {
--- a/browser/components/preferences/translation.js
+++ b/browser/components/preferences/translation.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
 /* 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";
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "gLangBundle", () =>
   Services.strings.createBundle("chrome://global/locale/languageNames.properties"));
 
 const kPermissionType = "translate";
--- a/browser/components/privatebrowsing/content/aboutPrivateBrowsing.js
+++ b/browser/components/privatebrowsing/content/aboutPrivateBrowsing.js
@@ -1,13 +1,13 @@
 /* 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;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const FAVICON_QUESTION = "chrome://global/skin/icons/question-16.png";
 const FAVICON_PRIVACY = "chrome://browser/skin/Privacy-16.png";
 
--- a/browser/components/sessionstore/content/aboutSessionRestore.js
+++ b/browser/components/sessionstore/content/aboutSessionRestore.js
@@ -1,15 +1,15 @@
 /* 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";
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
   "resource://gre/modules/AppConstants.jsm");
 
 var gStateObject;
 var gTreeData;
--- a/browser/components/sessionstore/test/browser_privatetabs.js
+++ b/browser/components/sessionstore/test/browser_privatetabs.js
@@ -1,15 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-var Imports = {};
-Cu.import("resource:///modules/sessionstore/SessionSaver.jsm", Imports);
-var {SessionSaver} = Imports;
-
 add_task(function cleanup() {
   info("Forgetting closed tabs");
   while (ss.getClosedTabCount(window)) {
     ss.forgetClosedTab(window, 0);
   }
 });
 
 add_task(function() {
--- a/browser/components/shell/test/unit/test_421977.js
+++ b/browser/components/shell/test/unit/test_421977.js
@@ -1,11 +1,11 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
 
 const GCONF_BG_COLOR_KEY = "/desktop/gnome/background/primary_color";
 
 var gShell;
 var gGConf;
 
 /**
  * Converts from a rgb numerical color valule (r << 16 | g << 8 | b)
--- a/browser/components/tabview/tabview.js
+++ b/browser/components/tabview/tabview.js
@@ -1,18 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 Cu.import("resource:///modules/tabview/utils.jsm");
 Cu.import("resource://gre/modules/AppConstants.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "tabviewBundle", function() {
   return Services.strings.
--- a/browser/components/uitour/test/browser_fxa.js
+++ b/browser/components/uitour/test/browser_fxa.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
                                   "resource://gre/modules/FxAccounts.jsm");
 
 var gTestTab;
 var gContentAPI;
 var gContentWindow;
 
--- a/browser/components/uitour/test/browser_openPreferences.js
+++ b/browser/components/uitour/test/browser_openPreferences.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 var gTestTab;
 var gContentAPI;
 var gContentWindow;
 
 function test() {
   UITourTest();
 }
--- a/browser/components/uitour/test/browser_showMenu_controlCenter.js
+++ b/browser/components/uitour/test/browser_showMenu_controlCenter.js
@@ -1,11 +1,11 @@
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const CONTROL_CENTER_PANEL = gIdentityHandler._identityPopup;
 const CONTROL_CENTER_MENU_NAME = "controlCenter";
 
 var gTestTab;
 var gContentAPI;
 var gContentWindow;
 
 function test() {
--- a/browser/components/uitour/test/browser_trackingProtection.js
+++ b/browser/components/uitour/test/browser_trackingProtection.js
@@ -1,11 +1,11 @@
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const PREF_INTRO_COUNT = "privacy.trackingprotection.introCount";
 const PREF_TP_ENABLED = "privacy.trackingprotection.enabled";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
 const TOOLTIP_PANEL = document.getElementById("UITourTooltip");
 const TOOLTIP_ANCHOR = document.getElementById("tracking-protection-icon");
 
 var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
--- a/browser/experiments/Experiments.jsm
+++ b/browser/experiments/Experiments.jsm
@@ -89,16 +89,17 @@ const TELEMETRY_LOG = {
     FROM_API: "FROM_API",
     // The experiment expired (e.g. by exceeding the end date).
     EXPIRED: "EXPIRED",
     // Disabled after re-evaluating conditions. If this is specified,
     // details will be provided.
     RECHECK: "RECHECK",
   },
 };
+XPCOMUtils.defineConstant(this, "TELEMETRY_LOG", TELEMETRY_LOG);
 
 const gPrefs = new Preferences(PREF_BRANCH);
 const gPrefsTelemetry = new Preferences(PREF_BRANCH_TELEMETRY);
 var gExperimentsEnabled = false;
 var gAddonProvider = null;
 var gExperiments = null;
 var gLogAppenderDump = null;
 var gPolicyCounter = 0;
--- a/browser/experiments/test/xpcshell/head.js
+++ b/browser/experiments/test/xpcshell/head.js
@@ -1,12 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
 Cu.import("resource://testing-common/AddonManagerTesting.jsm");
 
--- a/browser/modules/Chat.jsm
+++ b/browser/modules/Chat.jsm
@@ -13,17 +13,17 @@ Cu.import("resource://gre/modules/Servic
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 const kDefaultButtonSet = new Set(["minimize", "swap", "close"]);
 const kHiddenDefaultButtons = new Set(["minimize", "close"]);
-let gCustomButtons = new Map();
+var gCustomButtons = new Map();
 
 // A couple of internal helper function.
 function isWindowChromeless(win) {
   // XXX - stolen from browser-social.js, but there's no obvious place to
   // put this so it can be shared.
 
   // Is this a popup window that doesn't want chrome shown?
   let docElem = win.document.documentElement;
--- a/browser/modules/Sanitizer.jsm
+++ b/browser/modules/Sanitizer.jsm
@@ -10,13 +10,13 @@
 // sanitize is loaded from its own compartment, rather than from that
 // of the sanitize dialog.
 //
 
 this.EXPORTED_SYMBOLS = ["Sanitizer"];
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
-let scope = {};
+var scope = {};
 Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
  .loadSubScript("chrome://browser/content/sanitize.js", scope);
 
 this.Sanitizer = scope.Sanitizer;
--- a/browser/modules/Windows8WindowFrameColor.jsm
+++ b/browser/modules/Windows8WindowFrameColor.jsm
@@ -6,17 +6,17 @@
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 this.EXPORTED_SYMBOLS = ["Windows8WindowFrameColor"];
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 var Registry = Cu.import("resource://gre/modules/WindowsRegistry.jsm").WindowsRegistry;
 
-const Windows8WindowFrameColor = {
+var Windows8WindowFrameColor = {
   _windowFrameColor: null,
 
   get: function() {
     if (this._windowFrameColor)
       return this._windowFrameColor;
 
     const HKCU = Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER;
     const dwmKey = "Software\\Microsoft\\Windows\\DWM";
--- a/browser/modules/test/unit/social/head.js
+++ b/browser/modules/test/unit/social/head.js
@@ -1,13 +1,13 @@
 /* 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, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 var Social, SocialService;
 
 var manifests = [
   {
     name: "provider 1",
--- a/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
+++ b/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
@@ -2,17 +2,17 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 "use strict";
 
 /**
  * This file tests the DirectoryLinksProvider singleton in the DirectoryLinksProvider.jsm module.
  */
 
-const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu, Constructor: CC } = Components;
+var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu, Constructor: CC } = Components;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource:///modules/DirectoryLinksProvider.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
 Cu.import("resource://gre/modules/Http.jsm");
 Cu.import("resource://testing-common/httpd.js");
 Cu.import("resource://gre/modules/osfile.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
--- a/caps/tests/unit/test_origin.js
+++ b/caps/tests/unit/test_origin.js
@@ -1,11 +1,11 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 var ssm = Services.scriptSecurityManager;
 function makeURI(uri) { return Services.io.newURI(uri, null, null); }
 
 function checkThrows(f) {
   var threw = false;
   try { f(); } catch (e) { threw = true }
--- a/chrome/test/unit/head_crtestutils.js
+++ b/chrome/test/unit/head_crtestutils.js
@@ -1,14 +1,14 @@
 const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1";
 const XULAPPINFO_CID = Components.ID("{4ba645d3-be6f-40d6-a42a-01b2f40091b8}");
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
 
 
 function registerManifests(manifests)
 {
   var reg = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
   for each (var manifest in manifests)
     reg.autoRegister(manifest);
 }
--- a/configure.in
+++ b/configure.in
@@ -473,16 +473,19 @@ EOF
   fi
   if test -z "$MOZ_RUST"; then
     AC_MSG_ERROR([rustc does not support MacOS X $MACOSX_DEPLOYMENT_TARGET
       Add 'ac_add_options --enable-macos-target=10.7' (or later)
       to mozconfig, disable Rust support, or use an alternate toolchain.])
   fi
 fi
 
+AC_PROG_CPP
+AC_PROG_CXXCPP
+
 dnl ========================================================
 dnl Special win32 checks
 dnl ========================================================
 
 # Target the Windows 8.1 SDK by default
 WINSDK_TARGETVER=603
 WINVER=502
 
@@ -662,18 +665,16 @@ See https://developer.mozilla.org/en/Win
             AC_MSG_ERROR([Gecko exception wrapping doesn't understand your your MSVC/SDK.  Please file a bug describing this error and your build configuration.])
         fi
 
         if test "$WRAP_STL_INCLUDES" = "1"; then
             STL_FLAGS='-I$(DIST)/stl_wrappers'
         fi
         CFLAGS="$CFLAGS -D_HAS_EXCEPTIONS=0"
         CXXFLAGS="$CXXFLAGS -D_HAS_EXCEPTIONS=0"
-
-        MOZ_FIND_WINSDK_VERSION
     else
         # Check w32api version
         _W32API_MAJOR_VERSION=`echo $W32API_VERSION | $AWK -F\. '{ print $1 }'`
         _W32API_MINOR_VERSION=`echo $W32API_VERSION | $AWK -F\. '{ print $2 }'`
         AC_MSG_CHECKING([for w32api version >= $W32API_VERSION])
         AC_TRY_COMPILE([#include <w32api.h>],
             #if (__W32API_MAJOR_VERSION < $_W32API_MAJOR_VERSION) || \
                 (__W32API_MAJOR_VERSION == $_W32API_MAJOR_VERSION && \
@@ -715,20 +716,19 @@ See https://developer.mozilla.org/en/Win
                 MIDL_FLAGS="$MIDL_FLAGS --win64 -m64"
                 ;;
             esac
         fi
 
         # strsafe.h on mingw uses macros for function deprecation that pollutes namespace
         # causing problems with local implementations with the same name.
         AC_DEFINE(STRSAFE_NO_DEPRECATE)
-
-        MOZ_WINSDK_MAXVER=0x06030000
     fi # !GNU_CC
 
+    MOZ_FIND_WINSDK_VERSION
     AC_DEFINE_UNQUOTED(WINVER,0x$WINVER)
     AC_DEFINE_UNQUOTED(_WIN32_WINNT,0x$WINVER)
     # Require OS features provided by IE 6.0 SP2 (XP SP2)
     AC_DEFINE_UNQUOTED(_WIN32_IE,0x0603)
 
     # If the maximum version supported by this SDK is lower than the target
     # version, error out
     AC_MSG_CHECKING([for Windows SDK being recent enough])
@@ -740,19 +740,16 @@ See https://developer.mozilla.org/en/Win
     fi
 
     AC_DEFINE_UNQUOTED(MOZ_WINSDK_TARGETVER,0x$MOZ_WINSDK_TARGETVER)
     AC_DEFINE_UNQUOTED(MOZ_WINSDK_MAXVER,$MOZ_WINSDK_MAXVER)
     AC_SUBST(MOZ_WINSDK_MAXVER)
     ;;
 esac
 
-AC_PROG_CPP
-AC_PROG_CXXCPP
-
 if test -n "$_WIN32_MSVC"; then
     SKIP_PATH_CHECKS=1
     SKIP_COMPILER_CHECKS=1
     SKIP_LIBRARY_CHECKS=1
 
     # Since we're skipping compiler and library checks, hard-code
     # some facts here.
     AC_DEFINE(HAVE_IO_H)
@@ -1857,16 +1854,19 @@ case "$host" in
 esac
 
 dnl ==============================================================
 dnl Get mozilla version from central milestone file
 dnl ==============================================================
 MOZILLA_VERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir`
 MOZILLA_UAVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir --uaversion`
 MOZILLA_SYMBOLVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir --symbolversion`
+if test -z "$MOZILLA_VERSION"; then
+  AC_MSG_ERROR([failed to read version info from milestone file])
+fi
 
 dnl Get version of various core apps from the version files.
 FIREFOX_VERSION=`cat $_topsrcdir/browser/config/version.txt`
 FIREFOX_VERSION_DISPLAY=`cat $_topsrcdir/browser/config/version_display.txt`
 
 if test -z "$FIREFOX_VERSION"; then
     AC_MSG_ERROR([FIREFOX_VERSION is unexpectedly blank.])
 fi
--- a/devtools/client/aboutdebugging/aboutdebugging.js
+++ b/devtools/client/aboutdebugging/aboutdebugging.js
@@ -16,17 +16,17 @@ loader.lazyRequireGetter(this, "AddonsCo
 loader.lazyRequireGetter(this, "DebuggerClient",
   "devtools/shared/client/main", true);
 loader.lazyRequireGetter(this, "DebuggerServer",
   "devtools/server/main", true);
 loader.lazyRequireGetter(this, "WorkersComponent",
   "devtools/client/aboutdebugging/components/workers", true);
 loader.lazyRequireGetter(this, "Services");
 
-let AboutDebugging = {
+var AboutDebugging = {
   _categories: null,
   get categories() {
     // If needed, initialize the list of available categories.
     if (!this._categories) {
       let elements = document.querySelectorAll(".category");
       this._categories = Array.map(elements, element => {
         let value = element.getAttribute("value");
         element.addEventListener("click", this.showTab.bind(this, value));
--- a/devtools/client/animationinspector/animation-controller.js
+++ b/devtools/client/animationinspector/animation-controller.js
@@ -2,17 +2,17 @@
 /* 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/. */
 /* globals AnimationsPanel */
 
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/Task.jsm");
 var { loader, require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm");
 Cu.import("resource://gre/modules/devtools/shared/Console.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 
 loader.lazyRequireGetter(this, "promise");
 loader.lazyRequireGetter(this, "EventEmitter",
--- a/devtools/client/animationinspector/test/head.js
+++ b/devtools/client/animationinspector/test/head.js
@@ -1,15 +1,15 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {gDevTools} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const promise = require("promise");
 const {TargetFactory} = require("devtools/client/framework/target");
 const {console} = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
 const {ViewHelpers} = Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm", {});
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
 
--- a/devtools/client/animationinspector/test/unit/test_findOptimalTimeInterval.js
+++ b/devtools/client/animationinspector/test/unit/test_findOptimalTimeInterval.js
@@ -1,17 +1,17 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 /* eslint no-eval:0 */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {findOptimalTimeInterval} = require("devtools/client/animationinspector/utils");
 
 // This test array contains objects that are used to test the
 // findOptimalTimeInterval function. Each object should have the following
 // properties:
 // - desc: an optional string that will be printed out
 // - timeScale: a number that represents how many pixels is 1ms
--- a/devtools/client/animationinspector/test/unit/test_timeScale.js
+++ b/devtools/client/animationinspector/test/unit/test_timeScale.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {TimeScale} = require("devtools/client/animationinspector/components");
 
 const TEST_ANIMATIONS = [{
   desc: "Testing a few standard animations",
   animations: [{
     previousStartTime: 500,
     delay: 0,
--- a/devtools/client/app-manager/content/connection-footer.js
+++ b/devtools/client/app-manager/content/connection-footer.js
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
-const Ci = Components.interfaces;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 
 const {Simulator} = Cu.import("resource://gre/modules/devtools/shared/apps/Simulator.jsm")
 const {Devices} = Cu.import("resource://gre/modules/devtools/shared/apps/Devices.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 const {ConnectionManager, Connection} = require("devtools/shared/client/connection-manager");
--- a/devtools/client/app-manager/content/device.js
+++ b/devtools/client/app-manager/content/device.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource://gre/modules/Services.jsm");
 const {gDevTools} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {TargetFactory} = require("devtools/client/framework/target");
 
 const {ConnectionManager, Connection}
   = require("devtools/shared/client/connection-manager");
--- a/devtools/client/app-manager/content/index.js
+++ b/devtools/client/app-manager/content/index.js
@@ -1,13 +1,13 @@
 /* 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 {utils: Cu, interfaces: Ci} = Components;
+var {utils: Cu, interfaces: Ci} = Components;
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {Toolbox} = require("devtools/client/framework/toolbox");
 const {ConnectionManager, Connection} = require("devtools/shared/client/connection-manager");
 const promise = require("devtools/shared/deprecated-sync-thenables");
 const prefs = require("sdk/preferences/service");
 const Services = require("Services");
 const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/app-manager.properties");
--- a/devtools/client/app-manager/content/projects.js
+++ b/devtools/client/app-manager/content/projects.js
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {ConnectionManager, Connection} = require("devtools/shared/client/connection-manager");
 const {AppProjects} = require("devtools/client/app-manager/app-projects");
 const {AppValidator} = require("devtools/client/app-manager/app-validator");
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
 const {installHosted, installPackaged, getTargetForApp,
--- a/devtools/client/app-manager/test/head.js
+++ b/devtools/client/app-manager/test/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const {utils: Cu, classes: Cc, interfaces: Ci} = Components;
+var {utils: Cu, classes: Cc, interfaces: Ci} = Components;
 
 const {Promise: promise} =
   Cu.import("resource://gre/modules/devtools/shared/deprecated-sync-thenables.js", {});
 const {require} =
   Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 const {AppProjects} = require("devtools/client/app-manager/app-projects");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
--- a/devtools/client/canvasdebugger/canvasdebugger.js
+++ b/devtools/client/canvasdebugger/canvasdebugger.js
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/SideMenuWidget.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 Cu.import("resource://gre/modules/devtools/shared/Console.jsm");
 
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
@@ -72,16 +72,17 @@ const EVENTS = {
   // After all the thumbnails associated with an animation frame snapshot
   // are displayed in the UI.
   THUMBNAILS_DISPLAYED: "CanvasDebugger:ThumbnailsDisplayed",
 
   // When a source is shown in the JavaScript Debugger at a specific location.
   SOURCE_SHOWN_IN_JS_DEBUGGER: "CanvasDebugger:SourceShownInJsDebugger",
   SOURCE_NOT_FOUND_IN_JS_DEBUGGER: "CanvasDebugger:SourceNotFoundInJsDebugger"
 };
+XPCOMUtils.defineConstant(this, "EVENTS", EVENTS);
 
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 const STRINGS_URI = "chrome://browser/locale/devtools/canvasdebugger.properties";
 const SHARED_STRINGS_URI = "chrome://browser/locale/devtools/shared.properties";
 
 const SNAPSHOT_START_RECORDING_DELAY = 10; // ms
 const SNAPSHOT_DATA_EXPORT_MAX_BLOCK = 1000; // ms
 const SNAPSHOT_DATA_DISPLAY_DELAY = 10; // ms
--- a/devtools/client/canvasdebugger/test/head.js
+++ b/devtools/client/canvasdebugger/test/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 // Disable logging for all the tests. Both the debugger server and frontend will
 // be affected by this pref.
 var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
 Services.prefs.setBoolPref("devtools.debugger.log", false);
 
--- a/devtools/client/debugger/debugger-controller.js
+++ b/devtools/client/debugger/debugger-controller.js
@@ -1,16 +1,16 @@
 /* -*- 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";
 
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 const DBG_STRINGS_URI = "chrome://browser/locale/devtools/debugger.properties";
 const NEW_SOURCE_IGNORED_URLS = ["debugger eval code", "XStringBundle"];
 const NEW_SOURCE_DISPLAY_DELAY = 200; // ms
 const FETCH_SOURCE_RESPONSE_DELAY = 200; // ms
 const FRAME_STEP_CLEAR_DELAY = 100; // ms
 const CALL_STACK_PAGE_SIZE = 25; // frames
 
@@ -99,26 +99,29 @@ Cu.import("resource:///modules/devtools/
 Cu.import("resource:///modules/devtools/client/shared/widgets/BreadcrumbsWidget.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/SideMenuWidget.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/VariablesView.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/VariablesViewController.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 
 Cu.import("resource:///modules/devtools/client/shared/browser-loader.js");
 const require = BrowserLoader("resource:///modules/devtools/client/debugger/", this).require;
+XPCOMUtils.defineConstant(this, "require", require);
 
 const {TargetFactory} = require("devtools/client/framework/target");
 const {Toolbox} = require("devtools/client/framework/toolbox");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
 const promise = require("devtools/shared/deprecated-sync-thenables");
 const Editor = require("devtools/client/sourceeditor/editor");
 const DebuggerEditor = require("devtools/client/sourceeditor/debugger");
 const {Tooltip} = require("devtools/client/shared/widgets/Tooltip");
 const FastListWidget = require("devtools/client/shared/widgets/FastListWidget");
 
+XPCOMUtils.defineConstant(this, "EVENTS", EVENTS);
+
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
   "resource://gre/modules/Task.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Parser",
   "resource:///modules/devtools/client/shared/Parser.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "ShortcutUtils",
   "resource://gre/modules/ShortcutUtils.jsm");
--- a/devtools/client/debugger/debugger-view.js
+++ b/devtools/client/debugger/debugger-view.js
@@ -44,16 +44,29 @@ const { NAME: WAIT_UNTIL_NAME } = requir
 
 const services = {
   WAIT_UNTIL: WAIT_UNTIL_NAME
 };
 
 const EventListenersView = require('./content/views/event-listeners-view');
 const actions = require('./content/actions/event-listeners');
 
+Object.defineProperties(this, {
+  "store": {
+    value: store,
+    enumerable: true,
+    writable: false
+  },
+  "services": {
+    value: services,
+    enumerable: true,
+    writable: false
+  }
+});
+
 /**
  * Object defining the debugger view components.
  */
 var DebuggerView = {
   /**
    * Initializes the debugger view.
    *
    * @return object
--- a/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/bootstrap.js
+++ b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/bootstrap.js
@@ -1,12 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const { interfaces: Ci, classes: Cc, utils: Cu } = Components;
+var { interfaces: Ci, classes: Cc, utils: Cu } = Components;
 
 function notify() {
   // Log objects so makeDebuggeeValue can get the global to use
   console.log({ msg: "Hello again" });
 }
 
 function startup(aParams, aReason) {
   Cu.import("resource://gre/modules/Services.jsm");
--- a/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/bootstrap.js
+++ b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/bootstrap.js
@@ -1,12 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const { interfaces: Ci, classes: Cc } = Components;
+var { interfaces: Ci, classes: Cc } = Components;
 
 function startup(aParams, aReason) {
   Components.utils.import("resource://gre/modules/Services.jsm");
   let res = Services.io.getProtocolHandler("resource")
                        .QueryInterface(Ci.nsIResProtocolHandler);
   res.setSubstitution("browser_dbg_addon5", aParams.resourceURI);
 
   // Load a JS module
--- a/devtools/client/debugger/test/mochitest/browser_dbg_break-on-next-console.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_break-on-next-console.js
@@ -35,21 +35,23 @@ function test() {
     EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
     let jsterm = yield getSplitConsole();
     let executed = jsterm.execute("1+1");
     yield oncePaused;
 
     let updatedFrame = yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
     let variables = gDebugger.DebuggerView.Variables;
 
-    is(variables._store.length, 2, "Correct number of scopes available");
+    is(variables._store.length, 3, "Correct number of scopes available");
     is(variables.getScopeAtIndex(0).name, "With scope [Object]",
         "Paused with correct scope (0)");
-    is(variables.getScopeAtIndex(1).name, "Global scope [Window]",
+    is(variables.getScopeAtIndex(1).name, "Block scope",
         "Paused with correct scope (1)");
+    is(variables.getScopeAtIndex(2).name, "Global scope [Window]",
+        "Paused with correct scope (2)");
 
     let onceResumed = gTarget.once("thread-resumed");
     EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
     yield onceResumed;
 
     yield executed;
   });
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_break-on-next.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_break-on-next.js
@@ -44,23 +44,25 @@ function test() {
 
     let oncePaused = gTarget.once("thread-paused");
     EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
     yield oncePaused;
 
     let updatedFrame = yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
     let variables = gDebugger.DebuggerView.Variables;
 
-    is(variables._store.length, 3, "Correct number of scopes available");
+    is(variables._store.length, 4, "Correct number of scopes available");
     is(variables.getScopeAtIndex(0).name, "Function scope [interval<]",
         "Paused with correct scope (0)");
     is(variables.getScopeAtIndex(1).name, "Block scope",
         "Paused with correct scope (1)");
-    is(variables.getScopeAtIndex(2).name, "Global scope [Window]",
+    is(variables.getScopeAtIndex(2).name, "Block scope",
         "Paused with correct scope (2)");
+    is(variables.getScopeAtIndex(3).name, "Global scope [Window]",
+        "Paused with correct scope (3)");
 
     yield evalInTab(gTab, "clearInterval(interval)");
     let onceResumed = gTarget.once("thread-resumed");
     EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
     yield onceResumed;
   });
 
   let testEvent = Task.async(function*() {
@@ -71,23 +73,29 @@ function test() {
     once(gDebugger.gClient, "willInterrupt").then(() => {
       generateMouseClickInTab(gTab, "content.document.querySelector('button')");
     });
     yield oncePaused;
 
     let updatedFrame = yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
     let variables = gDebugger.DebuggerView.Variables;
 
-    is(variables._store.length, 4, "Correct number of scopes available");
+    is(variables._store.length, 6, "Correct number of scopes available");
     is(variables.getScopeAtIndex(0).name, "Function scope [onclick]",
         "Paused with correct scope (0)");
-    is(variables.getScopeAtIndex(1).name, "With scope [HTMLButtonElement]",
+    // Non-syntactic lexical scope introduced by non-syntactic scope chain.
+    is(variables.getScopeAtIndex(1).name, "Block scope",
         "Paused with correct scope (1)");
-    is(variables.getScopeAtIndex(2).name, "With scope [HTMLDocument]",
+    is(variables.getScopeAtIndex(2).name, "With scope [HTMLButtonElement]",
         "Paused with correct scope (2)");
-    is(variables.getScopeAtIndex(3).name, "Global scope [Window]",
+    is(variables.getScopeAtIndex(3).name, "With scope [HTMLDocument]",
         "Paused with correct scope (3)");
+    // Global lexical scope.
+    is(variables.getScopeAtIndex(4).name, "Block scope",
+        "Paused with correct scope (4)");
+    is(variables.getScopeAtIndex(5).name, "Global scope [Window]",
+        "Paused with correct scope (5)");
 
     let onceResumed = gTarget.once("thread-resumed");
     EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
     yield onceResumed;
   });
 }
--- a/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-01.js
@@ -48,18 +48,18 @@ function testPauseOnExceptionsDisabled()
     ok(isCaretPos(gPanel, 26),
       "Should be paused on the debugger statement (1).");
 
     let innerScope = gVariables.getScopeAtIndex(0);
     let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
 
     is(gFrames.itemCount, 1,
       "Should have one frame.");
-    is(gVariables._store.length, 3,
-      "Should have three scopes.");
+    is(gVariables._store.length, 4,
+      "Should have four scopes.");
 
     is(innerNodes[0].querySelector(".name").getAttribute("value"), "this",
       "Should have the right property name for 'this'.");
     is(innerNodes[0].querySelector(".value").getAttribute("value"), "<button>",
       "Should have the right property value for 'this'.");
 
     let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
       isnot(gDebugger.gThreadClient.state, "paused",
@@ -91,18 +91,18 @@ function testPauseOnExceptionsEnabled() 
     ok(isCaretPos(gPanel, 19),
       "Should be paused on the debugger statement.");
 
     let innerScope = gVariables.getScopeAtIndex(0);
     let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
 
     is(gFrames.itemCount, 1,
       "Should have one frame.");
-    is(gVariables._store.length, 3,
-      "Should have three scopes.");
+    is(gVariables._store.length, 4,
+      "Should have four scopes.");
 
     is(innerNodes[0].querySelector(".name").getAttribute("value"), "<exception>",
       "Should have the right property name for <exception>.");
     is(innerNodes[0].querySelector(".value").getAttribute("value"), "Error",
       "Should have the right property value for <exception>.");
 
     let finished = waitForCaretAndScopes(gPanel, 26).then(() => {
       info("Testing enabled pause-on-exceptions and resumed after pause.");
@@ -112,18 +112,18 @@ function testPauseOnExceptionsEnabled() 
       ok(isCaretPos(gPanel, 26),
         "Should be paused on the debugger statement.");
 
       let innerScope = gVariables.getScopeAtIndex(0);
       let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
 
       is(gFrames.itemCount, 1,
         "Should have one frame.");
-      is(gVariables._store.length, 3,
-        "Should have three scopes.");
+      is(gVariables._store.length, 4,
+        "Should have four scopes.");
 
       is(innerNodes[0].querySelector(".name").getAttribute("value"), "this",
         "Should have the right property name for 'this'.");
       is(innerNodes[0].querySelector(".value").getAttribute("value"), "<button>",
         "Should have the right property value for 'this'.");
 
       let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
         isnot(gDebugger.gThreadClient.state, "paused",
--- a/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-02.js
@@ -47,18 +47,18 @@ function testPauseOnExceptionsAfterReloa
     ok(isCaretPos(gPanel, 19),
       "Should be paused on the debugger statement.");
 
     let innerScope = gVariables.getScopeAtIndex(0);
     let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
 
     is(gFrames.itemCount, 1,
       "Should have one frame.");
-    is(gVariables._store.length, 3,
-      "Should have three scopes.");
+    is(gVariables._store.length, 4,
+      "Should have four scopes.");
 
     is(innerNodes[0].querySelector(".name").getAttribute("value"), "<exception>",
       "Should have the right property name for <exception>.");
     is(innerNodes[0].querySelector(".value").getAttribute("value"), "Error",
       "Should have the right property value for <exception>.");
 
     let finished = waitForCaretAndScopes(gPanel, 26).then(() => {
       info("Testing enabled pause-on-exceptions and resumed after pause.");
@@ -68,18 +68,18 @@ function testPauseOnExceptionsAfterReloa
       ok(isCaretPos(gPanel, 26),
         "Should be paused on the debugger statement.");
 
       let innerScope = gVariables.getScopeAtIndex(0);
       let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
 
       is(gFrames.itemCount, 1,
         "Should have one frame.");
-      is(gVariables._store.length, 3,
-        "Should have three scopes.");
+      is(gVariables._store.length, 4,
+        "Should have four scopes.");
 
       is(innerNodes[0].querySelector(".name").getAttribute("value"), "this",
         "Should have the right property name for 'this'.");
       is(innerNodes[0].querySelector(".value").getAttribute("value"), "<button>",
         "Should have the right property value for 'this'.");
 
       let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
         isnot(gDebugger.gThreadClient.state, "paused",
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-06.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-06.js
@@ -2,17 +2,17 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Test that Promises get their internal state added as psuedo properties.
  */
 
 const TAB_URL = EXAMPLE_URL + "doc_promise.html";
 
-const test = Task.async(function* () {
+var test = Task.async(function* () {
   const [tab,, panel] = yield initDebugger(TAB_URL);
   yield ensureSourceIs(panel, "doc_promise.html", true);
 
   const scopes = waitForCaretAndScopes(panel, 21);
   callInTab(tab, "doPause");
   yield scopes;
 
   const variables = panel.panelWin.DebuggerView.Variables;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-01.js
@@ -39,29 +39,32 @@ function test() {
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
   let protoVar = localScope.get("__proto__");
   let constrVar = protoVar.get("constructor");
   let proto2Var = constrVar.get("__proto__");
   let constr2Var = proto2Var.get("constructor");
 
   function testFiltered() {
     is(localScope.expanded, true,
       "The localScope should be expanded.");
     is(withScope.expanded, true,
       "The withScope should be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalLexicalScope should be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should be expanded.");
 
     is(protoVar.expanded, true,
       "The protoVar should be expanded.");
     is(constrVar.expanded, true,
       "The constrVar should be expanded.");
     is(proto2Var.expanded, true,
@@ -70,23 +73,27 @@ function testVariablesAndPropertiesFilte
       "The constr2Var should be expanded.");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 1,
       "There should be 1 variable displayed in the local scope.");
     is(withScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the with scope.");
     is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the function scope.");
+    is(globalLexicalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
+      "There should be 0 variables displayed in the global lexical scope.");
     is(globalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the global scope.");
 
     is(withScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the with scope.");
     is(functionScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the function scope.");
+    is(globalLexicalScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
+      "There should be 0 properties displayed in the global lexical scope.");
     is(globalScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the global scope.");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
       "__proto__", "The only inner variable displayed should be '__proto__'");
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched]) > .title > .name")[0].getAttribute("value"),
       "constructor", "The first inner property displayed should be 'constructor'");
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched]) > .title > .name")[1].getAttribute("value"),
@@ -101,28 +108,31 @@ function testVariablesAndPropertiesFilte
     gSearchBox.doCommand();
     return expanded.then(testFiltered);
   }
 
   function secondFilter() {
     localScope.collapse();
     withScope.collapse();
     functionScope.collapse();
+    globalLexicalScope.collapse();
     globalScope.collapse();
     protoVar.collapse();
     constrVar.collapse();
     proto2Var.collapse();
     constr2Var.collapse();
 
     is(localScope.expanded, false,
       "The localScope should not be expanded.");
     is(withScope.expanded, false,
       "The withScope should not be expanded.");
     is(functionScope.expanded, false,
       "The functionScope should not be expanded.");
+    is(globalLexicalScope.expanded, false,
+      "The globalLexicalScope should not be expanded.");
     is(globalScope.expanded, false,
       "The globalScope should not be expanded.");
 
     is(protoVar.expanded, false,
       "The protoVar should not be expanded.");
     is(constrVar.expanded, false,
       "The constrVar should not be expanded.");
     is(proto2Var.expanded, false,
@@ -140,36 +150,41 @@ function testVariablesAndPropertiesFilte
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
-    "The functionScope should not be expanded yet.");
+     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+     "The globalLexicalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
-      "The functionScope should now be expanded.");
+       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+       "The globalLexicalScope should be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     let protoVar = localScope.get("__proto__");
 
     waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
       let constrVar = protoVar.get("constructor");
 
@@ -201,16 +216,17 @@ function prepareVariablesAndProperties()
       constrVar.expand();
     });
 
     protoVar.expand();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-02.js
@@ -39,29 +39,32 @@ function test() {
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
   let protoVar = localScope.get("__proto__");
   let constrVar = protoVar.get("constructor");
   let proto2Var = constrVar.get("__proto__");
   let constr2Var = proto2Var.get("constructor");
 
   function testFiltered() {
     is(localScope.expanded, true,
       "The localScope should be expanded.");
     is(withScope.expanded, true,
       "The withScope should be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalScope should be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should be expanded.");
 
     is(protoVar.expanded, true,
       "The protoVar should be expanded.");
     is(constrVar.expanded, true,
       "The constrVar should be expanded.");
     is(proto2Var.expanded, true,
@@ -70,25 +73,29 @@ function testVariablesAndPropertiesFilte
       "The constr2Var should be expanded.");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 1,
       "There should be 1 variable displayed in the local scope.");
     is(withScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the with scope.");
     is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the function scope.");
+    is(globalLexicalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
+      "There should be no variables displayed in the global lexical scope.");
     is(globalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be no variables displayed in the global scope.");
 
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 4,
       "There should be 4 properties displayed in the local scope.");
     is(withScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the with scope.");
     is(functionScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the function scope.");
+    is(globalLexicalScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
+      "There should be 0 properties displayed in the global lexical scope.");
     is(globalScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the global scope.");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
       "__proto__", "The only inner variable displayed should be '__proto__'");
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched]) > .title > .name")[0].getAttribute("value"),
       "constructor", "The first inner property displayed should be 'constructor'");
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched]) > .title > .name")[1].getAttribute("value"),
@@ -108,28 +115,31 @@ function testVariablesAndPropertiesFilte
     gSearchBox.doCommand();
     return expanded.then(testFiltered);
   }
 
   function secondFilter() {
     localScope.collapse();
     withScope.collapse();
     functionScope.collapse();
+    globalLexicalScope.collapse();
     globalScope.collapse();
     protoVar.collapse();
     constrVar.collapse();
     proto2Var.collapse();
     constr2Var.collapse();
 
     is(localScope.expanded, false,
       "The localScope should not be expanded.");
     is(withScope.expanded, false,
       "The withScope should not be expanded.");
     is(functionScope.expanded, false,
       "The functionScope should not be expanded.");
+    is(globalLexicalScope.expanded, false,
+      "The globalScope should not be expanded.");
     is(globalScope.expanded, false,
       "The globalScope should not be expanded.");
 
     is(protoVar.expanded, false,
       "The protoVar should not be expanded.");
     is(constrVar.expanded, false,
       "The constrVar should not be expanded.");
     is(proto2Var.expanded, false,
@@ -148,36 +158,41 @@ function testVariablesAndPropertiesFilte
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+    "The globalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalScope should now be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     let protoVar = localScope.get("__proto__");
 
     waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
       let constrVar = protoVar.get("constructor");
 
@@ -209,16 +224,17 @@ function prepareVariablesAndProperties()
       constrVar.expand();
     });
 
     protoVar.expand();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-03.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-03.js
@@ -38,67 +38,77 @@ function test() {
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   function testFiltered() {
     is(localScope.expanded, true,
       "The localScope should be expanded.");
     is(withScope.expanded, true,
       "The withScope should be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalScope should be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should be expanded.");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 1,
       "There should be 1 variable displayed in the local scope.");
     is(withScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the with scope.");
     is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the function scope.");
+    is(globalLexicalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
+      "There should be 0 variables displayed in the global scope.");
     is(globalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the global scope.");
 
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the local scope.");
     is(withScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the with scope.");
     is(functionScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the function scope.");
+    is(globalLexicalScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
+      "There should be 0 properties displayed in the global scope.");
     is(globalScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the global scope.");
   }
 
   function firstFilter() {
     typeText(gSearchBox, "*alpha");
     testFiltered("alpha");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
       "alpha", "The only inner variable displayed should be 'alpha'");
   }
 
   function secondFilter() {
     localScope.collapse();
     withScope.collapse();
     functionScope.collapse();
+    globalLexicalScope.collapse();
     globalScope.collapse();
 
     is(localScope.expanded, false,
       "The localScope should not be expanded.");
     is(withScope.expanded, false,
       "The withScope should not be expanded.");
     is(functionScope.expanded, false,
       "The functionScope should not be expanded.");
+    is(globalLexicalScope.expanded, false,
+      "The globalScope should not be expanded.");
     is(globalScope.expanded, false,
       "The globalScope should not be expanded.");
 
     backspaceText(gSearchBox, 6);
     typeText(gSearchBox, "*beta");
     testFiltered("beta");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
@@ -110,44 +120,50 @@ function testVariablesAndPropertiesFilte
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+    "The globalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalScope should now be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     deferred.resolve();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-04.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-04.js
@@ -39,182 +39,195 @@ function test() {
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
   let step = 0;
 
   let tests = [
     function() {
-      assertExpansion([true, false, false, false]);
+      assertExpansion([true, false, false, false, false]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, false, false, false]);
+      assertExpansion([true, false, false, false, false]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, false, false, false]);
+      assertExpansion([true, false, false, false, false]);
       gEditor.focus();
     },
     function() {
-      assertExpansion([true, false, false, false]);
+      assertExpansion([true, false, false, false, false]);
       typeText(gSearchBox, "*");
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       gEditor.focus();
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       backspaceText(gSearchBox, 1);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       gEditor.focus();
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       localScope.collapse();
       withScope.collapse();
       functionScope.collapse();
+      globalLexicalScope.collapse();
       globalScope.collapse();
     },
     function() {
-      assertExpansion([false, false, false, false]);
+      assertExpansion([false, false, false, false, false]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([false, false, false, false]);
+      assertExpansion([false, false, false, false, false]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([false, false, false, false]);
+      assertExpansion([false, false, false, false, false]);
       gEditor.focus();
     },
     function() {
-      assertExpansion([false, false, false, false]);
+      assertExpansion([false, false, false, false, false]);
       clearText(gSearchBox);
       typeText(gSearchBox, "*");
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       gEditor.focus();
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       backspaceText(gSearchBox, 1);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       gEditor.focus();
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
     }
   ];
 
   function assertExpansion(aFlags) {
     is(localScope.expanded, aFlags[0],
       "The localScope should " + (aFlags[0] ? "" : "not ") +
       "be expanded at this point (" + step + ").");
 
     is(withScope.expanded, aFlags[1],
       "The withScope should " + (aFlags[1] ? "" : "not ") +
       "be expanded at this point (" + step + ").");
 
     is(functionScope.expanded, aFlags[2],
       "The functionScope should " + (aFlags[2] ? "" : "not ") +
       "be expanded at this point (" + step + ").");
 
-    is(globalScope.expanded, aFlags[3],
-      "The globalScope should " + (aFlags[3] ? "" : "not ") +
+    is(globalLexicalScope.expanded, aFlags[3],
+      "The globalLexicalScope should " + (aFlags[3] ? "" : "not ") +
+      "be expanded at this point (" + step + ").");
+
+    is(globalScope.expanded, aFlags[4],
+      "The globalScope should " + (aFlags[4] ? "" : "not ") +
       "be expanded at this point (" + step + ").");
 
     step++;
   }
 
   return promise.all(tests.map(f => f()));
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+    "The globalLexicalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalLexicalScope should now be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     withScope.collapse();
     functionScope.collapse();
+    globalLexicalScope.collapse();
     globalScope.collapse();
 
     deferred.resolve();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-05.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-05.js
@@ -38,54 +38,55 @@ function test() {
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
   let step = 0;
 
   let tests = [
     function() {
-      assertScopeExpansion([true, false, false, false]);
+      assertScopeExpansion([true, false, false, false, false]);
       typeText(gSearchBox, "*arguments");
     },
     function() {
-      assertScopeExpansion([true, true, true, true]);
-      assertVariablesCountAtLeast([0, 0, 1, 0]);
+      assertScopeExpansion([true, true, true, true, true]);
+      assertVariablesCountAtLeast([0, 0, 1, 0, 0]);
 
       is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
         "arguments", "The arguments pseudoarray should be visible.");
       is(functionScope.get("arguments").expanded, false,
         "The arguments pseudoarray in functionScope should not be expanded.");
 
       backspaceText(gSearchBox, 6);
     },
     function() {
-      assertScopeExpansion([true, true, true, true]);
-      assertVariablesCountAtLeast([0, 0, 1, 1]);
+      assertScopeExpansion([true, true, true, true, true]);
+      assertVariablesCountAtLeast([0, 0, 1, 0, 1]);
 
       is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
         "arguments", "The arguments pseudoarray should be visible.");
       is(functionScope.get("arguments").expanded, false,
         "The arguments pseudoarray in functionScope should not be expanded.");
 
       is(globalScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
         "EventTarget", "The EventTarget object should be visible.");
       is(globalScope.get("EventTarget").expanded, false,
         "The EventTarget object in globalScope should not be expanded.");
 
       backspaceText(gSearchBox, 2);
     },
     function() {
-      assertScopeExpansion([true, true, true, true]);
-      assertVariablesCountAtLeast([0, 1, 3, 1]);
+      assertScopeExpansion([true, true, true, true, true]);
+      assertVariablesCountAtLeast([0, 1, 3, 0, 1]);
 
       is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
         "aNumber", "The aNumber param should be visible.");
       is(functionScope.get("aNumber").expanded, false,
         "The aNumber param in functionScope should not be expanded.");
 
       is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[1].getAttribute("value"),
         "a", "The a variable should be visible.");
@@ -95,18 +96,18 @@ function testVariablesAndPropertiesFilte
       is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[2].getAttribute("value"),
         "arguments", "The arguments pseudoarray should be visible.");
       is(functionScope.get("arguments").expanded, false,
         "The arguments pseudoarray in functionScope should not be expanded.");
 
       backspaceText(gSearchBox, 1);
     },
     function() {
-      assertScopeExpansion([true, true, true, true]);
-      assertVariablesCountAtLeast([4, 1, 3, 1]);
+      assertScopeExpansion([true, true, true, true, true]);
+      assertVariablesCountAtLeast([4, 1, 3, 0, 1]);
 
       is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
         "this", "The this reference should be visible.");
       is(localScope.get("this").expanded, false,
         "The this reference in localScope should not be expanded.");
 
       is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[1].getAttribute("value"),
         "alpha", "The alpha variable should be visible.");
@@ -148,82 +149,97 @@ function testVariablesAndPropertiesFilte
     is(withScope.expanded, aFlags[1],
       "The withScope should " + (aFlags[1] ? "" : "not ") +
        "be expanded at this point (" + step + ").");
 
     is(functionScope.expanded, aFlags[2],
       "The functionScope should " + (aFlags[2] ? "" : "not ") +
        "be expanded at this point (" + step + ").");
 
-    is(globalScope.expanded, aFlags[3],
-      "The globalScope should " + (aFlags[3] ? "" : "not ") +
+    is(globalLexicalScope.expanded, aFlags[3],
+      "The globalLexicalScope should " + (aFlags[3] ? "" : "not ") +
+       "be expanded at this point (" + step + ").");
+
+    is(globalScope.expanded, aFlags[4],
+      "The globalScope should " + (aFlags[4] ? "" : "not ") +
        "be expanded at this point (" + step + ").");
   }
 
   function assertVariablesCountAtLeast(aCounts) {
     ok(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length >= aCounts[0],
       "There should be " + aCounts[0] +
       " variable displayed in the local scope (" + step + ").");
 
     ok(withScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length >= aCounts[1],
       "There should be " + aCounts[1] +
       " variable displayed in the with scope (" + step + ").");
 
     ok(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length >= aCounts[2],
       "There should be " + aCounts[2] +
       " variable displayed in the function scope (" + step + ").");
 
-    ok(globalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length >= aCounts[3],
+    ok(globalLexicalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length >= aCounts[3],
       "There should be " + aCounts[3] +
+       " variable displayed in the global scope (" + step + ").");
+
+    ok(globalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length >= aCounts[4],
+      "There should be " + aCounts[4] +
       " variable displayed in the global scope (" + step + ").");
 
     step++;
   }
 
   return promise.all(tests.map(f => f()));
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+    "The globalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalScope should now be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     withScope.collapse();
     functionScope.collapse();
+    globalLexicalScope.collapse();
     globalScope.collapse();
 
     deferred.resolve();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-01.js
@@ -30,37 +30,45 @@ function test() {
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function initialChecks() {
   let scopeNodes = gDebugger.document.querySelectorAll(".variables-view-scope");
-  is(scopeNodes.length, 2,
-    "There should be 2 scopes available.");
+  is(scopeNodes.length, 3,
+    "There should be 3 scopes available.");
 
   ok(scopeNodes[0].querySelector(".name").getAttribute("value").includes("[test]"),
     "The local scope should be properly identified.");
-  ok(scopeNodes[1].querySelector(".name").getAttribute("value").includes("[Window]"),
+  ok(scopeNodes[1].querySelector(".name").getAttribute("value").includes("Block"),
+    "The global lexical scope should be properly identified.");
+  ok(scopeNodes[2].querySelector(".name").getAttribute("value").includes("[Window]"),
     "The global scope should be properly identified.");
 
   is(gVariables.getScopeAtIndex(0).target, scopeNodes[0],
     "getScopeAtIndex(0) didn't return the expected scope.");
   is(gVariables.getScopeAtIndex(1).target, scopeNodes[1],
     "getScopeAtIndex(1) didn't return the expected scope.");
+  is(gVariables.getScopeAtIndex(2).target, scopeNodes[2],
+    "getScopeAtIndex(2) didn't return the expected scope.");
 
   is(gVariables.getItemForNode(scopeNodes[0]).target, scopeNodes[0],
     "getItemForNode([0]) didn't return the expected scope.");
   is(gVariables.getItemForNode(scopeNodes[1]).target, scopeNodes[1],
     "getItemForNode([1]) didn't return the expected scope.");
+  is(gVariables.getItemForNode(scopeNodes[2]).target, scopeNodes[2],
+    "getItemForNode([2]) didn't return the expected scope.");
 
   is(gVariables.getItemForNode(scopeNodes[0]).expanded, true,
     "The local scope should be expanded by default.");
   is(gVariables.getItemForNode(scopeNodes[1]).expanded, false,
+    "The global lexical scope should not be collapsed by default.");
+  is(gVariables.getItemForNode(scopeNodes[2]).expanded, false,
     "The global scope should not be collapsed by default.");
 }
 
 function testExpandVariables() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let localEnums = localScope.target.querySelector(".variables-view-element-details.enum").childNodes;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-03.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-03.js
@@ -33,31 +33,31 @@ function test() {
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function expandGlobalScope() {
   let deferred = promise.defer();
 
-  let globalScope = gVariables.getScopeAtIndex(1);
+  let globalScope = gVariables.getScopeAtIndex(2);
   is(globalScope.expanded, false,
     "The global scope should not be expanded by default.");
 
   gDebugger.once(gDebugger.EVENTS.FETCHED_VARIABLES, deferred.resolve);
 
   EventUtils.sendMouseEvent({ type: "mousedown" },
     globalScope.target.querySelector(".name"),
     gDebugger);
 
   return deferred.promise;
 }
 
 function testGlobalScope() {
-  let globalScope = gVariables.getScopeAtIndex(1);
+  let globalScope = gVariables.getScopeAtIndex(2);
   is(globalScope.expanded, true,
     "The global scope should now be expanded.");
 
   is(globalScope.get("InstallTrigger").target.querySelector(".name").getAttribute("value"), "InstallTrigger",
     "Should have the right property name for 'InstallTrigger'.");
   is(globalScope.get("InstallTrigger").target.querySelector(".value").getAttribute("value"), "InstallTriggerImpl",
     "Should have the right property value for 'InstallTrigger'.");
 
@@ -87,31 +87,31 @@ function testGlobalScope() {
     "Should have no child enumerable properties for 'undefined'.");
   is(globalScope.get("undefined").target.querySelector(".nonenum").childNodes.length, 0,
     "Should have no child non-enumerable properties for 'undefined'.");
 }
 
 function expandWindowVariable() {
   let deferred = promise.defer();
 
-  let windowVar = gVariables.getScopeAtIndex(1).get("window");
+  let windowVar = gVariables.getScopeAtIndex(2).get("window");
   is(windowVar.expanded, false,
     "The window variable should not be expanded by default.");
 
   gDebugger.once(gDebugger.EVENTS.FETCHED_PROPERTIES, deferred.resolve);
 
   EventUtils.sendMouseEvent({ type: "mousedown" },
     windowVar.target.querySelector(".name"),
     gDebugger);
 
   return deferred.promise;
 }
 
 function testWindowVariable() {
-  let windowVar = gVariables.getScopeAtIndex(1).get("window");
+  let windowVar = gVariables.getScopeAtIndex(2).get("window");
   is(windowVar.expanded, true,
     "The window variable should now be expanded.");
 
   is(windowVar.get("InstallTrigger").target.querySelector(".name").getAttribute("value"), "InstallTrigger",
     "Should have the right property name for 'InstallTrigger'.");
   is(windowVar.get("InstallTrigger").target.querySelector(".value").getAttribute("value"), "InstallTriggerImpl",
     "Should have the right property value for 'InstallTrigger'.");
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-override-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-override-01.js
@@ -16,47 +16,55 @@ function test() {
     let variables = win.DebuggerView.Variables;
 
     callInTab(tab, "test");
     yield waitForSourceAndCaretAndScopes(panel, ".html", 23);
 
     let firstScope = variables.getScopeAtIndex(0);
     let secondScope = variables.getScopeAtIndex(1);
     let thirdScope = variables.getScopeAtIndex(2);
-    let globalScope = variables.getScopeAtIndex(3);
+    let globalLexicalScope = variables.getScopeAtIndex(3);
+    let globalScope = variables.getScopeAtIndex(4);
 
     ok(firstScope, "The first scope is available.");
     ok(secondScope, "The second scope is available.");
     ok(thirdScope, "The third scope is available.");
+    ok(globalLexicalScope, "The global lexical scope is available.");
     ok(globalScope, "The global scope is available.");
 
     is(firstScope.name, "Function scope [secondNest]",
       "The first scope's name is correct.");
     is(secondScope.name, "Function scope [firstNest]",
       "The second scope's name is correct.");
     is(thirdScope.name, "Function scope [test]",
       "The third scope's name is correct.");
+    is(globalLexicalScope.name, "Block scope",
+      "The global lexical scope's name is correct.");
     is(globalScope.name, "Global scope [Window]",
       "The global scope's name is correct.");
 
     is(firstScope.expanded, true,
       "The first scope's expansion state is correct.");
     is(secondScope.expanded, false,
       "The second scope's expansion state is correct.");
     is(thirdScope.expanded, false,
       "The third scope's expansion state is correct.");
+    is(globalLexicalScope.expanded, false,
+      "The global lexical scope's expansion state is correct.");
     is(globalScope.expanded, false,
       "The global scope's expansion state is correct.");
 
     is(firstScope._store.size, 3,
       "The first scope should have all the variables available.");
     is(secondScope._store.size, 0,
       "The second scope should have no variables available yet.");
     is(thirdScope._store.size, 0,
       "The third scope should have no variables available yet.");
+    is(globalLexicalScope._store.size, 0,
+      "The global scope should have no variables available yet.");
     is(globalScope._store.size, 0,
       "The global scope should have no variables available yet.");
 
     // Test getOwnerScopeForVariableOrProperty with simple variables.
 
     let thisVar = firstScope.get("this");
     let thisOwner = variables.getOwnerScopeForVariableOrProperty(thisVar);
     is(thisOwner, firstScope,
@@ -95,16 +103,17 @@ function test() {
     // from non-topmost scopes.
 
     // Only need to wait for a single FETCHED_VARIABLES event, just for the
     // global scope, because the other local scopes already have the
     // arguments and variables available as evironment bindings.
     fetched = waitForDebuggerEvents(panel, events.FETCHED_VARIABLES);
     secondScope.expand();
     thirdScope.expand();
+    globalLexicalScope.expand();
     globalScope.expand();
     yield fetched;
 
     let someVar2 = secondScope.get("a");
     let someOwner2 = variables.getOwnerScopeForVariableOrProperty(someVar2);
     is(someOwner2, secondScope,
       "The getOwnerScopeForVariableOrProperty method works properly (5).");
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-16.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-16.js
@@ -37,17 +37,17 @@ function test() {
         ok(isDebugPos(panel, debugLine), "Editor debug location is correct.");
         deferred.resolve();
       });
 
       return deferred.promise;
     }
 
     function expandGlobalScope() {
-      let globalScope = variables.getScopeAtIndex(1);
+      let globalScope = variables.getScopeAtIndex(2);
       is(globalScope.expanded, false,
         "The globalScope should not be expanded yet.");
 
       let finished = waitForDebuggerEvents(panel, events.FETCHED_VARIABLES);
       globalScope.expand();
       return finished;
     }
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-reexpand-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-reexpand-01.js
@@ -69,87 +69,99 @@ function stepInDebuggee() {
     waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1),
   ]);
 }
 
 function testVariablesExpand() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   let thisVar = localScope.get("this");
   let windowVar = thisVar.get("window");
 
   is(localScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The localScope arrow should still be expanded.");
   is(withScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The withScope arrow should still be expanded.");
   is(functionScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The functionScope arrow should still be expanded.");
+  is(globalLexicalScope.target.querySelector(".arrow").hasAttribute("open"), true,
+    "The globalLexicalScope arrow should still be expanded.");
   is(globalScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The globalScope arrow should still be expanded.");
   is(thisVar.target.querySelector(".arrow").hasAttribute("open"), true,
     "The thisVar arrow should still be expanded.");
   is(windowVar.target.querySelector(".arrow").hasAttribute("open"), false,
     "The windowVar arrow should not be expanded.");
 
   is(localScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The localScope enumerables should still be expanded.");
   is(withScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The withScope enumerables should still be expanded.");
   is(functionScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The functionScope enumerables should still be expanded.");
+  is(globalLexicalScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
+    "The globalLexicalScope enumerables should still be expanded.");
   is(globalScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The globalScope enumerables should still be expanded.");
   is(thisVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The thisVar enumerables should still be expanded.");
   is(windowVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), false,
     "The windowVar enumerables should not be expanded.");
 
   is(localScope.expanded, true,
     "The localScope expanded getter should return true.");
   is(withScope.expanded, true,
     "The withScope expanded getter should return true.");
   is(functionScope.expanded, true,
     "The functionScope expanded getter should return true.");
+  is(globalLexicalScope.expanded, true,
+    "The globalScope expanded getter should return true.");
   is(globalScope.expanded, true,
     "The globalScope expanded getter should return true.");
   is(thisVar.expanded, true,
     "The thisVar expanded getter should return true.");
   is(windowVar.expanded, false,
     "The windowVar expanded getter should return true.");
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+    "The globalLexicalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalLexicalScope should now be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     let thisVar = localScope.get("this");
 
     waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
       let windowVar = thisVar.get("window");
 
@@ -181,16 +193,17 @@ function prepareVariablesAndProperties()
       windowVar.expand();
     });
 
     thisVar.expand();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-reexpand-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-reexpand-02.js
@@ -70,29 +70,32 @@ function stepInDebuggee() {
     waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 4),
   ]);
 }
 
 function testVariablesExpand() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   let thisVar = localScope.get("this");
   let windowVar = thisVar.get("window");
   let documentVar = windowVar.get("document");
   let locationVar = documentVar.get("location");
 
   is(localScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The localScope arrow should still be expanded.");
   is(withScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The withScope arrow should still be expanded.");
   is(functionScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The functionScope arrow should still be expanded.");
+  is(globalLexicalScope.target.querySelector(".arrow").hasAttribute("open"), true,
+    "The globalLexicalScope arrow should still be expanded.");
   is(globalScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The globalScope arrow should still be expanded.");
   is(thisVar.target.querySelector(".arrow").hasAttribute("open"), true,
     "The thisVar arrow should still be expanded.");
   is(windowVar.target.querySelector(".arrow").hasAttribute("open"), true,
     "The windowVar arrow should still be expanded.");
   is(documentVar.target.querySelector(".arrow").hasAttribute("open"), true,
     "The documentVar arrow should still be expanded.");
@@ -100,16 +103,18 @@ function testVariablesExpand() {
     "The locationVar arrow should still be expanded.");
 
   is(localScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The localScope enumerables should still be expanded.");
   is(withScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The withScope enumerables should still be expanded.");
   is(functionScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The functionScope enumerables should still be expanded.");
+  is(globalLexicalScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
+    "The globalLexicalScope enumerables should still be expanded.");
   is(globalScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The globalScope enumerables should still be expanded.");
   is(thisVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The thisVar enumerables should still be expanded.");
   is(windowVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The windowVar enumerables should still be expanded.");
   is(documentVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The documentVar enumerables should still be expanded.");
@@ -117,16 +122,18 @@ function testVariablesExpand() {
     "The locationVar enumerables should still be expanded.");
 
   is(localScope.expanded, true,
     "The localScope expanded getter should return true.");
   is(withScope.expanded, true,
     "The withScope expanded getter should return true.");
   is(functionScope.expanded, true,
     "The functionScope expanded getter should return true.");
+  is(globalLexicalScope.expanded, true,
+    "The globalLexicalScope expanded getter should return true.");
   is(globalScope.expanded, true,
     "The globalScope expanded getter should return true.");
   is(thisVar.expanded, true,
     "The thisVar expanded getter should return true.");
   is(windowVar.expanded, true,
     "The windowVar expanded getter should return true.");
   is(documentVar.expanded, true,
     "The documentVar expanded getter should return true.");
@@ -135,36 +142,41 @@ function testVariablesExpand() {
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+    "The globalLexicalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalLexicalScope should now be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     let thisVar = localScope.get("this");
 
     waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
       let windowVar = thisVar.get("window");
 
@@ -196,16 +208,17 @@ function prepareVariablesAndProperties()
       windowVar.expand();
     });
 
     thisVar.expand();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-webidl.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-webidl.js
@@ -31,32 +31,32 @@ function test() {
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function expandGlobalScope() {
   let deferred = promise.defer();
 
-  let globalScope = gVariables.getScopeAtIndex(1);
+  let globalScope = gVariables.getScopeAtIndex(2);
   is(globalScope.expanded, false,
     "The global scope should not be expanded by default.");
 
   gDebugger.once(gDebugger.EVENTS.FETCHED_VARIABLES, deferred.resolve);
 
   EventUtils.sendMouseEvent({ type: "mousedown" },
     globalScope.target.querySelector(".name"),
     gDebugger);
 
   return deferred.promise;
 }
 
 function performTest() {
   let deferred = promise.defer();
-  let globalScope = gVariables.getScopeAtIndex(1);
+  let globalScope = gVariables.getScopeAtIndex(2);
 
   let buttonVar = globalScope.get("button");
   let buttonAsProtoVar = globalScope.get("buttonAsProto");
   let documentVar = globalScope.get("document");
 
   is(buttonVar.target.querySelector(".name").getAttribute("value"), "button",
     "Should have the right property name for 'button'.");
   is(buttonVar.target.querySelector(".value").getAttribute("value"), "<button>",
--- a/devtools/client/debugger/test/mochitest/code_frame-script.js
+++ b/devtools/client/debugger/test/mochitest/code_frame-script.js
@@ -1,11 +1,11 @@
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 const { loadSubScript } = Cc['@mozilla.org/moz/jssubscript-loader;1'].
                           getService(Ci.mozIJSSubScriptLoader);
 
 const EventUtils = {};
 loadSubScript("chrome://marionette/content/EventUtils.js", EventUtils);
 
 dump("Frame script loaded.\n");
 
--- a/devtools/client/debugger/test/mochitest/doc_function-search.html
+++ b/devtools/client/debugger/test/mochitest/doc_function-search.html
@@ -12,19 +12,19 @@
     <p>Peanut butter jelly time!</p>
 
     <script type="text/javascript" src="code_function-search-01.js"></script>
     <script type="text/javascript" src="code_function-search-02.js"></script>
     <script type="text/javascript" src="code_function-search-03.js"></script>
 
     <script type="text/javascript;version=1.8">
       function inline() {}
-      let arrow = () => {}
+      var arrow = () => {}
 
-      let foo = bar => {}
-      let foo2 = bar2 = baz2 => 42;
+      var foo = bar => {}
+      var foo2 = bar2 = baz2 => 42;
 
       setTimeout((foo, bar, baz) => {});
       setTimeout((foo, bar, baz) => 42);
     </script>
   </body>
 
 </html>
--- a/devtools/client/debugger/test/mochitest/head.js
+++ b/devtools/client/debugger/test/mochitest/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 // Disable logging for faster test runs. Set this pref to true if you want to
 // debug a test in your try runs. Both the debugger server and frontend will
 // be affected by this pref.
 var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
 Services.prefs.setBoolPref("devtools.debugger.log", false);
--- a/devtools/client/debugger/utils.js
+++ b/devtools/client/debugger/utils.js
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
-const XULUtils = {
+var XULUtils = {
   /**
    * Create <command> elements within `commandset` with event handlers
    * bound to the `command` event
    *
    * @param commandset HTML Element
    *        A <commandset> element
    * @param commands Object
    *        An object where keys specify <command> ids and values
@@ -30,17 +30,17 @@ const XULUtils = {
 // Used to detect minification for automatic pretty printing
 const SAMPLE_SIZE = 50; // no of lines
 const INDENT_COUNT_THRESHOLD = 5; // percentage
 const CHARACTER_LIMIT = 250; // line character limit
 
 /**
  * Utility functions for handling sources.
  */
-const SourceUtils = {
+var SourceUtils = {
   _labelsCache: new Map(), // Can't use WeakMaps because keys are strings.
   _groupsCache: new Map(),
   _minifiedCache: new WeakMap(),
 
   /**
    * Returns true if the specified url and/or content type are specific to
    * javascript files.
    *
--- a/devtools/client/fontinspector/font-inspector.js
+++ b/devtools/client/fontinspector/font-inspector.js
@@ -1,17 +1,17 @@
 /* -*- 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";
 
-const { utils: Cu } = Components;
+var { utils: Cu } = Components;
 const DEFAULT_PREVIEW_TEXT = "Abc";
 const PREVIEW_UPDATE_DELAY = 150;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
   "resource://gre/modules/Task.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "console",
   "resource://gre/modules/devtools/shared/Console.jsm");
--- a/devtools/client/framework/connect/connect.js
+++ b/devtools/client/framework/connect/connect.js
@@ -1,17 +1,17 @@
 /* -*- 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";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 var {gDevTools} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {TargetFactory} = require("devtools/client/framework/target");
 var {Toolbox} = require("devtools/client/framework/toolbox")
 var promise = require("promise");
--- a/devtools/client/framework/test/shared-head.js
+++ b/devtools/client/framework/test/shared-head.js
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This shared-head.js file is used for multiple directories in devtools.
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 function scopedCuImport(path) {
   const scope = {};
   Cu.import(path, scope);
   return scope;
 }
 
 const {Services} = scopedCuImport("resource://gre/modules/Services.jsm");
--- a/devtools/client/framework/toolbox-process-window.js
+++ b/devtools/client/framework/toolbox-process-window.js
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 var { gDevTools } = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 var { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var { TargetFactory } = require("devtools/client/framework/target");
 var { Toolbox } = require("devtools/client/framework/toolbox");
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 var { DebuggerClient } = require("devtools/shared/client/main");
 var { ViewHelpers } =
--- a/devtools/client/inspector/inspector-panel.js
+++ b/devtools/client/inspector/inspector-panel.js
@@ -983,23 +983,23 @@ InspectorPanel.prototype = {
    * temp variable on the content window.  Also opens the split console and
    * autofills it with the temp variable.
    */
   useInConsole: function() {
     this._toolbox.openSplitConsole().then(() => {
       let panel = this._toolbox.getPanel("webconsole");
       let jsterm = panel.hud.jsterm;
 
-      let evalString = `let i = 0;
+      let evalString = `{ let i = 0;
         while (window.hasOwnProperty("temp" + i) && i < 1000) {
           i++;
         }
         window["temp" + i] = $0;
         "temp" + i;
-      `;
+      }`;
 
       let options = {
         selectedNodeActor: this.selection.nodeFront.actorID,
       };
       jsterm.requestEvaluation(evalString, options).then((res) => {
         jsterm.setInputValue(res.result);
         this.emit("console-var-ready");
       });
--- a/devtools/client/inspector/test/head.js
+++ b/devtools/client/inspector/test/head.js
@@ -1,18 +1,18 @@
 /* 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/. */
 "use strict";
 
-const Cu = Components.utils;
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-const CC = Components.Constructor;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var CC = Components.Constructor;
 
 // Services.prefs.setBoolPref("devtools.debugger.log", true);
 // SimpleTest.registerCleanupFunction(() => {
 //   Services.prefs.clearUserPref("devtools.debugger.log");
 // });
 
 // Uncomment this pref to dump all devtools emitted events to the console.
 // Services.prefs.setBoolPref("devtools.dump.emit", true);
--- a/devtools/client/layoutview/test/head.js
+++ b/devtools/client/layoutview/test/head.js
@@ -1,15 +1,15 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {gDevTools} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {console} = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
 var {TargetFactory} = require("devtools/client/framework/target");
 var promise = require("promise");
 var DevToolsUtils = require("devtools/shared/DevToolsUtils");
 
 // All test are asynchronous
--- a/devtools/client/layoutview/view.js
+++ b/devtools/client/layoutview/view.js
@@ -1,17 +1,17 @@
 /* -*- 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";
 
-const {utils: Cu, interfaces: Ci, classes: Cc} = Components;
+var {utils: Cu, interfaces: Ci, classes: Cc} = Components;
 
 Cu.import("resource://gre/modules/Task.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 Cu.import("resource://gre/modules/devtools/shared/Console.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 
 const {InplaceEditor, editableItem} = require("devtools/client/shared/inplace-editor");
 const {ReflowFront} = require("devtools/server/actors/layout");
--- a/devtools/client/markupview/test/actor_events_form.js
+++ b/devtools/client/markupview/test/actor_events_form.js
@@ -9,17 +9,17 @@
 
 const Events = require("sdk/event/core");
 const {ActorClass, Actor, FrontClass, Front, method} =
   require("devtools/server/protocol");
 
 const {Cu} = require("chrome");
 const {NodeActor} = require("devtools/server/actors/inspector");
 
-const EventsFormActor = ActorClass({
+var EventsFormActor = ActorClass({
   typeName: "eventsFormActor",
 
   initialize: function() {
     Actor.prototype.initialize.apply(this, arguments);
   },
 
   attach: method(function() {
     Events.on(NodeActor, "form", this.onNodeActorForm);
@@ -39,17 +39,17 @@ const EventsFormActor = ActorClass({
     let nodeActor = event.target;
     if (nodeActor.rawNode.id == "container") {
       let form = event.data;
       form.setFormProperty("test-property", "test-value");
     }
   }
 });
 
-const EventsFormFront = FrontClass(EventsFormActor, {
+var EventsFormFront = FrontClass(EventsFormActor, {
   initialize: function(client, form) {
     Front.prototype.initialize.apply(this, arguments);
 
     this.actorID = form[EventsFormActor.prototype.typeName];
     this.manage(this);
   }
 });
 
--- a/devtools/client/markupview/test/frame-script-utils.js
+++ b/devtools/client/markupview/test/frame-script-utils.js
@@ -1,15 +1,15 @@
 /* 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";
 
-const {classes: Cc, interfaces: Ci} = Components;
+var {classes: Cc, interfaces: Ci} = Components;
 const subScriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
                           .getService(Ci.mozIJSSubScriptLoader);
 var EventUtils = {};
 subScriptLoader.loadSubScript("chrome://marionette/content/EventUtils.js", EventUtils);
 
 /**
  * Synthesize a mouse event on an element. This handler doesn't send a message
  * back. Consumers should listen to specific events on the inspector/highlighter
--- a/devtools/client/markupview/test/head.js
+++ b/devtools/client/markupview/test/head.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {TargetFactory} = require("devtools/client/framework/target");
 var {console} = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
 var promise = require("promise");
 var {getInplaceEditorForSpan: inplaceEditor} = require("devtools/client/shared/inplace-editor");
 var clipboard = require("sdk/clipboard");
 var {setTimeout, clearTimeout} = require("sdk/timers");
 var {promiseInvoke} = require("devtools/shared/async-utils");
--- a/devtools/client/memory/initializer.js
+++ b/devtools/client/memory/initializer.js
@@ -1,22 +1,22 @@
 /* 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";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 const { require } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
 const { Task } = require("resource://gre/modules/Task.jsm");
 const { MemoryController } = require("devtools/client/memory/controller");
 
 /**
  * The current target, toolbox and MemoryFront, set by this tool's host.
  */
-let gToolbox, gTarget, gFront;
+var gToolbox, gTarget, gFront;
 
 /**
  * Initializes the profiler controller and views.
  */
 var controller = null;
 function initialize () {
   return Task.spawn(function *() {
     controller = new MemoryController({ toolbox: gToolbox, target: gTarget, front: gFront });
--- a/devtools/client/memory/test/mochitest/head.js
+++ b/devtools/client/memory/test/mochitest/head.js
@@ -1,12 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-const CC = Components.Constructor;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+var CC = Components.Constructor;
 
 const { require } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
--- a/devtools/client/memory/test/unit/test_action-take-snapshot.js
+++ b/devtools/client/memory/test/unit/test_action-take-snapshot.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Tests the async action creator `takeSnapshot(front)`
  */
 
-let actions = require("devtools/client/memory/actions/snapshot");
+var actions = require("devtools/client/memory/actions/snapshot");
 
 function run_test() {
   run_next_test();
 }
 
 add_task(function *() {
   let front = new StubbedMemoryFront();
   yield front.attach();
--- a/devtools/client/netmonitor/netmonitor-controller.js
+++ b/devtools/client/netmonitor/netmonitor-controller.js
@@ -1,16 +1,16 @@
 /* -*- 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";
 
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 const NET_STRINGS_URI = "chrome://browser/locale/devtools/netmonitor.properties";
 const PKI_STRINGS_URI = "chrome://pippki/locale/pippki.properties";
 const LISTENERS = [ "NetworkActivity" ];
 const NET_PREFS = { "NetworkMonitor.saveRequestAndResponseBodies": true };
 
 // The panel's window global is an EventEmitter firing the following events:
 const EVENTS = {
@@ -120,16 +120,20 @@ Cu.import("resource:///modules/devtools/
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const promise = require("promise");
 const EventEmitter = require("devtools/shared/event-emitter");
 const Editor = require("devtools/client/sourceeditor/editor");
 const {Tooltip} = require("devtools/client/shared/widgets/Tooltip");
 const {ToolSidebar} = require("devtools/client/framework/sidebar");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
 
+XPCOMUtils.defineConstant(this, "EVENTS", EVENTS);
+XPCOMUtils.defineConstant(this, "ACTIVITY_TYPE", ACTIVITY_TYPE);
+XPCOMUtils.defineConstant(this, "Editor", Editor);
+
 XPCOMUtils.defineLazyModuleGetter(this, "Chart",
   "resource:///modules/devtools/client/shared/widgets/Chart.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Curl",
   "resource:///modules/devtools/client/shared/Curl.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "CurlUtils",
   "resource:///modules/devtools/client/shared/Curl.jsm");
--- a/devtools/client/netmonitor/test/head.js
+++ b/devtools/client/netmonitor/test/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 var { gDevTools } = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 var { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var { CurlUtils } = Cu.import("resource:///modules/devtools/client/shared/Curl.jsm", {});
 var promise = require("promise");
 var NetworkHelper = require("devtools/shared/webconsole/network-helper");
--- a/devtools/client/performance/performance-controller.js
+++ b/devtools/client/performance/performance-controller.js
@@ -1,21 +1,26 @@
 /* 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";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 const { loader, require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 const { Task } = require("resource://gre/modules/Task.jsm");
 const { Heritage, ViewHelpers, WidgetMethods } = require("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 
 // Events emitted by various objects in the panel.
 const EVENTS = require("devtools/client/performance/events");
+Object.defineProperty(this, "EVENTS", {
+  value: EVENTS,
+  enumerable: true,
+  writable: false
+});
 
 loader.lazyRequireGetter(this, "Services");
 loader.lazyRequireGetter(this, "promise");
 loader.lazyRequireGetter(this, "EventEmitter",
   "devtools/shared/event-emitter");
 loader.lazyRequireGetter(this, "DevToolsUtils",
   "devtools/shared/DevToolsUtils");
 loader.lazyRequireGetter(this, "system",
--- a/devtools/client/performance/test/browser_perf-private-browsing.js
+++ b/devtools/client/performance/test/browser_perf-private-browsing.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Tests that disables the frontend when in private browsing mode.
  */
 
-let gPanelWinTuples = [];
+var gPanelWinTuples = [];
 
 function* spawnTest() {
   yield testNormalWindow();
   yield testPrivateWindow();
   yield testRecordingFailingInWindow(0);
   yield testRecordingFailingInWindow(1);
   yield teardownPerfInWindow(1);
   yield testRecordingSucceedingInWindow(0);
--- a/devtools/client/performance/test/head.js
+++ b/devtools/client/performance/test/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 var { Preferences } = Cu.import("resource://gre/modules/Preferences.jsm", {});
 var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 var { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var { gDevTools } = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 var { console } = require("resource://gre/modules/devtools/shared/Console.jsm");
 var { TargetFactory } = require("devtools/client/framework/target");
@@ -42,16 +42,19 @@ const ALLOCATIONS_PREF = "devtools.perfo
 const PLATFORM_DATA_PREF = "devtools.performance.ui.show-platform-data";
 const IDLE_PREF = "devtools.performance.ui.show-idle-blocks";
 const INVERT_PREF = "devtools.performance.ui.invert-call-tree";
 const INVERT_FLAME_PREF = "devtools.performance.ui.invert-flame-graph";
 const FLATTEN_PREF = "devtools.performance.ui.flatten-tree-recursion";
 const JIT_PREF = "devtools.performance.ui.enable-jit-optimizations";
 const EXPERIMENTAL_PREF = "devtools.performance.ui.experimental";
 
+// Keep in sync with FRAMERATE_GRAPH_HIGH_RES_INTERVAL in views/overview.js
+const FRAMERATE_GRAPH_HIGH_RES_INTERVAL = 16; // ms
+
 // All tests are asynchronous.
 waitForExplicitFinish();
 
 DevToolsUtils.testing = true;
 
 var DEFAULT_PREFS = [
   "devtools.debugger.log",
   "devtools.performance.ui.invert-call-tree",
@@ -418,17 +421,17 @@ function* stopRecording(panel, options =
     : Promise.resolve();
 
   yield hasStopped;
 
   // Wait for the final rendering of the overview, not a low res
   // incremental rendering and less likely to be from another rendering that was selected
   while (!overviewRendered && options.waitForOverview) {
     let [_, res] = yield onceSpread(win.OverviewView, win.EVENTS.OVERVIEW_RENDERED);
-    if (res === win.FRAMERATE_GRAPH_HIGH_RES_INTERVAL) {
+    if (res === FRAMERATE_GRAPH_HIGH_RES_INTERVAL) {
       overviewRendered = true;
     }
   }
 
   yield stateChanged;
 
   is(win.PerformanceView.getState(), "recorded",
     "The current state is 'recorded'.");
--- a/devtools/client/performance/test/unit/head.js
+++ b/devtools/client/performance/test/unit/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 var { console } = require("resource://gre/modules/devtools/shared/Console.jsm");
 const RecordingUtils = require("devtools/shared/performance/utils");
 
 const PLATFORM_DATA_PREF = "devtools.performance.ui.show-platform-data";
 
--- a/devtools/client/performance/views/overview.js
+++ b/devtools/client/performance/views/overview.js
@@ -14,17 +14,17 @@ const GRAPH_REQUIREMENTS = {
     features: ["withMarkers"]
   },
   framerate: {
     features: ["withTicks"]
   },
   memory: {
     features: ["withMemory"]
   },
-}
+};
 
 /**
  * View handler for the overview panel's time view, displaying
  * framerate, timeline and memory over time.
  */
 var OverviewView = {
 
   /**
--- a/devtools/client/projecteditor/chrome/content/projecteditor-loader.js
+++ b/devtools/client/projecteditor/chrome/content/projecteditor-loader.js
@@ -1,9 +1,9 @@
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
 const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {});
 const promise = require("promise");
 const ProjectEditor = require("devtools/client/projecteditor/lib/projecteditor");
 
 const SAMPLE_PATH = buildTempDirectoryStructure();
 const SAMPLE_NAME = "DevTools Content Application Name";
--- a/devtools/client/projecteditor/test/head.js
+++ b/devtools/client/projecteditor/test/head.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {TargetFactory} = require("devtools/client/framework/target");
 const {console} = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
 const promise = require("promise");
 const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
 const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {});
 const ProjectEditor = require("devtools/client/projecteditor/lib/projecteditor");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
--- a/devtools/client/promisedebugger/promise-controller.js
+++ b/devtools/client/promisedebugger/promise-controller.js
@@ -3,17 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* global PromisesPanel */
 
 "use strict";
 
-const { utils: Cu } = Components;
+var { utils: Cu } = Components;
 const { loader, require } =
   Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 const { Task } = require("resource://gre/modules/Task.jsm");
 
 loader.lazyRequireGetter(this, "promise");
 loader.lazyRequireGetter(this, "EventEmitter",
   "devtools/shared/event-emitter");
--- a/devtools/client/responsivedesign/responsivedesign-child.js
+++ b/devtools/client/responsivedesign/responsivedesign-child.js
@@ -1,13 +1,13 @@
 /* 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 Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const gDeviceSizeWasPageSize = docShell.deviceSizeIsPageSize;
 const gFloatingScrollbarsStylesheet = Services.io.newURI("chrome://devtools/skin/themes/floating-scrollbars.css", null, null);
 var gRequiresFloatingScrollbars;
 
 var active = false;
 
 addMessageListener("ResponsiveMode:Start", startResponsiveMode);
 addMessageListener("ResponsiveMode:Stop", stopResponsiveMode);
--- a/devtools/client/responsivedesign/test/head.js
+++ b/devtools/client/responsivedesign/test/head.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-var {require} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
+var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {TargetFactory} = require("devtools/client/framework/target");
 var DevToolsUtils = require("devtools/shared/DevToolsUtils");
 var promise = require("promise");
 
 // Import the GCLI test helper
 var testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
 Services.scriptloader.loadSubScript(testDir + "../../../commandline/test/helpers.js", this);
 
--- a/devtools/client/scratchpad/scratchpad.js
+++ b/devtools/client/scratchpad/scratchpad.js
@@ -9,19 +9,19 @@
  *
  * Copied and relicensed from the Public Domain.
  * See bug 653934 for details.
  * https://bugzilla.mozilla.org/show_bug.cgi?id=653934
  */
 
 "use strict";
 
-const Cu = Components.utils;
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 const SCRATCHPAD_CONTEXT_CONTENT = 1;
 const SCRATCHPAD_CONTEXT_BROWSER = 2;
 const BUTTON_POSITION_SAVE       = 0;
 const BUTTON_POSITION_CANCEL     = 1;
 const BUTTON_POSITION_DONT_SAVE  = 2;
 const BUTTON_POSITION_REVERT     = 0;
 const EVAL_FUNCTION_TIMEOUT      = 1000; // milliseconds
@@ -58,16 +58,23 @@ Cu.import("resource://gre/modules/Servic
 Cu.import("resource://gre/modules/NetUtil.jsm");
 Cu.import("resource:///modules/devtools/client/scratchpad/scratchpad-manager.jsm");
 Cu.import("resource://gre/modules/jsdebugger.jsm");
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 Cu.import("resource://gre/modules/reflect.jsm");
 
+XPCOMUtils.defineConstant(this, "SCRATCHPAD_CONTEXT_CONTENT", SCRATCHPAD_CONTEXT_CONTENT);
+XPCOMUtils.defineConstant(this, "SCRATCHPAD_CONTEXT_BROWSER", SCRATCHPAD_CONTEXT_BROWSER);
+XPCOMUtils.defineConstant(this, "BUTTON_POSITION_SAVE", BUTTON_POSITION_SAVE);
+XPCOMUtils.defineConstant(this, "BUTTON_POSITION_CANCEL", BUTTON_POSITION_CANCEL);
+XPCOMUtils.defineConstant(this, "BUTTON_POSITION_DONT_SAVE", BUTTON_POSITION_DONT_SAVE);
+XPCOMUtils.defineConstant(this, "BUTTON_POSITION_REVERT", BUTTON_POSITION_REVERT);
+
 XPCOMUtils.defineLazyModuleGetter(this, "VariablesView",
   "resource:///modules/devtools/client/shared/widgets/VariablesView.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "VariablesViewController",
   "resource:///modules/devtools/client/shared/widgets/VariablesViewController.jsm");
 
 loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
 
--- a/devtools/client/scratchpad/test/browser_scratchpad_files.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_files.js
@@ -1,16 +1,12 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-var tempScope = {};
-Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
-var NetUtil = tempScope.NetUtil;
-
 // Reference to the Scratchpad object.
 var gScratchpad;
 
 // Reference to the temporary nsIFile we will work with.
 var gFile;
 
 // The temporary file content.
 var gFileContent = "hello.world('bug636725');";
--- a/devtools/client/scratchpad/test/browser_scratchpad_modeline.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_modeline.js
@@ -1,20 +1,13 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 /* Bug 644413 */
 
-var tempScope = {};
-Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
-Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
-var NetUtil = tempScope.NetUtil;
-var FileUtils = tempScope.FileUtils;
-
-
 var gScratchpad; // Reference to the Scratchpad object.
 var gFile; // Reference to the temporary nsIFile we will work with.
 var DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
 
 // The temporary file content.
 var gFileContent = "function main() { return 0; }";
 
 function test() {
--- a/devtools/client/scratchpad/test/browser_scratchpad_recent_files.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_recent_files.js
@@ -1,19 +1,13 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 /* Bug 651942 */
 
-var tempScope = {};
-Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
-Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
-var NetUtil = tempScope.NetUtil;
-var FileUtils = tempScope.FileUtils;
-
 // Reference to the Scratchpad object.
 var gScratchpad;
 
 // References to the temporary nsIFiles.
 var gFile01;
 var gFile02;
 var gFile03;
 var gFile04;
--- a/devtools/client/scratchpad/test/browser_scratchpad_reset_undo.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_reset_undo.js
@@ -1,19 +1,13 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 /* Bug 684546 */
 
-var tempScope = {};
-Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
-Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
-var NetUtil = tempScope.NetUtil;
-var FileUtils = tempScope.FileUtils;
-
 // Reference to the Scratchpad chrome window object.
 var gScratchpadWindow;
 
 // Reference to the Scratchpad object.
 var gScratchpad;
 
 // Reference to the temporary nsIFile we will work with.
 var gFileA;
--- a/devtools/client/scratchpad/test/browser_scratchpad_revert_to_saved.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_revert_to_saved.js
@@ -1,19 +1,13 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 /* Bug 751744 */
 
-var tempScope = {};
-Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
-Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
-var NetUtil = tempScope.NetUtil;
-var FileUtils = tempScope.FileUtils;
-
 // Reference to the Scratchpad object.
 var gScratchpad;
 
 // Reference to the temporary nsIFiles.
 var gFile;
 
 // Temporary file name.
 var gFileName = "testFileForBug751744.tmp"
--- a/devtools/client/shadereditor/shadereditor.js
+++ b/devtools/client/shadereditor/shadereditor.js
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/SideMenuWidget.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 Cu.import("resource://gre/modules/devtools/shared/Console.jsm");
 
@@ -33,16 +33,17 @@ const EVENTS = {
   SHADER_COMPILED: "ShaderEditor:ShaderCompiled",
 
   // When the UI is reset from tab navigation
   UI_RESET: "ShaderEditor:UIReset",
 
   // When the editor's error markers are all removed
   EDITOR_ERROR_MARKERS_REMOVED: "ShaderEditor:EditorCleaned"
 };
+XPCOMUtils.defineConstant(this, "EVENTS", EVENTS);
 
 const STRINGS_URI = "chrome://browser/locale/devtools/shadereditor.properties"
 const HIGHLIGHT_TINT = [1, 0, 0.25, 1]; // rgba
 const TYPING_MAX_DELAY = 500; // ms
 const SHADERS_AUTOGROW_ITEMS = 4;
 const GUTTER_ERROR_PANEL_OFFSET_X = 7; // px
 const GUTTER_ERROR_PANEL_DELAY = 100; // ms
 const DEFAULT_EDITOR_CONFIG = {
--- a/devtools/client/shadereditor/test/head.js
+++ b/devtools/client/shadereditor/test/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
 // To enable logging for try runs, just set the pref to true.
 Services.prefs.setBoolPref("devtools.debugger.log", false);
 
 var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
--- a/devtools/client/shared/browser-loader.js
+++ b/devtools/client/shared/browser-loader.js
@@ -1,9 +1,9 @@
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 const loaders = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {});
 const devtools = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {}).devtools;
 const { joinURI } = devtools.require("devtools/shared/path");
 var appConstants;
 
 // Some of the services that the system module requires is not
 // available in xpcshell tests. This is ok, we can easily polyfill the
--- a/devtools/client/shared/frame-script-utils.js
+++ b/devtools/client/shared/frame-script-utils.js
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const {require, loader} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const promise = require("promise");
 loader.lazyImporter(this, "Task", "resource://gre/modules/Task.jsm", "Task");
 const subScriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
                           .getService(Ci.mozIJSSubScriptLoader);
 var EventUtils = {};
 subScriptLoader.loadSubScript("chrome://marionette/content/EventUtils.js", EventUtils);
 loader.lazyGetter(this, "nsIProfilerModule", () => {
--- a/devtools/client/shared/test/browser_layoutHelpers-getBoxQuads.js
+++ b/devtools/client/shared/test/browser_layoutHelpers-getBoxQuads.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests getAdjustedQuads works properly in a variety of use cases including
 // iframes, scroll and zoom
 
-const {utils: Cu} = Components;
-let {getAdjustedQuads} = require("devtools/shared/layout/utils");
+var {utils: Cu} = Components;
+var {getAdjustedQuads} = require("devtools/shared/layout/utils");
 
 const TEST_URI = TEST_URI_ROOT + "browser_layoutHelpers-getBoxQuads.html";
 
 function test() {
   addTab(TEST_URI, function(browser, tab) {
     let doc = browser.contentDocument;
 
     ok(typeof getAdjustedQuads === "function", "getAdjustedQuads is defined");
--- a/devtools/client/shared/test/browser_layoutHelpers.js
+++ b/devtools/client/shared/test/browser_layoutHelpers.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that scrollIntoViewIfNeeded works properly.
-let {scrollIntoViewIfNeeded} = require("devtools/shared/layout/utils");
+var {scrollIntoViewIfNeeded} = require("devtools/shared/layout/utils");
 
 const TEST_URI = TEST_URI_ROOT + "browser_layoutHelpers.html";
 
 add_task(function*() {
   let [host, win, doc] = yield createHost("bottom", TEST_URI);
   runTest(win);
   host.destroy();
 });
--- a/devtools/client/shared/test/test-actor.js
+++ b/devtools/client/shared/test/test-actor.js
@@ -1,17 +1,17 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // A helper actor for brower/devtools/inspector tests.
 
-let { Cc, Ci, Cu, Cr } = require("chrome");
+var { Cc, Ci, Cu, Cr } = require("chrome");
 const {getRect, getElementFromPoint, getAdjustedQuads} = require("devtools/shared/layout/utils");
 const promise = require("promise");
 const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
 var DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
 var loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
             .getService(Ci.mozIJSSubScriptLoader);
 var EventUtils = {};
 loader.loadSubScript("chrome://marionette/content/EventUtils.js", EventUtils);
@@ -33,17 +33,17 @@ var dumpn = msg => {
  */
 function getHighlighterCanvasFrameHelper(conn, actorID) {
   let actor = conn.getActor(actorID);
   if (actor && actor._highlighter) {
     return actor._highlighter.markup;
   }
 }
 
-const TestActor = exports.TestActor = protocol.ActorClass({
+var TestActor = exports.TestActor = protocol.ActorClass({
   typeName: "testActor",
 
   initialize: function(conn, tabActor, options) {
     this.conn = conn;
     this.tabActor = tabActor;
   },
 
   get content() {
@@ -520,17 +520,17 @@ const TestActor = exports.TestActor = pr
       selector: Arg(0, "string")
     },
     response: {
       value: RetVal("json")
     }
   }),
 });
 
-const TestActorFront = exports.TestActorFront = protocol.FrontClass(TestActor, {
+var TestActorFront = exports.TestActorFront = protocol.FrontClass(TestActor, {
   initialize: function(client, { testActor }, toolbox) {
     protocol.Front.prototype.initialize.call(this, client, { actor: testActor });
     this.manage(this);
     this.toolbox = toolbox;
   },
 
   /**
    * Zoom the current page to a given level.
--- a/devtools/client/shared/test/unit/test_VariablesView_filtering-without-controller.js
+++ b/devtools/client/shared/test/unit/test_VariablesView_filtering-without-controller.js
@@ -1,19 +1,19 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test that VariablesView._doSearch() works even without an attached
 // VariablesViewController (bug 1196341).
 
-const Cu = Components.utils;
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 const DOMParser = Cc["@mozilla.org/xmlextras/domparser;1"]
                     .createInstance(Ci.nsIDOMParser);
 const { VariablesView } =
   Cu.import("resource:///modules/devtools/client/shared/widgets/VariablesView.jsm", {});
 
 function run_test() {
   let doc = DOMParser.parseFromString("<div>", "text/html");
   let container = doc.body.firstChild;
--- a/devtools/client/shared/test/unit/test_VariablesView_getString_promise.js
+++ b/devtools/client/shared/test/unit/test_VariablesView_getString_promise.js
@@ -1,14 +1,14 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const { VariablesView } = Cu.import("resource:///modules/devtools/client/shared/widgets/VariablesView.jsm", {});
 
 const PENDING = {
   "type": "object",
   "class": "Promise",
   "actor": "conn0.pausedobj35",
   "extensible": true,
   "frozen": false,
--- a/devtools/client/shared/test/unit/test_advanceValidate.js
+++ b/devtools/client/shared/test/unit/test_advanceValidate.js
@@ -2,18 +2,18 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // Tests the advanceValidate function from rule-view.js.
 
-const Cu = Components.utils;
-const Ci = Components.interfaces;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {advanceValidate} = require("devtools/client/styleinspector/utils");
 
 //                            1         2         3
 //                  0123456789012345678901234567890
 var sampleInput = '\\symbol "string" url(somewhere)';
 
 function testInsertion(where, result, testName) {
--- a/devtools/client/shared/test/unit/test_attribute-parsing-01.js
+++ b/devtools/client/shared/test/unit/test_attribute-parsing-01.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test splitBy from node-attribute-parser.js
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {splitBy} = require("devtools/client/shared/node-attribute-parser");
 
 const TEST_DATA = [{
   value: "this is a test",
   splitChar: " ",
   expected: [
     {value: "this"},
--- a/devtools/client/shared/test/unit/test_attribute-parsing-02.js
+++ b/devtools/client/shared/test/unit/test_attribute-parsing-02.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test parseAttribute from node-attribute-parser.js
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {parseAttribute} = require("devtools/client/shared/node-attribute-parser");
 
 const TEST_DATA = [{
   tagName: "body",
   namespaceURI: "http://www.w3.org/1999/xhtml",
   attributeName: "class",
   attributeValue: "some css class names",
--- a/devtools/client/shared/test/unit/test_bezierCanvas.js
+++ b/devtools/client/shared/test/unit/test_bezierCanvas.js
@@ -2,17 +2,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // Tests the BezierCanvas API in the CubicBezierWidget module
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {CubicBezier, BezierCanvas} = require("devtools/client/shared/widgets/CubicBezierWidget");
 
 function run_test() {
   offsetsGetterReturnsData();
   convertsOffsetsToCoordinates();
   plotsCanvas();
 }
--- a/devtools/client/shared/test/unit/test_cubicBezier.js
+++ b/devtools/client/shared/test/unit/test_cubicBezier.js
@@ -2,17 +2,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // Tests the CubicBezier API in the CubicBezierWidget module
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {CubicBezier, _parseTimingFunction} = require("devtools/client/shared/widgets/CubicBezierWidget");
 
 function run_test() {
   throwsWhenMissingCoordinates();
   throwsWhenIncorrectCoordinates();
   convertsStringCoordinates();
   coordinatesToStringOutputsAString();
--- a/devtools/client/shared/test/unit/test_undoStack.js
+++ b/devtools/client/shared/test/unit/test_undoStack.js
@@ -1,14 +1,14 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {Loader} = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {});
 
 var loader = new Loader.Loader({
   paths: {
     "": "resource://gre/modules/commonjs/",
     "devtools": "resource:///modules/devtools",
   },
   globals: {},
--- a/devtools/client/shared/widgets/TableWidget.js
+++ b/devtools/client/shared/widgets/TableWidget.js
@@ -15,16 +15,21 @@ const EVENTS = {
   TABLE_CLEARED: "table-cleared",
   COLUMN_SORTED: "column-sorted",
   COLUMN_TOGGLED: "column-toggled",
   ROW_SELECTED: "row-selected",
   ROW_UPDATED: "row-updated",
   HEADER_CONTEXT_MENU: "header-context-menu",
   ROW_CONTEXT_MENU: "row-context-menu"
 };
+Object.defineProperty(this, "EVENTS", {
+  value: EVENTS,
+  enumerable: true,
+  writable: false
+});
 
 // Maximum number of character visible in any cell in the table. This is to avoid
 // making the cell take up all the space in a row.
 const MAX_VISIBLE_STRING_SIZE = 100;
 
 /**
  * A table widget with various features like resizble/toggleable columns,
  * sorting, keyboard navigation etc.
--- a/devtools/client/styleeditor/test/browser_styleeditor_filesave.js
+++ b/devtools/client/styleeditor/test/browser_styleeditor_filesave.js
@@ -3,18 +3,18 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
 // Test that 'Save' function works.
 
 const TESTCASE_URI_HTML = TEST_BASE_HTTP + "simple.html";
 const TESTCASE_URI_CSS = TEST_BASE_HTTP + "simple.css";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 var tempScope = {};
 Components.utils.import("resource://gre/modules/FileUtils.jsm", tempScope);
 Components.utils.import("resource://gre/modules/NetUtil.jsm", tempScope);
 var FileUtils = tempScope.FileUtils;
 var NetUtil = tempScope.NetUtil;
 
 add_task(function* () {
--- a/devtools/client/styleeditor/test/browser_styleeditor_sourcemap_watching.js
+++ b/devtools/client/styleeditor/test/browser_styleeditor_sourcemap_watching.js
@@ -14,18 +14,18 @@ const TESTCASE_URI_REG_CSS = TEST_BASE_H
 const TESTCASE_URI_SCSS = TEST_BASE_HTTP + "sourcemap-sass/sourcemaps.scss";
 const TESTCASE_URI_MAP = TEST_BASE_HTTP + "sourcemap-css/sourcemaps.css.map";
 const TESTCASE_SCSS_NAME = "sourcemaps.scss";
 
 const TRANSITIONS_PREF = "devtools.styleeditor.transitions";
 
 const CSS_TEXT = "* { color: blue }";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 var tempScope = {};
 Components.utils.import("resource://gre/modules/FileUtils.jsm", tempScope);
 Components.utils.import("resource://gre/modules/NetUtil.jsm", tempScope);
 var FileUtils = tempScope.FileUtils;
 var NetUtil = tempScope.NetUtil;
 
 function test() {
--- a/devtools/client/styleinspector/test/head.js
+++ b/devtools/client/styleinspector/test/head.js
@@ -1,15 +1,15 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {gDevTools} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {TargetFactory} = require("devtools/client/framework/target");
 var {CssComputedView} = require("devtools/client/styleinspector/computed-view");
 var {CssRuleView, _ElementStyle} = require("devtools/client/styleinspector/rule-view");
 var {CssLogic, CssSelector} = require("devtools/shared/styleinspector/css-logic");
 var DevToolsUtils = require("devtools/shared/DevToolsUtils");
 var promise = require("promise");
--- a/devtools/client/styleinspector/test/unit/test_escapeCSSComment.js
+++ b/devtools/client/styleinspector/test/unit/test_escapeCSSComment.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource://gre/modules/devtools/Loader.jsm");
 const {escapeCSSComment, _unescapeCSSComment} =
       devtools.require("devtools/client/styleinspector/css-parsing-utils");
 
 const TEST_DATA = [
   {
     input: "simple",
     expected: "simple"
--- a/devtools/client/styleinspector/test/unit/test_parseDeclarations.js
+++ b/devtools/client/styleinspector/test/unit/test_parseDeclarations.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {parseDeclarations, _parseCommentDeclarations} =
   require("devtools/client/styleinspector/css-parsing-utils");
 
 const TEST_DATA = [
   // Simple test
   {
     input: "p:v;",
--- a/devtools/client/styleinspector/test/unit/test_parsePseudoClassesAndAttributes.js
+++ b/devtools/client/styleinspector/test/unit/test_parsePseudoClassesAndAttributes.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {
   parsePseudoClassesAndAttributes,
   SELECTOR_ATTRIBUTE,
   SELECTOR_ELEMENT,
   SELECTOR_PSEUDO_CLASS
 } = require("devtools/client/styleinspector/css-parsing-utils");
 
--- a/devtools/client/styleinspector/test/unit/test_parseSingleValue.js
+++ b/devtools/client/styleinspector/test/unit/test_parseSingleValue.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {parseSingleValue} = require("devtools/client/styleinspector/css-parsing-utils");
 
 const TEST_DATA = [
   {input: null, throws: true},
   {input: undefined, throws: true},
   {input: "", expected: {value: "", priority: ""}},
   {input: "  \t \t \n\n  ", expected: {value: "", priority: ""}},
--- a/devtools/client/styleinspector/test/unit/test_rewriteDeclarations.js
+++ b/devtools/client/styleinspector/test/unit/test_rewriteDeclarations.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource://gre/modules/devtools/Loader.jsm");
 const {parseDeclarations, RuleRewriter} =
       devtools.require("devtools/client/styleinspector/css-parsing-utils");
 
 const TEST_DATA = [
   {
     desc: "simple set",
     input: "p:v;",
--- a/devtools/client/webaudioeditor/includes.js
+++ b/devtools/client/webaudioeditor/includes.js
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 
 const { loader, require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
@@ -69,16 +69,17 @@ const EVENTS = {
   // Is called with two arguments, first representing number of nodes
   // rendered, second being the number of edge connections rendering (not counting
   // param edges), followed by the count of the param edges rendered.
   UI_GRAPH_RENDERED: "WebAudioEditor:UIGraphRendered",
 
   // Called when the inspector splitter is moved and resized.
   UI_INSPECTOR_RESIZE: "WebAudioEditor:UIInspectorResize"
 };
+XPCOMUtils.defineConstant(this, "EVENTS", EVENTS);
 
 /**
  * The current target and the Web Audio Editor front, set by this tool's host.
  */
 var gToolbox, gTarget, gFront;
 
 /**
  * Convenient way of emitting events from the panel window.
--- a/devtools/client/webaudioeditor/test/head.js
+++ b/devtools/client/webaudioeditor/test/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 // Enable logging for all the tests. Both the debugger server and frontend will
 // be affected by this pref.
 var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
 Services.prefs.setBoolPref("devtools.debugger.log", false);
 
--- a/devtools/client/webaudioeditor/views/context.js
+++ b/devtools/client/webaudioeditor/views/context.js
@@ -16,16 +16,21 @@ const GRAPH_DEFAULTS = {
 const ARROW_HEIGHT = 5;
 const ARROW_WIDTH = 8;
 
 // Styles for markers as they cannot be done with CSS.
 const MARKER_STYLING = {
   light: "#AAA",
   dark: "#CED3D9"
 };
+Object.defineProperty(this, "MARKER_STYLING", {
+  value: MARKER_STYLING,
+  enumerable: true,
+  writable: false
+});
 
 const GRAPH_DEBOUNCE_TIMER = 100;
 
 // `gAudioNodes` events that should require the graph
 // to redraw
 const GRAPH_REDRAW_EVENTS = ["add", "connect", "disconnect", "remove"];
 
 /**
--- a/devtools/client/webconsole/test/browser_webconsole_autocomplete-properties-with-non-alphanumeric-names.js
+++ b/devtools/client/webconsole/test/browser_webconsole_autocomplete-properties-with-non-alphanumeric-names.js
@@ -23,17 +23,21 @@ var test = asyncTest(function*() {
     yield deferred.promise;
 
     ok(popup.itemCount > 0, "There's suggestions for '" + term + "'");
   }
 
   let { jsterm } = yield openConsole();
   let popup = jsterm.autocompletePopup;
 
-  yield jsterm.execute("let testObject = {$$aaab: '', $$aaac: ''}");
+  yield jsterm.execute("var testObject = {$$aaab: '', $$aaac: ''}");
+
+  // FIXMEshu: global lexicals can't be autocompleted without extra platform
+  // support. See bug 1207868.
+  //yield jsterm.execute("let testObject = {$$aaab: '', $$aaac: ''}");
 
   // Should work with bug 967468.
   yield autocomplete("Object.__d");
   yield autocomplete("testObject.$$a");
 
   // Here's when things go wrong in bug 967468.
   yield autocomplete("Object.__de");
   yield autocomplete("testObject.$$aa");
--- a/devtools/client/webconsole/test/browser_webconsole_netlogging_reset_filter.js
+++ b/devtools/client/webconsole/test/browser_webconsole_netlogging_reset_filter.js
@@ -7,19 +7,19 @@
 
 "use strict";
 
 const TEST_FILE_URI =
   "http://example.com/browser/devtools/client/webconsole/test/" +
   "test-network.html";
 const TEST_URI = "data:text/html;charset=utf8,<p>test file URI";
 
-let hud;
+var hud;
 
-let test = asyncTest(function* () {
+var test = asyncTest(function* () {
   let requests = [];
   let { browser } = yield loadTab(TEST_URI);
 
   yield pushPrefEnv();
   hud = yield openConsole();
   hud.jsterm.clearOutput();
 
   HUDService.lastFinishedRequest.callback = request => requests.push(request);
--- a/devtools/client/webide/content/addons.js
+++ b/devtools/client/webide/content/addons.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {GetAvailableAddons, ForgetAddonsList} = require("devtools/client/webide/modules/addons");
 const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad);
   document.querySelector("#aboutaddons").onclick = function() {
--- a/devtools/client/webide/content/details.js
+++ b/devtools/client/webide/content/details.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {AppProjects} = require("devtools/client/app-manager/app-projects");
 const {AppValidator} = require("devtools/client/app-manager/app-validator");
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const {ProjectBuilding} = require("devtools/client/webide/modules/build");
 
--- a/devtools/client/webide/content/devicepreferences.js
+++ b/devtools/client/webide/content/devicepreferences.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const {Connection} = require("devtools/shared/client/connection-manager");
 const ConfigView = require("devtools/client/webide/modules/config-view");
 
 var configView = new ConfigView(window);
 
 window.addEventListener("load", function onLoad() {
--- a/devtools/client/webide/content/devicesettings.js
+++ b/devtools/client/webide/content/devicesettings.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const {Connection} = require("devtools/shared/client/connection-manager");
 const ConfigView = require("devtools/client/webide/modules/config-view");
 
 var configView = new ConfigView(window);
 
 window.addEventListener("load", function onLoad() {
--- a/devtools/client/webide/content/logs.js
+++ b/devtools/client/webide/content/logs.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad);
 
   Logs.init();
--- a/devtools/client/webide/content/monitor.js
+++ b/devtools/client/webide/content/monitor.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import('resource:///modules/devtools/client/framework/gDevTools.jsm');
 const {require} = Cu.import('resource://gre/modules/devtools/shared/Loader.jsm', {});
 const {Services} = Cu.import('resource://gre/modules/Services.jsm');
 const {AppManager} = require('devtools/client/webide/modules/app-manager');
 const {AppActorFront} = require('devtools/shared/apps/app-actor-front');
 const {Connection} = require('devtools/shared/client/connection-manager');
 const EventEmitter = require('devtools/shared/event-emitter');
 
--- a/devtools/client/webide/content/newapp.js
+++ b/devtools/client/webide/content/newapp.js
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cc = Components.classes;
-const Cu = Components.utils;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "ZipUtils", "resource://gre/modules/ZipUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Downloads", "resource://gre/modules/Downloads.jsm");
 
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
--- a/devtools/client/webide/content/permissionstable.js
+++ b/devtools/client/webide/content/permissionstable.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const {Connection} = require("devtools/shared/client/connection-manager");
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad);
   document.querySelector("#close").onclick = CloseUI;
--- a/devtools/client/webide/content/prefs.js
+++ b/devtools/client/webide/content/prefs.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad);
 
   // Listen to preference changes
   let inputs = document.querySelectorAll("[data-pref]");
   for (let i of inputs) {
--- a/devtools/client/webide/content/project-listing.js
+++ b/devtools/client/webide/content/project-listing.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
 /* eslint-env browser */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const ProjectList = require("devtools/client/webide/modules/project-list");
 
 var projectList = new ProjectList(window, window.parent);
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad, true);
   document.getElementById("new-app").onclick = CreateNewApp;
--- a/devtools/client/webide/content/runtime-listing.js
+++ b/devtools/client/webide/content/runtime-listing.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const RuntimeList = require("devtools/client/webide/modules/runtime-list");
 
 var runtimeList = new RuntimeList(window, window.parent);
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad, true);
   document.getElementById("runtime-screenshot").onclick = TakeScreenshot;
--- a/devtools/client/webide/content/runtimedetails.js
+++ b/devtools/client/webide/content/runtimedetails.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const {Connection} = require("devtools/shared/client/connection-manager");
 const {RuntimeTypes} = require("devtools/client/webide/modules/runtimes");
 const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
 
 const UNRESTRICTED_HELP_URL = "https://developer.mozilla.org/docs/Tools/WebIDE/Running_and_debugging_apps#Unrestricted_app_debugging_%28including_certified_apps_main_process_etc.%29";
--- a/devtools/client/webide/content/simulator.js
+++ b/devtools/client/webide/content/simulator.js
@@ -1,13 +1,13 @@
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const { GetDevices, GetDeviceString } = require("devtools/client/shared/devices");
 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
 const { Simulators, Simulator } = require("devtools/client/webide/modules/simulators");
 const EventEmitter = require('devtools/shared/event-emitter');
 const promise = require("promise");
 const utils = require("devtools/client/webide/modules/utils");
--- a/devtools/client/webide/content/webide.js
+++ b/devtools/client/webide/content/webide.js
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cc = Components.classes;
-const Cu = Components.utils;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
 
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {Toolbox} = require("devtools/client/framework/toolbox");
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 const {AppProjects} = require("devtools/client/app-manager/app-projects");
@@ -31,16 +31,26 @@ const Strings = Services.strings.createB
 const HTML = "http://www.w3.org/1999/xhtml";
 const HELP_URL = "https://developer.mozilla.org/docs/Tools/WebIDE/Troubleshooting";
 
 const MAX_ZOOM = 1.4;
 const MIN_ZOOM = 0.6;
 
 const MS_PER_DAY = 86400000;
 
+[["AppManager", AppManager],
+ ["AppProjects", AppProjects],
+ ["Connection", Connection]].forEach(([key, value]) => {
+   Object.defineProperty(this, key, {
+     value: value,
+     enumerable: true,
+     writable: false
+   });
+ });
+
 // Download remote resources early
 getJSON("devtools.webide.addonsURL", true);
 getJSON("devtools.webide.templatesURL", true);
 getJSON("devtools.devices.url", true);
 
 // See bug 989619
 console.log = console.log.bind(console);
 console.warn = console.warn.bind(console);
--- a/devtools/client/webide/content/wifi-auth.js
+++ b/devtools/client/webide/content/wifi-auth.js
@@ -1,15 +1,15 @@
 /* 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";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
 const { require } =
   Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const QR = require("devtools/shared/qrcode/index");
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad);
   document.getElementById("close").onclick = () => window.close();
--- a/devtools/client/webide/test/head.js
+++ b/devtools/client/webide/test/head.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {utils: Cu, classes: Cc, interfaces: Ci} = Components;
+var {utils: Cu, classes: Cc, interfaces: Ci} = Components;
 
 Cu.import('resource://gre/modules/Services.jsm');
 Cu.import("resource://gre/modules/FileUtils.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {gDevTools} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 const promise = require("promise");
--- a/devtools/server/actors/highlighters.js
+++ b/devtools/server/actors/highlighters.js
@@ -74,17 +74,17 @@ exports.register = register;
  *
  * Other types of highlighter actors exist and can be accessed via the
  * InspectorActor's 'getHighlighterByType' method.
  */
 
 /**
  * The HighlighterActor class
  */
-let HighlighterActor = exports.HighlighterActor = protocol.ActorClass({
+var HighlighterActor = exports.HighlighterActor = protocol.ActorClass({
   typeName: "highlighter",
 
   initialize: function(inspector, autohide) {
     protocol.Actor.prototype.initialize.call(this, null);
 
     this._autohide = autohide;
     this._inspector = inspector;
     this._walker = this._inspector.walker;
@@ -403,30 +403,30 @@ let HighlighterActor = exports.Highlight
       this._highlighter.hide();
       this._stopPickerListeners();
       this._isPicking = false;
       this._hoveredNode = null;
     }
   })
 });
 
-let HighlighterFront = protocol.FrontClass(HighlighterActor, {
+var HighlighterFront = protocol.FrontClass(HighlighterActor, {
   // Update the object given a form representation off the wire.
   form: function(json) {
     this.actorID = json.actor;
     // FF42+ HighlighterActors starts exposing custom form, with traits object
     this.traits = json.traits || {};
   }
 });
 
 /**
  * A generic highlighter actor class that instantiate a highlighter given its
  * type name and allows to show/hide it.
  */
-let CustomHighlighterActor = exports.CustomHighlighterActor = protocol.ActorClass({
+var CustomHighlighterActor = exports.CustomHighlighterActor = protocol.ActorClass({
   typeName: "customhighlighter",
 
   /**
    * Create a highlighter instance given its typename
    * The typename must be one of HIGHLIGHTER_CLASSES and the class must
    * implement constructor(tabActor), show(node), hide(), destroy()
    */
   initialize: function(inspector, typeName) {
@@ -522,17 +522,17 @@ let CustomHighlighterActor = exports.Cus
       this._highlighterEnv.destroy();
       this._highlighterEnv = null;
     }
   }, {
     oneway: true
   })
 });
 
-let CustomHighlighterFront = protocol.FrontClass(CustomHighlighterActor, {});
+var CustomHighlighterFront = protocol.FrontClass(CustomHighlighterActor, {});
 
 /**
  * The HighlighterEnvironment is an object that holds all the required data for
  * highlighters to work: the window, docShell, event listener target, ...
  * It also emits "will-navigate" and "navigate" events, similarly to the
  * TabActor.
  *
  * It can be initialized either from a TabActor (which is the most frequent way
--- a/devtools/server/actors/highlighters/css-transform.js
+++ b/devtools/server/actors/highlighters/css-transform.js
@@ -10,17 +10,17 @@ const {
   CanvasFrameAnonymousContentHelper, getComputedStyle,
   createSVGNode, createNode } = require("./utils/markup");
 const { setIgnoreLayoutChanges,
   getNodeBounds } = require("devtools/shared/layout/utils");
 
 // The minimum distance a line should be before it has an arrow marker-end
 const ARROW_LINE_MIN_DISTANCE = 10;
 
-let MARKER_COUNTER = 1;
+var MARKER_COUNTER = 1;
 
 /**
  * The CssTransformHighlighter is the class that draws an outline around a
  * transformed element and an outline around where it would be if untransformed
  * as well as arrows connecting the 2 outlines' corners.
  */
 function CssTransformHighlighter(highlighterEnv) {
   AutoRefreshHighlighter.call(this, highlighterEnv);
--- a/devtools/server/actors/highlighters/geometry-editor.js
+++ b/devtools/server/actors/highlighters/geometry-editor.js
@@ -14,17 +14,17 @@ const { setIgnoreLayoutChanges,
   getAdjustedQuads } = require("devtools/shared/layout/utils");
 
 const GEOMETRY_LABEL_SIZE = 6;
 
 /**
  * Element geometry properties helper that gives names of position and size
  * properties.
  */
-let GeoProp = {
+var GeoProp = {
   SIDES: ["top", "right", "bottom", "left"],
   SIZES: ["width", "height"],
 
   allProps: function() {
     return [...this.SIDES, ...this.SIZES];
   },
 
   isSide: function(name) {
--- a/devtools/server/actors/highlighters/utils/markup.js
+++ b/devtools/server/actors/highlighters/utils/markup.js
@@ -45,17 +45,17 @@ const STYLESHEET_URI = "resource://gre/m
 function isXUL(window) {
   return window.document.documentElement.namespaceURI === XUL_NS;
 }
 exports.isXUL = isXUL;
 
 /**
  * Inject a helper stylesheet in the window.
  */
-let installedHelperSheets = new WeakMap();
+var installedHelperSheets = new WeakMap();
 
 function installHelperSheet(win, source, type = "agent") {
   if (installedHelperSheets.has(win.document)) {
     return;
   }
   let {Style} = require("sdk/stylesheet/style");
   let {attach} = require("sdk/content/mod");
   let style = Style({source, type});
--- a/devtools/server/actors/memprof.js
+++ b/devtools/server/actors/memprof.js
@@ -1,21 +1,21 @@
 /* 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";
 
 const { Cc, Ci, Cu } = require("chrome");
-let protocol = require("devtools/server/protocol");
-let { method, RetVal, Arg, types } = protocol;
+var protocol = require("devtools/server/protocol");
+var { method, RetVal, Arg, types } = protocol;
 const { reportException } = require("devtools/shared/DevToolsUtils");
 loader.lazyRequireGetter(this, "events", "sdk/event/core");
 
-let MemprofActor = protocol.ActorClass({
+var MemprofActor = protocol.ActorClass({
   typeName: "memprof",
 
   initialize: function(conn) {
     protocol.Actor.prototype.initialize.call(this, conn);
     this._profiler = Cc["@mozilla.org/tools/memory-profiler;1"]
       .getService(Ci.nsIMemoryProfiler);
   },
 
--- a/devtools/server/tests/browser/head.js
+++ b/devtools/server/tests/browser/head.js
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 const {console} = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {DebuggerClient} = require("devtools/shared/client/main");
 const {DebuggerServer} = require("devtools/server/main");
 const {defer} = require("promise");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
--- a/devtools/server/tests/mochitest/hello-actor.js
+++ b/devtools/server/tests/mochitest/hello-actor.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const protocol = require("devtools/server/protocol");
 
-const HelloActor = protocol.ActorClass({
+var HelloActor = protocol.ActorClass({
   typeName: "helloActor",
 
   initialize: function() {
     protocol.Actor.prototype.initialize.apply(this, arguments);
     this.counter = 0;
   },
 
   count: protocol.method(function () {
--- a/devtools/server/tests/mochitest/memprof-helpers.js
+++ b/devtools/server/tests/mochitest/memprof-helpers.js
@@ -1,27 +1,27 @@
-let Cu = Components.utils;
-let Cc = Components.classes;
-let Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
-let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
+var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 // Always log packets when running tests.
 Services.prefs.setBoolPref("devtools.debugger.log", true);
 SimpleTest.registerCleanupFunction(function() {
   Services.prefs.clearUserPref("devtools.debugger.log");
 });
 
-let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
-let { require } =
+var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
+var { require } =
   Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
-let { DebuggerClient } = require("devtools/shared/client/main");
-let { DebuggerServer } = require("devtools/server/main");
-let { MemprofFront } = require("devtools/server/actors/memprof");
+var { DebuggerClient } = require("devtools/shared/client/main");
+var { DebuggerServer } = require("devtools/server/main");
+var { MemprofFront } = require("devtools/server/actors/memprof");
 
 function startServerAndGetSelectedTabMemprof() {
   DebuggerServer.init();
   DebuggerServer.addBrowserActors();
   var client = new DebuggerClient(DebuggerServer.connectPipe());
 
   return new Promise((resolve, reject) => {
     client.connect(response => {
--- a/devtools/server/tests/mochitest/test_registerActor.html
+++ b/devtools/server/tests/mochitest/test_registerActor.html
@@ -62,17 +62,17 @@ window.onload = function() {
           });
         });
       });
     });
   });
 }
 
 function checkActorState(helloActor, callback) {
-  getCount(helloActor, response => {
+getCount(helloActor, response => {
     ok(!response.error, "No error");
     is(response.count, 1, "The counter must be valid");
 
     getCount(helloActor, response => {
       ok(!response.error, "No error");
       is(response.count, 2, "The counter must be valid");
 
       gClient.listTabs(response => {
--- a/devtools/server/tests/unit/head_dbg.js
+++ b/devtools/server/tests/unit/head_dbg.js
@@ -1,17 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-const CC = Components.Constructor;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+var CC = Components.Constructor;
 
 const { require, loader } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const { worker } = Cu.import("resource://gre/modules/devtools/shared/worker-loader.js", {})
 const promise = require("promise");
 const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 const { promiseInvoke } = require("devtools/shared/async-utils");
 
 const Services = require("Services");
--- a/devtools/server/tests/unit/hello-actor.js
+++ b/devtools/server/tests/unit/hello-actor.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const protocol = require("devtools/server/protocol");
 
-const HelloActor = protocol.ActorClass({
+var HelloActor = protocol.ActorClass({
   typeName: "helloActor",
 
   hello: protocol.method(function () {
     return;
   }, {
     request: {},
     response: {}
   })
--- a/devtools/server/tests/unit/test_framebindings-02.js
+++ b/devtools/server/tests/unit/test_framebindings-02.js
@@ -31,17 +31,18 @@ function test_pause_frame()
     let args = bindings.arguments;
     let vars = bindings.variables;
     do_check_neq(parentEnv, undefined);
     do_check_eq(args.length, 0);
     do_check_eq(vars.stopMe.value.type, "object");
     do_check_eq(vars.stopMe.value.class, "Function");
     do_check_true(!!vars.stopMe.value.actor);
 
-    parentEnv = parentEnv.parent.parent;
+    // Skip both the eval lexical scope and the global lexical scope.
+    parentEnv = parentEnv.parent.parent.parent;
     do_check_neq(parentEnv, undefined);
     let objClient = gThreadClient.pauseGrip(parentEnv.object);
     objClient.getPrototypeAndProperties(function(aResponse) {
       do_check_eq(aResponse.ownProperties.Object.value.type, "object");
       do_check_eq(aResponse.ownProperties.Object.value.class, "Function");
       do_check_true(!!aResponse.ownProperties.Object.value.actor);
 
       gThreadClient.resume(function() {
--- a/devtools/server/tests/unit/test_framebindings-05.js
+++ b/devtools/server/tests/unit/test_framebindings-05.js
@@ -31,17 +31,18 @@ function test_pause_frame()
 
     let objClient = gThreadClient.pauseGrip(env.object);
     objClient.getPrototypeAndProperties(function(aResponse) {
       do_check_eq(aResponse.ownProperties.PI.value, Math.PI);
       do_check_eq(aResponse.ownProperties.cos.value.type, "object");
       do_check_eq(aResponse.ownProperties.cos.value.class, "Function");
       do_check_true(!!aResponse.ownProperties.cos.value.actor);
 
-      let parentEnv = env.parent.parent;
+      // Skip both the eval lexical scope and the global lexical scope.
+      let parentEnv = env.parent.parent.parent;
       do_check_neq(parentEnv, undefined);
 
       let parentClient = gThreadClient.pauseGrip(parentEnv.object);
       parentClient.getPrototypeAndProperties(function(aResponse) {
         do_check_eq(aResponse.ownProperties.a.value, Math.PI * 100);
         do_check_eq(aResponse.ownProperties.r.value, 10);
         do_check_eq(aResponse.ownProperties.Object.value.type, "object");
         do_check_eq(aResponse.ownProperties.Object.value.class, "Function");
--- a/devtools/shared/acorn/tests/unit/head_acorn.js
+++ b/devtools/shared/acorn/tests/unit/head_acorn.js
@@ -1,10 +1,10 @@
 "use strict";
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 
 function isObject(value) {
   return typeof value === "object" && value !== null;
 }
 
 function intersect(a, b) {
--- a/devtools/shared/apps/Devices.jsm
+++ b/devtools/shared/apps/Devices.jsm
@@ -39,10 +39,15 @@ const Devices = {
   available: function () {
     return Object.keys(this._devices).sort();
   },
 
   getByName: function (name) {
     return this._devices[name];
   }
 };
+Object.defineProperty(this, "Devices", {
+  value: Devices,
+  enumerable: true,
+  writable: false
+});
 
 EventEmitter.decorate(Devices);
--- a/devtools/shared/apps/tests/debugger-protocol-helper.js
+++ b/devtools/shared/apps/tests/debugger-protocol-helper.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const { DebuggerClient } = require("devtools/shared/client/main");
 const { DebuggerServer } = require("devtools/server/main");
 const { FileUtils } = Cu.import("resource://gre/modules/FileUtils.jsm");
 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
 
 var gClient, gActor;
--- a/devtools/shared/apps/tests/unit/head_apps.js
+++ b/devtools/shared/apps/tests/unit/head_apps.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-const CC = Components.Constructor;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+var CC = Components.Constructor;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/FileUtils.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {DebuggerClient} = require("devtools/shared/client/main");
 const {DebuggerServer} = require("devtools/server/main");
 const {AppActorFront} = require("devtools/shared/apps/app-actor-front");
--- a/devtools/shared/discovery/tests/unit/test_discovery.js
+++ b/devtools/shared/discovery/tests/unit/test_discovery.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 
 const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 Services.prefs.setBoolPref("devtools.discovery.log", true);
 
 do_register_cleanup(() => {
   Services.prefs.clearUserPref("devtools.discovery.log");
 });
 
--- a/devtools/shared/heapsnapshot/tests/unit/head_heapsnapshot.js
+++ b/devtools/shared/heapsnapshot/tests/unit/head_heapsnapshot.js
@@ -1,18 +1,18 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-const CC = Components.Constructor;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+var CC = Components.Constructor;
 
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const { Match } = Cu.import("resource://test/Match.jsm", {});
 const { Census } = Cu.import("resource://test/Census.jsm", {});
 const { addDebuggerToGlobal } =
   Cu.import("resource://gre/modules/jsdebugger.jsm", {});
 const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 
--- a/devtools/shared/jsbeautify/tests/unit/head_jsbeautify.js
+++ b/devtools/shared/jsbeautify/tests/unit/head_jsbeautify.js
@@ -1,17 +1,17 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 var beautify = require("devtools/shared/jsbeautify/beautify");
 var SanityTest = require('devtools/shared/jsbeautify/lib/sanitytest');
 var Urlencoded = require('devtools/shared/jsbeautify/lib/urlencode_unpacker');
 var {run_beautifier_tests} = require('devtools/shared/jsbeautify/src/beautify-tests');
--- a/devtools/shared/performance/test/head.js
+++ b/devtools/shared/performance/test/head.js
@@ -1,7 +1,7 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
--- a/devtools/shared/pretty-fast/tests/unit/head_pretty-fast.js
+++ b/devtools/shared/pretty-fast/tests/unit/head_pretty-fast.js
@@ -1,13 +1,13 @@
 "use strict";
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 this.sourceMap = require("source-map");
 this.acorn = require("acorn/acorn");
 this.prettyFast = require("devtools/shared/pretty-fast/pretty-fast");
 const { console } = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
 
--- a/devtools/shared/qrcode/tests/unit/test_encode.js
+++ b/devtools/shared/qrcode/tests/unit/test_encode.js
@@ -1,17 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
 /**
  * Test encoding a simple message.
  */
 
-const { utils: Cu } = Components;
+var { utils: Cu } = Components;
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 const QR = require("devtools/shared/qrcode/index");
 
 function run_test() {
   let imgData = QR.encodeToDataURI("HELLO", "L");
   do_check_eq(imgData.src,
               "data:image/gif;base64,R0lGODdhOgA6AIAAAAAAAP///ywAAAAAOgA6AAAC" +
--- a/devtools/shared/security/tests/unit/head_dbg.js
+++ b/devtools/shared/security/tests/unit/head_dbg.js
@@ -1,17 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-const CC = Components.Constructor;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+var CC = Components.Constructor;
 
 const { require } =
   Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const promise = require("promise");
 const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 
 const Services = require("Services");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
--- a/devtools/shared/shared/tests/unit/test_indentation.js
+++ b/devtools/shared/shared/tests/unit/test_indentation.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm");
 const Services = require("Services");
 const {
   EXPAND_TAB,
   TAB_SIZE,
   DETECT_INDENT,
   getIndentationFromPrefs,
   getIndentationFromIteration,
--- a/devtools/shared/shims/dbg-client.jsm
+++ b/devtools/shared/shims/dbg-client.jsm
@@ -26,17 +26,17 @@ const { require } =
 
 this.EXPORTED_SYMBOLS = ["DebuggerTransport",
                          "DebuggerClient",
                          "RootClient",
                          "LongStringClient",
                          "EnvironmentClient",
                          "ObjectClient"];
 
-let client = require("devtools/shared/client/main");
+var client = require("devtools/shared/client/main");
 
 this.DebuggerClient = client.DebuggerClient;
 this.RootClient = client.RootClient;
 this.LongStringClient = client.LongStringClient;
 this.EnvironmentClient = client.EnvironmentClient;
 this.ObjectClient = client.ObjectClient;
 
 this.DebuggerTransport =
--- a/devtools/shared/sourcemap/tests/unit/head_sourcemap.js
+++ b/devtools/shared/sourcemap/tests/unit/head_sourcemap.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 function doesNotThrow(f) {
   try {
     f();
   } catch(e) {
     ok(false, e + e.stack);
   }
 }
--- a/devtools/shared/tern/tests/unit/head_tern.js
+++ b/devtools/shared/tern/tests/unit/head_tern.js
@@ -1,3 +1,3 @@
 "use strict";
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
--- a/devtools/shared/tests/unit/head_devtools.js
+++ b/devtools/shared/tests/unit/head_devtools.js
@@ -1,13 +1,13 @@
 "use strict";
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
 
 // Register a console listener, so console messages don't just disappear
 // into the ether.
 var errorCount = 0;
 var listener = {
--- a/devtools/shared/transport/tests/unit/head_dbg.js
+++ b/devtools/shared/transport/tests/unit/head_dbg.js
@@ -1,17 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-const CC = Components.Constructor;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+var CC = Components.Constructor;
 
 const { require } =
   Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const promise = require("promise");
 const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 
 const Services = require("Services");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
--- a/devtools/shared/webconsole/test/common.js
+++ b/devtools/shared/webconsole/test/common.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 const XHTML_NS = "http://www.w3.org/1999/xhtml";
 
 Cu.import("resource://gre/modules/Services.jsm");
 const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
 
 // This gives logging to stdout for tests
 var {console} = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
--- a/devtools/shared/webconsole/test/test_commands_registration.html
+++ b/devtools/shared/webconsole/test/test_commands_registration.html
@@ -13,17 +13,16 @@
 <p id="quack"></p>
 
 <script class="testbody" type="text/javascript;version=1.8">
 SimpleTest.waitForExplicitFinish();
 
 let gState;
 let tests;
 
-let {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 let {WebConsoleCommands} = require("devtools/shared/webconsole/utils");
 
 function evaluateJS(input) {
   return new Promise((resolve) => gState.client.evaluateJS(input, resolve));
 }
 
 function* evaluateJSAndCheckResult(input, result) {
   let response = yield evaluateJS(input);
--- a/devtools/shared/webconsole/test/test_jsterm.html
+++ b/devtools/shared/webconsole/test/test_jsterm.html
@@ -11,17 +11,16 @@
 <body>
 <p>Test for JavaScript terminal functionality</p>
 
 <script class="testbody" type="text/javascript;version=1.8">
 SimpleTest.waitForExplicitFinish();
 
 let gState;
 
-let {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 let {MAX_AUTOCOMPLETE_ATTEMPTS,MAX_AUTOCOMPLETIONS} = require("devtools/shared/webconsole/utils");
 
 // This test runs all of its assertions twice - once with
 // evaluateJS and once with evaluateJSAsync.
 let evaluatingSync = true;
 function evaluateJS(input, callback) {
   if (evaluatingSync) {
     gState.client.evaluateJS(input, callback);
--- a/devtools/shared/webconsole/test/unit/test_network_helper.js
+++ b/devtools/shared/webconsole/test/unit/test_network_helper.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
-const Cu = Components.utils;
+var Cu = Components.utils;
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 Object.defineProperty(this, "NetworkHelper", {
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
--- a/devtools/shared/webconsole/test/unit/test_security-info-certificate.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-certificate.js
@@ -12,17 +12,17 @@ Object.defineProperty(this, "NetworkHelp
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
   enumerable: true
 });
 
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const DUMMY_CERT = {
   commonName: "cn",
   organization: "o",
   organizationalUnit: "ou",
   issuerCommonName: "issuerCN",
   issuerOrganization: "issuerO",
   issuerOrganizationUnit: "issuerOU",
   sha256Fingerprint: "qwertyuiopoiuytrewq",
--- a/devtools/shared/webconsole/test/unit/test_security-info-parser.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-parser.js
@@ -12,17 +12,17 @@ Object.defineProperty(this, "NetworkHelp
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
   enumerable: true
 });
 
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const wpl = Ci.nsIWebProgressListener;
 const MockCertificate = {
   commonName: "cn",
   organization: "o",
   organizationalUnit: "ou",
   issuerCommonName: "issuerCN",
   issuerOrganization: "issuerO",
   issuerOrganizationUnit: "issuerOU",
--- a/devtools/shared/webconsole/test/unit/test_security-info-protocol-version.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-protocol-version.js
@@ -12,17 +12,17 @@ Object.defineProperty(this, "NetworkHelp
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
   enumerable: true
 });
 
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const TEST_CASES = [
   {
     description: "TLS_VERSION_1",
     input: 1,
     expected: "TLSv1"
   }, {
     description: "TLS_VERSION_1.1",
     input: 2,
--- a/devtools/shared/webconsole/test/unit/test_security-info-state.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-state.js
@@ -13,17 +13,17 @@ Object.defineProperty(this, "NetworkHelp
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
   enumerable: true
 });
 
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const wpl = Ci.nsIWebProgressListener;
 const MockSecurityInfo = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsITransportSecurityInfo,
                                          Ci.nsISSLStatusProvider]),
   securityState: wpl.STATE_IS_BROKEN,
   errorCode: 0,
   SSLStatus: {
     protocolVersion: 3, // nsISSLStatus.TLS_VERSION_1_2
--- a/devtools/shared/webconsole/test/unit/test_security-info-static-hpkp.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-static-hpkp.js
@@ -13,17 +13,17 @@ Object.defineProperty(this, "NetworkHelp
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
   enumerable: true
 });
 
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const wpl = Ci.nsIWebProgressListener;
 
 const MockSecurityInfo = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsITransportSecurityInfo,
                                          Ci.nsISSLStatusProvider]),
   securityState: wpl.STATE_IS_SECURE,
   errorCode: 0,
   SSLStatus: {
--- a/devtools/shared/webconsole/test/unit/test_security-info-weakness-reasons.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-weakness-reasons.js
@@ -12,17 +12,17 @@ Object.defineProperty(this, "NetworkHelp
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
   enumerable: true
 });
 
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const wpl = Ci.nsIWebProgressListener;
 const TEST_CASES = [
   {
     description: "weak cipher",
     input: wpl.STATE_IS_BROKEN | wpl.STATE_USES_WEAK_CRYPTO,
     expected: ["cipher"]
   }, {
     description: "only STATE_IS_BROKEN flag",
--- a/devtools/shared/worker-loader.js
+++ b/devtools/shared/worker-loader.js
@@ -424,17 +424,17 @@ var {
     }
 
     let xpcInspector = Cc["@mozilla.org/jsinspector;1"].
                        getService(Ci.nsIJSInspector);
 
     return {
       Debugger,
       createSandbox,
-      dump,
+      dump: this.dump,
       rpc,
       loadSubScript,
       reportError,
       setImmediate,
       xpcInspector
     };
   } else { // Worker thread
     let requestors = [];
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -10892,26 +10892,23 @@ nsDocShell::DoChannelLoad(nsIChannel* aC
       }
       break;
   }
 
   if (!aBypassClassifier) {
     loadFlags |= nsIChannel::LOAD_CLASSIFY_URI;
   }
 
-  (void)aChannel->SetLoadFlags(loadFlags);
-
   // If the user pressed shift-reload, then do not allow ServiceWorker
   // interception to occur. See step 12.1 of the SW HandleFetch algorithm.
   if (IsForceReloadType(mLoadType)) {
-    nsCOMPtr<nsIHttpChannelInternal> internal = do_QueryInterface(aChannel);
-    if (internal) {
-      internal->ForceNoIntercept();
-    }
-  }
+    loadFlags |= nsIChannel::LOAD_BYPASS_SERVICE_WORKER;
+  }
+
+  (void)aChannel->SetLoadFlags(loadFlags);
 
   uint32_t openFlags = 0;
   if (mLoadType == LOAD_LINK) {
     openFlags |= nsIURILoader::IS_CONTENT_PREFERRED;
   }
   if (!mAllowContentRetargeting) {
     openFlags |= nsIURILoader::DONT_RETARGET;
   }
@@ -13445,17 +13442,17 @@ nsDocShell::OnLinkClickSync(nsIContent* 
 
   // If this is an anchor element, grab its type property to use as a hint
   nsAutoString typeHint;
   nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(aContent));
   if (anchor) {
     anchor->GetType(typeHint);
     NS_ConvertUTF16toUTF8 utf8Hint(typeHint);
     nsAutoCString type, dummy;
-    NS_ParseContentType(utf8Hint, type, dummy);
+    NS_ParseRequestContentType(utf8Hint, type, dummy);
     CopyUTF8toUTF16(type, typeHint);
   }
 
   // Clone the URI now, in case a content policy or something messes
   // with it under InternalLoad; we do _not_ want to change the URI
   // our caller passed in.
   nsCOMPtr<nsIURI> clonedURI;
   aURI->Clone(getter_AddRefs(clonedURI));
--- a/docshell/test/browser/browser_loadURI.js
+++ b/docshell/test/browser/browser_loadURI.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 const gPostData = "postdata=true";
 
 function test() {
   waitForExplicitFinish();
 
   let tab = gBrowser.selectedTab = gBrowser.addTab();
   registerCleanupFunction(function () {
--- a/docshell/test/browser/frame-head.js
+++ b/docshell/test/browser/frame-head.js
@@ -1,15 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Functions that are automatically loaded as frame scripts for
 // timeline tests.
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 var { Promise } = Cu.import('resource://gre/modules/Promise.jsm', {});
 
 Cu.import("resource://gre/modules/Timer.jsm");
 
 // Functions that look like mochitest functions but forward to the
 // browser process.
 
--- a/docshell/test/chrome/chrome.ini
+++ b/docshell/test/chrome/chrome.ini
@@ -75,17 +75,17 @@ skip-if = toolkit == "gtk2"
 [test_bug565388.xul]
 skip-if = os == 'linux' || os == 'mac' # Bug 1026815
 [test_bug582176.xul]
 [test_bug608669.xul]
 [test_bug662200.xul]
 [test_bug690056.xul]
 [test_bug789773.xul]
 [test_bug846906.xul]
-skip-if = os == 'linux' && asan # Bug 1207161
+skip-if = (os == 'linux' && asan) || debug # Bug 1207161
 [test_bug89419.xul]
 [test_bug909218.html]
 [test_bug92598.xul]
 [test_mozFrameType.xul]
 [test_principalInherit.xul]
 [test_private_hidden_window.html]
 [test_viewsource_forbidden_in_iframe.xul]
 skip-if = true # bug 1019315
--- a/docshell/test/unit/head_docshell.js
+++ b/docshell/test/unit/head_docshell.js
@@ -1,11 +1,11 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
 
 var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
              getService(Ci.nsIProperties);
 var profileDir = do_get_profile();
--- a/docshell/test/unit/test_nsDefaultURIFixup_search.js
+++ b/docshell/test/unit/test_nsDefaultURIFixup_search.js
@@ -1,40 +1,40 @@
-let urifixup = Cc["@mozilla.org/docshell/urifixup;1"].
+var urifixup = Cc["@mozilla.org/docshell/urifixup;1"].
                getService(Ci.nsIURIFixup);
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/AppConstants.jsm");
 
 Services.prefs.setBoolPref("keyword.enabled", true);
 
 const kSearchEngineID = "test_urifixup_search_engine";
 const kSearchEngineURL = "http://www.example.org/?search={searchTerms}";
 Services.search.addEngineWithDetails(kSearchEngineID, "", "", "", "get",
                                      kSearchEngineURL);
 
-let oldDefaultEngine = Services.search.defaultEngine;
+var oldDefaultEngine = Services.search.defaultEngine;
 Services.search.defaultEngine = Services.search.getEngineByName(kSearchEngineID);
 
-let selectedName = Services.search.defaultEngine.name;
+var selectedName = Services.search.defaultEngine.name;
 do_check_eq(selectedName, kSearchEngineID);
 
 do_register_cleanup(function() {
   if (oldDefaultEngine) {
     Services.search.defaultEngine = oldDefaultEngine;
   }
   let engine = Services.search.getEngineByName(kSearchEngineID);
   if (engine) {
     Services.search.removeEngine(engine);
   }
   Services.prefs.clearUserPref("keyword.enabled");
 });
 
-let isWin = AppConstants.platform == "win";
+var isWin = AppConstants.platform == "win";
 
-let data = [
+var data = [
   {
     // Valid should not be changed.
     wrong: 'https://example.com/this/is/a/test.html',
     fixed: 'https://example.com/this/is/a/test.html',
   },
   {
     // Unrecognized protocols should be changed.
     wrong: 'whatever://this/is/a/test.html',
@@ -85,31 +85,31 @@ let data = [
     fixed: 'http://user:pass@example.com:8080/this/is/a/test.html',
   },
   {
     wrong: 'whatever://this/is/a@b/test.html',
     fixed: kSearchEngineURL.replace("{searchTerms}", encodeURIComponent('whatever://this/is/a@b/test.html')),
   },
 ];
 
-let extProtocolSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"]
+var extProtocolSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"]
                      .getService(Ci.nsIExternalProtocolService);
 
 if (extProtocolSvc && extProtocolSvc.externalProtocolHandlerExists("mailto")) {
   data.push({
     wrong: "mailto:foo@bar.com",
     fixed: "mailto:foo@bar.com"
   });
 }
 
 function run_test() {
   run_next_test();
 }
 
-let len = data.length;
+var len = data.length;
 // Make sure we fix what needs fixing
 add_task(function test_fix_unknown_schemes() {
   for (let i = 0; i < len; ++i) {
     let item = data[i];
     let result =
       urifixup.createFixupURI(item.wrong,
                               urifixup.FIXUP_FLAG_FIX_SCHEME_TYPOS).spec;
     do_check_eq(result, item.fixed);
--- a/docshell/test/unit_ipc/test_pb_notification_ipc.js
+++ b/docshell/test/unit_ipc/test_pb_notification_ipc.js
@@ -1,10 +1,10 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 function run_test() {
   var notifications = 0;
   var obs = {
     observe: function(aSubject, aTopic, aData) {
       do_check_eq(aTopic, "last-pb-context-exited");
       notifications++;
     }
--- a/dom/activities/tests/mochi/common.js
+++ b/dom/activities/tests/mochi/common.js
@@ -1,9 +1,9 @@
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 const ACTIVITY_GLUE_CID = Components.ID("{f4cfbe10-a106-4cd1-b04e-0d2a6aac138b}");
 const SYS_MSG_GLUE_CID = Components.ID("{b0b6b9af-bc4e-4200-bffe-fb7691065ec9}");
 
 const gRootUrl = "http://test/chrome/dom/activities/tests/mochi/";
 
 function registerComponent(aObject, aDescription, aContract, aCid) {
   info("Registering " + aCid);
--- a/dom/alarm/test/system_message_chrome_script.js
+++ b/dom/alarm/test/system_message_chrome_script.js
@@ -1,14 +1,14 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 'use strict';
 
-const { classes: Cc, interfaces: Ci } = Components;
+var { classes: Cc, interfaces: Ci } = Components;
 
 const systemMessenger = Cc["@mozilla.org/system-message-internal;1"]
                           .getService(Ci.nsISystemMessagesInternal);
 const ioService = Cc["@mozilla.org/network/io-service;1"]
                     .getService(Ci.nsIIOService);
 
 addMessageListener("trigger-register-page", function(aData) {
   systemMessenger.registerPage(aData.type,
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -46,25 +46,27 @@ Animation::WrapObject(JSContext* aCx, JS
 //
 // Animation interface:
 //
 // ---------------------------------------------------------------------------
 
 void
 Animation::SetEffect(KeyframeEffectReadOnly* aEffect)
 {
+  nsRefPtr<Animation> kungFuDeathGrip(this);
+
   if (mEffect == aEffect) {
     return;
   }
   if (mEffect) {
-    mEffect->SetParentTime(Nullable<TimeDuration>());
+    mEffect->SetAnimation(nullptr);
   }
   mEffect = aEffect;
   if (mEffect) {
-    mEffect->SetParentTime(GetCurrentTime());
+    mEffect->SetAnimation(this);
   }
 
   UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
 }
 
 void
 Animation::SetTimeline(AnimationTimeline* aTimeline)
 {
@@ -81,16 +83,17 @@ Animation::SetTimeline(AnimationTimeline
   // FIXME(spec): Once we implement the seeking defined in the spec
   // surely this should be SeekFlag::DidSeek but the spec says otherwise.
   UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
 
   // FIXME: When we expose this method to script we'll need to call PostUpdate
   // (but *not* when this method gets called from style).
 }
 
+// https://w3c.github.io/web-animations/#set-the-animation-start-time
 void
 Animation::SetStartTime(const Nullable<TimeDuration>& aNewStartTime)
 {
   Nullable<TimeDuration> timelineTime;
   if (mTimeline) {
     // The spec says to check if the timeline is active (has a resolved time)
     // before using it here, but we don't need to since it's harmless to set
     // the already null time to null.
@@ -116,17 +119,17 @@ Animation::SetStartTime(const Nullable<T
     // MaybeResolve is a no-op, so that's okay.
     mReady->MaybeResolve(this);
   }
 
   UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
   PostUpdate();
 }
 
-// http://w3c.github.io/web-animations/#current-time
+// https://w3c.github.io/web-animations/#current-time
 Nullable<TimeDuration>
 Animation::GetCurrentTime() const
 {
   Nullable<TimeDuration> result;
   if (!mHoldTime.IsNull()) {
     result = mHoldTime;
     return result;
   }
@@ -136,17 +139,17 @@ Animation::GetCurrentTime() const
     if (!timelineTime.IsNull()) {
       result.SetValue((timelineTime.Value() - mStartTime.Value())
                         .MultDouble(mPlaybackRate));
     }
   }
   return result;
 }
 
-// Implements http://w3c.github.io/web-animations/#set-the-current-time
+// https://w3c.github.io/web-animations/#set-the-current-time
 void
 Animation::SetCurrentTime(const TimeDuration& aSeekTime)
 {
   SilentlySetCurrentTime(aSeekTime);
 
   if (mPendingState == PendingState::PausePending) {
     // Finish the pause operation
     mHoldTime.SetValue(aSeekTime);
@@ -157,26 +160,28 @@ Animation::SetCurrentTime(const TimeDura
     }
     CancelPendingTasks();
   }
 
   UpdateTiming(SeekFlag::DidSeek, SyncNotifyFlag::Async);
   PostUpdate();
 }
 
+// https://w3c.github.io/web-animations/#set-the-animation-playback-rate
 void
 Animation::SetPlaybackRate(double aPlaybackRate)
 {
   Nullable<TimeDuration> previousTime = GetCurrentTime();
   mPlaybackRate = aPlaybackRate;
   if (!previousTime.IsNull()) {
     SetCurrentTime(previousTime.Value());
   }
 }
 
+// https://w3c.github.io/web-animations/#play-state
 AnimationPlayState
 Animation::PlayState() const
 {
   if (mPendingState != PendingState::NotPending) {
     return AnimationPlayState::Pending;
   }
 
   Nullable<TimeDuration> currentTime = GetCurrentTime();
@@ -290,16 +295,17 @@ Animation::Play(ErrorResult& aRv, LimitB
 
 void
 Animation::Pause(ErrorResult& aRv)
 {
   DoPause(aRv);
   PostUpdate();
 }
 
+// https://w3c.github.io/web-animations/#reverse-an-animation
 void
 Animation::Reverse(ErrorResult& aRv)
 {
   if (!mTimeline || mTimeline->GetCurrentTime().IsNull()) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 
@@ -349,25 +355,28 @@ Animation::SetCurrentTimeAsDouble(const 
   return SetCurrentTime(TimeDuration::FromMilliseconds(aCurrentTime.Value()));
 }
 
 // ---------------------------------------------------------------------------
 
 void
 Animation::Tick()
 {
-  // Since we are not guaranteed to get only one call per refresh driver tick,
-  // it's possible that mPendingReadyTime is set to a time in the future.
-  // In that case, we should wait until the next refresh driver tick before
-  // resuming.
+  // Finish pending if we have a pending ready time, but only if we also
+  // have an active timeline.
   if (mPendingState != PendingState::NotPending &&
       !mPendingReadyTime.IsNull() &&
       mTimeline &&
-      !mTimeline->GetCurrentTime().IsNull() &&
-      mPendingReadyTime.Value() <= mTimeline->GetCurrentTime().Value()) {
+      !mTimeline->GetCurrentTime().IsNull()) {
+    // Even though mPendingReadyTime is initialized using TimeStamp::Now()
+    // during the *previous* tick of the refresh driver, it can still be
+    // ahead of the *current* timeline time when we are using the
+    // vsync timer so we need to clamp it to the timeline time.
+    mPendingReadyTime.SetValue(std::min(mTimeline->GetCurrentTime().Value(),
+                                        mPendingReadyTime.Value()));
     FinishPendingAt(mPendingReadyTime.Value());
     mPendingReadyTime.SetNull();
   }
 
   if (IsPossiblyOrphanedPendingAnimation()) {
     MOZ_ASSERT(mTimeline && !mTimeline->GetCurrentTime().IsNull(),
                "Orphaned pending animtaions should have an active timeline");
     FinishPendingAt(mTimeline->GetCurrentTime().Value());
@@ -441,17 +450,17 @@ Animation::GetCurrentOrPendingStartTime(
 
   // Calculate the equivalent start time from the pending ready time.
   // This is the same as the calculation performed in ResumeAt and will
   // need to incorporate the playbackRate when implemented (bug 1127380).
   result.SetValue(mPendingReadyTime.Value() - mHoldTime.Value());
   return result;
 }
 
-// http://w3c.github.io/web-animations/#silently-set-the-current-time
+// https://w3c.github.io/web-animations/#silently-set-the-current-time
 void
 Animation::SilentlySetCurrentTime(const TimeDuration& aSeekTime)
 {
   if (!mHoldTime.IsNull() ||
       mStartTime.IsNull() ||
       !mTimeline ||
       mTimeline->GetCurrentTime().IsNull() ||
       mPlaybackRate == 0.0) {
@@ -472,16 +481,17 @@ Animation::SilentlySetPlaybackRate(doubl
 {
   Nullable<TimeDuration> previousTime = GetCurrentTime();
   mPlaybackRate = aPlaybackRate;
   if (!previousTime.IsNull()) {
     SilentlySetCurrentTime(previousTime.Value());
   }
 }
 
+// https://w3c.github.io/web-animations/#cancel-an-animation
 void
 Animation::DoCancel()
 {
   if (mPendingState != PendingState::NotPending) {
     CancelPendingTasks();
     if (mReady) {
       mReady->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
     }
@@ -561,27 +571,26 @@ Animation::CanThrottle() const
   }
 
   return IsRunningOnCompositor();
 }
 
 void
 Animation::ComposeStyle(nsRefPtr<AnimValuesStyleRule>& aStyleRule,
                         nsCSSPropertySet& aSetProperties,
-                        bool& aNeedsRefreshes)
+                        bool& aStyleChanging)
 {
   if (!mEffect) {
     return;
   }
 
   AnimationPlayState playState = PlayState();
   if (playState == AnimationPlayState::Running ||
-      playState == AnimationPlayState::Pending ||
-      HasEndEventToQueue()) {
-    aNeedsRefreshes = true;
+      playState == AnimationPlayState::Pending) {
+    aStyleChanging = true;
   }
 
   if (!IsInEffect()) {
     return;
   }
 
   // In order to prevent flicker, there are a few cases where we want to use
   // a different time for rendering that would otherwise be returned by
@@ -657,17 +666,17 @@ Animation::NotifyEffectTimingUpdated()
 {
   MOZ_ASSERT(mEffect,
              "We should only update timing effect when we have a target "
              "effect");
   UpdateTiming(Animation::SeekFlag::NoSeek,
                Animation::SyncNotifyFlag::Async);
 }
 
-// http://w3c.github.io/web-animations/#play-an-animation
+// https://w3c.github.io/web-animations/#play-an-animation
 void
 Animation::DoPlay(ErrorResult& aRv, LimitBehavior aLimitBehavior)
 {
   bool abortedPause = mPendingState == PendingState::PausePending;
 
   Nullable<TimeDuration> currentTime = GetCurrentTime();
   if (mPlaybackRate > 0.0 &&
       (currentTime.IsNull() ||
@@ -732,17 +741,17 @@ Animation::DoPlay(ErrorResult& aRv, Limi
     tracker->AddPlayPending(*this);
   } else {
     TriggerOnNextTick(Nullable<TimeDuration>());
   }
 
   UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
 }
 
-// http://w3c.github.io/web-animations/#pause-an-animation
+// https://w3c.github.io/web-animations/#pause-an-animation
 void
 Animation::DoPause(ErrorResult& aRv)
 {
   if (IsPausedOrPausing()) {
     return;
   }
 
   // If we are transitioning from idle, fill in the current time
@@ -843,16 +852,17 @@ Animation::UpdateTiming(SeekFlag aSeekFl
   UpdateFinishedState(aSeekFlag, aSyncNotifyFlag);
   UpdateEffect();
 
   if (mTimeline) {
     mTimeline->NotifyAnimationUpdated(*this);
   }
 }
 
+// https://w3c.github.io/web-animations/#update-an-animations-finished-state
 void
 Animation::UpdateFinishedState(SeekFlag aSeekFlag,
                                SyncNotifyFlag aSyncNotifyFlag)
 {
   Nullable<TimeDuration> currentTime = GetCurrentTime();
   TimeDuration effectEnd = TimeDuration(EffectEnd());
 
   if (!mStartTime.IsNull() &&
@@ -897,17 +907,16 @@ Animation::UpdateFinishedState(SeekFlag 
   // changes the code above made.
   mPreviousCurrentTime = GetCurrentTime();
 }
 
 void
 Animation::UpdateEffect()
 {
   if (mEffect) {
-    mEffect->SetParentTime(GetCurrentTime());
     UpdateRelevance();
   }
 }
 
 void
 Animation::FlushStyle() const
 {
   nsIDocument* doc = GetRenderedDocument();
--- a/dom/animation/Animation.h
+++ b/dom/animation/Animation.h
@@ -233,21 +233,21 @@ public:
   bool IsPausedOrPausing() const
   {
     return PlayState() == AnimationPlayState::Paused ||
            mPendingState == PendingState::PausePending;
   }
 
   bool HasInPlayEffect() const
   {
-    return GetEffect() && GetEffect()->IsInPlay(*this);
+    return GetEffect() && GetEffect()->IsInPlay();
   }
   bool HasCurrentEffect() const
   {
-    return GetEffect() && GetEffect()->IsCurrent(*this);
+    return GetEffect() && GetEffect()->IsCurrent();
   }
   bool IsInEffect() const
   {
     return GetEffect() && GetEffect()->IsInEffect();
   }
 
   /**
    * "Playing" is different to "running". An animation in its delay phase is
@@ -280,36 +280,23 @@ public:
    * running on the compositor).
    */
   bool CanThrottle() const;
   /**
    * Updates |aStyleRule| with the animation values of this animation's effect,
    * if any.
    * Any properties already contained in |aSetProperties| are not changed. Any
    * properties that are changed are added to |aSetProperties|.
-   * |aNeedsRefreshes| will be set to true if this animation expects to update
+   * |aStyleChanging| will be set to true if this animation expects to update
    * the style rule on the next refresh driver tick as well (because it
    * is running and has an effect to sample).
    */
   void ComposeStyle(nsRefPtr<AnimValuesStyleRule>& aStyleRule,
                     nsCSSPropertySet& aSetProperties,
-                    bool& aNeedsRefreshes);
-
-
-  // FIXME: Because we currently determine if we need refresh driver ticks
-  // during restyling (specifically ComposeStyle above) and not necessarily
-  // during a refresh driver tick, we can arrive at a situation where we
-  // have finished running an animation but are waiting until the next tick
-  // to queue the final end event. This method tells us when we are in that
-  // situation so we can avoid unregistering from the refresh driver until
-  // we've finished dispatching events.
-  //
-  // This is a temporary measure until bug 1195180 is done and we can do all
-  // our registering and unregistering within a tick callback.
-  virtual bool HasEndEventToQueue() const { return false; }
+                    bool& aStyleChanging);
 
   void NotifyEffectTimingUpdated();
 
 protected:
   void SilentlySetCurrentTime(const TimeDuration& aNewCurrentTime);
   void SilentlySetPlaybackRate(double aPlaybackRate);
   void DoCancel();
   void DoPlay(ErrorResult& aRv, LimitBehavior aLimitBehavior);
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -104,17 +104,18 @@ ComputedTimingFunction::AppendToString(n
 // In the Web Animations model, the iteration progress can be outside the range
 // [0.0, 1.0] but it shouldn't be Infinity.
 const double ComputedTiming::kNullProgress = PositiveInfinity<double>();
 
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(KeyframeEffectReadOnly,
                                    AnimationEffectReadOnly,
-                                   mTarget)
+                                   mTarget,
+                                   mAnimation)
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(KeyframeEffectReadOnly,
                                                AnimationEffectReadOnly)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(KeyframeEffectReadOnly)
 NS_INTERFACE_MAP_END_INHERITING(AnimationEffectReadOnly)
 
@@ -138,30 +139,37 @@ KeyframeEffectReadOnly::KeyframeEffectRe
 JSObject*
 KeyframeEffectReadOnly::WrapObject(JSContext* aCx,
                                    JS::Handle<JSObject*> aGivenProto)
 {
   return KeyframeEffectReadOnlyBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
-KeyframeEffectReadOnly::SetParentTime(Nullable<TimeDuration> aParentTime)
-{
-  mParentTime = aParentTime;
-}
-
-void
-KeyframeEffectReadOnly::SetTiming(const AnimationTiming& aTiming,
-                                  Animation& aOwningAnimation)
+KeyframeEffectReadOnly::SetTiming(const AnimationTiming& aTiming)
 {
   if (mTiming == aTiming) {
     return;
   }
   mTiming = aTiming;
-  aOwningAnimation.NotifyEffectTimingUpdated();
+  if (mAnimation) {
+    mAnimation->NotifyEffectTimingUpdated();
+  }
+}
+
+Nullable<TimeDuration>
+KeyframeEffectReadOnly::GetLocalTime() const
+{
+  // Since the *animation* start time is currently always zero, the local
+  // time is equal to the parent time.
+  Nullable<TimeDuration> result;
+  if (mAnimation) {
+    result = mAnimation->GetCurrentTime();
+  }
+  return result;
 }
 
 ComputedTiming
 KeyframeEffectReadOnly::GetComputedTimingAt(
                           const Nullable<TimeDuration>& aLocalTime,
                           const AnimationTiming& aTiming)
 {
   const TimeDuration zeroDuration;
@@ -299,47 +307,54 @@ KeyframeEffectReadOnly::ActiveDuration(c
     return aTiming.mIterationDura