Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Thu, 03 May 2012 11:40:52 -0700
changeset 106146 c660397f6ab25e596d6fd1a2ce3eb2ca1b52626f
parent 106145 525b3eba3bcb40e1340140c7552dde19c9e7821e (current diff)
parent 92900 5be71aa88a163df3f3de490d737dec12562a3b34 (diff)
child 106147 89dc67e650160839e2f83c1bc732992f77ddd8e7
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
milestone15.0a1
Merge from mozilla-central.
accessible/src/atk/ApplicationAccessibleWrap.cpp
accessible/src/atk/ApplicationAccessibleWrap.h
accessible/src/atk/nsAccessibleWrap.cpp
accessible/src/base/Makefile.in
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsAccessible.h
accessible/src/base/nsDocAccessible.cpp
accessible/src/base/nsDocAccessible.h
accessible/src/base/nsRootAccessible.cpp
accessible/src/base/nsRootAccessible.h
accessible/src/base/nsTextEquivUtils.cpp
accessible/src/generic/ApplicationAccessible.cpp
accessible/src/generic/ApplicationAccessible.h
accessible/src/html/nsHTMLSelectAccessible.cpp
accessible/src/msaa/nsAccessibleWrap.cpp
accessible/src/xul/nsXULAlertAccessible.cpp
accessible/src/xul/nsXULAlertAccessible.h
accessible/src/xul/nsXULTreeAccessible.cpp
accessible/src/xul/nsXULTreeAccessible.h
accessible/src/xul/nsXULTreeGridAccessible.cpp
accessible/src/xul/nsXULTreeGridAccessible.h
browser/app/profile/firefox.js
browser/base/content/browser.js
browser/base/content/browser.xul
browser/base/content/tabbrowser.xml
browser/components/nsBrowserGlue.js
browser/components/tabview/tabview.js
browser/components/tabview/test/Makefile.in
browser/components/tabview/ui.js
browser/devtools/debugger/test/browser_dbg_createRemote.js
browser/devtools/debugger/test/browser_dbg_scripts-searching-01.js
browser/devtools/debugger/test/browser_dbg_scripts-searching-02.js
browser/devtools/debugger/test/browser_dbg_scripts-sorting.js
browser/devtools/jar.mn
browser/devtools/shared/DeveloperToolbar.jsm
browser/devtools/shared/Templater.jsm
browser/devtools/shared/test/browser_gcli_break.html
browser/devtools/shared/test/browser_gcli_break.js
browser/devtools/shared/test/browser_gcli_commands.js
browser/devtools/shared/test/browser_gcli_inspect.html
browser/devtools/shared/test/browser_gcli_inspect.js
browser/devtools/shared/test/browser_gcli_integrate.js
browser/devtools/shared/test/browser_gcli_require.js
browser/devtools/shared/test/browser_gcli_web.js
browser/devtools/shared/test/browser_toolbar_basic.html
browser/devtools/shared/test/browser_toolbar_basic.js
browser/devtools/webconsole/HUDService.jsm
browser/devtools/webconsole/gcli.css
browser/devtools/webconsole/gcliblank.xhtml
browser/devtools/webconsole/test/Makefile.in
browser/devtools/webconsole/test/browser_webconsole_bug_595934_message_categories.js
browser/devtools/webconsole/test/browser_webconsole_bug_653531_highlighter_console_helper.js
browser/locales/en-US/chrome/browser/browser.dtd
build/mobile/devicemanagerADB.py
build/mobile/devicemanagerSUT.py
caps/include/nsPrincipal.h
caps/include/nsScriptSecurityManager.h
caps/src/nsNullPrincipal.cpp
caps/src/nsPrincipal.cpp
caps/src/nsScriptSecurityManager.cpp
caps/src/nsSecurityManagerFactory.cpp
caps/src/nsSystemPrincipal.cpp
config/autoconf.mk.in
configure.in
content/base/src/nsCCUncollectableMarker.cpp
content/base/src/nsXMLHttpRequest.cpp
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/WebGLContextValidate.cpp
content/events/src/nsDOMEvent.cpp
content/html/content/public/nsHTMLMediaElement.h
content/html/content/src/nsHTMLMediaElement.cpp
content/html/content/src/nsTextEditorState.cpp
content/xul/content/src/nsXULElement.cpp
content/xul/content/src/nsXULElement.h
content/xul/document/src/nsXULPrototypeDocument.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMWindowUtils.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsGlobalWindowCommands.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/base/nsPIDOMWindow.h
dom/indexedDB/IDBFactory.cpp
dom/indexedDB/IndexedDatabaseManager.cpp
dom/ipc/ContentParent.cpp
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginInstance.h
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginHost.h
dom/plugins/base/nsPluginTags.cpp
dom/plugins/base/nsPluginTags.h
dom/plugins/ipc/PluginModuleChild.cpp
editor/libeditor/base/nsEditor.cpp
editor/libeditor/base/nsEditor.h
editor/libeditor/html/nsHTMLEditRules.cpp
editor/libeditor/html/nsHTMLEditor.cpp
editor/libeditor/html/nsHTMLEditor.h
editor/libeditor/html/nsHTMLEditorStyle.cpp
editor/libeditor/text/nsPlaintextEditor.cpp
editor/libeditor/text/nsTextEditRules.cpp
gfx/angle/Makefile.in
gfx/angle/src/libEGL/Makefile.in
gfx/angle/src/libGLESv2/Makefile.in
gfx/gl/EGLUtils.h
gfx/gl/GLContext.cpp
gfx/gl/GLContextProviderEGL.cpp
gfx/gl/GLContextProviderGLX.cpp
gfx/gl/GLXLibrary.h
gfx/layers/opengl/ImageLayerOGL.cpp
gfx/thebes/gfxPlatformGtk.cpp
gfx/thebes/gfxPlatformGtk.h
ipc/testshell/XPCShellEnvironment.cpp
js/src/Makefile.in
js/src/MemoryMetrics.cpp
js/src/config/autoconf.mk.in
js/src/configure.in
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/frontend/Parser.cpp
js/src/gc/Barrier.h
js/src/ion/CodeGenerator.cpp
js/src/ion/IonCaches.cpp
js/src/ion/IonCaches.h
js/src/ion/VMFunctions.h
js/src/jit-test/jit_test.py
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsarray.h
js/src/jsatom.cpp
js/src/jsatominlines.h
js/src/jsclass.h
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jscompartment.cpp
js/src/jscompartment.h
js/src/jsdate.cpp
js/src/jsdbgapi.cpp
js/src/jsexn.cpp
js/src/jsfriendapi.cpp
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsfuninlines.h
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsgcinlines.h
js/src/jsgcmark.cpp
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/jsinterpinlines.h
js/src/jsiter.cpp
js/src/jsiter.h
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/json.cpp
js/src/jsopcode.cpp
js/src/jsproxy.cpp
js/src/jspubtd.h
js/src/jsreflect.cpp
js/src/jsscope.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsscriptinlines.h
js/src/jsstr.cpp
js/src/jstypedarray.cpp
js/src/jsweakmap.cpp
js/src/jswrapper.cpp
js/src/jsxml.cpp
js/src/methodjit/InvokeHelpers.cpp
js/src/methodjit/MonoIC.cpp
js/src/methodjit/PolyIC.cpp
js/src/methodjit/StubCalls.cpp
js/src/shell/js.cpp
js/src/vm/ArgumentsObject.cpp
js/src/vm/Debugger.cpp
js/src/vm/GlobalObject.cpp
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpObject.h
js/src/vm/Stack-inl.h
js/xpconnect/shell/xpcshell.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/qsgen.py
layout/base/crashtests/crashtests.list
layout/generic/nsFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/mathml/nsMathMLChar.cpp
layout/reftests/bugs/reftest.list
mobile/android/base/AndroidManifest.xml.in
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/Makefile.in
modules/libpref/src/init/all.js
netwerk/cache/nsCacheService.cpp
netwerk/cache/nsCacheService.h
netwerk/cache/nsDiskCacheDeviceSQL.cpp
netwerk/cache/nsDiskCacheDeviceSQL.h
security/manager/boot/src/nsSecureBrowserUIImpl.cpp
security/manager/boot/src/nsSecureBrowserUIImpl.h
security/manager/ssl/src/nsNSSIOLayer.cpp
security/manager/ssl/src/nsNSSIOLayer.h
testing/mochitest/runtests.py
testing/testsuite-targets.mk
toolkit/components/telemetry/TelemetryHistograms.h
toolkit/components/telemetry/TelemetryPing.js
toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
toolkit/content/license.html
toolkit/devtools/debugger/tests/unit/test_framebindings-01.js
toolkit/mozapps/update/nsUpdateService.js
toolkit/mozapps/update/test/unit/head_update.js.in
tools/elf-dynstr-gc/Makefile.in
tools/elf-dynstr-gc/elf-gc-dynstr.c
tools/leaky/LibPreload.cpp
tools/leaky/Makefile.in
tools/leaky/Makefile.linux
tools/leaky/ShowLibs.cpp
tools/leaky/TestLeaky.cpp
tools/leaky/TestPreload.cpp
tools/leaky/TestPreload.h
tools/leaky/bfd.cpp
tools/leaky/close-over.gif
tools/leaky/close.gif
tools/leaky/coff.cpp
tools/leaky/config.h
tools/leaky/dict.cpp
tools/leaky/dict.h
tools/leaky/elf.cpp
tools/leaky/leaky.cpp
tools/leaky/leaky.css
tools/leaky/leaky.h
tools/leaky/leaky.html
tools/leaky/leaky.js
tools/leaky/libmalloc.cpp
tools/leaky/libmalloc.h
tools/leaky/open-over.gif
tools/leaky/open.gif
tools/leaky/strset.cpp
tools/leaky/strset.h
view/public/nsIView.h
view/src/nsView.cpp
view/src/nsView.h
view/src/nsViewManager.cpp
widget/android/GfxInfo.cpp
widget/android/nsWindow.cpp
widget/gtk2/nsDragService.cpp
widget/gtk2/nsDragService.h
widget/gtk2/nsWindow.cpp
widget/gtk2/nsWindow.h
widget/nsIDragSessionGTK.h
xpcom/base/nsMemoryReporterManager.cpp
xpcom/ds/nsObserverList.cpp
xpcom/ds/nsObserverList.h
xpcom/ds/nsObserverService.cpp
xpcom/ds/nsObserverService.h
--- a/accessible/src/atk/ApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/ApplicationAccessibleWrap.cpp
@@ -685,24 +685,25 @@ ApplicationAccessibleWrap::Unload()
         sGail.shutdown = NULL;
     }
     // if (sATKLib) {
     //     PR_UnloadLibrary(sATKLib);
     //     sATKLib = nsnull;
     // }
 }
 
-NS_IMETHODIMP
-ApplicationAccessibleWrap::GetName(nsAString& aName)
+ENameValueFlag
+ApplicationAccessibleWrap::Name(nsString& aName)
 {
   // ATK doesn't provide a way to obtain an application name (for example,
   // Firefox or Thunderbird) like IA2 does. Thus let's return an application
   // name as accessible name that was used to get a branding name (for example,
   // Minefield aka nightly Firefox or Daily aka nightly Thunderbird).
-  return GetAppName(aName);
+  GetAppName(aName);
+  return eNameOK;
 }
 
 NS_IMETHODIMP
 ApplicationAccessibleWrap::GetNativeInterface(void** aOutAccessible)
 {
     *aOutAccessible = nsnull;
 
     if (!mAtkObject) {
--- a/accessible/src/atk/ApplicationAccessibleWrap.h
+++ b/accessible/src/atk/ApplicationAccessibleWrap.h
@@ -52,18 +52,17 @@ public:
 public:
     ApplicationAccessibleWrap();
     virtual ~ApplicationAccessibleWrap();
 
     // nsAccessNode
     virtual bool Init();
 
     // nsAccessible
-    NS_IMETHOD GetName(nsAString &aName);
-
+    virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
     virtual bool AppendChild(nsAccessible* aChild);
     virtual bool RemoveChild(nsAccessible* aChild);
 
     // return the atk object for app root accessible
     NS_IMETHOD GetNativeInterface(void **aOutAccessible);
 };
 
 #endif   /* __NS_APP_ROOT_ACCESSIBLE_H__ */
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -673,35 +673,31 @@ finalizeCB(GObject *aObj)
                    (sMaiAtkObjCreated-sMaiAtkObjDeleted)));
 
     // call parent finalize function
     // finalize of GObjectClass will unref the accessible parent if has
     if (G_OBJECT_CLASS (parent_class)->finalize)
         G_OBJECT_CLASS (parent_class)->finalize(aObj);
 }
 
-const gchar *
-getNameCB(AtkObject *aAtkObj)
+const gchar*
+getNameCB(AtkObject* aAtkObj)
 {
-    nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
-    if (!accWrap) {
-        return nsnull;
-    }
+  nsAccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
+  if (!accWrap)
+    return nsnull;
 
-    /* nsIAccessible is responsible for the non-NULL name */
-    nsAutoString uniName;
-    nsresult rv = accWrap->GetName(uniName);
-    NS_ENSURE_SUCCESS(rv, nsnull);
+  nsAutoString uniName;
+  accWrap->Name(uniName);
 
-    NS_ConvertUTF8toUTF16 objName(aAtkObj->name);
-    if (!uniName.Equals(objName)) {
-        atk_object_set_name(aAtkObj,
-                            NS_ConvertUTF16toUTF8(uniName).get());
-    }
-    return aAtkObj->name;
+  NS_ConvertUTF8toUTF16 objName(aAtkObj->name);
+  if (!uniName.Equals(objName))
+    atk_object_set_name(aAtkObj, NS_ConvertUTF16toUTF8(uniName).get());
+
+  return aAtkObj->name;
 }
 
 const gchar *
 getDescriptionCB(AtkObject *aAtkObj)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
     if (!accWrap || accWrap->IsDefunct())
         return nsnull;
@@ -1038,18 +1034,18 @@ nsAccessibleWrap::FirePlatformEvent(AccE
             nsRefPtr<AccEvent> stateChangeEvent =
               new AccStateChangeEvent(accessible, states::FOCUSED, true);
             return FireAtkStateChangeEvent(stateChangeEvent, atkObj);
         }
       } break;
 
     case nsIAccessibleEvent::EVENT_NAME_CHANGE:
       {
-        nsString newName;
-        accessible->GetName(newName);
+        nsAutoString newName;
+        accessible->Name(newName);
         NS_ConvertUTF16toUTF8 utf8Name(newName);
         if (!atkObj->name || !utf8Name.Equals(atkObj->name))
           atk_object_set_name(atkObj, utf8Name.get());
 
         break;
       }
     case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
       {
--- a/accessible/src/base/FocusManager.h
+++ b/accessible/src/base/FocusManager.h
@@ -206,17 +206,17 @@ private:
   }
 
 #define A11YDEBUG_FOCUS_LOG_ACCESSIBLE(aAccessible)                            \
   printf("accessible: %p; ", (void*)aAccessible);                              \
   if (aAccessible) {                                                           \
     nsAutoString role;                                                         \
     GetAccService()->GetStringRole(aAccessible->Role(), role);                 \
     nsAutoString name;                                                         \
-    aAccessible->GetName(name);                                                \
+    aAccessible->Name(name);                                                   \
     printf(" role: %s, name: %s; ", NS_ConvertUTF16toUTF8(role).get(),         \
            NS_ConvertUTF16toUTF8(name).get());                                 \
     A11YDEBUG_FOCUS_LOG_DOMNODE(aAccessible->GetNode())                        \
   }
 
 // Public macros
 #define A11YDEBUG_FOCUS_LOG_DOMTARGET(aMsg, aTarget)                           \
   A11YDEBUG_FOCUS_STARTBLOCK                                                   \
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -109,9 +109,25 @@ LOCAL_INCLUDES += \
   -I$(srcdir)/../../../layout/style \
   -I$(srcdir)/../../../layout/xul/base/src \
   $(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 LOCAL_INCLUDES += \
   -I$(srcdir)/../atk \
   $(NULL)
+else
+ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
+LOCAL_INCLUDES += \
+  -I$(srcdir)/../msaa \
+  $(NULL)
+else
+ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
+LOCAL_INCLUDES += \
+  -I$(srcdir)/../mac \
+  $(NULL)
+else
+LOCAL_INCLUDES += \
+  -I$(srcdir)/../other \
+  $(NULL)
 endif
+endif
+endif
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -204,19 +204,18 @@ nsAccessible::nsAccessible(nsIContent* a
             (void*)static_cast<nsIAccessible*>(this), (void*)aNode,
             (void*)shell.get());
     nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
     if (content) {
       printf(" Con: %s@%p",
              NS_ConvertUTF16toUTF8(content->NodeInfo()->QualifiedName()).get(),
              (void *)content.get());
       nsAutoString buf;
-      if (NS_SUCCEEDED(GetName(buf))) {
-        printf(" Name:[%s]", NS_ConvertUTF16toUTF8(buf).get());
-       }
+      Name(buf);
+      printf(" Name:[%s]", NS_ConvertUTF16toUTF8(buf).get());
      }
      printf("\n");
    }
 #endif
 }
 
 //-----------------------------------------------------
 // destruction
@@ -273,55 +272,62 @@ nsAccessible::GetLanguage(nsAString& aLa
 NS_IMETHODIMP
 nsAccessible::GetName(nsAString& aName)
 {
   aName.Truncate();
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
+  nsAutoString name;
+  Name(name);
+  aName.Assign(name);
+
+  return NS_OK;
+}
+
+ENameValueFlag
+nsAccessible::Name(nsString& aName)
+{
+  aName.Truncate();
+
   GetARIAName(aName);
   if (!aName.IsEmpty())
-    return NS_OK;
+    return eNameOK;
 
   nsCOMPtr<nsIXBLAccessible> xblAccessible(do_QueryInterface(mContent));
   if (xblAccessible) {
     xblAccessible->GetAccessibleName(aName);
     if (!aName.IsEmpty())
-      return NS_OK;
+      return eNameOK;
   }
 
   nsresult rv = GetNameInternal(aName);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   if (!aName.IsEmpty())
-    return NS_OK;
+    return eNameOK;
 
   // In the end get the name from tooltip.
-  nsIAtom *tooltipAttr = nsnull;
-
-  if (mContent->IsHTML())
-    tooltipAttr = nsGkAtoms::title;
-  else if (mContent->IsXUL())
-    tooltipAttr = nsGkAtoms::tooltiptext;
-  else
-    return NS_OK;
-
-  // XXX: if CompressWhiteSpace worked on nsAString we could avoid a copy.
-  nsAutoString name;
-  if (mContent->GetAttr(kNameSpaceID_None, tooltipAttr, name)) {
-    name.CompressWhitespace();
-    aName = name;
-    return NS_OK_NAME_FROM_TOOLTIP;
+  if (mContent->IsHTML()) {
+    if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName)) {
+      aName.CompressWhitespace();
+      return eNameFromTooltip;
+    }
+  } else if (mContent->IsXUL()) {
+    if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext, aName)) {
+      aName.CompressWhitespace();
+      return eNameFromTooltip;
+    }
+  } else {
+    return eNameOK;
   }
 
   if (rv != NS_OK_EMPTY_NAME)
     aName.SetIsVoid(true);
 
-  return NS_OK;
+  return eNameOK;
 }
 
 NS_IMETHODIMP
 nsAccessible::GetDescription(nsAString& aDescription)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
@@ -359,17 +365,17 @@ nsAccessible::Description(nsString& aDes
                                                      &aDescription);
       }
 
       if (aDescription.IsEmpty()) {
         nsIAtom *descAtom = isXUL ? nsGkAtoms::tooltiptext :
                                     nsGkAtoms::title;
         if (mContent->GetAttr(kNameSpaceID_None, descAtom, aDescription)) {
           nsAutoString name;
-          GetName(name);
+          Name(name);
           if (name.IsEmpty() || aDescription == name)
             // Don't use tooltip for a description if this object
             // has no name or the tooltip is the same as the name
             aDescription.Truncate();
         }
       }
     }
     aDescription.CompressWhitespace();
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -60,19 +60,35 @@ class EmbeddedObjCollector;
 class KeyBinding;
 class nsAccessible;
 class nsHyperTextAccessible;
 class nsHTMLImageAccessible;
 class nsHTMLImageMapAccessible;
 class nsHTMLLIAccessible;
 struct nsRoleMapEntry;
 class Relation;
+
 namespace mozilla {
 namespace a11y {
 class TableAccessible;
+
+/**
+ * Name type flags.
+ */
+enum ENameValueFlag {
+  /**
+   * Name either
+   *  a) present (not empty): !name.IsEmpty()
+   *  b) no name (was missed): name.IsVoid()
+   *  c) was left empty by the author on demand: name.IsEmpty() && !name.IsVoid()
+   */
+ eNameOK,
+ eNameFromTooltip // Tooltip was used as a name
+};
+
 }
 }
 class nsTextAccessible;
 class nsXULTreeAccessible;
 
 struct nsRect;
 class nsIContent;
 class nsIFrame;
@@ -136,16 +152,21 @@ public:
   virtual void Description(nsString& aDescription);
 
   /**
    * Get the value of this accessible.
    */
   virtual void Value(nsString& aValue);
 
   /**
+   * Get the name of this accessible.
+   */
+  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
+
+  /**
    * Return DOM node associated with this accessible.
    */
   inline already_AddRefed<nsIDOMNode> DOMNode() const
   {
     nsIDOMNode *DOMNode = nsnull;
     if (GetNode())
       CallQueryInterface(GetNode(), &DOMNode);
     return DOMNode;
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -208,36 +208,36 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
 }
 
 NS_IMPL_ADDREF_INHERITED(nsDocAccessible, nsHyperTextAccessible)
 NS_IMPL_RELEASE_INHERITED(nsDocAccessible, nsHyperTextAccessible)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessible
 
-NS_IMETHODIMP
-nsDocAccessible::GetName(nsAString& aName)
+ENameValueFlag
+nsDocAccessible::Name(nsString& aName)
 {
-  nsresult rv = NS_OK;
   aName.Truncate();
+
   if (mParent) {
-    rv = mParent->GetName(aName); // Allow owning iframe to override the name
+    mParent->Name(aName); // Allow owning iframe to override the name
   }
   if (aName.IsEmpty()) {
     // Allow name via aria-labelledby or title attribute
-    rv = nsAccessible::GetName(aName);
+    nsAccessible::Name(aName);
   }
   if (aName.IsEmpty()) {
-    rv = GetTitle(aName);   // Try title element
+    GetTitle(aName);   // Try title element
   }
   if (aName.IsEmpty()) {   // Last resort: use URL
-    rv = GetURL(aName);
+    GetURL(aName);
   }
-
-  return rv;
+ 
+  return eNameOK;
 }
 
 // nsAccessible public method
 role
 nsDocAccessible::NativeRole()
 {
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
     nsCoreUtils::GetDocShellTreeItemFor(mDocument);
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -87,17 +87,16 @@ class nsDocAccessible : public nsHyperTe
 public:
   using nsAccessible::GetParent;
 
   nsDocAccessible(nsIDocument *aDocument, nsIContent *aRootContent,
                   nsIPresShell* aPresShell);
   virtual ~nsDocAccessible();
 
   // nsIAccessible
-  NS_IMETHOD GetName(nsAString& aName);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
   NS_IMETHOD TakeFocus(void);
 
   // nsIScrollPositionListener
   virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) {}
   virtual void ScrollPositionDidChange(nscoord aX, nscoord aY);
 
   // nsIDocumentObserver
@@ -106,16 +105,17 @@ public:
   // nsAccessNode
   virtual bool Init();
   virtual void Shutdown();
   virtual nsIFrame* GetFrame() const;
   virtual nsINode* GetNode() const { return mDocument; }
   virtual nsIDocument* GetDocumentNode() const { return mDocument; }
 
   // nsAccessible
+  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual void Description(nsString& aDescription);
   virtual nsAccessible* FocusedChild();
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
   virtual void ApplyARIAState(PRUint64* aState);
 
   virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
 
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -105,37 +105,32 @@ nsRootAccessible::
   mFlags |= eRootAccessible;
 }
 
 nsRootAccessible::~nsRootAccessible()
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsIAccessible
+// nsAccessible
 
-/* readonly attribute AString name; */
-NS_IMETHODIMP
-nsRootAccessible::GetName(nsAString& aName)
+ENameValueFlag
+nsRootAccessible::Name(nsString& aName)
 {
   aName.Truncate();
 
-  if (!mDocument) {
-    return NS_ERROR_FAILURE;
-  }
-
   if (mRoleMapEntry) {
-    nsAccessible::GetName(aName);
-    if (!aName.IsEmpty()) {
-      return NS_OK;
-    }
+    nsAccessible::Name(aName);
+    if (!aName.IsEmpty())
+      return eNameOK;
   }
 
   nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(mDocument);
-  return document->GetTitle(aName);
+  document->GetTitle(aName);
+  return eNameOK;
 }
 
 role
 nsRootAccessible::NativeRole()
 {
   // If it's a <dialog> or <wizard>, use roles::DIALOG instead
   dom::Element *root = mDocument->GetRootElement();
   if (root) {
--- a/accessible/src/base/nsRootAccessible.h
+++ b/accessible/src/base/nsRootAccessible.h
@@ -57,26 +57,24 @@ class nsRootAccessible : public nsDocAcc
 {
   NS_DECL_ISUPPORTS_INHERITED
 
 public:
   nsRootAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
                    nsIPresShell* aPresShell);
   virtual ~nsRootAccessible();
 
-  // nsIAccessible
-  NS_IMETHOD GetName(nsAString& aName);
-
   // nsIDOMEventListener
   NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
 
   // nsAccessNode
   virtual void Shutdown();
 
   // nsAccessible
+  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual Relation RelationByType(PRUint32 aType);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
 
   // nsRootAccessible
   nsCaretAccessible* GetCaretAccessible();
 
   /**
--- a/accessible/src/base/nsTextEquivUtils.cpp
+++ b/accessible/src/base/nsTextEquivUtils.cpp
@@ -43,16 +43,18 @@
 #include "AccIterator.h"
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 
 #include "nsIDOMXULLabeledControlEl.h"
 
 #include "nsArrayUtils.h"
 
+using namespace mozilla::a11y;
+
 #define NS_OK_NO_NAME_CLAUSE_HANDLED \
 NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 0x24)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsTextEquivUtils. Public.
 
 nsresult
 nsTextEquivUtils::GetNameFromSubtree(nsAccessible *aAccessible,
@@ -222,29 +224,26 @@ nsTextEquivUtils::AppendFromAccessible(n
   //XXX: is it necessary to care the accessible is not a document?
   if (aAccessible->IsContent()) {
     nsresult rv = AppendTextEquivFromTextContent(aAccessible->GetContent(),
                                                  aString);
     if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
       return rv;
   }
 
-  nsAutoString text;
-  nsresult rv = aAccessible->GetName(text);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   bool isEmptyTextEquiv = true;
 
   // If the name is from tooltip then append it to result string in the end
   // (see h. step of name computation guide).
-  if (rv != NS_OK_NAME_FROM_TOOLTIP)
+  nsAutoString text;
+  if (aAccessible->Name(text) != eNameFromTooltip)
     isEmptyTextEquiv = !AppendString(aString, text);
 
   // Implementation of f. step.
-  rv = AppendFromValue(aAccessible, aString);
+  nsresult rv = AppendFromValue(aAccessible, aString);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
     isEmptyTextEquiv = false;
 
   // Implementation of g) step of text equivalent computation guide. Go down
   // into subtree if accessible allows "text equivalent from subtree rule" or
   // it's not root and not control.
--- a/accessible/src/generic/ApplicationAccessible.cpp
+++ b/accessible/src/generic/ApplicationAccessible.cpp
@@ -91,42 +91,44 @@ ApplicationAccessible::GetNextSibling(ns
 NS_IMETHODIMP
 ApplicationAccessible::GetPreviousSibling(nsIAccessible** aPreviousSibling)
 {
   NS_ENSURE_ARG_POINTER(aPreviousSibling);
   *aPreviousSibling = nsnull;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-ApplicationAccessible::GetName(nsAString& aName)
+ENameValueFlag
+ApplicationAccessible::Name(nsString& aName)
 {
   aName.Truncate();
 
   nsCOMPtr<nsIStringBundleService> bundleService =
     mozilla::services::GetStringBundleService();
 
   NS_ASSERTION(bundleService, "String bundle service must be present!");
-  NS_ENSURE_STATE(bundleService);
+  if (!bundleService)
+    return eNameOK;
 
   nsCOMPtr<nsIStringBundle> bundle;
   nsresult rv = bundleService->CreateBundle("chrome://branding/locale/brand.properties",
                                             getter_AddRefs(bundle));
-  NS_ENSURE_SUCCESS(rv, rv);
+  if (NS_FAILED(rv))
+    return eNameOK;
 
   nsXPIDLString appName;
   rv = bundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
                                  getter_Copies(appName));
   if (NS_FAILED(rv) || appName.IsEmpty()) {
     NS_WARNING("brandShortName not found, using default app name");
     appName.AssignLiteral("Gecko based application");
   }
 
   aName.Assign(appName);
-  return NS_OK;
+  return eNameOK;
 }
 
 void
 ApplicationAccessible::Description(nsString& aDescription)
 {
   aDescription.Truncate();
 }
 
--- a/accessible/src/generic/ApplicationAccessible.h
+++ b/accessible/src/generic/ApplicationAccessible.h
@@ -74,17 +74,16 @@ public:
   NS_SCRIPTABLE NS_IMETHOD GetDocument(nsIAccessibleDocument** aDocument);
   NS_SCRIPTABLE NS_IMETHOD GetRootDocument(nsIAccessibleDocument** aRootDocument);
   NS_SCRIPTABLE NS_IMETHOD ScrollTo(PRUint32 aScrollType);
   NS_SCRIPTABLE NS_IMETHOD ScrollToPoint(PRUint32 aCoordinateType, PRInt32 aX, PRInt32 aY);
   NS_SCRIPTABLE NS_IMETHOD GetLanguage(nsAString& aLanguage);
   NS_IMETHOD GetParent(nsIAccessible **aParent);
   NS_IMETHOD GetNextSibling(nsIAccessible **aNextSibling);
   NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
-  NS_IMETHOD GetName(nsAString &aName);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
   NS_IMETHOD GroupPosition(PRInt32 *aGroupLevel, PRInt32 *aSimilarItemsInGroup,
                            PRInt32 *aPositionInGroup);
   NS_IMETHOD GetBounds(PRInt32 *aX, PRInt32 *aY,
                        PRInt32 *aWidth, PRInt32 *aHeight);
   NS_IMETHOD SetSelected(bool aIsSelected);
   NS_IMETHOD TakeSelection();
   NS_IMETHOD TakeFocus();
@@ -96,16 +95,17 @@ public:
   NS_DECL_NSIACCESSIBLEAPPLICATION
 
   // nsAccessNode
   virtual bool Init();
   virtual void Shutdown();
   virtual bool IsPrimaryForNode() const;
 
   // nsAccessible
+  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual void ApplyARIAState(PRUint64* aState);
   virtual void Description(nsString& aDescription);
   virtual void Value(nsString& aValue);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 State();
   virtual PRUint64 NativeState();
   virtual Relation RelationByType(PRUint32 aRelType);
 
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -589,17 +589,17 @@ nsHTMLComboboxAccessible::Description(ns
 }
 
 void
 nsHTMLComboboxAccessible::Value(nsString& aValue)
 {
   // Use accessible name of selected option.
   nsAccessible* option = SelectedOption();
   if (option)
-    option->GetName(aValue);
+    option->Name(aValue);
 }
 
 PRUint8
 nsHTMLComboboxAccessible::ActionCount()
 {
   return 1;
 }
 
--- a/accessible/src/html/nsHTMLTextAccessible.cpp
+++ b/accessible/src/html/nsHTMLTextAccessible.cpp
@@ -63,22 +63,22 @@ using namespace mozilla::a11y;
 nsHTMLTextAccessible::
   nsHTMLTextAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
   nsTextAccessibleWrap(aContent, aDoc)
 {
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLTextAccessible, nsTextAccessible)
 
-NS_IMETHODIMP
-nsHTMLTextAccessible::GetName(nsAString& aName)
+ENameValueFlag
+nsHTMLTextAccessible::Name(nsString& aName)
 {
   // Text node, ARIA can't be used.
   aName = mText;
-  return NS_OK;
+  return eNameOK;
 }
 
 role
 nsHTMLTextAccessible::NativeRole()
 {
   nsIFrame *frame = GetFrame();
   // Don't return on null frame -- we still return a role
   // after accessible is shutdown/DEFUNCT
@@ -343,35 +343,32 @@ bool
 nsHTMLListBulletAccessible::IsPrimaryForNode() const
 {
   return false;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLListBulletAccessible: nsAccessible
 
-NS_IMETHODIMP
-nsHTMLListBulletAccessible::GetName(nsAString &aName)
+ENameValueFlag
+nsHTMLListBulletAccessible::Name(nsString &aName)
 {
   aName.Truncate();
 
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
   // Native anonymous content, ARIA can't be used. Get list bullet text.
   nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
   NS_ASSERTION(blockFrame, "No frame for list item!");
   if (blockFrame) {
     blockFrame->GetBulletText(aName);
 
     // Append space otherwise bullets are jammed up against list text.
     aName.Append(' ');
   }
 
-  return NS_OK;
+  return eNameOK;
 }
 
 role
 nsHTMLListBulletAccessible::NativeRole()
 {
   return roles::STATICTEXT;
 }
 
--- a/accessible/src/html/nsHTMLTextAccessible.h
+++ b/accessible/src/html/nsHTMLTextAccessible.h
@@ -50,20 +50,18 @@
 class nsHTMLTextAccessible : public nsTextAccessibleWrap
 {
 public:
   nsHTMLTextAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIAccessible
-  NS_IMETHOD GetName(nsAString& aName);
-
   // nsAccessible
+  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
 };
 
 /**
  * Used for HTML hr element.
  */
@@ -124,23 +122,21 @@ public:
 /**
  * Used for bullet of HTML list item element (for example, HTML li).
  */
 class nsHTMLListBulletAccessible : public nsLeafAccessible
 {
 public:
   nsHTMLListBulletAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
 
-  // nsIAccessible
-  NS_IMETHOD GetName(nsAString& aName);
-
   // nsAccessNode
   virtual bool IsPrimaryForNode() const;
 
   // nsAccessible
+  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
   virtual void AppendTextTo(nsAString& aText, PRUint32 aStartOffset = 0,
                             PRUint32 aLength = PR_UINT32_MAX);
 };
 
 /**
  * Used for HTML list (like HTML ul).
--- a/accessible/src/mac/Makefile.in
+++ b/accessible/src/mac/Makefile.in
@@ -57,17 +57,16 @@ CMMSRCS = nsAccessNodeWrap.mm \
           mozActionElements.mm \
           mozTextAccessible.mm \
           mozHTMLAccessible.mm \
           MacUtils.mm \
           $(NULL)
 
 
 EXPORTS = \
-  ApplicationAccessibleWrap.h \
   ARIAGridAccessibleWrap.h \
   nsAccessNodeWrap.h \
   nsTextAccessibleWrap.h \
   nsAccessibleWrap.h \
   nsDocAccessibleWrap.h \
   nsRootAccessibleWrap.h \
   nsXULMenuAccessibleWrap.h \
   nsXULListboxAccessibleWrap.h \
--- a/accessible/src/mac/mozAccessible.mm
+++ b/accessible/src/mac/mozAccessible.mm
@@ -509,17 +509,17 @@ GetNativeFromGeckoAccessible(nsIAccessib
   return NSAccessibilityRoleDescription([self role], subrole);
 }
 
 - (NSString*)title
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   nsAutoString title;
-  mGeckoAccessible->GetName (title);
+  mGeckoAccessible->Name(title);
   return title.IsEmpty() ? nil : [NSString stringWithCharacters:title.BeginReading() length:title.Length()];
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (id)value
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
--- a/accessible/src/msaa/Makefile.in
+++ b/accessible/src/msaa/Makefile.in
@@ -73,17 +73,16 @@ CPPSRCS = \
   ia2AccessibleRelation.cpp \
   CAccessibleTable.cpp \
   CAccessibleTableCell.cpp \
   CAccessibleValue.cpp \
   Compatibility.cpp \
   $(NULL)
 
 EXPORTS = \
-  ApplicationAccessibleWrap.h \
   ARIAGridAccessibleWrap.h \
   nsAccessNodeWrap.h \
   nsAccessibleWrap.h \
   nsTextAccessibleWrap.h \
   nsDocAccessibleWrap.h \
   nsRootAccessibleWrap.h \
   nsHTMLWin32ObjectAccessible.h \
   nsXULMenuAccessibleWrap.h \
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -280,19 +280,17 @@ STDMETHODIMP nsAccessibleWrap::get_accNa
   nsAccessible* xpAccessible = GetXPAccessibleFor(varChild);
   if (!xpAccessible)
     return E_INVALIDARG;
 
   if (xpAccessible->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoString name;
-  nsresult rv = xpAccessible->GetName(name);
-  if (NS_FAILED(rv))
-    return GetHRESULT(rv);
+  xpAccessible->Name(name);
 
   // The name was not provided, e.g. no alt attribute for an image. A screen
   // reader may choose to invent its own accessible name, e.g. from an image src
   // attribute. Refer to NS_OK_EMPTY_NAME return value.
   if (name.IsVoid())
     return S_FALSE;
 
   *pszName = ::SysAllocStringLen(name.get(), name.Length());
--- a/accessible/src/msaa/nsXULMenuAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsXULMenuAccessibleWrap.cpp
@@ -33,36 +33,36 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsXULMenuAccessibleWrap.h"
 #include "nsINameSpaceManager.h"
 
+using namespace mozilla::a11y;
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULMenuAccessibleWrap
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULMenuitemAccessibleWrap::
   nsXULMenuitemAccessibleWrap(nsIContent* aContent, nsDocAccessible* aDoc) :
   nsXULMenuitemAccessible(aContent, aDoc)
 {
 }
 
-NS_IMETHODIMP
-nsXULMenuitemAccessibleWrap::GetName(nsAString& aName)
+ENameValueFlag
+nsXULMenuitemAccessibleWrap::Name(nsString& aName)
 {
   // XXX This should be done in get_accName() so that nsIAccessible::GetName()]
   // provides the same results on all platforms
-  nsresult rv = nsXULMenuitemAccessible::GetName(aName);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
+  nsXULMenuitemAccessible::Name(aName);
+  if (aName.IsEmpty())
+    return eNameOK;
   
   nsAutoString accel;
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::acceltext, accel);
-  if (!accel.IsEmpty()) {
+  if (!accel.IsEmpty())
     aName += NS_LITERAL_STRING("\t") + accel;
-  }
 
-  return NS_OK;
+  return eNameOK;
 }
--- a/accessible/src/msaa/nsXULMenuAccessibleWrap.h
+++ b/accessible/src/msaa/nsXULMenuAccessibleWrap.h
@@ -42,12 +42,12 @@
 
 class nsXULMenuitemAccessibleWrap : public nsXULMenuitemAccessible
 {
 public:
   nsXULMenuitemAccessibleWrap(nsIContent* aContent, nsDocAccessible* aDoc);
   virtual ~nsXULMenuitemAccessibleWrap() {}
 
   // nsIAccessible
-  NS_IMETHOD GetName(nsAString& aName);
+  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
 };
 
 #endif
--- a/accessible/src/other/Makefile.in
+++ b/accessible/src/other/Makefile.in
@@ -49,17 +49,16 @@ LIBXUL_LIBRARY = 1
 
 CPPSRCS = \
   nsAccessNodeWrap.cpp \
   nsAccessibleWrap.cpp \
   nsRootAccessibleWrap.cpp \
   $(NULL)
 
 EXPORTS = \
-  ApplicationAccessibleWrap.h \
   ARIAGridAccessibleWrap.h \
   nsAccessNodeWrap.h \
   nsTextAccessibleWrap.h \
   nsAccessibleWrap.h \
   nsDocAccessibleWrap.h \
   nsRootAccessibleWrap.h \
   nsXULMenuAccessibleWrap.h \
   nsXULListboxAccessibleWrap.h \
--- a/accessible/src/xul/nsXULAlertAccessible.cpp
+++ b/accessible/src/xul/nsXULAlertAccessible.cpp
@@ -61,23 +61,23 @@ nsXULAlertAccessible::NativeRole()
 }
 
 PRUint64
 nsXULAlertAccessible::NativeState()
 {
   return nsAccessible::NativeState() | states::ALERT;
 }
 
-NS_IMETHODIMP
-nsXULAlertAccessible::GetName(nsAString& aName)
+ENameValueFlag
+nsXULAlertAccessible::Name(nsString& aName)
 {
   // Screen readers need to read contents of alert, not the accessible name.
   // If we have both some screen readers will read the alert twice.
   aName.Truncate();
-  return NS_OK;
+  return eNameOK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Widgets
 
 bool
 nsXULAlertAccessible::IsWidget() const
 {
--- a/accessible/src/xul/nsXULAlertAccessible.h
+++ b/accessible/src/xul/nsXULAlertAccessible.h
@@ -46,20 +46,18 @@
 
 class nsXULAlertAccessible : public nsAccessibleWrap
 {
 public:
   nsXULAlertAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
 
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIAccessible
-  NS_IMETHOD GetName(nsAString& aName);
-
   // nsAccessible
+  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
 
   // Widgets
   virtual bool IsWidget() const;
   virtual nsAccessible* ContainerWidget() const;
 };
 
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -1171,38 +1171,35 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXULTreeItemAccessible)
 NS_INTERFACE_MAP_END_INHERITING(nsXULTreeItemAccessibleBase)
 NS_IMPL_ADDREF_INHERITED(nsXULTreeItemAccessible, nsXULTreeItemAccessibleBase)
 NS_IMPL_RELEASE_INHERITED(nsXULTreeItemAccessible, nsXULTreeItemAccessibleBase)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeItemAccessible: nsIAccessible implementation
 
-NS_IMETHODIMP
-nsXULTreeItemAccessible::GetName(nsAString& aName)
+ENameValueFlag
+nsXULTreeItemAccessible::Name(nsString& aName)
 {
   aName.Truncate();
 
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
   GetCellName(mColumn, aName);
-  return NS_OK;
+  return eNameOK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeItemAccessible: nsAccessNode implementation
 
 bool
 nsXULTreeItemAccessible::Init()
 {
   if (!nsXULTreeItemAccessibleBase::Init())
     return false;
 
-  GetName(mCachedName);
+  Name(mCachedName);
   return true;
 }
 
 void
 nsXULTreeItemAccessible::Shutdown()
 {
   mColumn = nsnull;
   nsXULTreeItemAccessibleBase::Shutdown();
@@ -1230,17 +1227,17 @@ nsXULTreeItemAccessible::NativeRole()
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeItemAccessible: nsXULTreeItemAccessibleBase implementation
 
 void
 nsXULTreeItemAccessible::RowInvalidated(PRInt32 aStartColIdx,
                                         PRInt32 aEndColIdx)
 {
   nsAutoString name;
-  GetName(name);
+  Name(name);
 
   if (name != mCachedName) {
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, this);
     mCachedName = name;
   }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/xul/nsXULTreeAccessible.h
+++ b/accessible/src/xul/nsXULTreeAccessible.h
@@ -262,23 +262,22 @@ public:
                           nsAccessible* aParent, nsITreeBoxObject* aTree,
                           nsITreeView* aTreeView, PRInt32 aRow);
 
   // nsISupports and cycle collection
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULTreeItemAccessible,
                                            nsXULTreeItemAccessibleBase)
 
-  NS_IMETHOD GetName(nsAString& aName);
-
   // nsAccessNode
   virtual bool Init();
   virtual void Shutdown();
 
   // nsAccessible
+  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual mozilla::a11y::role NativeRole();
 
   // nsXULTreeItemAccessibleBase
   virtual void RowInvalidated(PRInt32 aStartColIdx, PRInt32 aEndColIdx);
 
 protected:
 
   // nsAccessible
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -652,38 +652,35 @@ nsXULTreeGridRowAccessible::Shutdown()
 // nsXULTreeGridRowAccessible: nsAccessible implementation
 
 role
 nsXULTreeGridRowAccessible::NativeRole()
 {
   return roles::ROW;
 }
 
-NS_IMETHODIMP
-nsXULTreeGridRowAccessible::GetName(nsAString& aName)
+ENameValueFlag
+nsXULTreeGridRowAccessible::Name(nsString& aName)
 {
   aName.Truncate();
 
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
   // XXX: the row name sholdn't be a concatenation of cell names (bug 664384).
   nsCOMPtr<nsITreeColumn> column = nsCoreUtils::GetFirstSensibleColumn(mTree);
   while (column) {
     if (!aName.IsEmpty())
       aName.AppendLiteral(" ");
 
     nsAutoString cellName;
     GetCellName(column, cellName);
     aName.Append(cellName);
 
     column = nsCoreUtils::GetNextSensibleColumn(column);
   }
 
-  return NS_OK;
+  return eNameOK;
 }
 
 nsAccessible*
 nsXULTreeGridRowAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
                                          EWhichChildAtPoint aWhichChild)
 {
   nsIFrame *frame = GetFrame();
   if (!frame)
@@ -839,35 +836,35 @@ NS_IMPL_RELEASE_INHERITED(nsXULTreeGridC
 // nsXULTreeGridCellAccessible: nsIAccessible implementation
 
 nsAccessible*
 nsXULTreeGridCellAccessible::FocusedChild()
 {
   return nsnull;
 }
 
-NS_IMETHODIMP
-nsXULTreeGridCellAccessible::GetName(nsAString& aName)
+ENameValueFlag
+nsXULTreeGridCellAccessible::Name(nsString& aName)
 {
   aName.Truncate();
 
-  if (IsDefunct() || !mTreeView)
-    return NS_ERROR_FAILURE;
+  if (!mTreeView)
+    return eNameOK;
 
   mTreeView->GetCellText(mRow, mColumn, aName);
 
   // If there is still no name try the cell value:
   // This is for graphical cells. We need tree/table view implementors to implement
   // FooView::GetCellValue to return a meaningful string for cases where there is
   // something shown in the cell (non-text) such as a star icon; in which case
   // GetCellValue for that cell would return "starred" or "flagged" for example.
   if (aName.IsEmpty())
     mTreeView->GetCellValue(mRow, mColumn, aName);
 
-  return NS_OK;
+  return eNameOK;
 }
 
 NS_IMETHODIMP
 nsXULTreeGridCellAccessible::GetBounds(PRInt32 *aX, PRInt32 *aY,
                                        PRInt32 *aWidth, PRInt32 *aHeight)
 {
   NS_ENSURE_ARG_POINTER(aX);
   *aX = 0;
--- a/accessible/src/xul/nsXULTreeGridAccessible.h
+++ b/accessible/src/xul/nsXULTreeGridAccessible.h
@@ -98,17 +98,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULTreeGridRowAccessible,
                                            nsXULTreeItemAccessibleBase)
 
   // nsAccessNode
   virtual void Shutdown();
 
   // nsAccessible
   virtual mozilla::a11y::role NativeRole();
-  NS_IMETHOD GetName(nsAString& aName);
+  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual nsAccessible* ChildAtPoint(PRInt32 aX, PRInt32 aY,
                                      EWhichChildAtPoint aWhichChild);
 
   virtual nsAccessible* GetChildAt(PRUint32 aIndex);
   virtual PRInt32 GetChildCount();
 
   // nsXULTreeItemAccessibleBase
   virtual nsAccessible* GetCellAccessible(nsITreeColumn *aColumn);
@@ -150,31 +150,31 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULTreeGridCellAccessible,
                                            nsLeafAccessible)
 
   // nsIAccessible
 
-  NS_IMETHOD GetName(nsAString& aName);
   NS_IMETHOD GetBounds(PRInt32 *aX, PRInt32 *aY,
                        PRInt32 *aWidth, PRInt32 *aHeight);
 
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 aIndex);
 
   // nsIAccessibleTableCell
   NS_DECL_NSIACCESSIBLETABLECELL
 
   // nsAccessNode
   virtual bool Init();
   virtual bool IsPrimaryForNode() const;
 
   // nsAccessible
+  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual nsAccessible* FocusedChild();
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
   virtual PRInt32 IndexInParent() const;
   virtual Relation RelationByType(PRUint32 aType);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
 
   // ActionAccessible
--- a/accessible/tests/mochitest/events/test_focus_general.xul
+++ b/accessible/tests/mochitest/events/test_focus_general.xul
@@ -68,17 +68,17 @@
       gQueue.push(new synthClick("popupbutton", new nofocusChecker()));
       // select first menu item ("item 1"), focus on menu item
       gQueue.push(new synthDownKey("popupbutton", new focusChecker("bp_item1")));
       // choose select menu item, focus gets back to menubutton
       gQueue.push(new synthEnterKey("bp_item1", new focusChecker("menubutton")));
       // show popup again for the next test
       gQueue.push(new synthClick("popupbutton", new nofocusChecker()));
 
-if (MAC) {
+if (!MAC) {
       // click menubutton of the 'menubutton' button while popup of button open.
       gQueue.push(new synthClick("mbb", new focusChecker("mbb"), { where: "right" }));
       // close popup, focus stays on menubutton, fire focus event
       gQueue.push(new synthEscapeKey("mbb", new focusChecker("mbb")));
       // click menubutton, open popup, focus stays on menubutton
       gQueue.push(new synthClick("mbb", new nofocusChecker(), { where: "right" }));
       // select first menu item ("item 1"), focus on menu item
       gQueue.push(new synthDownKey("mbb", new focusChecker("mbb_item1")));
--- a/accessible/tests/mochitest/tree/test_dochierarchy.html
+++ b/accessible/tests/mochitest/tree/test_dochierarchy.html
@@ -26,17 +26,17 @@
       getAccessible(window.parent.document, [nsIAccessibleDocument]) :
       getAccessible(document, [nsIAccessibleDocument]);
     var testDoc = getAccessible(document, [nsIAccessibleDocument]);
     var iframeDoc = getAccessible("iframe").firstChild.
       QueryInterface(nsIAccessibleDocument);
 
     is(root.parentDocument, null,
        "Wrong parent document of root accessible");
-    is(root.childDocumentCount, SEAMONKEY ? 1 : 3,
+    is(root.childDocumentCount, 1,
        "Wrong child document count of root accessible");
     is(root.getChildDocumentAt(0), tabDoc,
        "Wrong child document at index 0 of root accessible");
 
     is(tabDoc.parentDocument, root,
        "Wrong parent document of tab document");
     is(tabDoc.childDocumentCount, 1,
        "Wrong child document count of tab document");
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -430,17 +430,17 @@ pref("dom.mozBrowserFramesEnabled", true
 pref("dom.mozBrowserFramesWhitelist", "http://homescreen.gaiamobile.org,http://browser.gaiamobile.org");
 pref("dom.ipc.tabs.disabled", true);
 
 // Temporary permission hack for WebSMS
 pref("dom.sms.enabled", true);
 pref("dom.sms.whitelist", "file://,http://homescreen.gaiamobile.org,http://sms.gaiamobile.org");
 
 // Temporary permission hack for WebMobileConnection
-pref("dom.mobileconnection.whitelist", "http://homescreen.gaiamobile.org");
+pref("dom.mobileconnection.whitelist", "http://system.gaiamobile.org,http://homescreen.gaiamobile.org,http://dialer.gaiamobile.org");
 
 // Temporary permission hack for WebContacts
 pref("dom.mozContacts.enabled", true);
 pref("dom.mozContacts.whitelist", "http://dialer.gaiamobile.org,http://sms.gaiamobile.org");
 
 // WebSettings
 pref("dom.mozSettings.enabled", true);
 
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1040,40 +1040,32 @@ pref("services.sync.prefs.sync.security.
 pref("services.sync.prefs.sync.signon.rememberSignons", true);
 pref("services.sync.prefs.sync.spellchecker.dictionary", true);
 pref("services.sync.prefs.sync.xpinstall.whitelist.required", true);
 #endif
 
 // Disable the error console
 pref("devtools.errorconsole.enabled", false);
 
-// Enable the developer toolbar
-pref("devtools.toolbar.enabled", false);
-
 // Enable the Inspector
 pref("devtools.inspector.enabled", true);
 pref("devtools.inspector.htmlHeight", 112);
 pref("devtools.inspector.htmlPanelOpen", false);
 pref("devtools.inspector.sidebarOpen", false);
 pref("devtools.inspector.activeSidebar", "ruleview");
 
 // Enable the Layout View
 pref("devtools.layoutview.enabled", false);
 pref("devtools.layoutview.open", false);
 
 // Enable the Debugger
 pref("devtools.debugger.enabled", false);
-pref("devtools.debugger.remote-enabled", false);
-pref("devtools.debugger.remote-host", "localhost");
-pref("devtools.debugger.remote-port", 6000);
 
 // The default Debugger UI height
 pref("devtools.debugger.ui.height", 250);
-pref("devtools.debugger.ui.remote-win.width", 900);
-pref("devtools.debugger.ui.remote-win.height", 400);
 
 // Enable the style inspector
 pref("devtools.styleinspector.enabled", true);
 
 // Enable the Tilt inspector
 pref("devtools.tilt.enabled", true);
 pref("devtools.tilt.intro_transition", true);
 pref("devtools.tilt.outro_transition", true);
@@ -1086,24 +1078,18 @@ pref("devtools.scratchpad.enabled", true
 
 // Enable the Style Editor.
 pref("devtools.styleeditor.enabled", true);
 pref("devtools.styleeditor.transitions", true);
 
 // Enable tools for Chrome development.
 pref("devtools.chrome.enabled", false);
 
-// Display the introductory text
-pref("devtools.gcli.hideIntro", false);
-
-// How eager are we to show help: never=1, sometimes=2, always=3
-pref("devtools.gcli.eagerHelper", 2);
-
-// Do we allow the 'pref set' command
-pref("devtools.gcli.allowSet", false);
+// Disable the GCLI enhanced command line.
+pref("devtools.gcli.enable", false);
 
 // The last Web Console height. This is initially 0 which means that the Web
 // Console will use the default height next time it shows.
 // Change to -1 if you do not want the Web Console to remember its last height.
 pref("devtools.hud.height", 0);
 
 // Remember the Web Console position. Possible values:
 //   above - above the web page,
--- a/browser/base/content/browser-appmenu.inc
+++ b/browser/base/content/browser-appmenu.inc
@@ -171,45 +171,34 @@
             <menuitem id="appmenu_printSetup"
                       label="&printSetupCmd.label;"
                       command="cmd_pageSetup"/>
           </menupopup>
       </splitmenu>
       <menuseparator class="appmenu-menuseparator"/>
       <menu id="appmenu_webDeveloper"
             label="&appMenuWebDeveloper.label;">
-        <menupopup id="appmenu_webDeveloper_popup">
-          <menuitem id="appmenu_devToolbar"
-                    type="checkbox"
-                    autocheck="false"
-                    hidden="true"
-                    label="&devToolbarMenu.label;"
-                    command="Tools:DevToolbar"
-                    key="key_devToolbar"/>
+        <menupopup id="appmenu_webDeveloper_popup"
+                   onpopupshowing="onWebDeveloperMenuShowing();">
           <menuitem id="appmenu_webConsole"
                     label="&webConsoleCmd.label;"
                     type="checkbox"
                     command="Tools:WebConsole"
                     key="key_webConsole"/>
           <menuitem id="appmenu_pageInspect"
                     hidden="true"
                     label="&inspectMenu.label;"
                     type="checkbox"
                     command="Tools:Inspect"
                     key="key_inspect"/>
           <menuitem id="appmenu_debugger"
                     hidden="true"
-                    type="checkbox"
                     label="&debuggerMenu.label;"
                     key="key_debugger"
                     command="Tools:Debugger"/>
-          <menuitem id="appmenu_remoteDebugger"
-                    hidden="true"
-                    label="&remoteDebuggerMenu.label;"
-                    command="Tools:RemoteDebugger"/>
           <menuitem id="appmenu_scratchpad"
                     hidden="true"
                     label="&scratchpad.label;"
                     key="key_scratchpad"
                     command="Tools:Scratchpad"/>
           <menuitem id="appmenu_styleeditor"
                     hidden="true"
                     label="&styleeditor.label;"
--- a/browser/base/content/browser-fullZoom.js
+++ b/browser/base/content/browser-fullZoom.js
@@ -220,17 +220,17 @@ var FullZoom = {
    * @param aBrowser
    *        (optional) browser object displaying the document
    */
   onLocationChange: function FullZoom_onLocationChange(aURI, aIsTabSwitch, aBrowser) {
     if (!aURI || (aIsTabSwitch && !this.siteSpecific))
       return;
 
     // Avoid the cps roundtrip and apply the default/global pref.
-    if (aURI.spec == "about:blank") {
+    if (isBlankPageURL(aURI.spec)) {
       this._applyPrefToSetting(undefined, aBrowser);
       return;
     }
 
     let browser = aBrowser || gBrowser.selectedBrowser;
 
     // Media documents should always start at 1, and are not affected by prefs.
     if (!aIsTabSwitch && browser.contentDocument.mozSyntheticDocument) {
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -526,48 +526,36 @@
                         accesskey="&syncSyncNowItem.accesskey;"
                         observes="sync-syncnow-state"
                         oncommand="gSyncUI.doSync(event);"/>
 #endif
               <menuseparator id="devToolsSeparator"/>
               <menu id="webDeveloperMenu"
                     label="&webDeveloperMenu.label;"
                     accesskey="&webDeveloperMenu.accesskey;">
-                <menupopup id="menuWebDeveloperPopup">
-                  <menuitem id="menu_devToolbar"
-                            type="checkbox"
-                            autocheck="false"
-                            hidden="true"
-                            label="&devToolbarMenu.label;"
-                            accesskey="&devToolbarMenu.accesskey;"
-                            key="key_devToolbar"
-                            command="Tools:DevToolbar"/>
+                <menupopup id="menuWebDeveloperPopup"
+                           onpopupshowing="onWebDeveloperMenuShowing();">
                   <menuitem id="webConsole"
                             type="checkbox"
                             label="&webConsoleCmd.label;"
                             accesskey="&webConsoleCmd.accesskey;"
                             key="key_webConsole"
                             command="Tools:WebConsole"/>
                   <menuitem id="menu_pageinspect"
                             type="checkbox"
                             hidden="true"
                             label="&inspectMenu.label;"
                             accesskey="&inspectMenu.accesskey;"
                             key="key_inspect"
                             command="Tools:Inspect"/>
                   <menuitem id="menu_debugger"
                             hidden="true"
-                            type="checkbox"
                             label="&debuggerMenu.label;"
                             key="key_debugger"
                             command="Tools:Debugger"/>
-                  <menuitem id="menu_remoteDebugger"
-                            hidden="true"
-                            label="&remoteDebuggerMenu.label;"
-                            command="Tools:RemoteDebugger"/>
                   <menuitem id="menu_scratchpad"
                             hidden="true"
                             label="&scratchpad.label;"
                             accesskey="&scratchpad.accesskey;"
                             key="key_scratchpad"
                             command="Tools:Scratchpad"/>
                   <menuitem id="menu_styleeditor"
                             hidden="true"
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -121,21 +121,19 @@
     <command id="cmd_fullZoomReduce"  oncommand="FullZoom.reduce()"/>
     <command id="cmd_fullZoomEnlarge" oncommand="FullZoom.enlarge()"/>
     <command id="cmd_fullZoomReset"   oncommand="FullZoom.reset()"/>
     <command id="cmd_fullZoomToggle"  oncommand="ZoomManager.toggleZoom();"/>
     <command id="Browser:OpenLocation" oncommand="openLocation();"/>
 
     <command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
     <command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>
-    <command id="Tools:DevToolbar" oncommand="DeveloperToolbar.toggle();" disabled="true"/>
     <command id="Tools:WebConsole" oncommand="HUDConsoleUI.toggleHUD();"/>
     <command id="Tools:Inspect" oncommand="InspectorUI.toggleInspectorUI();" disabled="true"/>
     <command id="Tools:Debugger" oncommand="DebuggerUI.toggleDebugger();" disabled="true"/>
-    <command id="Tools:RemoteDebugger" oncommand="DebuggerUI.toggleRemoteDebugger();" disabled="true"/>
     <command id="Tools:Scratchpad" oncommand="Scratchpad.openScratchpad();" disabled="true"/>
     <command id="Tools:StyleEditor" oncommand="StyleEditor.openChrome();" disabled="true"/>
     <command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
     <command id="Tools:Sanitize"
      oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
     <command id="Tools:PrivateBrowsing" oncommand="gPrivateBrowsingUI.toggleMode();"/>
     <command id="History:UndoCloseTab" oncommand="undoCloseTab();"/>
     <command id="History:UndoCloseWindow" oncommand="undoCloseWindow();"/>
@@ -252,23 +250,16 @@
 #ifdef XP_GNOME
     <key id="key_search2" key="&searchFocusUnix.commandkey;" command="Tools:Search" modifiers="accel"/>
     <key id="key_openDownloads" key="&downloadsUnix.commandkey;" command="Tools:Downloads" modifiers="accel,shift"/>
 #else
     <key id="key_openDownloads" key="&downloads.commandkey;" command="Tools:Downloads" modifiers="accel"/>
 #endif
     <key id="key_openAddons" key="&addons.commandkey;" command="Tools:Addons" modifiers="accel,shift"/>
     <key id="key_errorConsole" key="&errorConsoleCmd.commandkey;" oncommand="toJavaScriptConsole();" modifiers="accel,shift" disabled="true"/>
-    <key id="key_devToolbar" key="&devToolbar.commandkey;" command="Tools:DevToolbar"
-#ifdef XP_MACOSX
-         modifiers="accel,alt"
-#else
-         modifiers="accel,shift"
-#endif
-    />
     <key id="key_webConsole" key="&webConsoleCmd.commandkey;" oncommand="HUDConsoleUI.toggleHUD();"
 #ifdef XP_MACOSX
         modifiers="accel,alt"
 #else
         modifiers="accel,shift"
 #endif
     />
     <key id="key_debugger" key="&debuggerMenu.commandkey;" command="Tools:Debugger"
--- a/browser/base/content/browser-tabview.js
+++ b/browser/base/content/browser-tabview.js
@@ -209,31 +209,35 @@ let TabView = {
     if (hasCallback)
       this._initFrameCallbacks.push(callback);
 
     if (this._isFrameLoading)
       return;
 
     this._isFrameLoading = true;
 
+    TelemetryStopwatch.start("PANORAMA_INITIALIZATION_TIME_MS");
+
     // ___ find the deck
     this._deck = document.getElementById("tab-view-deck");
 
     // ___ create the frame
     this._iframe = document.createElement("iframe");
     this._iframe.id = "tab-view";
     this._iframe.setAttribute("transparent", "true");
     this._iframe.setAttribute("tooltip", "tab-view-tooltip");
     this._iframe.flex = 1;
 
     let self = this;
 
     window.addEventListener("tabviewframeinitialized", function onInit() {
       window.removeEventListener("tabviewframeinitialized", onInit, false);
 
+      TelemetryStopwatch.finish("PANORAMA_INITIALIZATION_TIME_MS");
+
       self._isFrameLoading = false;
       self._window = self._iframe.contentWindow;
       self._setBrowserKeyHandlers();
 
       if (self._tabShowEventListener) {
         gBrowser.tabContainer.removeEventListener(
           "TabShow", self._tabShowEventListener, false);
         self._tabShowEventListener = null;
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -174,22 +174,16 @@ XPCOMUtils.defineLazyGetter(this, "Popup
     return new tmp.PopupNotifications(gBrowser,
                                       document.getElementById("notification-popup"),
                                       document.getElementById("notification-popup-box"));
   } catch (ex) {
     Cu.reportError(ex);
   }
 });
 
-XPCOMUtils.defineLazyGetter(this, "DeveloperToolbar", function() {
-  let tmp = {};
-  Cu.import("resource:///modules/devtools/DeveloperToolbar.jsm", tmp);
-  return new tmp.DeveloperToolbar(window, document.getElementById("developer-toolbar"));
-});
-
 XPCOMUtils.defineLazyGetter(this, "InspectorUI", function() {
   let tmp = {};
   Cu.import("resource:///modules/inspector.jsm", tmp);
   return new tmp.InspectorUI(window);
 });
 
 XPCOMUtils.defineLazyGetter(this, "DebuggerUI", function() {
   let tmp = {};
@@ -1697,56 +1691,34 @@ function delayedStartup(isLoadingBlank, 
   TabView.init();
 
   setUrlAndSearchBarWidthForConditionalForwardButton();
   window.addEventListener("resize", function resizeHandler(event) {
     if (event.target == window)
       setUrlAndSearchBarWidthForConditionalForwardButton();
   });
 
-  // Enable developer toolbar?
-  let devToolbarEnabled = gPrefService.getBoolPref("devtools.toolbar.enabled");
-  if (devToolbarEnabled) {
-    document.getElementById("menu_devToolbar").hidden = false;
-    document.getElementById("Tools:DevToolbar").removeAttribute("disabled");
-#ifdef MENUBAR_CAN_AUTOHIDE
-    document.getElementById("appmenu_devToolbar").hidden = false;
-#endif
-  }
-
   // Enable Inspector?
   let enabled = gPrefService.getBoolPref("devtools.inspector.enabled");
   if (enabled) {
     document.getElementById("menu_pageinspect").hidden = false;
     document.getElementById("Tools:Inspect").removeAttribute("disabled");
 #ifdef MENUBAR_CAN_AUTOHIDE
     document.getElementById("appmenu_pageInspect").hidden = false;
 #endif
-    document.getElementById("developer-toolbar-inspector").hidden = false;
   }
 
   // Enable Debugger?
   let enabled = gPrefService.getBoolPref("devtools.debugger.enabled");
   if (enabled) {
     document.getElementById("menu_debugger").hidden = false;
     document.getElementById("Tools:Debugger").removeAttribute("disabled");
 #ifdef MENUBAR_CAN_AUTOHIDE
     document.getElementById("appmenu_debugger").hidden = false;
 #endif
-    document.getElementById("developer-toolbar-debugger").hidden = false;
-  }
-
-  // Enable Remote Debugger?
-  let enabled = gPrefService.getBoolPref("devtools.debugger.remote-enabled");
-  if (enabled) {
-    document.getElementById("menu_remoteDebugger").hidden = false;
-    document.getElementById("Tools:RemoteDebugger").removeAttribute("disabled");
-#ifdef MENUBAR_CAN_AUTOHIDE
-    document.getElementById("appmenu_remoteDebugger").hidden = false;
-#endif
   }
 
   // Enable Error Console?
   // XXX Temporarily always-enabled, see bug 601201
   let consoleEnabled = true || gPrefService.getBoolPref("devtools.errorconsole.enabled");
   if (consoleEnabled) {
     document.getElementById("javascriptConsole").hidden = false;
     document.getElementById("key_errorConsole").removeAttribute("disabled");
@@ -9304,16 +9276,20 @@ var StyleEditor = {
     args.wrappedJSObject = args;
     let chromeWindow = Services.ww.openWindow(null, CHROME_URL, "_blank",
                                               CHROME_WINDOW_FLAGS, args);
     chromeWindow.focus();
     return chromeWindow;
   }
 };
 
+function onWebDeveloperMenuShowing() {
+  document.getElementById("Tools:WebConsole").setAttribute("checked", HUDConsoleUI.getOpenHUD() != null);
+}
+
 
 XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function () {
 #ifdef XP_WIN
   // Only show resizers on Windows 2000 and XP
   let sysInfo = Components.classes["@mozilla.org/system-info;1"]
                           .getService(Components.interfaces.nsIPropertyBag2);
   return parseFloat(sysInfo.getProperty("version")) < 6;
 #else
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -1034,70 +1034,16 @@
         <!-- registered tools go here -->
       </hbox>
 #ifndef XP_MACOSX
       <toolbarbutton id="highlighter-closebutton"
                      oncommand="InspectorUI.closeInspectorUI(false);"
                      tooltiptext="&inspectCloseButton.tooltiptext;"/>
 #endif
     </toolbar>
-
-    <panel id="gcli-tooltip"
-           type="arrow"
-           noautofocus="true"
-           noautohide="true"
-           class="gcli-panel">
-      <iframe id="gcli-tooltip-frame"
-              src="chrome://browser/content/devtools/gcliblank.xhtml"
-              flex="1"/>
-    </panel>
-    <panel id="gcli-output"
-           type="arrow"
-           noautofocus="true"
-           noautohide="true"
-           class="gcli-panel">
-      <iframe id="gcli-output-frame"
-              src="chrome://browser/content/devtools/gcliblank.xhtml"
-              flex="1"/>
-    </panel>
-
-    <toolbar id="developer-toolbar"
-             class="devtools-toolbar"
-             hidden="true">
-#ifdef XP_MACOSX
-          <toolbarbutton id="developer-toolbar-closebutton"
-                         oncommand="DeveloperToolbar.hide();"
-                         tooltiptext="&devToolbarCloseButton.tooltiptext;"/>
-#endif
-          <stack class="gclitoolbar-stack-node" flex="1">
-            <description class="gclitoolbar-prompt">&#187;</description>
-            <description class="gclitoolbar-complete-node"/>
-            <textbox class="gclitoolbar-input-node" rows="1"/>
-          </stack>
-          <toolbarbutton id="developer-toolbar-webconsole"
-                         label="&webConsoleButton.label;"
-                         class="devtools-toolbarbutton"
-                         command="Tools:WebConsole"/>
-          <toolbarbutton id="developer-toolbar-inspector"
-                         label="&inspectorButton.label;"
-                         class="devtools-toolbarbutton"
-                         hidden="true"
-                         command="Tools:Inspect"/>
-          <toolbarbutton id="developer-toolbar-debugger"
-                         label="&scriptsButton.label;"
-                         class="devtools-toolbarbutton"
-                         hidden="true"
-                         command="Tools:Debugger"/>
-#ifndef XP_MACOSX
-          <toolbarbutton id="developer-toolbar-closebutton"
-                         oncommand="DeveloperToolbar.hide();"
-                         tooltiptext="&devToolbarCloseButton.tooltiptext;"/>
-#endif
-   </toolbar>
-
     <toolbar id="addon-bar"
              toolbarname="&addonBarCmd.label;" accesskey="&addonBarCmd.accesskey;"
              collapsed="true"
              class="toolbar-primary chromeclass-toolbar"
              context="toolbar-context-menu" toolboxid="navigator-toolbox"
              mode="icons" iconsize="small" defaulticonsize="small"
              lockiconsize="true"
              defaultset="addonbar-closebutton,spring,status-bar"
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -87,23 +87,27 @@
                 onget="return this.tabContainer.contextMenu;"/>
 
       <field name="tabContainer" readonly="true">
         document.getElementById(this.getAttribute("tabcontainer"));
       </field>
       <field name="tabs" readonly="true">
         this.tabContainer.childNodes;
       </field>
+
       <property name="visibleTabs" readonly="true">
         <getter><![CDATA[
-          return Array.filter(this.tabs, function(tab) {
-            return !tab.hidden && !tab.closing;
-          });
+          if (!this._visibleTabs)
+            this._visibleTabs = Array.filter(this.tabs,
+                                             function (tab) !tab.hidden && !tab.closing);
+          return this._visibleTabs;
         ]]></getter>
       </property>
+      <field name="_visibleTabs">null</field>
+
       <field name="mURIFixup" readonly="true">
         Components.classes["@mozilla.org/docshell/urifixup;1"]
                   .getService(Components.interfaces.nsIURIFixup);
       </field>
       <field name="mFaviconService" readonly="true">
         Components.classes["@mozilla.org/browser/favicon-service;1"]
                   .getService(Components.interfaces.nsIFaviconService);
       </field>
@@ -146,19 +150,16 @@
       </field>
       <field name="arrowKeysShouldWrap" readonly="true">
 #ifdef XP_MACOSX
         true
 #else
         false
 #endif
       </field>
-      <field name="_browsers">
-        null
-      </field>
 
       <field name="_autoScrollPopup">
         null
       </field>
 
       <field name="_previewMode">
         false
       </field>
@@ -1235,18 +1236,16 @@
               aOwner                = params.ownerTab;
               aAllowThirdPartyFixup = params.allowThirdPartyFixup;
               aFromExternal         = params.fromExternal;
               aRelatedToCurrent     = params.relatedToCurrent;
               aSkipAnimation        = params.skipAnimation;
               aIsUTF8               = params.isUTF8;
             }
 
-            this._browsers = null; // invalidate cache
-
             // if we're adding tabs, we're past interrupt mode, ditch the owner
             if (this.mCurrentTab.owner)
               this.mCurrentTab.owner = null;
 
             var t = document.createElementNS(
               "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                              "tab");
 
@@ -1286,21 +1285,22 @@
                   // when opening a second tab, the first tab's close buttons
                   // appears immediately rather than when the transition ends.
                   if (tabContainer.childNodes.length == 2)
                     tabContainer.adjustTabstrip();
                 }
               }, 0, this.tabContainer);
             }
 
+            // invalidate caches
+            this._browsers = null;
+            this._visibleTabs = null;
+
             this.tabContainer.appendChild(t);
 
-            // invalidate cache, because tabContainer is about to change
-            this._browsers = null;
-
             // If this new tab is owned by another, assert that relationship
             if (aOwner)
               t.owner = aOwner;
 
             var b = document.createElementNS(
               "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                              "browser");
             b.setAttribute("type", "content-targetable");
@@ -1620,16 +1620,17 @@
                   (this._windowIsClosing = window.closeWindow(true)))
                 return null;
 
               newTab = true;
             }
 
             aTab.closing = true;
             this._removingTabs.push(aTab);
+            this._visibleTabs = null; // invalidate cache
             if (newTab)
               this.addTab(BROWSER_NEW_TAB_URL, {skipAnimation: true});
             else
               this.tabContainer.updateVisibility();
 
             // We're committed to closing the tab now.
             // Dispatch a notification.
             // We dispatch it before any teardown so that event listeners can
@@ -2004,33 +2005,39 @@
       </method>
 
       <method name="showTab">
         <parameter name="aTab"/>
         <body>
         <![CDATA[
           if (aTab.hidden) {
             aTab.removeAttribute("hidden");
+            this._visibleTabs = null; // invalidate cache
+
             this.tabContainer.adjustTabstrip();
+
             let event = document.createEvent("Events");
             event.initEvent("TabShow", true, false);
             aTab.dispatchEvent(event);
           }
         ]]>
         </body>
       </method>
 
       <method name="hideTab">
         <parameter name="aTab"/>
         <body>
         <![CDATA[
           if (!aTab.hidden && !aTab.pinned && !aTab.selected &&
               !aTab.closing) {
             aTab.setAttribute("hidden", "true");
+            this._visibleTabs = null; // invalidate cache
+
             this.tabContainer.adjustTabstrip();
+
             let event = document.createEvent("Events");
             event.initEvent("TabHide", true, false);
             aTab.dispatchEvent(event);
           }
         ]]>
         </body>
       </method>
 
@@ -2076,16 +2083,17 @@
       <property name="browsers" readonly="true">
        <getter>
           <![CDATA[
             return this._browsers ||
                    (this._browsers = Array.map(this.tabs, function (tab) tab.linkedBrowser));
           ]]>
         </getter>
       </property>
+      <field name="_browsers">null</field>
 
       <!-- Moves a tab to a new browser window, unless it's already the only tab
            in the current window, in which case this will do nothing. -->
       <method name="replaceTabWithWindow">
         <parameter name="aTab"/>
         <parameter name="aOptions"/>
         <body>
           <![CDATA[
@@ -2121,21 +2129,24 @@
 
           this._lastRelatedTab = null;
 
           this.mTabFilters.splice(aIndex, 0, this.mTabFilters.splice(aTab._tPos, 1)[0]);
           this.mTabListeners.splice(aIndex, 0, this.mTabListeners.splice(aTab._tPos, 1)[0]);
 
           aIndex = aIndex < aTab._tPos ? aIndex: aIndex+1;
           this.mCurrentTab._selected = false;
+
+          // invalidate caches
+          this._browsers = null;
+          this._visibleTabs = null;
+
           // use .item() instead of [] because dragging to the end of the strip goes out of
           // bounds: .item() returns null (so it acts like appendChild), but [] throws
           this.tabContainer.insertBefore(aTab, this.tabs.item(aIndex));
-          // invalidate cache, because tabContainer is about to change
-          this._browsers = null;
 
           for (let i = 0; i < this.tabs.length; i++) {
             this.tabs[i]._tPos = i;
             this.tabs[i]._selected = false;
           }
           this.mCurrentTab._selected = true;
           this.tabContainer.mTabstrip.ensureElementIsVisible(this.mCurrentTab, false);
 
--- a/browser/base/content/test/browser_alltabslistener.js
+++ b/browser/base/content/test/browser_alltabslistener.js
@@ -126,17 +126,16 @@ function startTest1() {
 }
 
 function startTest2() {
   info("\nTest 2");
   gAllNotifications = [
     "onStateChange",
     "onLocationChange",
     "onSecurityChange",
-    "onSecurityChange",
     "onStateChange"
   ];
   gFrontNotifications = gAllNotifications;
   runTest(gForegroundBrowser, "https://example.com" + gTestPage, startTest3);
 }
 
 function startTest3() {
   info("\nTest 3");
@@ -151,17 +150,16 @@ function startTest3() {
 }
 
 function startTest4() {
   info("\nTest 4");
   gAllNotifications = [
     "onStateChange",
     "onLocationChange",
     "onSecurityChange",
-    "onSecurityChange",
     "onStateChange"
   ];
   gFrontNotifications = [];
   runTest(gBackgroundBrowser, "https://example.com" + gTestPage, startTest5);
 }
 
 function startTest5() {
   info("\nTest 5");
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -63,16 +63,19 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/PlacesUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "BookmarkHTMLUtils",
                                   "resource://gre/modules/BookmarkHTMLUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "webappsUI", 
                                   "resource:///modules/webappsUI.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs",
+                                  "resource:///modules/PageThumbs.jsm");
+
 const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
 const PREF_PLUGINS_UPDATEURL  = "plugins.update.url";
 
 // We try to backup bookmarks at idle times, to avoid doing that at shutdown.
 // Number of idle seconds before trying to backup bookmarks.  15 minutes.
 const BOOKMARKS_BACKUP_IDLE_TIME = 15 * 60;
 // Minimum interval in milliseconds between backups.
 const BOOKMARKS_BACKUP_INTERVAL = 86400 * 1000;
@@ -353,16 +356,18 @@ BrowserGlue.prototype = {
     this._distributionCustomizer.applyCustomizations();
 
     // handle any UI migration
     this._migrateUI();
 
     // Initialize webapps UI
     webappsUI.init();
 
+    PageThumbs.init();
+
     Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
   },
 
   // the first browser window has finished initializing
   _onFirstWindowLoaded: function BG__onFirstWindowLoaded() {
 #ifdef XP_WIN
     // For windows seven, initialize the jump list module.
     const WINTASKBAR_CONTRACTID = "@mozilla.org/windows-taskbar;1";
@@ -374,16 +379,17 @@ BrowserGlue.prototype = {
     }
 #endif
   },
 
   // profile shutdown handler (contains profile cleanup routines)
   _onProfileShutdown: function BG__onProfileShutdown() {
     this._shutdownPlaces();
     this._sanitizer.onShutdown();
+    PageThumbs.uninit();
   },
 
   // All initial windows have opened.
   _onWindowsRestored: function BG__onWindowsRestored() {
     // Show about:rights notification, if needed.
     if (this._shouldShowRights()) {
       this._showRightsNotification();
 #ifdef MOZ_TELEMETRY_REPORTING
--- a/browser/components/sessionstore/test/browser_394759_basic.js
+++ b/browser/components/sessionstore/test/browser_394759_basic.js
@@ -30,46 +30,16 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-function provideWindow(aCallback, aURL, aFeatures) {
-  function callback() {
-    executeSoon(function () {
-      aCallback(win);
-    });
-  }
-
-  let win = openDialog(getBrowserURL(), "", aFeatures || "chrome,all,dialog=no", aURL);
-
-  whenWindowLoaded(win, function () {
-    if (!aURL) {
-      callback();
-      return;
-    }
-    win.gBrowser.selectedBrowser.addEventListener("load", function() {
-      win.gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
-      callback();
-    }, true);
-  });
-}
-
-function whenWindowLoaded(aWin, aCallback) {
-  aWin.addEventListener("load", function () {
-    aWin.removeEventListener("load", arguments.callee, false);
-    executeSoon(function () {
-      aCallback(aWin);
-    });
-  }, false);
-}
-
 function test() {
   waitForExplicitFinish();
 
   let testURL = "about:config";
   let uniqueKey = "bug 394759";
   let uniqueValue = "unik" + Date.now();
   let uniqueText = "pi != " + Math.random();
 
--- a/browser/components/sessionstore/test/browser_394759_behavior.js
+++ b/browser/components/sessionstore/test/browser_394759_behavior.js
@@ -30,53 +30,23 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-function provideWindow(aCallback, aURL, aFeatures) {
-  function callback() {
-    executeSoon(function () {
-      aCallback(win);
-    });
-  }
-
-  let win = openDialog(getBrowserURL(), "", aFeatures || "chrome,all,dialog=no", aURL);
-
-  whenWindowLoaded(win, function () {
-    if (!aURL) {
-      callback();
-      return;
-    }
-    win.gBrowser.selectedBrowser.addEventListener("load", function() {
-      win.gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
-      callback();
-    }, true);
-  });
-}
-
-function whenWindowLoaded(aWin, aCallback) {
-  aWin.addEventListener("load", function () {
-    aWin.removeEventListener("load", arguments.callee, false);
-    executeSoon(function () {
-      aCallback(aWin);
-    });
-  }, false);
-}
-
 function test() {
   // This test takes quite some time, and timeouts frequently, so we require
   // more time to run.
   // See Bug 518970.
   requestLongerTimeout(2);
 
-  waitForExplicitFinish();  
+  waitForExplicitFinish();
 
   // helper function that does the actual testing
   function openWindowRec(windowsToOpen, expectedResults, recCallback) {
     // do actual checking
     if (!windowsToOpen.length) {
       let closedWindowData = JSON.parse(ss.getClosedWindowData());
       let numPopups = closedWindowData.filter(function(el, i, arr) {
         return el.isPopup;
@@ -89,23 +59,24 @@ function test() {
          "There were " + oResults.popup + " popup windows to repoen");
       is(numNormal, oResults.normal,
          "There were " + oResults.normal + " normal windows to repoen");
 
       // cleanup & return
       executeSoon(recCallback);
       return;
     }
+
     // hack to force window to be considered a popup (toolbar=no didn't work)
     let winData = windowsToOpen.shift();
     let settings = "chrome,dialog=no," +
                    (winData.isPopup ? "all=no" : "all");
     let url = "http://example.com/?window=" + windowsToOpen.length;
 
-    provideWindow(function (win) {
+    provideWindow(function onTestURLLoaded(win) {
       win.close();
       openWindowRec(windowsToOpen, expectedResults, recCallback);
     }, url, settings);
   }
 
   let windowsToOpen = [{isPopup: false},
                        {isPopup: false},
                        {isPopup: true},
--- a/browser/components/sessionstore/test/browser_595601-restore_hidden.js
+++ b/browser/components/sessionstore/test/browser_595601-restore_hidden.js
@@ -89,29 +89,21 @@ let TabsProgressListener = {
         needsRestore++;
     }
 
     return [needsRestore, isRestoring];
   }
 }
 
 // ----------
-function whenWindowLoaded(win, callback) {
-  win.addEventListener("load", function onLoad() {
-    win.removeEventListener("load", onLoad, false);
-    executeSoon(callback);
-  }, false);
-}
-
-// ----------
 function newWindowWithState(state, callback) {
   let opts = "chrome,all,dialog=no,height=800,width=800";
   let win = window.openDialog(getBrowserURL(), "_blank", opts);
 
   registerCleanupFunction(function () win.close());
 
-  whenWindowLoaded(win, function () {
-    TabsProgressListener.init(win);
+  whenWindowLoaded(win, function onWindowLoaded(aWin) {
+    TabsProgressListener.init(aWin);
     TabsProgressListener.setCallback(callback);
 
-    ss.setWindowState(win, JSON.stringify(state), true);
+    ss.setWindowState(aWin, JSON.stringify(state), true);
   });
 }
--- a/browser/components/sessionstore/test/browser_701377.js
+++ b/browser/components/sessionstore/test/browser_701377.js
@@ -23,27 +23,19 @@ function test() {
     tab.removeEventListener("TabShow", tabShowCallback, false);
     ok(tab.hidden && !tabShown, "tab remains hidden");
 
     finish();
   });
 }
 
 // ----------
-function whenWindowLoaded(aWindow, aCallback) {
-  aWindow.addEventListener("load", function onLoad() {
-    aWindow.removeEventListener("load", onLoad, false);
-    executeSoon(aCallback);
-  }, false);
-}
-
-// ----------
 function newWindowWithState(aState, aCallback) {
   let opts = "chrome,all,dialog=no,height=800,width=800";
   let win = window.openDialog(getBrowserURL(), "_blank", opts);
 
   registerCleanupFunction(function () win.close());
 
-  whenWindowLoaded(win, function () {
-    ss.setWindowState(win, JSON.stringify(aState), true);
-    executeSoon(function () aCallback(win));
+  whenWindowLoaded(win, function onWindowLoaded(aWin) {
+    ss.setWindowState(aWin, JSON.stringify(aState), true);
+    executeSoon(function () aCallback(aWin));
   });
 }
--- a/browser/components/sessionstore/test/head.js
+++ b/browser/components/sessionstore/test/head.js
@@ -44,16 +44,38 @@ Services.prefs.setBoolPref("browser.sess
 registerCleanupFunction(function () {
   Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
 });
 
 // This kicks off the search service used on about:home and allows the
 // session restore tests to be run standalone without triggering errors.
 Cc["@mozilla.org/browser/clh;1"].getService(Ci.nsIBrowserHandler).defaultArgs;
 
+function provideWindow(aCallback, aURL, aFeatures) {
+  function callbackSoon(aWindow) {
+    executeSoon(function executeCallbackSoon() {
+      aCallback(aWindow);
+    });
+  }
+
+  let win = openDialog(getBrowserURL(), "", aFeatures || "chrome,all,dialog=no", aURL);
+  whenWindowLoaded(win, function onWindowLoaded(aWin) {
+    if (!aURL) {
+      info("Loaded a blank window.");
+      callbackSoon(aWin);
+      return;
+    }
+
+    aWin.gBrowser.selectedBrowser.addEventListener("load", function selectedBrowserLoadListener() {
+      aWin.gBrowser.selectedBrowser.removeEventListener("load", selectedBrowserLoadListener, true);
+      callbackSoon(aWin);
+    }, true);
+  });
+}
+
 // This assumes that tests will at least have some state/entries
 function waitForBrowserState(aState, aSetStateCallback) {
   let windows = [window];
   let tabsRestored = 0;
   let expectedTabsRestored = 0;
   let expectedWindows = aState.windows.length;
   let windowsOpen = 1;
   let listening = false;
@@ -193,12 +215,21 @@ function waitForSaveState(aSaveStateCall
 
 function whenBrowserLoaded(aBrowser, aCallback) {
   aBrowser.addEventListener("load", function onLoad() {
     aBrowser.removeEventListener("load", onLoad, true);
     executeSoon(aCallback);
   }, true);
 }
 
+function whenWindowLoaded(aWindow, aCallback) {
+  aWindow.addEventListener("load", function windowLoadListener() {
+    aWindow.removeEventListener("load", windowLoadListener, false);
+    executeSoon(function executeWhenWindowLoaded() {
+      aCallback(aWindow);
+    });
+  }, false);
+}
+
 var gUniqueCounter = 0;
 function r() {
   return Date.now() + "-" + (++gUniqueCounter);
 }
--- a/browser/components/tabview/tabview.js
+++ b/browser/components/tabview/tabview.js
@@ -68,9 +68,10 @@ let AllTabs = {
 #include storage.js
 #include items.js
 #include groupitems.js
 #include tabitems.js
 #include favicons.js
 #include drag.js
 #include trench.js
 #include search.js
+#include telemetry.js
 #include ui.js
new file mode 100644
--- /dev/null
+++ b/browser/components/tabview/telemetry.js
@@ -0,0 +1,63 @@
+/* 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/. */
+
+/**
+ * Collects telemetry data for Tabview.
+ */
+let Telemetry = {
+  TOPIC_GATHER_TELEMETRY: "gather-telemetry",
+
+  /**
+   * Initializes the object.
+   */
+  init: function Telemetry_init() {
+    Services.obs.addObserver(this, this.TOPIC_GATHER_TELEMETRY, false);
+  }, 
+
+  /**
+   * Uninitializes the object.
+   */
+  uninit: function Telemetry_uninit() {
+    Services.obs.removeObserver(this, this.TOPIC_GATHER_TELEMETRY);
+  },
+
+  /**
+   * Adds telemetry values to gather usage statistics.
+   */
+  _collect: function Telemetry_collect() {
+    let stackedGroupsCount = 0;
+    let childCounts = [];
+
+    GroupItems.groupItems.forEach(function (groupItem) {
+      if (!groupItem.isEmpty()) {
+        childCounts.push(groupItem.getChildren().length);
+
+        if (groupItem.isStacked())
+          stackedGroupsCount++;
+      }
+    });
+
+    function addTelemetryValue(aId, aValue) {
+      Services.telemetry.getHistogramById("PANORAMA_" + aId).add(aValue);
+    }
+    function median(aChildCounts) {
+      aChildCounts.sort(function(x, y) { return x - y; });
+      let middle = Math.floor(aChildCounts.length / 2);
+      return aChildCounts[middle];
+    }
+
+    addTelemetryValue("GROUPS_COUNT", GroupItems.groupItems.length);
+    addTelemetryValue("STACKED_GROUPS_COUNT", stackedGroupsCount);
+    addTelemetryValue("MEDIAN_TABS_IN_GROUPS_COUNT", median(childCounts));
+  },
+
+  /**
+   * Observes for gather telemetry topic.
+   */
+  observe: function Telemetry_observe(aSubject, aTopic, aData) {
+    if (!gPrivateBrowsing.privateBrowsingEnabled)
+      this._collect();
+  }
+}
+
--- a/browser/components/tabview/test/Makefile.in
+++ b/browser/components/tabview/test/Makefile.in
@@ -168,16 +168,17 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug706430.js \
                  browser_tabview_bug706736.js \
                  browser_tabview_bug707466.js \
                  browser_tabview_bug712203.js \
                  browser_tabview_bug715454.js \
                  browser_tabview_bug716880.js \
                  browser_tabview_bug728887.js \
                  browser_tabview_bug733115.js \
+                 browser_tabview_bug749658.js \
                  browser_tabview_click_group.js \
                  browser_tabview_dragdrop.js \
                  browser_tabview_exit_button.js \
                  browser_tabview_expander.js \
                  browser_tabview_firstrun_pref.js \
                  browser_tabview_group.js \
                  browser_tabview_launch.js \
                  browser_tabview_multiwindow_search.js \
new file mode 100644
--- /dev/null
+++ b/browser/components/tabview/test/browser_tabview_bug749658.js
@@ -0,0 +1,26 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+let win;
+
+function test() {
+  waitForExplicitFinish();
+
+  newWindowWithTabView(function(newWin) {
+    win = newWin;
+
+    registerCleanupFunction(function() {
+      win.close();
+    });
+
+    is(win.gBrowser.tabContainer.getAttribute("overflow"), "",
+       "The tabstrip should not be overflowing");
+
+    finish();
+  }, function(newWin) {
+    /* add a tab with a ridiculously long title to trigger bug 749658 */
+    var longTitle = "this is a very long title for the new tab ";
+    longTitle = longTitle + longTitle + longTitle + longTitle + longTitle;
+    longTitle = longTitle + longTitle + longTitle + longTitle + longTitle;
+    newWin.gBrowser.addTab("data:text/html,<head><title>" + longTitle);
+  });
+}
--- a/browser/components/tabview/ui.js
+++ b/browser/components/tabview/ui.js
@@ -166,16 +166,18 @@ let UI = {
 
       let data = Storage.readUIData(gWindow);
       this._storageSanity(data);
       this._pageBounds = data.pageBounds;
 
       // ___ search
       Search.init();
 
+      Telemetry.init();
+
       // ___ currentTab
       this._currentTab = gBrowser.selectedTab;
 
       // ___ exit button
       iQ("#exit-button").click(function() {
         self.exit();
         self.blurAll();
       })
@@ -307,16 +309,17 @@ let UI = {
     });
     this._cleanupFunctions = [];
 
     // additional clean up
     TabItems.uninit();
     GroupItems.uninit();
     FavIcons.uninit();
     Storage.uninit();
+    Telemetry.uninit();
 
     this._removeTabActionHandlers();
     this._currentTab = null;
     this._pageBounds = null;
     this._reorderTabItemsOnShow = null;
     this._reorderTabsOnHide = null;
     this._frameInitialized = false;
   },
--- a/browser/components/thumbnails/PageThumbs.jsm
+++ b/browser/components/thumbnails/PageThumbs.jsm
@@ -1,40 +1,63 @@
 /* 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";
 
-let EXPORTED_SYMBOLS = ["PageThumbs", "PageThumbsCache"];
+let EXPORTED_SYMBOLS = ["PageThumbs", "PageThumbsStorage", "PageThumbsCache"];
 
 const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
 
 /**
+ * Name of the directory in the profile that contains the thumbnails.
+ */
+const THUMBNAIL_DIRECTORY = "thumbnails";
+
+/**
  * The default background color for page thumbnails.
  */
 const THUMBNAIL_BG_COLOR = "#fff";
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
   "resource://gre/modules/NetUtil.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
   "resource://gre/modules/Services.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
+  "resource://gre/modules/FileUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
+  "resource://gre/modules/PlacesUtils.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "gCryptoHash", function () {
+  return Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash);
+});
+
+XPCOMUtils.defineLazyGetter(this, "gUnicodeConverter", function () {
+  let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
+                    .createInstance(Ci.nsIScriptableUnicodeConverter);
+  converter.charset = 'utf8';
+  return converter;
+});
+
 /**
  * Singleton providing functionality for capturing web page thumbnails and for
  * accessing them if already cached.
  */
 let PageThumbs = {
+  _initialized: false,
 
   /**
    * The calculated width and height of the thumbnails.
    */
   _thumbnailWidth : 0,
   _thumbnailHeight : 0,
 
   /**
@@ -47,16 +70,30 @@ let PageThumbs = {
    */
   get staticHost() "thumbnail",
 
   /**
    * The thumbnails' image type.
    */
   get contentType() "image/png",
 
+  init: function PageThumbs_init() {
+    if (!this._initialized) {
+      this._initialized = true;
+      PlacesUtils.history.addObserver(PageThumbsHistoryObserver, false);
+    }
+  },
+
+  uninit: function PageThumbs_uninit() {
+    if (this._initialized) {
+      this._initialized = false;
+      PlacesUtils.history.removeObserver(PageThumbsHistoryObserver);
+    }
+  },
+
   /**
    * Gets the thumbnail image's url for a given web page's url.
    * @param aUrl The web page's url that is depicted in the thumbnail.
    * @return The thumbnail image's url.
    */
   getThumbnailURL: function PageThumbs_getThumbnailURL(aUrl) {
     return this.scheme + "://" + this.staticHost +
            "?url=" + encodeURIComponent(aUrl);
@@ -119,42 +156,24 @@ let PageThumbs = {
           //    links redirect to a different URL then we want to be able to
           //    provide thumbnails for both of them.
           //
           // 2) The newtab page should actually display redirect targets, only.
           //    Because of bug 559175 this information can get lost when using
           //    Sync and therefore also redirect sources appear on the newtab
           //    page. We also want thumbnails for those.
           if (url != originalURL)
-            PageThumbsCache._copy(url, originalURL);
+            PageThumbsStorage.copy(url, originalURL);
         }
 
         if (aCallback)
           aCallback(aSuccessful);
       }
 
-      // Get a writeable cache entry.
-      PageThumbsCache.getWriteEntry(url, function (aEntry) {
-        if (!aEntry) {
-          finish(false);
-          return;
-        }
-
-        let outputStream = aEntry.openOutputStream(0);
-
-        // Write the image data to the cache entry.
-        NetUtil.asyncCopy(aInputStream, outputStream, function (aResult) {
-          let success = Components.isSuccessCode(aResult);
-          if (success)
-            aEntry.markValid();
-
-          aEntry.close();
-          finish(success);
-        });
-      });
+      PageThumbsStorage.write(url, aInputStream, finish);
     });
   },
 
   /**
    * Determines the crop size for a given content window.
    * @param aWindow The content window.
    * @return An array containing width, height and scale.
    */
@@ -192,100 +211,124 @@ let PageThumbs = {
   },
 
   /**
    * Calculates the thumbnail size based on current desktop's dimensions.
    * @return The calculated thumbnail size or a default if unable to calculate.
    */
   _getThumbnailSize: function PageThumbs_getThumbnailSize() {
     if (!this._thumbnailWidth || !this._thumbnailHeight) {
-      let screenManager = Cc["@mozilla.org/gfx/screenmanager;1"]
+      let screenManager = Cc["@mozilla.org/gfx/screenmanager;1"]
                             .getService(Ci.nsIScreenManager);
       let left = {}, top = {}, width = {}, height = {};
       screenManager.primaryScreen.GetRect(left, top, width, height);
       this._thumbnailWidth = Math.round(width.value / 3);
       this._thumbnailHeight = Math.round(height.value / 3);
     }
     return [this._thumbnailWidth, this._thumbnailHeight];
   }
 };
 
+let PageThumbsStorage = {
+  getFileForURL: function Storage_getFileForURL(aURL) {
+    let hash = this._calculateMD5Hash(aURL);
+    let parts = [THUMBNAIL_DIRECTORY, hash[0], hash[1], hash.slice(2) + ".png"];
+    return FileUtils.getFile("ProfD", parts);
+  },
+
+  write: function Storage_write(aURL, aDataStream, aCallback) {
+    let file = this.getFileForURL(aURL);
+    let fos = FileUtils.openSafeFileOutputStream(file);
+
+    NetUtil.asyncCopy(aDataStream, fos, function (aResult) {
+      FileUtils.closeSafeFileOutputStream(fos);
+      aCallback(Components.isSuccessCode(aResult));
+    });
+  },
+
+  copy: function Storage_copy(aSourceURL, aTargetURL) {
+    let sourceFile = this.getFileForURL(aSourceURL);
+    let targetFile = this.getFileForURL(aTargetURL);
+
+    try {
+      sourceFile.copyTo(targetFile.parent, targetFile.leafName);
+    } catch (e) {
+      /* We might not be permitted to write to the file. */
+    }
+  },
+
+  remove: function Storage_remove(aURL) {
+    try {
+      this.getFileForURL(aURL).remove(false);
+    } catch (e) {
+      /* The file might not exist or we're not permitted to remove it. */
+    }
+  },
+
+  wipe: function Storage_wipe() {
+    try {
+      FileUtils.getDir("ProfD", [THUMBNAIL_DIRECTORY]).remove(true);
+    } catch (e) {
+      /* The file might not exist or we're not permitted to remove it. */
+    }
+  },
+
+  _calculateMD5Hash: function Storage_calculateMD5Hash(aValue) {
+    let hash = gCryptoHash;
+    let value = gUnicodeConverter.convertToByteArray(aValue);
+
+    hash.init(hash.MD5);
+    hash.update(value, value.length);
+    return this._convertToHexString(hash.finish(false));
+  },
+
+  _convertToHexString: function Storage_convertToHexString(aData) {
+    let hex = "";
+    for (let i = 0; i < aData.length; i++)
+      hex += ("0" + aData.charCodeAt(i).toString(16)).slice(-2);
+    return hex;
+  },
+
+};
+
+let PageThumbsHistoryObserver = {
+  onDeleteURI: function Thumbnails_onDeleteURI(aURI, aGUID) {
+    PageThumbsStorage.remove(aURI.spec);
+  },
+
+  onClearHistory: function Thumbnails_onClearHistory() {
+    PageThumbsStorage.wipe();
+  },
+
+  onTitleChanged: function () {},
+  onBeginUpdateBatch: function () {},
+  onEndUpdateBatch: function () {},
+  onVisit: function () {},
+  onBeforeDeleteURI: function () {},
+  onPageChanged: function () {},
+  onDeleteVisits: function () {},
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver])
+};
+
 /**
  * A singleton handling the storage of page thumbnails.
  */
 let PageThumbsCache = {
   /**
    * Calls the given callback with a cache entry opened for reading.
    * @param aKey The key identifying the desired cache entry.
    * @param aCallback The callback that is called when the cache entry is ready.
    */
   getReadEntry: function Cache_getReadEntry(aKey, aCallback) {
     // Try to open the desired cache entry.
     this._openCacheEntry(aKey, Ci.nsICache.ACCESS_READ, aCallback);
   },
 
   /**
-   * Calls the given callback with a cache entry opened for writing.
-   * @param aKey The key identifying the desired cache entry.
-   * @param aCallback The callback that is called when the cache entry is ready.
-   */
-  getWriteEntry: function Cache_getWriteEntry(aKey, aCallback) {
-    // Try to open the desired cache entry.
-    this._openCacheEntry(aKey, Ci.nsICache.ACCESS_WRITE, aCallback);
-  },
-
-  /**
-   * Copies an existing cache entry's data to a new cache entry.
-   * @param aSourceKey The key that contains the data to copy.
-   * @param aTargetKey The key that will be the copy of aSourceKey's data.
-   */
-  _copy: function Cache_copy(aSourceKey, aTargetKey) {
-    let sourceEntry, targetEntry, waitingCount = 2;
-
-    function finish() {
-      if (sourceEntry)
-        sourceEntry.close();
-
-      if (targetEntry)
-        targetEntry.close();
-    }
-
-    function copyDataWhenReady() {
-      if (--waitingCount > 0)
-        return;
-
-      if (!sourceEntry || !targetEntry) {
-        finish();
-        return;
-      }
-
-      let inputStream = sourceEntry.openInputStream(0);
-      let outputStream = targetEntry.openOutputStream(0);
-
-      // Copy the image data to a new entry.
-      NetUtil.asyncCopy(inputStream, outputStream, function (aResult) {
-        if (Components.isSuccessCode(aResult))
-          targetEntry.markValid();
-
-        finish();
-      });
-    }
-
-    this.getReadEntry(aSourceKey, function (aSourceEntry) {
-      sourceEntry = aSourceEntry;
-      copyDataWhenReady();
-    });
-
-    this.getWriteEntry(aTargetKey, function (aTargetEntry) {
-      targetEntry = aTargetEntry;
-      copyDataWhenReady();
-    });
-  },
-
-  /**
    * Opens the cache entry identified by the given key.
    * @param aKey The key identifying the desired cache entry.
    * @param aAccess The desired access mode (see nsICache.ACCESS_* constants).
    * @param aCallback The function to be called when the cache entry was opened.
    */
   _openCacheEntry: function Cache_openCacheEntry(aKey, aAccess, aCallback) {
     function onCacheEntryAvailable(aEntry, aAccessGranted, aStatus) {
       let validAccess = aAccess == aAccessGranted;
--- a/browser/components/thumbnails/PageThumbsProtocol.js
+++ b/browser/components/thumbnails/PageThumbsProtocol.js
@@ -67,16 +67,24 @@ Protocol.prototype = {
   },
 
   /**
    * Constructs a new channel from the given URI for this protocol handler.
    * @param aURI The URI for which to construct a channel.
    * @return The newly created channel.
    */
   newChannel: function Proto_newChannel(aURI) {
+    let {url} = parseURI(aURI);
+    let file = PageThumbsStorage.getFileForURL(url);
+
+    if (file.exists()) {
+      let fileuri = Services.io.newFileURI(file);
+      return Services.io.newChannelFromURI(fileuri);
+    }
+
     return new Channel(aURI);
   },
 
   /**
    * Decides whether to allow a blacklisted port.
    * @return Always false, we'll never allow ports.
    */
   allowPort: function () false,
--- a/browser/components/thumbnails/test/Makefile.in
+++ b/browser/components/thumbnails/test/Makefile.in
@@ -9,16 +9,17 @@ VPATH		= @srcdir@
 relativesrcdir  = browser/components/thumbnails/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_FILES = \
 	browser_thumbnails_capture.js \
 	browser_thumbnails_redirect.js \
+	browser_thumbnails_storage.js \
 	browser_thumbnails_bug726727.js \
 	head.js \
 	background_red.html \
 	background_red_redirect.sjs \
 	$(NULL)
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
--- a/browser/components/thumbnails/test/browser_thumbnails_redirect.js
+++ b/browser/components/thumbnails/test/browser_thumbnails_redirect.js
@@ -1,51 +1,32 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const URL = "http://mochi.test:8888/browser/browser/components/thumbnails/" +
             "test/background_red_redirect.sjs";
 
-let cacheService = Cc["@mozilla.org/network/cache-service;1"]
-                   .getService(Ci.nsICacheService);
-
 /**
  * These tests ensure that we save and provide thumbnails for redirecting sites.
  */
 function runTests() {
   // Kick off history by loading a tab first or the test fails in single mode.
   yield addTab(URL);
   gBrowser.removeTab(gBrowser.selectedTab);
 
   // Create a tab, redirecting to a page with a red background.
   yield addTab(URL);
   yield captureAndCheckColor(255, 0, 0, "we have a red thumbnail");
 
-  // Wait until the referrer's thumbnail's cache entry has been written.
-  yield whenCacheEntryExists(URL);
+  // Wait until the referrer's thumbnail's file has been written.
+  yield whenFileExists(URL);
   yield checkThumbnailColor(URL, 255, 0, 0, "referrer has a red thumbnail");
 }
 
-function whenCacheEntryExists(aKey) {
+function whenFileExists(aURL) {
   let callback = next;
 
-  checkCacheEntryExists(aKey, function (aExists) {
-    if (!aExists)
-      callback = function () whenCacheEntryExists(aKey);
-
-    executeSoon(callback);
-  });
-}
+  let file = PageThumbsStorage.getFileForURL(aURL);
+  if (!file.exists())
+    callback = function () whenFileExists(aURL);
 
-function checkCacheEntryExists(aKey, aCallback) {
-  PageThumbsCache.getReadEntry(aKey, function (aEntry) {
-    let inputStream = aEntry && aEntry.openInputStream(0);
-    let exists = inputStream && inputStream.available();
-
-    if (inputStream)
-      inputStream.close();
-
-    if (aEntry)
-      aEntry.close();
-
-    aCallback(exists);
-  });
+  executeSoon(callback);
 }
new file mode 100644
--- /dev/null
+++ b/browser/components/thumbnails/test/browser_thumbnails_storage.js
@@ -0,0 +1,89 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const URL = "http://mochi.test:8888/";
+const URL_COPY = URL + "#copy";
+
+XPCOMUtils.defineLazyGetter(this, "Sanitizer", function () {
+  let tmp = {};
+  Cc["@mozilla.org/moz/jssubscript-loader;1"]
+    .getService(Ci.mozIJSSubScriptLoader)
+    .loadSubScript("chrome://browser/content/sanitize.js", tmp);
+  return tmp.Sanitizer;
+});
+
+/**
+ * These tests ensure that the thumbnail storage is working as intended.
+ * Newly captured thumbnails should be saved as files and they should as well
+ * be removed when the user sanitizes their history.
+ */
+function runTests() {
+  clearHistory();
+
+  // create a thumbnail
+  yield addTab(URL);
+  yield whenFileExists();
+  gBrowser.removeTab(gBrowser.selectedTab);
+
+  // clear all browser history
+  yield clearHistory();
+
+  // create a thumbnail
+  yield addTab(URL);
+  yield whenFileExists();
+  gBrowser.removeTab(gBrowser.selectedTab);
+
+  // make sure copy() updates an existing file
+  PageThumbsStorage.copy(URL, URL_COPY);
+  let copy = PageThumbsStorage.getFileForURL(URL_COPY);
+  let mtime = copy.lastModifiedTime -= 60;
+
+  PageThumbsStorage.copy(URL, URL_COPY);
+  isnot(PageThumbsStorage.getFileForURL(URL_COPY).lastModifiedTime, mtime,
+        "thumbnail file was updated");
+
+  // clear last 10 mins of history
+  yield clearHistory(true);
+  ok(!copy.exists(), "copy of thumbnail has been removed");
+}
+
+function clearHistory(aUseRange) {
+  let s = new Sanitizer();
+  s.prefDomain = "privacy.cpd.";
+
+  let prefs = gPrefService.getBranch(s.prefDomain);
+  prefs.setBoolPref("history", true);
+  prefs.setBoolPref("downloads", false);
+  prefs.setBoolPref("cache", false);
+  prefs.setBoolPref("cookies", false);
+  prefs.setBoolPref("formdata", false);
+  prefs.setBoolPref("offlineApps", false);
+  prefs.setBoolPref("passwords", false);
+  prefs.setBoolPref("sessions", false);
+  prefs.setBoolPref("siteSettings", false);
+
+  if (aUseRange) {
+    let usec = Date.now() * 1000;
+    s.range = [usec - 10 * 60 * 1000 * 1000, usec];
+  }
+
+  s.sanitize();
+  s.range = null;
+
+  executeSoon(function () {
+    if (PageThumbsStorage.getFileForURL(URL).exists())
+      clearHistory(aFile, aUseRange);
+    else
+      next();
+  });
+}
+
+function whenFileExists() {
+  let callback = whenFileExists;
+
+  let file = PageThumbsStorage.getFileForURL(URL);
+  if (file.exists() && file.fileSize)
+    callback = next;
+
+  executeSoon(callback);
+}
--- a/browser/components/thumbnails/test/head.js
+++ b/browser/components/thumbnails/test/head.js
@@ -1,15 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 let tmp = {};
 Cu.import("resource:///modules/PageThumbs.jsm", tmp);
 let PageThumbs = tmp.PageThumbs;
-let PageThumbsCache = tmp.PageThumbsCache;
+let PageThumbsStorage = tmp.PageThumbsStorage;
 
 registerCleanupFunction(function () {
   while (gBrowser.tabs.length > 1)
     gBrowser.removeTab(gBrowser.tabs[1]);
 });
 
 let cachedXULDocument;
 
--- a/browser/devtools/debugger/DebuggerUI.jsm
+++ b/browser/devtools/debugger/DebuggerUI.jsm
@@ -40,137 +40,90 @@
  *
  * ***** END LICENSE BLOCK ***** */
 "use strict";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
-const DBG_XUL = "chrome://browser/content/debugger.xul";
-const REMOTE_PROFILE_NAME = "_remote-debug";
-
-Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 let EXPORTED_SYMBOLS = ["DebuggerUI"];
 
 /**
  * Provides a simple mechanism of managing debugger instances per tab.
  *
  * @param nsIDOMWindow aWindow
  *        The chrome window for which the DebuggerUI instance is created.
  */
 function DebuggerUI(aWindow) {
   this.chromeWindow = aWindow;
 }
 
 DebuggerUI.prototype = {
-  /**
-   * Called by the DebuggerPane to update the Debugger toggle switches with the
-   * debugger state.
-   */
-  refreshCommand: function DUI_refreshCommand() {
-    let selectedTab = this.chromeWindow.getBrowser().selectedTab;
-    let command = this.chromeWindow.document.getElementById("Tools:Debugger");
-
-    if (this.getDebugger(selectedTab) != null) {
-      command.setAttribute("checked", "true");
-    } else {
-      command.removeAttribute("checked");
-    }
-  },
 
   /**
    * Starts a debugger for the current tab, or stops it if already started.
    * @return DebuggerPane if the debugger is started, null if it's stopped.
    */
   toggleDebugger: function DUI_toggleDebugger() {
     let tab = this.chromeWindow.gBrowser.selectedTab;
 
     if (tab._scriptDebugger) {
       tab._scriptDebugger.close();
       return null;
     }
-    return new DebuggerPane(this, tab);
-  },
-
-  /**
-   * Starts a remote debugger in a new process, or stops it if already started.
-   * @see DebuggerProcess.constructor
-   * @return DebuggerProcess if the debugger is started, null if it's stopped.
-   */
-  toggleRemoteDebugger: function DUI_toggleRemoteDebugger(aOnClose, aOnRun) {
-    let win = this.chromeWindow;
-
-    if (win._remoteDebugger) {
-      win._remoteDebugger.close();
-      return null;
-    }
-    return new DebuggerProcess(win, aOnClose, aOnRun);
+    return new DebuggerPane(tab);
   },
 
   /**
    * Get the debugger for a specified tab.
    * @return DebuggerPane if a debugger exists for the tab, null otherwise
    */
   getDebugger: function DUI_getDebugger(aTab) {
-    return '_scriptDebugger' in aTab ? aTab._scriptDebugger : null;
+    return aTab._scriptDebugger;
   },
 
   /**
    * Get the preferences associated with the debugger frontend.
    * @return object
    */
   get preferences() {
-    return DebuggerPreferences;
+    return DebuggerUIPreferences;
   }
 };
 
 /**
  * Creates a pane that will host the debugger.
  *
  * @param XULElement aTab
  *        The tab in which to create the debugger.
  */
-function DebuggerPane(aDebuggerUI, aTab) {
-  this._globalUI = aDebuggerUI;
+function DebuggerPane(aTab) {
   this._tab = aTab;
-  this._initServer();
   this._create();
 }
 
 DebuggerPane.prototype = {
 
   /**
-   * Initializes the debugger server.
-   */
-  _initServer: function DP__initServer() {
-    if (!DebuggerServer.initialized) {
-      DebuggerServer.init();
-      DebuggerServer.addBrowserActors();
-    }
-  },
-
-  /**
    * Creates and initializes the widgets containing the debugger UI.
    */
   _create: function DP__create() {
     this._tab._scriptDebugger = this;
 
     let gBrowser = this._tab.linkedBrowser.getTabBrowser();
     let ownerDocument = gBrowser.parentNode.ownerDocument;
 
     this._splitter = ownerDocument.createElement("splitter");
     this._splitter.setAttribute("class", "hud-splitter");
 
     this._frame = ownerDocument.createElement("iframe");
-    this._frame.height = DebuggerPreferences.height;
+    this._frame.height = DebuggerUIPreferences.height;
 
     this._nbox = gBrowser.getNotificationBox(this._tab.linkedBrowser);
     this._nbox.appendChild(this._splitter);
     this._nbox.appendChild(this._frame);
 
     this.close = this.close.bind(this);
     let self = this;
 
@@ -181,43 +134,39 @@ DebuggerPane.prototype = {
 
       // Bind shortcuts for accessing the breakpoint methods in the debugger.
       let bkp = self.debuggerWindow.DebuggerController.Breakpoints;
       self.addBreakpoint = bkp.addBreakpoint;
       self.removeBreakpoint = bkp.removeBreakpoint;
       self.getBreakpoint = bkp.getBreakpoint;
     }, true);
 
-    this._frame.setAttribute("src", DBG_XUL);
-
-    this._globalUI.refreshCommand();
+    this._frame.setAttribute("src", "chrome://browser/content/debugger.xul");
   },
 
   /**
    * Closes the debugger, removing child nodes and event listeners.
    */
   close: function DP_close() {
     if (!this._tab) {
       return;
     }
-    delete this._tab._scriptDebugger;
+    this._tab._scriptDebugger = null;
     this._tab = null;
 
-    DebuggerPreferences.height = this._frame.height;
+    DebuggerUIPreferences.height = this._frame.height;
     this._frame.removeEventListener("Debugger:Close", this.close, true);
     this._frame.removeEventListener("unload", this.close, true);
 
     this._nbox.removeChild(this._splitter);
     this._nbox.removeChild(this._frame);
 
     this._splitter = null;
     this._frame = null;
     this._nbox = null;
-
-    this._globalUI.refreshCommand();
   },
 
   /**
    * Gets the debugger content window.
    * @return nsIDOMWindow if a debugger window exists, null otherwise
    */
   get debuggerWindow() {
     return this._frame ? this._frame.contentWindow : null;
@@ -232,122 +181,19 @@ DebuggerPane.prototype = {
     if (debuggerWindow) {
       return debuggerWindow.DebuggerController.Breakpoints.store;
     }
     return null;
   }
 };
 
 /**
- * Creates a process that will hold the remote debugger.
- *
- * @param function aOnClose
- *        Optional, a function called when the process exits.
- * @param function aOnRun
- *        Optional, a function called when the process starts running.
- * @param nsIDOMWindow aWindow
- *        The chrome window for which the remote debugger instance is created.
+ * Various debugger UI preferences (currently just the pane height).
  */
-function DebuggerProcess(aWindow, aOnClose, aOnRun) {
-  this._win = aWindow;
-  this._closeCallback = aOnClose;
-  this._runCallback = aOnRun;
-  this._initProfile();
-  this._create();
-}
-
-DebuggerProcess.prototype = {
-
-  /**
-   * Initializes the debugger server.
-   */
-  _initServer: function RDP__initServer() {
-    if (!DebuggerServer.initialized) {
-      DebuggerServer.init();
-      DebuggerServer.addBrowserActors();
-    }
-    DebuggerServer.closeListener();
-    DebuggerServer.openListener(DebuggerPreferences.remotePort, false);
-  },
-
-  /**
-   * Initializes a profile for the remote debugger process.
-   */
-  _initProfile: function RDP__initProfile() {
-    let profileService = Cc["@mozilla.org/toolkit/profile-service;1"]
-      .createInstance(Ci.nsIToolkitProfileService);
-
-    let dbgProfileName;
-    try {
-      dbgProfileName = profileService.selectedProfile.name + REMOTE_PROFILE_NAME;
-    } catch(e) {
-      dbgProfileName = REMOTE_PROFILE_NAME;
-      Cu.reportError(e);
-    }
-
-    this._dbgProfile = profileService.createProfile(null, null, dbgProfileName);
-    profileService.flush();
-  },
-
-  /**
-   * Creates and initializes the profile & process for the remote debugger.
-   */
-  _create: function RDP__create() {
-    this._win._remoteDebugger = this;
-
-    let file = FileUtils.getFile("CurProcD",
-      [Services.appinfo.OS == "WINNT" ? "firefox.exe"
-                                      : "firefox-bin"]);
-
-    let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
-    process.init(file);
-
-    let args = [
-      "-no-remote", "-P", this._dbgProfile.name,
-      "-chrome", DBG_XUL,
-      "-width", DebuggerPreferences.remoteWinWidth,
-      "-height", DebuggerPreferences.remoteWinHeight];
-
-    process.runwAsync(args, args.length, { observe: this.close.bind(this) });
-    this._dbgProcess = process;
-
-    if (typeof this._runCallback === "function") {
-      this._runCallback.call({}, this);
-    }
-  },
-
-  /**
-   * Closes the remote debugger, removing the profile and killing the process.
-   */
-  close: function RDP_close() {
-    if (!this._win) {
-      return;
-    }
-    delete this._win._remoteDebugger;
-    this._win = null;
-
-    if (this._dbgProcess.isRunning) {
-      this._dbgProcess.kill();
-    }
-    if (this._dbgProfile) {
-      this._dbgProfile.remove(false);
-    }
-    if (typeof this._closeCallback === "function") {
-      this._closeCallback.call({}, this);
-    }
-
-    this._dbgProcess = null;
-    this._dbgProfile = null;
-  }
-};
-
-/**
- * Various debugger preferences.
- */
-let DebuggerPreferences = {
+let DebuggerUIPreferences = {
 
   /**
    * Gets the preferred height of the debugger pane.
    * @return number
    */
   get height() {
     if (this._height === undefined) {
       this._height = Services.prefs.getIntPref("devtools.debugger.ui.height");
@@ -359,40 +205,8 @@ let DebuggerPreferences = {
    * Sets the preferred height of the debugger pane.
    * @param number value
    */
   set height(value) {
     Services.prefs.setIntPref("devtools.debugger.ui.height", value);
     this._height = value;
   }
 };
-
-/**
- * Gets the preferred width of the remote debugger window.
- * @return number
- */
-XPCOMUtils.defineLazyGetter(DebuggerPreferences, "remoteWinWidth", function() {
-  return Services.prefs.getIntPref("devtools.debugger.ui.remote-win.width");
-});
-
-/**
- * Gets the preferred height of the remote debugger window.
- * @return number
- */
-XPCOMUtils.defineLazyGetter(DebuggerPreferences, "remoteWinHeight", function() {
-  return Services.prefs.getIntPref("devtools.debugger.ui.remote-win.height");
-});
-
-/**
- * Gets the preferred default remote debugging host.
- * @return string
- */
-XPCOMUtils.defineLazyGetter(DebuggerPreferences, "remoteHost", function() {
-  return Services.prefs.getCharPref("devtools.debugger.remote-host");
-});
-
-/**
- * Gets the preferred default remote debugging port.
- * @return number
- */
-XPCOMUtils.defineLazyGetter(DebuggerPreferences, "remotePort", function() {
-  return Services.prefs.getIntPref("devtools.debugger.remote-port");
-});
--- a/browser/devtools/debugger/debugger-controller.js
+++ b/browser/devtools/debugger/debugger-controller.js
@@ -109,28 +109,29 @@ let DebuggerController = {
     DebuggerView.Properties.destroy();
 
     DebuggerController.SourceScripts.disconnect();
     DebuggerController.StackFrames.disconnect();
     DebuggerController.ThreadState.disconnect();
 
     this.dispatchEvent("Debugger:Unloaded");
     this._disconnect();
-    this._isRemote && this._quitApp();
   },
 
   /**
    * Initializes a debugger client and connects it to the debugger server,
    * wiring event handlers as necessary.
    */
   _connect: function DC__connect() {
-    let transport =
-      this._isRemote ? debuggerSocketConnect(Prefs.remoteHost, Prefs.remotePort)
-                     : DebuggerServer.connectPipe();
+    if (!DebuggerServer.initialized) {
+      DebuggerServer.init();
+      DebuggerServer.addBrowserActors();
+    }
 
+    let transport = DebuggerServer.connectPipe();
     let client = this.client = new DebuggerClient(transport);
 
     client.addListener("tabNavigated", this._onTabNavigated);
     client.addListener("tabDetached", this._onTabDetached);
 
     client.connect(function(aType, aTraits) {
       client.listTabs(function(aResponse) {
         let tab = aResponse.tabs[aResponse.selected];
@@ -215,41 +216,16 @@ let DebuggerController = {
           });
         });
 
       }.bind(this));
     }.bind(this));
   },
 
   /**
-   * Returns true if this is a remote debugger instance.
-   * @return boolean
-   */
-  get _isRemote() {
-    return !window.parent.content;
-  },
-
-  /**
-   * Attempts to quit the current process if allowed.
-   */
-  _quitApp: function DC__quitApp() {
-    let canceled = Cc["@mozilla.org/supports-PRBool;1"]
-      .createInstance(Ci.nsISupportsPRBool);
-
-    Services.obs.notifyObservers(canceled, "quit-application-requested", null);
-
-    // Somebody canceled our quit request.
-    if (canceled.data) {
-      return;
-    }
-
-    Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit);
-  },
-
-  /**
    * Convenience method, dispatching a custom event.
    *
    * @param string aType
    *        The name of the event.
    * @param string aDetail
    *        The data passed when initializing the event.
    */
   dispatchEvent: function DC_dispatchEvent(aType, aDetail) {
@@ -489,71 +465,52 @@ StackFrames.prototype = {
       let thisVar = localScope.addVar("this");
       thisVar.setGrip({
         type: frame.this.type,
         class: frame.this.class
       });
       this._addExpander(thisVar, frame.this);
     }
 
-    if (frame.environment) {
-      // Add nodes for every argument.
-      let variables = frame.environment.bindings.arguments;
-      for each (let variable in variables) {
-        let name = Object.getOwnPropertyNames(variable)[0];
-        let paramVar = localScope.addVar(name);
-        let paramVal = variable[name].value;
-        paramVar.setGrip(paramVal);
-        this._addExpander(paramVar, paramVal);
-      }
-
-      // Add nodes for every other variable in scope.
-      variables = frame.environment.bindings.variables;
-      for (let variable in variables) {
-        let paramVar = localScope.addVar(variable);
-        let paramVal = variables[variable].value;
-        paramVar.setGrip(paramVal);
-        this._addExpander(paramVar, paramVal);
-      }
-
-      // If we already found 'arguments', we are done here.
-      if ("arguments" in frame.environment.bindings.variables) {
-        // Signal that variables have been fetched.
-        DebuggerController.dispatchEvent("Debugger:FetchedVariables");
-        return;
-      }
-    }
-
-    // Sometimes in call frames with arguments we don't get 'arguments' in the
-    // environment (bug 746601) and we have to construct it manually. Note, that
-    // in this case arguments.callee will be absent, even in the cases where it
-    // shouldn't be.
     if (frame.arguments && frame.arguments.length > 0) {
       // Add "arguments".
       let argsVar = localScope.addVar("arguments");
       argsVar.setGrip({
         type: "object",
         class: "Arguments"
       });
       this._addExpander(argsVar, frame.arguments);
 
-      // Signal that variables have been fetched.
-      DebuggerController.dispatchEvent("Debugger:FetchedVariables");
+      // Add variables for every argument.
+      let objClient = this.activeThread.pauseGrip(frame.callee);
+      objClient.getSignature(function SF_getSignature(aResponse) {
+        for (let i = 0, l = aResponse.parameters.length; i < l; i++) {
+          let param = aResponse.parameters[i];
+          let paramVar = localScope.addVar(param);
+          let paramVal = frame.arguments[i];
+
+          paramVar.setGrip(paramVal);
+          this._addExpander(paramVar, paramVal);
+        }
+
+        // Signal that call parameters have been fetched.
+        DebuggerController.dispatchEvent("Debugger:FetchedParameters");
+
+      }.bind(this));
     }
-
   },
 
   /**
-   * Adds an 'onexpand' callback for a variable, lazily handling the addition of
+   * Adds a onexpand callback for a variable, lazily handling the addition of
    * new properties.
    */
   _addExpander: function SF__addExpander(aVar, aObject) {
     // No need for expansion for null and undefined values, but we do need them
     // for frame.arguments which is a regular array.
-    if (!aVar || !aObject || typeof aObject !== "object" ||
+    if (!aObject || typeof aObject !== "object" ||
         (aObject.type !== "object" && !Array.isArray(aObject))) {
       return;
     }
 
     // Force the twisty to show up.
     aVar.forceShowArrow();
     aVar.onexpand = this._addVarProperties.bind(this, aVar, aObject);
   },
@@ -724,27 +681,26 @@ SourceScripts.prototype = {
     this.activeThread.removeListener("scriptsadded", this._onScriptsAdded);
     this.activeThread.removeListener("scriptscleared", this._onScriptsCleared);
   },
 
   /**
    * Handler for the debugger client's unsolicited newScript notification.
    */
   _onNewScript: function SS__onNewScript(aNotification, aPacket) {
-    this._addScript({ url: aPacket.url, startLine: aPacket.startLine }, true);
+    this._addScript({ url: aPacket.url, startLine: aPacket.startLine });
   },
 
   /**
    * Handler for the thread client's scriptsadded notification.
    */
   _onScriptsAdded: function SS__onScriptsAdded() {
     for each (let script in this.activeThread.cachedScripts) {
-      this._addScript(script, false);
+      this._addScript(script);
     }
-    DebuggerView.Scripts.commitScripts();
   },
 
   /**
    * Handler for the thread client's scriptscleared notification.
    */
   _onScriptsCleared: function SS__onScriptsCleared() {
     DebuggerView.Scripts.empty();
   },
@@ -787,70 +743,51 @@ SourceScripts.prototype = {
     let q = aUrl.indexOf('?');
     if (q > -1) {
       return aUrl.slice(0, q);
     }
     return aUrl;
   },
 
   /**
-   * Gets the prePath for a script URL.
-   *
-   * @param string aUrl
-   *        The script url.
-   * @return string
-   *         The script prePath if the url is valid, null otherwise.
-   */
-  _getScriptPrePath: function SS__getScriptDomain(aUrl) {
-    try {
-      return Services.io.newURI(aUrl, null, null).prePath + "/";
-    } catch (e) {
-    }
-    return null;
-  },
-
-  /**
    * Gets a unique, simplified label from a script url.
    * ex: a). ici://some.address.com/random/subrandom/
    *     b). ni://another.address.org/random/subrandom/page.html
    *     c). san://interesting.address.gro/random/script.js
    *     d). si://interesting.address.moc/random/another/script.js
    * =>
    *     a). subrandom/
    *     b). page.html
    *     c). script.js
    *     d). another/script.js
    *
    * @param string aUrl
    *        The script url.
    * @param string aHref
    *        The content location href to be used. If unspecified, it will
-   *        default to the script url prepath.
+   *        defalult to debugged panrent window location.
    * @return string
    *         The simplified label.
    */
   _getScriptLabel: function SS__getScriptLabel(aUrl, aHref) {
     let url = this._trimUrlQuery(aUrl);
 
     if (this._labelsCache[url]) {
       return this._labelsCache[url];
     }
 
-    let content = window.parent.content;
-    let domain = content ? content.location.href : this._getScriptPrePath(aUrl);
-
-    let href = aHref || domain;
+    let href = aHref || window.parent.content.location.href;
     let pathElements = url.split("/");
     let label = pathElements.pop() || (pathElements.pop() + "/");
 
-    // If the label as a leaf name is already present in the scripts list.
+    // if the label as a leaf name is alreay present in the scripts list
     if (DebuggerView.Scripts.containsLabel(label)) {
       label = url.replace(href.substring(0, href.lastIndexOf("/") + 1), "");
 
-      // If the path/to/script is exactly the same, we're in different domains.
+      // if the path/to/script is exactly the same, we're in different domains
       if (DebuggerView.Scripts.containsLabel(label)) {
         label = url;
       }
     }
 
     return this._labelsCache[url] = label;
   },
 
@@ -858,26 +795,25 @@ SourceScripts.prototype = {
    * Clears the labels cache, populated by SS_getScriptLabel.
    * This should be done every time the content location changes.
    */
   _clearLabelsCache: function SS__clearLabelsCache() {
     this._labelsCache = {};
   },
 
   /**
-   * Add the specified script to the list.
-   *
-   * @param object aScript
-   *        The script object coming from the active thread.
-   * @param boolean aForceFlag
-   *        True to force the script to be immediately added.
+   * Add the specified script to the list and display it in the editor if the
+   * editor is empty.
    */
-  _addScript: function SS__addScript(aScript, aForceFlag) {
-    DebuggerView.Scripts.addScript(
-      this._getScriptLabel(aScript.url), aScript, aForceFlag);
+  _addScript: function SS__addScript(aScript) {
+    DebuggerView.Scripts.addScript(this._getScriptLabel(aScript.url), aScript);
+
+    if (DebuggerView.editor.getCharCount() == 0) {
+      this.showScript(aScript);
+    }
   },
 
   /**
    * Load the editor with the script text if available, otherwise fire an event
    * to load and display the script text.
    *
    * @param object aScript
    *        The script object coming from the active thread.
@@ -935,17 +871,17 @@ SourceScripts.prototype = {
       url: aScript.url
     });
   },
 
   /**
    * Handles notifications to load a source script from the cache or from a
    * local file.
    *
-   * XXX: It may be better to use nsITraceableChannel to get to the sources
+   * XXX: Tt may be better to use nsITraceableChannel to get to the sources
    * without relying on caching when we can (not for eval, etc.):
    * http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/
    */
   _onLoadSource: function SS__onLoadSource(aEvent) {
     let url = aEvent.detail.url;
     let options = aEvent.detail.options;
     let self = this;
 
@@ -1026,17 +962,17 @@ SourceScripts.prototype = {
    * Log an error message in the error console when a script fails to load.
    *
    * @param string aUrl
    *        The URL of the source script.
    * @param string aStatus
    *        The failure status code.
    */
   _logError: function SS__logError(aUrl, aStatus) {
-    Cu.reportError(L10N.getFormatStr("loadingError", [aUrl, aStatus]));
+    Components.utils.reportError(L10N.getFormatStr("loadingError", [aUrl, aStatus]));
   },
 };
 
 /**
  * Handles all the breakpoints in the current debugger.
  */
 function Breakpoints() {
   this._onEditorBreakpointChange = this._onEditorBreakpointChange.bind(this);
@@ -1318,37 +1254,16 @@ let L10N = {
   }
 };
 
 XPCOMUtils.defineLazyGetter(L10N, "stringBundle", function() {
   return Services.strings.createBundle(DBG_STRINGS_URI);
 });
 
 /**
- * Shortcuts for accessing various debugger preferences.
- */
-let Prefs = {};
-
-/**
- * Gets the preferred default remote debugging host.
- * @return string
- */
-XPCOMUtils.defineLazyGetter(Prefs, "remoteHost", function() {
-  return Services.prefs.getCharPref("devtools.debugger.remote-host");
-});
-
-/**
- * Gets the preferred default remote debugging port.
- * @return number
- */
-XPCOMUtils.defineLazyGetter(Prefs, "remotePort", function() {
-  return Services.prefs.getIntPref("devtools.debugger.remote-port");
-});
-
-/**
  * Preliminary setup for the DebuggerController object.
  */
 DebuggerController.init();
 DebuggerController.ThreadState = new ThreadState();
 DebuggerController.StackFrames = new StackFrames();
 DebuggerController.SourceScripts = new SourceScripts();
 DebuggerController.Breakpoints = new Breakpoints();
 
--- a/browser/devtools/debugger/debugger-view.js
+++ b/browser/devtools/debugger/debugger-view.js
@@ -85,72 +85,53 @@ let DebuggerView = {
   }
 };
 
 /**
  * Functions handling the scripts UI.
  */
 function ScriptsView() {
   this._onScriptsChange = this._onScriptsChange.bind(this);
-  this._onScriptsSearch = this._onScriptsSearch.bind(this);
 }
 
 ScriptsView.prototype = {
 
   /**
    * Removes all elements from the scripts container, leaving it empty.
    */
   empty: function DVS_empty() {
     while (this._scripts.firstChild) {
       this._scripts.removeChild(this._scripts.firstChild);
     }
   },
 
   /**
-   * Removes the input in the searchbox and unhides all the scripts.
-   */
-  clearSearch: function DVS_clearSearch() {
-    this._searchbox.value = "";
-    this._onScriptsSearch({});
-  },
-
-  /**
    * Checks whether the script with the specified URL is among the scripts
    * known to the debugger and shown in the list.
    *
    * @param string aUrl
    *        The script URL.
    * @return boolean
    */
   contains: function DVS_contains(aUrl) {
-    if (this._tmpScripts.some(function(element) {
-      return element.script.url == aUrl;
-    })) {
-      return true;
-    }
     if (this._scripts.getElementsByAttribute("value", aUrl).length > 0) {
       return true;
     }
     return false;
   },
 
   /**
    * Checks whether the script with the specified label is among the scripts
    * known to the debugger and shown in the list.
    *
    * @param string aLabel
    *        The script label.
    * @return boolean
    */
   containsLabel: function DVS_containsLabel(aLabel) {
-    if (this._tmpScripts.some(function(element) {
-      return element.label == aLabel;
-    })) {
-      return true;
-    }
     if (this._scripts.getElementsByAttribute("label", aLabel).length > 0) {
       return true;
     }
     return false;
   },
 
   /**
    * Selects the script with the specified URL from the list.
@@ -186,258 +167,80 @@ ScriptsView.prototype = {
    * @return string | null
    */
   get selected() {
     return this._scripts.selectedItem ?
            this._scripts.selectedItem.value : null;
   },
 
   /**
-   * Returns the list of labels in the scripts container.
-   * @return array
-   */
-  get scriptLabels() {
-    let labels = [];
-    for (let i = 0, l = this._scripts.itemCount; i < l; i++) {
-      labels.push(this._scripts.getItemAtIndex(i).label);
-    }
-    return labels;
-  },
-
-  /**
    * Returns the list of URIs for scripts in the page.
    * @return array
    */
   get scriptLocations() {
     let locations = [];
     for (let i = 0, l = this._scripts.itemCount; i < l; i++) {
       locations.push(this._scripts.getItemAtIndex(i).value);
     }
     return locations;
   },
 
   /**
-   * Gets the number of visible (hidden=false) scripts in the container.
-   * @return number
-   */
-  get visibleItemsCount() {
-    let count = 0;
-    for (let i = 0, l = this._scripts.itemCount; i < l; i++) {
-      count += this._scripts.getItemAtIndex(i).hidden ? 0 : 1;
-    }
-    return count;
-  },
-
-  /**
-   * Prepares a script to be added to the scripts container. This allows
-   * for a large number of scripts to be batched up before being
-   * alphabetically sorted and added in the container.
-   * @see ScriptsView.commitScripts
-   *
-   * If aForceFlag is true, the script will be immediately inserted at the
-   * necessary position in the container so that all the scripts remain sorted.
-   * This can be much slower than batching up multiple scripts.
-   *
-   * @param string aLabel
-   *        The simplified script location to be shown.
-   * @param string aScript
-   *        The source script.
-   * @param boolean aForceFlag
-   *        True to force the script to be immediately added.
-   */
-  addScript: function DVS_addScript(aLabel, aScript, aForceFlag) {
-    // Batch the script to be added later.
-    if (!aForceFlag) {
-      this._tmpScripts.push({ label: aLabel, script: aScript });
-      return;
-    }
-
-    // Find the target position in the menulist and insert the script there.
-    for (let i = 0, l = this._scripts.itemCount; i < l; i++) {
-      if (this._scripts.getItemAtIndex(i).label > aLabel) {
-        this._createScriptElement(aLabel, aScript, i);
-        return;
-      }
-    }
-    // The script is alphabetically the last one.
-    this._createScriptElement(aLabel, aScript, -1, true);
-  },
-
-  /**
-   * Adds all the prepared scripts to the scripts container.
-   * If a script already exists (was previously added), nothing happens.
-   */
-  commitScripts: function DVS_commitScripts() {
-    let newScripts = this._tmpScripts;
-    this._tmpScripts = [];
-
-    if (!newScripts || !newScripts.length) {
-      return;
-    }
-    newScripts.sort(function(a, b) {
-      return a.label.toLowerCase() > b.label.toLowerCase();
-    });
-
-    for (let i = 0, l = newScripts.length; i < l; i++) {
-      let item = newScripts[i];
-      this._createScriptElement(item.label, item.script, -1, true);
-    }
-  },
-
-  /**
-   * Creates a custom script element and adds it to the scripts container.
-   * If the script with the specified label already exists, nothing happens.
+   * Adds a script to the scripts container.
+   * If the script already exists (was previously added), null is returned.
+   * Otherwise, the newly created element is returned.
    *
    * @param string aLabel
    *        The simplified script location to be shown.
    * @param string aScript
    *        The source script.
-   * @param number aIndex
-   *        The index where to insert to new script in the container.
-   *        Pass -1 to append the script at the end.
-   * @param boolean aSelectIfEmptyFlag
-   *        True to set the newly created script as the currently selected item
-   *        if there are no other existing scripts in the container.
+   * @return object
+   *         The newly created html node representing the added script.
    */
-  _createScriptElement: function DVS__createScriptElement(
-    aLabel, aScript, aIndex, aSelectIfEmptyFlag)
-  {
+  addScript: function DVS_addScript(aLabel, aScript) {
     // Make sure we don't duplicate anything.
-    if (aLabel == "null" || this.containsLabel(aLabel)) {
-      return;
+    if (this.containsLabel(aLabel)) {
+      return null;
     }
 
-    let scriptItem =
-      aIndex == -1 ? this._scripts.appendItem(aLabel, aScript.url)
-                   : this._scripts.insertItemAt(aIndex, aLabel, aScript.url);
+    let script = this._scripts.appendItem(aLabel, aScript.url);
+    script.setAttribute("tooltiptext", aScript.url);
+    script.setUserData("sourceScript", aScript, null);
 
-    scriptItem.setAttribute("tooltiptext", aScript.url);
-    scriptItem.setUserData("sourceScript", aScript, null);
-
-    if (this._scripts.itemCount == 1 && aSelectIfEmptyFlag) {
-      this._scripts.selectedItem = scriptItem;
-    }
+    this._scripts.selectedItem = script;
+    return script;
   },
 
   /**
-   * The click listener for the scripts container.
+   * The cached click listener for the scripts container.
    */
   _onScriptsChange: function DVS__onScriptsChange() {
     let script = this._scripts.selectedItem.getUserData("sourceScript");
-    this._preferredScript = script;
     DebuggerController.SourceScripts.showScript(script);
   },
 
   /**
-   * The search listener for the scripts search box.
-   */
-  _onScriptsSearch: function DVS__onScriptsSearch(e) {
-    let editor = DebuggerView.editor;
-    let scripts = this._scripts;
-    let rawValue = this._searchbox.value.toLowerCase();
-
-    let rawLength = rawValue.length;
-    let lastColon = rawValue.lastIndexOf(":");
-    let lastAt = rawValue.lastIndexOf("@");
-
-    let fileEnd = lastColon != -1 ? lastColon : lastAt != -1 ? lastAt : rawLength;
-    let lineEnd = lastAt != -1 ? lastAt : rawLength;
-
-    let file = rawValue.slice(0, fileEnd);
-    let line = window.parseInt(rawValue.slice(fileEnd + 1, lineEnd)) || -1;
-    let token = rawValue.slice(lineEnd + 1);
-
-    // Presume we won't find anything.
-    scripts.selectedItem = this._preferredScript;
-
-    // If we're not searching for a file anymore, unhide all the scripts.
-    if (!file) {
-      for (let i = 0, l = scripts.itemCount; i < l; i++) {
-        scripts.getItemAtIndex(i).hidden = false;
-      }
-    } else {
-      for (let i = 0, l = scripts.itemCount, found = false; i < l; i++) {
-        let item = scripts.getItemAtIndex(i);
-        let target = item.value.toLowerCase();
-
-        // Search is not case sensitive, and is tied to the url not the label.
-        if (target.match(file)) {
-          item.hidden = false;
-
-          if (!found) {
-            found = true;
-            scripts.selectedItem = item;
-          }
-        }
-        // Hide what doesn't match our search.
-        else {
-          item.hidden = true;
-        }
-      }
-    }
-    if (line > -1) {
-      editor.setCaretPosition(line - 1);
-    }
-    if (token) {
-      let offset = editor.find(token, { ignoreCase: true });
-      if (offset > -1) {
-        editor.setCaretPosition(0);
-        editor.setCaretOffset(offset);
-      }
-    }
-  },
-
-  /**
-   * The keyup listener for the scripts search box.
-   */
-  _onScriptsKeyUp: function DVS__onScriptsKeyUp(e) {
-    if (e.keyCode === e.DOM_VK_ESCAPE) {
-      DebuggerView.editor.focus();
-      return;
-    }
-
-    if (e.keyCode === e.DOM_VK_RETURN || e.keyCode === e.DOM_VK_ENTER) {
-      let editor = DebuggerView.editor;
-      let offset = editor.findNext(true);
-      if (offset > -1) {
-        editor.setCaretPosition(0);
-        editor.setCaretOffset(offset);
-      }
-    }
-  },
-
-  /**
-   * The cached scripts container and search box.
+   * The cached scripts container.
    */
   _scripts: null,
-  _searchbox: null,
 
   /**
    * Initialization function, called when the debugger is initialized.
    */
   initialize: function DVS_initialize() {
     this._scripts = document.getElementById("scripts");
-    this._searchbox = document.getElementById("scripts-search");
     this._scripts.addEventListener("select", this._onScriptsChange, false);
-    this._searchbox.addEventListener("select", this._onScriptsSearch, false);
-    this._searchbox.addEventListener("input", this._onScriptsSearch, false);
-    this._searchbox.addEventListener("keyup", this._onScriptsKeyUp, false);
-    this.commitScripts();
   },
 
   /**
    * Destruction function, called when the debugger is shut down.
    */
   destroy: function DVS_destroy() {
     this._scripts.removeEventListener("select", this._onScriptsChange, false);
-    this._searchbox.removeEventListener("select", this._onScriptsSearch, false);
-    this._searchbox.removeEventListener("input", this._onScriptsSearch, false);
-    this._searchbox.removeEventListener("keyup", this._onScriptsKeyUp, false);
     this._scripts = null;
-    this._searchbox = null;
   }
 };
 
 /**
  * Functions handling the html stackframes UI.
  */
 function StackFramesView() {
   this._onFramesScroll = this._onFramesScroll.bind(this);
@@ -469,18 +272,16 @@ StackFramesView.prototype = {
     else if (aState == "attached") {
       status.textContent = L10N.getStr("runningState");
       resume.label = L10N.getStr("pauseLabel");
     }
     // No valid state parameter.
     else {
       status.textContent = "";
     }
-
-    DebuggerView.Scripts.clearSearch();
   },
 
   /**
    * Removes all elements from the stackframes container, leaving it empty.
    */
   empty: function DVF_empty() {
     while (this._frames.firstChild) {
       this._frames.removeChild(this._frames.firstChild);
@@ -494,17 +295,17 @@ StackFramesView.prototype = {
   emptyText: function DVF_emptyText() {
     // Make sure the container is empty first.
     this.empty();
 
     let item = document.createElement("div");
 
     // The empty node should look grayed out to avoid confusion.
     item.className = "empty list-item";
-    item.appendChild(document.createTextNode(L10N.getStr("emptyStackText")));
+    item.appendChild(document.createTextNode(L10N.getStr("emptyText")));
 
     this._frames.appendChild(item);
   },
 
   /**
    * Adds a frame to the stackframes container.
    * If the frame already exists (was previously added), null is returned.
    * Otherwise, the newly created element is returned.
@@ -575,17 +376,17 @@ StackFramesView.prototype = {
 
   /**
    * Deselects a frame from the stackframe container.
    *
    * @param number aDepth
    *        The frame depth specified by the debugger.
    */
   unhighlightFrame: function DVF_unhighlightFrame(aDepth) {
-    this.highlightFrame(aDepth, true);
+    this.highlightFrame(aDepth, true)
   },
 
   /**
    * Gets the current dirty state.
    *
    * @return boolean value
    *         True if should load more frames.
    */
--- a/browser/devtools/debugger/debugger.xul
+++ b/browser/devtools/debugger/debugger.xul
@@ -76,18 +76,16 @@
   <div id="body" class="vbox flex">
     <xul:toolbar id="dbg-toolbar">
       <xul:button id="close">&debuggerUI.closeButton;</xul:button>
       <xul:button id="resume"/>
       <xul:button id="step-over">&debuggerUI.stepOverButton;</xul:button>
       <xul:button id="step-in">&debuggerUI.stepInButton;</xul:button>
       <xul:button id="step-out">&debuggerUI.stepOutButton;</xul:button>
       <xul:menulist id="scripts"/>
-      <xul:textbox id="scripts-search" type="search"
-                   emptytext="&debuggerUI.emptyFilterText;"/>
     </xul:toolbar>
     <div id="dbg-content" class="hbox flex">
       <div id="stack" class="vbox">
         <div class="title unselectable">&debuggerUI.stackTitle;</div>
         <div id="stackframes" class="vbox flex"></div>
       </div>
       <div id="script" class="vbox flex">
         <div class="title unselectable">&debuggerUI.scriptTitle;</div>
--- a/browser/devtools/debugger/test/Makefile.in
+++ b/browser/devtools/debugger/test/Makefile.in
@@ -41,17 +41,16 @@ topsrcdir       = @top_srcdir@
 srcdir          = @srcdir@
 VPATH           = @srcdir@
 relativesrcdir  = browser/devtools/debugger/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_TEST_FILES = \
-	browser_dbg_createRemote.js \
 	browser_dbg_debuggerstatement.js \
 	browser_dbg_listtabs.js \
 	browser_dbg_tabactor-01.js \
 	browser_dbg_tabactor-02.js \
 	browser_dbg_contextactor-01.js \
 	browser_dbg_contextactor-02.js \
 	testactors.js \
 	browser_dbg_nav-01.js \
@@ -66,19 +65,16 @@ include $(topsrcdir)/config/rules.mk
 	browser_dbg_panesize.js \
 	browser_dbg_stack-01.js \
 	browser_dbg_stack-02.js \
 	browser_dbg_stack-03.js \
 	browser_dbg_stack-04.js \
 	browser_dbg_stack-05.js \
 	browser_dbg_location-changes.js \
 	browser_dbg_script-switching.js \
-	browser_dbg_scripts-sorting.js \
-	browser_dbg_scripts-searching-01.js \
-	browser_dbg_scripts-searching-02.js \
 	browser_dbg_pause-resume.js \
 	browser_dbg_update-editor-mode.js \
 	$(warning browser_dbg_select-line.js temporarily disabled due to oranges, see bug 726609) \
 	browser_dbg_clean-exit.js \
 	browser_dbg_bug723069_editor-breakpoints.js \
 	browser_dbg_bug731394_editor-contextmenu.js \
 	browser_dbg_displayName.js \
 	browser_dbg_iframes.js \
--- a/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js
+++ b/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js
@@ -18,54 +18,47 @@ let gBreakpoints = null;
 
 function test()
 {
   let tempScope = {};
   Cu.import("resource:///modules/source-editor.jsm", tempScope);
   let SourceEditor = tempScope.SourceEditor;
   let scriptShown = false;
   let framesAdded = false;
-  let resumed = false;
-  let testStarted = false;
 
   debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPane = aPane;
     gDebugger = gPane.debuggerWindow;
-    resumed = true;
-
     gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
       framesAdded = true;
-      executeSoon(startTest);
+      runTest();
     });
 
-    executeSoon(function() {
-      gDebuggee.firstCall();
-    });
+    gDebuggee.firstCall();
   });
 
-  function onScriptShown(aEvent)
-  {
-    scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
-    executeSoon(startTest);
-  }
+  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
+    let url = aEvent.detail.url;
+    if (url.indexOf("-02.js") != -1) {
+      scriptShown = true;
+      window.removeEventListener(aEvent.type, _onEvent);
+      runTest();
+    }
+  });
 
-  window.addEventListener("Debugger:ScriptShown", onScriptShown);
-
-  function startTest()
+  function runTest()
   {
-    if (scriptShown && framesAdded && resumed && !testStarted) {
-      window.removeEventListener("Debugger:ScriptShown", onScriptShown);
-      testStarted = true;
-      Services.tm.currentThread.dispatch({ run: performTest }, 0);
+    if (scriptShown && framesAdded) {
+      Services.tm.currentThread.dispatch({ run: onScriptShown }, 0);
     }
   }
 
-  function performTest()
+  function onScriptShown()
   {
     gScripts = gDebugger.DebuggerView.Scripts;
 
     is(gDebugger.DebuggerController.activeThread.state, "paused",
       "Should only be getting stack frames while paused.");
 
     is(gScripts._scripts.itemCount, 2, "Found the expected number of scripts.");
 
--- a/browser/devtools/debugger/test/browser_dbg_bug731394_editor-contextmenu.js
+++ b/browser/devtools/debugger/test/browser_dbg_bug731394_editor-contextmenu.js
@@ -16,53 +16,47 @@ function test()
 {
   let tempScope = {};
   Cu.import("resource:///modules/source-editor.jsm", tempScope);
   let SourceEditor = tempScope.SourceEditor;
 
   let contextMenu = null;
   let scriptShown = false;
   let framesAdded = false;
-  let resumed = false;
-  let testStarted = false;
 
   debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPane = aPane;
     gDebugger = gPane.debuggerWindow;
-    resumed = true;
 
     gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
       framesAdded = true;
-      executeSoon(startTest);
+      runTest();
     });
-
-    executeSoon(function() {
-      gDebuggee.firstCall();
-    });
+    gDebuggee.firstCall();
   });
 
-  function onScriptShown(aEvent) {
-    scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
-    executeSoon(startTest);
-  }
-
-  window.addEventListener("Debugger:ScriptShown", onScriptShown);
+  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
+    let url = aEvent.detail.url;
+    if (url.indexOf("-02.js") != -1) {
+      scriptShown = true;
+      window.removeEventListener(aEvent.type, _onEvent);
+      runTest();
+    }
+  });
 
-  function startTest()
+  function runTest()
   {
-    if (scriptShown && framesAdded && resumed && !testStarted) {
-      testStarted = true;
-      window.removeEventListener("Debugger:ScriptShown", onScriptShown);
-      Services.tm.currentThread.dispatch({ run: performTest }, 0);
+    if (scriptShown && framesAdded) {
+      Services.tm.currentThread.dispatch({ run: onScriptShown }, 0);
     }
   }
 
-  function performTest()
+  function onScriptShown()
   {
     let scripts = gDebugger.DebuggerView.Scripts._scripts;
 
     is(gDebugger.DebuggerController.activeThread.state, "paused",
       "Should only be getting stack frames while paused.");
 
     is(scripts.itemCount, 2, "Found the expected number of scripts.");
 
deleted file mode 100644
--- a/browser/devtools/debugger/test/browser_dbg_createRemote.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-var gProcess = null;
-var gTab = null;
-var gDebuggee = null;
-
-function test() {
-  remote_debug_tab_pane(STACK_URL, aOnClosing, function(aTab, aDebuggee, aProcess) {
-    gTab = aTab;
-    gDebuggee = aDebuggee;
-    gProcess = aProcess;
-
-    testSimpleCall();
-  });
-}
-
-function testSimpleCall() {
-  Services.tm.currentThread.dispatch({ run: function() {
-
-    ok(gProcess._dbgProcess,
-      "The remote debugger process wasn't created properly!");
-    ok(gProcess._dbgProcess.isRunning,
-      "The remote debugger process isn't running!");
-    is(typeof gProcess._dbgProcess.pid, "number",
-      "The remote debugger process doesn't have a pid (?!)");
-
-    info("process location: " + gProcess._dbgProcess.location);
-    info("process pid: " + gProcess._dbgProcess.pid);
-    info("process name: " + gProcess._dbgProcess.processName);
-    info("process sig: " + gProcess._dbgProcess.processSignature);
-
-    ok(gProcess._dbgProfile,
-      "The remote debugger profile wasn't created properly!");
-    ok(gProcess._dbgProfile.localDir,
-      "The remote debugger profile doesn't have a localDir...");
-    ok(gProcess._dbgProfile.rootDir,
-      "The remote debugger profile doesn't have a rootDir...");
-    ok(gProcess._dbgProfile.name,
-      "The remote debugger profile doesn't have a name...");
-
-    info("profile localDir: " + gProcess._dbgProfile.localDir);
-    info("profile rootDir: " + gProcess._dbgProfile.rootDir);
-    info("profile name: " + gProcess._dbgProfile.name);
-
-    let profileService = Cc["@mozilla.org/toolkit/profile-service;1"]
-      .createInstance(Ci.nsIToolkitProfileService);
-
-    let profile = profileService.getProfileByName(gProcess._dbgProfile.name);
-
-    ok(profile,
-      "The remote debugger profile wasn't *actually* created properly!");
-    is(profile.localDir.path, gProcess._dbgProfile.localDir.path,
-      "The remote debugger profile doesn't have the correct localDir!");
-    is(profile.rootDir.path, gProcess._dbgProfile.rootDir.path,
-      "The remote debugger profile doesn't have the correct rootDir!");
-
-    DebuggerUI.toggleRemoteDebugger();
-  }}, 0);
-}
-
-function aOnClosing() {
-  ok(!gProcess._dbgProcess.isRunning,
-    "The remote debugger process isn't closed as it should be!");
-  is(gProcess._dbgProcess.exitValue, (Services.appinfo.OS == "WINNT" ? 0 : 256),
-    "The remote debugger process didn't die cleanly.");
-
-  info("process exit value: " + gProcess._dbgProcess.exitValue);
-
-  info("profile localDir: " + gProcess._dbgProfile.localDir.path);
-  info("profile rootDir: " + gProcess._dbgProfile.rootDir.path);
-  info("profile name: " + gProcess._dbgProfile.name);
-
-  executeSoon(function() {
-    finish();
-  });
-}
-
-registerCleanupFunction(function() {
-  removeTab(gTab);
-  gProcess = null;
-  gTab = null;
-  gDebuggee = null;
-});
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-01.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-01.js
@@ -80,38 +80,38 @@ function testSimpleCall() {
 
   gDebuggee.simpleCall();
 }
 
 function resumeAndFinish() {
   gDebugger.DebuggerController.activeThread.resume(function() {
     let vs = gDebugger.DebuggerView.Scripts;
     let ss = gDebugger.DebuggerController.SourceScripts;
-    vs.empty();
-    vs._scripts.removeEventListener("select", vs._onScriptsChange, false);
+    ss._onScriptsCleared();
 
     is(ss._trimUrlQuery("a/b/c.d?test=1&random=4"), "a/b/c.d",
       "Trimming the url query isn't done properly.");
 
     let urls = [
       { href: "ici://some.address.com/random/", leaf: "subrandom/" },
       { href: "ni://another.address.org/random/subrandom/", leaf: "page.html" },
       { href: "san://interesting.address.gro/random/", leaf: "script.js" },
       { href: "si://interesting.address.moc/random/", leaf: "script.js" },
       { href: "si://interesting.address.moc/random/", leaf: "x/script.js" },
       { href: "si://interesting.address.moc/random/", leaf: "x/y/script.js?a=1" },
       { href: "si://interesting.address.moc/random/x/", leaf: "y/script.js?a=1&b=2" },
       { href: "si://interesting.address.moc/random/x/y/", leaf: "script.js?a=1&b=2&c=3" }
     ];
 
+    vs._scripts.removeEventListener("select", vs._onScriptsChange, false);
+
     urls.forEach(function(url) {
       executeSoon(function() {
         let loc = url.href + url.leaf;
         vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc });
-        vs.commitScripts();
       });
     });
 
     executeSoon(function() {
       for (let i = 0; i < vs._scripts.itemCount; i++) {
         let lab = vs._scripts.getItemAtIndex(i).getAttribute("label");
         let loc = urls[i].href + urls[i].leaf;
 
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-07.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-07.js
@@ -22,20 +22,20 @@ function test()
     testFrameParameters();
   });
 }
 
 function testFrameParameters()
 {
   dump("Started testFrameParameters!\n");
 
-  gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
-    dump("Entered Debugger:FetchedVariables!\n");
+  gDebugger.addEventListener("Debugger:FetchedParameters", function test() {
+    dump("Entered Debugger:FetchedParameters!\n");
 
-    gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
+    gDebugger.removeEventListener("Debugger:FetchedParameters", test, false);
     Services.tm.currentThread.dispatch({ run: function() {
 
       dump("After currentThread.dispatch!\n");
 
       var frames = gDebugger.DebuggerView.StackFrames._frames,
           childNodes = frames.childNodes,
           localScope = gDebugger.DebuggerView.Properties.localScope,
           localNodes = localScope.querySelector(".details").childNodes;
@@ -47,52 +47,43 @@ function testFrameParameters()
       dump("localNodes - " + localNodes.constructor + "\n");
 
       is(gDebugger.DebuggerController.activeThread.state, "paused",
         "Should only be getting stack frames while paused.");
 
       is(frames.querySelectorAll(".dbg-stackframe").length, 3,
         "Should have three frames.");
 
-      is(localNodes.length, 11,
+      is(localNodes.length, 8,
         "The localScope should contain all the created variable elements.");
 
       is(localNodes[0].querySelector(".info").textContent, "[object Proxy]",
         "Should have the right property value for 'this'.");
 
-      is(localNodes[1].querySelector(".info").textContent, "[object Object]",
+      is(localNodes[1].querySelector(".info").textContent, "[object Arguments]",
+        "Should have the right property value for 'arguments'.");
+
+      is(localNodes[2].querySelector(".info").textContent, "[object Object]",
         "Should have the right property value for 'aArg'.");
 
-      is(localNodes[2].querySelector(".info").textContent, '"beta"',
+      is(localNodes[3].querySelector(".info").textContent, '"beta"',
         "Should have the right property value for 'bArg'.");
 
-      is(localNodes[3].querySelector(".info").textContent, "3",
+      is(localNodes[4].querySelector(".info").textContent, "3",
         "Should have the right property value for 'cArg'.");
 
-      is(localNodes[4].querySelector(".info").textContent, "false",
+      is(localNodes[5].querySelector(".info").textContent, "false",
         "Should have the right property value for 'dArg'.");
 
-      is(localNodes[5].querySelector(".info").textContent, "null",
+      is(localNodes[6].querySelector(".info").textContent, "null",
         "Should have the right property value for 'eArg'.");
 
-      is(localNodes[6].querySelector(".info").textContent, "undefined",
+      is(localNodes[7].querySelector(".info").textContent, "undefined",
         "Should have the right property value for 'fArg'.");
 
-      is(localNodes[7].querySelector(".info").textContent, "1",
-        "Should have the right property value for 'a'.");
-
-      is(localNodes[8].querySelector(".info").textContent, "[object Object]",
-        "Should have the right property value for 'b'.");
-
-      is(localNodes[9].querySelector(".info").textContent, "[object Object]",
-        "Should have the right property value for 'c'.");
-
-      is(localNodes[10].querySelector(".info").textContent, "[object Arguments]",
-        "Should have the right property value for 'arguments'.");
-
       resumeAndFinish();
     }}, 0);
   }, false);
 
   EventUtils.sendMouseEvent({ type: "click" },
     content.document.querySelector("button"),
     content.window);
 }
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-08.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-08.js
@@ -22,20 +22,20 @@ function test()
     testFrameParameters();
   });
 }
 
 function testFrameParameters()
 {
   dump("Started testFrameParameters!\n");
 
-  gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
-    dump("Entered Debugger:FetchedVariables!\n");
+  gDebugger.addEventListener("Debugger:FetchedParameters", function test() {
+    dump("Entered Debugger:FetchedParameters!\n");
 
-    gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
+    gDebugger.removeEventListener("Debugger:FetchedParameters", test, false);
     Services.tm.currentThread.dispatch({ run: function() {
 
       dump("After currentThread.dispatch!\n");
 
       var frames = gDebugger.DebuggerView.StackFrames._frames,
           localScope = gDebugger.DebuggerView.Properties.localScope,
           localNodes = localScope.querySelector(".details").childNodes;
 
@@ -45,98 +45,82 @@ function testFrameParameters()
       dump("localNodes - " + localNodes.constructor + "\n");
 
       is(gDebugger.DebuggerController.activeThread.state, "paused",
         "Should only be getting stack frames while paused.");
 
       is(frames.querySelectorAll(".dbg-stackframe").length, 3,
         "Should have three frames.");
 
-      is(localNodes.length, 11,
+      is(localNodes.length, 8,
         "The localScope should contain all the created variable elements.");
 
       is(localNodes[0].querySelector(".info").textContent, "[object Proxy]",
         "Should have the right property value for 'this'.");
 
-      // Expand the '__proto__', 'arguments' and 'a' tree nodes. This causes
-      // their properties to be retrieved and displayed.
+      // Expand the __proto__ and arguments tree nodes. This causes their
+      // properties to be retrieved and displayed.
       localNodes[0].expand();
-      localNodes[9].expand();
-      localNodes[10].expand();
+      localNodes[1].expand();
 
       // Poll every few milliseconds until the properties are retrieved.
       // It's important to set the timer in the chrome window, because the
       // content window timers are disabled while the debuggee is paused.
       let count = 0;
       let intervalID = window.setInterval(function(){
         if (++count > 50) {
           ok(false, "Timed out while polling for the properties.");
           resumeAndFinish();
         }
-        if (!localNodes[0].fetched ||
-            !localNodes[9].fetched ||
-            !localNodes[10].fetched) {
+        if (!localNodes[0].fetched || !localNodes[1].fetched) {
           return;
         }
         window.clearInterval(intervalID);
         is(localNodes[0].querySelector(".property > .title > .key")
                         .textContent, "__proto__ ",
           "Should have the right property name for __proto__.");
 
         ok(localNodes[0].querySelector(".property > .title > .value")
                         .textContent.search(/object/) != -1,
           "__proto__ should be an object.");
 
-        is(localNodes[9].querySelector(".info").textContent, "[object Object]",
-          "Should have the right property value for 'c'.");
-
-        is(localNodes[9].querySelectorAll(".property > .title > .key")[1]
-                        .textContent, "a",
-          "Should have the right property name for 'a'.");
-
-        is(localNodes[9].querySelectorAll(".property > .title > .value")[1]
-                        .textContent, 1,
-          "Should have the right value for 'c.a'.");
-
-        is(localNodes[10].querySelector(".info").textContent,
-          "[object Arguments]",
+        is(localNodes[1].querySelector(".info").textContent, "[object Arguments]",
           "Should have the right property value for 'arguments'.");
 
-        is(localNodes[10].querySelector(".property > .title > .key")
+        is(localNodes[1].querySelector(".property > .title > .key")
                         .textContent, "length",
-          "Should have the right property name for 'length'.");
+          "Should have the right property name for length.");
 
-        is(localNodes[10].querySelector(".property > .title > .value")
+        is(localNodes[1].querySelector(".property > .title > .value")
                         .textContent, 5,
           "Should have the right argument length.");
 
         resumeAndFinish();
       }, 100);
     }}, 0);
   }, false);
 
   EventUtils.sendMouseEvent({ type: "click" },
     content.document.querySelector("button"),
     content.window);
 }
 
 function resumeAndFinish() {
-  let thread = gDebugger.DebuggerController.activeThread;
-  thread.addOneTimeListener("framescleared", function() {
+  gDebugger.DebuggerController.activeThread.addOneTimeListener("framescleared", function() {
     Services.tm.currentThread.dispatch({ run: function() {
       var frames = gDebugger.DebuggerView.StackFrames._frames;
 
       is(frames.querySelectorAll(".dbg-stackframe").length, 0,
         "Should have no frames.");
 
       closeDebuggerAndFinish(gTab);
     }}, 0);
   });
 
-  thread.resume();
+  gDebugger.DebuggerController.activeThread.resume();
 }
 
 registerCleanupFunction(function() {
   removeTab(gTab);
   gPane = null;
   gTab = null;
   gDebugger = null;
 });
--- a/browser/devtools/debugger/test/browser_dbg_script-switching.js
+++ b/browser/devtools/debugger/test/browser_dbg_script-switching.js
@@ -3,59 +3,57 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Make sure that switching the displayed script in the UI works as advertised.
  */
 
 const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
 
+let tempScope = {};
+Cu.import("resource:///modules/source-editor.jsm", tempScope);
+let SourceEditor = tempScope.SourceEditor;
+
 var gPane = null;
 var gTab = null;
 var gDebuggee = null;
 var gDebugger = null;
 var gScripts = null;
 
 function test()
 {
   let scriptShown = false;
   let framesAdded = false;
-  let resumed = false;
-  let testStarted = false;
 
   debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPane = aPane;
     gDebugger = gPane.debuggerWindow;
-    resumed = true;
 
     gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
       framesAdded = true;
-      executeSoon(startTest);
+      runTest();
     });
 
-    executeSoon(function() {
-      gDebuggee.firstCall();
-    });
+    gDebuggee.firstCall();
   });
 
-  function onScriptShown(aEvent)
-  {
-    scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
-    executeSoon(startTest);
-  }
+  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
+    let url = aEvent.detail.url;
+    if (url.indexOf("-02.js") != -1) {
+      scriptShown = true;
+      window.removeEventListener(aEvent.type, _onEvent);
+      runTest();
+    }
+  });
 
-  window.addEventListener("Debugger:ScriptShown", onScriptShown);
-
-  function startTest()
+  function runTest()
   {
-    if (scriptShown && framesAdded && resumed && !testStarted) {
-      window.removeEventListener("Debugger:ScriptShown", onScriptShown);
-      testStarted = true;
+    if (scriptShown && framesAdded) {
       Services.tm.currentThread.dispatch({ run: testScriptsDisplay }, 0);
     }
   }
 }
 
 function testScriptsDisplay() {
   gScripts = gDebugger.DebuggerView.Scripts._scripts;
 
@@ -76,16 +74,18 @@ function testScriptsDisplay() {
   ok(gDebugger.DebuggerView.Scripts.contains(EXAMPLE_URL +
     label2), "Second script url is incorrect.");
 
   ok(gDebugger.DebuggerView.Scripts.containsLabel(
     label1), "First script label is incorrect.");
   ok(gDebugger.DebuggerView.Scripts.containsLabel(
     label2), "Second script label is incorrect.");
 
+  dump("Debugger editor text:\n" + gDebugger.editor.getText() + "\n");
+
   ok(gDebugger.editor.getText().search(/debugger/) != -1,
     "The correct script was loaded initially.");
 
   is(gDebugger.editor.getDebugLocation(), 5,
      "editor debugger location is correct.");
 
   window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
     let url = aEvent.detail.url;
@@ -95,16 +95,18 @@ function testScriptsDisplay() {
     }
   });
 
   gDebugger.DebuggerView.Scripts.selectScript(EXAMPLE_URL + label1);
 }
 
 function testSwitchPaused()
 {
+  dump("Debugger editor text:\n" + gDebugger.editor.getText() + "\n");
+
   ok(gDebugger.editor.getText().search(/debugger/) == -1,
     "The second script is no longer displayed.");
 
   ok(gDebugger.editor.getText().search(/firstCall/) != -1,
     "The first script is displayed.");
 
   is(gDebugger.editor.getDebugLocation(), -1,
      "editor debugger location has been cleared.");
@@ -120,18 +122,16 @@ function testSwitchPaused()
 
     gDebugger.DebuggerView.Scripts.selectScript(EXAMPLE_URL +
                                                 "test-script-switching-02.js");
   });
 }
 
 function testSwitchRunning()
 {
-  dump("Debugger editor text:\n" + gDebugger.editor.getText() + "\n");
-
   ok(gDebugger.editor.getText().search(/debugger/) != -1,
     "The second script is displayed again.");
 
   ok(gDebugger.editor.getText().search(/firstCall/) == -1,
     "The first script is no longer displayed.");
 
   is(gDebugger.editor.getDebugLocation(), -1,
      "editor debugger location is still -1.");
deleted file mode 100644
--- a/browser/devtools/debugger/test/browser_dbg_scripts-searching-01.js
+++ /dev/null
@@ -1,188 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var gPane = null;
-var gTab = null;
-var gDebuggee = null;
-var gDebugger = null;
-var gEditor = null;
-var gScripts = null;
-var gSearchBox = null;
-var gMenulist = null;
-
-function test()
-{
-  let scriptShown = false;
-  let framesAdded = false;
-
-  debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
-    gTab = aTab;
-    gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.debuggerWindow;
-
-    gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
-      framesAdded = true;
-      runTest();
-    });
-
-    gDebuggee.simpleCall();
-  });
-
-  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
-    window.removeEventListener(aEvent.type, _onEvent);
-    scriptShown = true;
-    runTest();
-  });
-
-  function runTest()
-  {
-    if (scriptShown && framesAdded) {
-      Services.tm.currentThread.dispatch({ run: testScriptSearching }, 0);
-    }
-  }
-}
-
-function testScriptSearching() {
-  gDebugger.DebuggerController.activeThread.resume(function() {
-    gEditor = gDebugger.DebuggerView.editor;
-    gScripts = gDebugger.DebuggerView.Scripts;
-    gSearchBox = gScripts._searchbox;
-    gMenulist = gScripts._scripts;
-
-    write(":12");
-    ok(gEditor.getCaretPosition().line == 11 &&
-       gEditor.getCaretPosition().col == 0,
-      "The editor didn't jump to the correct line.");
-
-    write("@debugger");
-    ok(gEditor.getCaretPosition().line == 2 &&
-       gEditor.getCaretPosition().col == 44,
-      "The editor didn't jump to the correct token. (1)");
-
-    EventUtils.sendKey("RETURN");
-    ok(gEditor.getCaretPosition().line == 8 &&
-       gEditor.getCaretPosition().col == 2,
-      "The editor didn't jump to the correct token. (2)");
-
-    EventUtils.sendKey("ENTER");
-    ok(gEditor.getCaretPosition().line == 12 &&
-       gEditor.getCaretPosition().col == 8,
-      "The editor didn't jump to the correct token. (3)");
-
-    EventUtils.sendKey("ENTER");
-    ok(gEditor.getCaretPosition().line == 19 &&
-       gEditor.getCaretPosition().col == 4,
-      "The editor didn't jump to the correct token. (4)");
-
-    EventUtils.sendKey("RETURN");
-    ok(gEditor.getCaretPosition().line == 2 &&
-       gEditor.getCaretPosition().col == 44,
-      "The editor didn't jump to the correct token. (5)");
-
-
-    write(":bogus@debugger;");
-    ok(gEditor.getCaretPosition().line == 8 &&
-       gEditor.getCaretPosition().col == 2,
-      "The editor didn't jump to the correct token. (7)");
-
-    write(":13@debugger;");
-    ok(gEditor.getCaretPosition().line == 8 &&
-       gEditor.getCaretPosition().col == 2,
-      "The editor didn't jump to the correct token. (7)");
-
-    write(":@debugger;");
-    ok(gEditor.getCaretPosition().line == 8 &&
-       gEditor.getCaretPosition().col == 2,
-      "The editor didn't jump to the correct token. (8)");
-
-    write("::@debugger;");
-    ok(gEditor.getCaretPosition().line == 8 &&
-       gEditor.getCaretPosition().col == 2,
-      "The editor didn't jump to the correct token. (9)");
-
-    write(":::@debugger;");
-    ok(gEditor.getCaretPosition().line == 8 &&
-       gEditor.getCaretPosition().col == 2,
-      "The editor didn't jump to the correct token. (10)");
-
-
-    write(":i am not a number");
-    ok(gEditor.getCaretPosition().line == 8 &&
-       gEditor.getCaretPosition().col == 2,
-      "The editor didn't remain at the correct token. (11)");
-
-    write("@__i do not exist__");
-    ok(gEditor.getCaretPosition().line == 8 &&
-       gEditor.getCaretPosition().col == 2,
-      "The editor didn't remain at the correct token. (12)");
-
-
-    write(":1:2:3:a:b:c:::12");
-    ok(gEditor.getCaretPosition().line == 11 &&
-       gEditor.getCaretPosition().col == 0,
-      "The editor didn't jump to the correct line. (13)");
-
-    write("@don't@find@me@instead@find@debugger");
-    ok(gEditor.getCaretPosition().line == 2 &&
-       gEditor.getCaretPosition().col == 44,
-      "The editor didn't jump to the correct token. (14)");
-
-    EventUtils.sendKey("RETURN");
-    ok(gEditor.getCaretPosition().line == 8 &&
-       gEditor.getCaretPosition().col == 2,
-      "The editor didn't jump to the correct token. (15)");
-
-    EventUtils.sendKey("ENTER");
-    ok(gEditor.getCaretPosition().line == 12 &&
-       gEditor.getCaretPosition().col == 8,
-      "The editor didn't jump to the correct token. (16)");
-
-    EventUtils.sendKey("RETURN");
-    ok(gEditor.getCaretPosition().line == 19 &&
-       gEditor.getCaretPosition().col == 4,
-      "The editor didn't jump to the correct token. (17)");
-
-    EventUtils.sendKey("ENTER");
-    ok(gEditor.getCaretPosition().line == 2 &&
-       gEditor.getCaretPosition().col == 44,
-      "The editor didn't jump to the correct token. (18)");
-
-
-    clear();
-    ok(gEditor.getCaretPosition().line == 2 &&
-       gEditor.getCaretPosition().col == 44,
-      "The editor didn't remain at the correct token. (19)");
-    is(gScripts.visibleItemsCount, 1,
-      "Not all the scripts are shown after the search. (20)");
-
-    closeDebuggerAndFinish(gTab);
-  });
-}
-
-function clear() {
-  gSearchBox.focus();
-  gSearchBox.value = "";
-}
-
-function write(text) {
-  clear();
-
-  for (let i = 0; i < text.length; i++) {
-    EventUtils.sendChar(text[i]);
-  }
-  dump("editor caret position: " + gEditor.getCaretPosition().toSource() + "\n");
-}
-
-registerCleanupFunction(function() {
-  removeTab(gTab);
-  gPane = null;
-  gTab = null;
-  gDebuggee = null;
-  gDebugger = null;
-  gEditor = null;
-  gScripts = null;
-  gSearchBox = null;
-  gMenulist = null;
-});
deleted file mode 100644
--- a/browser/devtools/debugger/test/browser_dbg_scripts-searching-02.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
-
-var gPane = null;
-var gTab = null;
-var gDebuggee = null;
-var gDebugger = null;
-var gEditor = null;
-var gScripts = null;
-var gSearchBox = null;
-var gMenulist = null;
-
-function test()
-{
-  let scriptShown = false;
-  let framesAdded = false;
-
-  debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
-    gTab = aTab;
-    gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.debuggerWindow;
-
-    gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
-      framesAdded = true;
-      runTest();
-    });
-
-    gDebuggee.firstCall();
-  });
-
-  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
-    let url = aEvent.detail.url;
-    if (url.indexOf("-02.js") != -1) {
-      scriptShown = true;
-      window.removeEventListener(aEvent.type, _onEvent);
-      runTest();
-    }
-  });
-
-  function runTest()
-  {
-    if (scriptShown && framesAdded) {
-      Services.tm.currentThread.dispatch({ run: testScriptSearching }, 0);
-    }
-  }
-}
-
-function testScriptSearching() {
-  gDebugger.DebuggerController.activeThread.resume(function() {
-    gEditor = gDebugger.DebuggerView.editor;
-    gScripts = gDebugger.DebuggerView.Scripts;
-    gSearchBox = gScripts._searchbox;
-    gMenulist = gScripts._scripts;
-
-    firstSearch();
-  });
-}
-
-function firstSearch() {
-  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
-    dump("Current script url:\n" + aEvent.detail.url + "\n");
-    dump("Debugger editor text:\n" + gEditor.getText() + "\n");
-
-    let url = aEvent.detail.url;
-    if (url.indexOf("-01.js") != -1) {
-      window.removeEventListener(aEvent.type, _onEvent);
-
-      executeSoon(function() {
-        dump("Editor caret position: " + gEditor.getCaretPosition().toSource() + "\n");
-        ok(gEditor.getCaretPosition().line == 4 &&
-           gEditor.getCaretPosition().col == 0,
-          "The editor didn't jump to the correct line. (1)");
-        is(gScripts.visibleItemsCount, 1,
-          "Not all the correct scripts are shown after the search. (1)");
-
-        secondSearch();
-      });
-    }
-  });
-  write(".*-01\.js:5");
-}
-
-function secondSearch() {
-  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
-    dump("Current script url:\n" + aEvent.detail.url + "\n");
-    dump("Debugger editor text:\n" + gEditor.getText() + "\n");
-
-    let url = aEvent.detail.url;
-    if (url.indexOf("-02.js") != -1) {
-      window.removeEventListener(aEvent.type, _onEvent);
-
-      executeSoon(function() {
-        dump("Editor caret position: " + gEditor.getCaretPosition().toSource() + "\n");
-        ok(gEditor.getCaretPosition().line == 5 &&
-           gEditor.getCaretPosition().col == 8,
-          "The editor didn't jump to the correct line. (2)");
-        is(gScripts.visibleItemsCount, 1,
-          "Not all the correct scripts are shown after the search. (2)");
-
-        finalCheck();
-      });
-    }
-  });
-  write(".*-02\.js@debugger;");
-}
-
-function finalCheck() {
-  clear();
-  ok(gEditor.getCaretPosition().line == 5 &&
-     gEditor.getCaretPosition().col == 8,
-    "The editor didn't remain at the correct token. (3)");
-  is(gScripts.visibleItemsCount, 2,
-    "Not all the scripts are shown after the search. (3)");
-
-  closeDebuggerAndFinish(gTab);
-}
-
-function clear() {
-  gSearchBox.focus();
-  gSearchBox.value = "";
-}
-
-function write(text) {
-  clear();
-
-  for (let i = 0; i < text.length; i++) {
-    EventUtils.sendChar(text[i]);
-  }
-  dump("editor caret position: " + gEditor.getCaretPosition().toSource() + "\n");
-}
-
-registerCleanupFunction(function() {
-  removeTab(gTab);
-  gPane = null;
-  gTab = null;
-  gDebuggee = null;
-  gDebugger = null;
-  gEditor = null;
-  gScripts = null;
-  gSearchBox = null;
-  gMenulist = null;
-});
deleted file mode 100644
--- a/browser/devtools/debugger/test/browser_dbg_scripts-sorting.js
+++ /dev/null
@@ -1,124 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-var gPane = null;
-var gTab = null;
-var gDebuggee = null;
-var gDebugger = null;
-
-function test() {
-  debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
-    gTab = aTab;
-    gDebuggee = aDebuggee;
-    gPane = aPane;
-    gDebugger = gPane.debuggerWindow;
-
-    testSimpleCall();
-  });
-}
-
-function testSimpleCall() {
-  gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
-    Services.tm.currentThread.dispatch({ run: function() {
-      resumeAndFinish();
-    }}, 0);
-  });
-
-  gDebuggee.simpleCall();
-}
-
-function resumeAndFinish() {
-  gDebugger.DebuggerController.activeThread.resume(function() {
-    checkScriptsOrder();
-    addScriptsAndCheckOrder(1, function() {
-      addScriptsAndCheckOrder(2, function() {
-        addScriptsAndCheckOrder(3, function() {
-          closeDebuggerAndFinish(gTab);
-        });
-      });
-    });
-  });
-}
-
-function addScriptsAndCheckOrder(method, callback) {
-  let vs = gDebugger.DebuggerView.Scripts;
-  let ss = gDebugger.DebuggerController.SourceScripts;
-  vs.empty();
-  vs._scripts.removeEventListener("select", vs._onScriptsChange, false);
-
-  let urls = [
-    { href: "ici://some.address.com/random/", leaf: "subrandom/" },
-    { href: "ni://another.address.org/random/subrandom/", leaf: "page.html" },
-    { href: "san://interesting.address.gro/random/", leaf: "script.js" },
-    { href: "si://interesting.address.moc/random/", leaf: "script.js" },
-    { href: "si://interesting.address.moc/random/", leaf: "x/script.js" },
-    { href: "si://interesting.address.moc/random/", leaf: "x/y/script.js?a=1" },
-    { href: "si://interesting.address.moc/random/x/", leaf: "y/script.js?a=1&b=2" },
-    { href: "si://interesting.address.moc/random/x/y/", leaf: "script.js?a=1&b=2&c=3" }
-  ];
-
-  urls.sort(function(a, b) {
-    return Math.random() - 0.5;
-  });
-
-  switch (method) {
-    case 1:
-      urls.forEach(function(url) {
-        let loc = url.href + url.leaf;
-        vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc });
-      });
-      vs.commitScripts();
-      break;
-
-    case 2:
-      urls.forEach(function(url) {
-        let loc = url.href + url.leaf;
-        vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc }, true);
-      });
-      break;
-
-    case 3:
-      let i = 0
-      for (; i < urls.length / 2; i++) {
-        let url = urls[i];
-        let loc = url.href + url.leaf;
-        vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc });
-      }
-      vs.commitScripts();
-
-      for (; i < urls.length; i++) {
-        let url = urls[i];
-        let loc = url.href + url.leaf;
-        vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc }, true);
-      }
-      break;
-  }
-
-  executeSoon(function() {
-    checkScriptsOrder(method);
-    callback();
-  });
-}
-
-function checkScriptsOrder(method) {
-  let labels = gDebugger.DebuggerView.Scripts.scriptLabels;
-  let sorted = labels.reduce(function(prev, curr, index, array) {
-    return array[index - 1] < array[index];
-  });
-
-  ok(sorted,
-    "Using method " + method + ", " +
-    "the scripts weren't in the correct order: " + labels.toSource());
-
-  return sorted;
-}
-
-registerCleanupFunction(function() {
-  removeTab(gTab);
-  gPane = null;
-  gTab = null;
-  gDebuggee = null;
-  gDebugger = null;
-});
--- a/browser/devtools/debugger/test/browser_dbg_update-editor-mode.js
+++ b/browser/devtools/debugger/test/browser_dbg_update-editor-mode.js
@@ -17,48 +17,42 @@ var gTab = null;
 var gDebuggee = null;
 var gDebugger = null;
 var gScripts = null;
 
 function test()
 {
   let scriptShown = false;
   let framesAdded = false;
-  let testStarted = false;
-  let resumed = false;
 
   debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPane = aPane;
     gDebugger = gPane.debuggerWindow;
-    resumed = true;
 
     gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
       framesAdded = true;
-      executeSoon(startTest);
+      runTest();
     });
-
-    executeSoon(function() {
-      gDebuggee.firstCall();
-    });
+    gDebuggee.firstCall();
   });
 
-  function onScriptShown(aEvent) {
-    scriptShown = aEvent.detail.url.indexOf("test-editor-mode") != -1;
-    executeSoon(startTest);
-  }
+  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
+    let url = aEvent.detail.url;
+    if (url.indexOf("editor-mode") != -1) {
+      scriptShown = true;
+      window.removeEventListener(aEvent.type, _onEvent);
+      runTest();
+    }
+  });
 
-  window.addEventListener("Debugger:ScriptShown", onScriptShown);
-
-  function startTest()
+  function runTest()
   {
-    if (scriptShown && framesAdded && resumed && !testStarted) {
-      window.removeEventListener("Debugger:ScriptShown", onScriptShown);
-      testStarted = true;
+    if (scriptShown && framesAdded) {
       Services.tm.currentThread.dispatch({ run: testScriptsDisplay }, 0);
     }
   }
 }
 
 function testScriptsDisplay() {
   gScripts = gDebugger.DebuggerView.Scripts._scripts;
 
--- a/browser/devtools/debugger/test/head.js
+++ b/browser/devtools/debugger/test/head.js
@@ -87,35 +87,22 @@ function attach_thread_actor_for_url(aCl
     });
   });
 }
 
 function debug_tab_pane(aURL, aOnDebugging)
 {
   let tab = addTab(aURL, function() {
     gBrowser.selectedTab = gTab;
+
     let debuggee = tab.linkedBrowser.contentWindow.wrappedJSObject;
 
     let pane = DebuggerUI.toggleDebugger();
     pane._frame.addEventListener("Debugger:Connecting", function dbgConnected() {
       pane._frame.removeEventListener("Debugger:Connecting", dbgConnected, true);
 
       // Wait for the initial resume...
       pane.debuggerWindow.gClient.addOneTimeListener("resumed", function() {
         aOnDebugging(tab, debuggee, pane);
       });
     }, true);
   });
 }
-
-function remote_debug_tab_pane(aURL, aOnClosing, aOnDebugging)
-{
-  let tab = addTab(aURL, function() {
-    gBrowser.selectedTab = gTab;
-    let debuggee = tab.linkedBrowser.contentWindow.wrappedJSObject;
-
-    DebuggerUI.toggleRemoteDebugger(aOnClosing, function dbgRan(process) {
-
-      // Wait for the remote debugging process to start...
-      aOnDebugging(tab, debuggee, process);
-    });
-  });
-}
--- a/browser/devtools/highlighter/inspector.jsm
+++ b/browser/devtools/highlighter/inspector.jsm
@@ -393,17 +393,17 @@ InspectorUI.prototype = {
 
   /**
    * Is the inspector UI open? Simply check if the toolbar is visible or not.
    *
    * @returns boolean
    */
   get isInspectorOpen()
   {
-    return !!(this.toolbar && !this.toolbar.hidden && this.highlighter);
+    return this.toolbar && !this.toolbar.hidden && this.highlighter;
   },
 
   /**
    * Return the default selection element for the inspected document.
    */
   get defaultSelection()
   {
     let doc = this.win.document;
@@ -642,17 +642,17 @@ InspectorUI.prototype = {
       this.breadcrumbs.destroy();
       this.breadcrumbs = null;
     }
 
     delete this._currentInspector;
     if (!aKeepInspector)
       this.store.deleteInspector(this.winID);
 
-    this.inspectMenuitem.removeAttribute("checked");
+    this.inspectMenuitem.setAttribute("checked", false);
     this.browser = this.win = null; // null out references to browser and window
     this.winID = null;
     this.selection = null;
     this.closing = false;
     this.isDirty = false;
 
     delete this.treePanel;
     delete this.stylePanel;
--- a/browser/devtools/jar.mn
+++ b/browser/devtools/jar.mn
@@ -12,10 +12,8 @@ browser.jar:
 *   content/browser/devtools/layoutview/view.xhtml  (layoutview/view.xhtml)
     content/browser/devtools/layoutview/view.css  (layoutview/view.css)
     content/browser/orion.js                      (sourceeditor/orion/orion.js)
 *   content/browser/source-editor-overlay.xul     (sourceeditor/source-editor-overlay.xul)
 *   content/browser/debugger.xul                  (debugger/debugger.xul)
     content/browser/debugger.css                  (debugger/debugger.css)
     content/browser/debugger-controller.js        (debugger/debugger-controller.js)
     content/browser/debugger-view.js              (debugger/debugger-view.js)
-    content/browser/devtools/gcli.css             (webconsole/gcli.css)
-    content/browser/devtools/gcliblank.xhtml      (webconsole/gcliblank.xhtml)
deleted file mode 100644
--- a/browser/devtools/shared/DeveloperToolbar.jsm
+++ /dev/null
@@ -1,476 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Firefox Developer Toolbar.
- *
- * The Initial Developer of the Original Code is
- * The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2012
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Dave Camp <dcamp@mozilla.com> (Original Author)
- *   Joe Walker <jwalker@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-"use strict";
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-let EXPORTED_SYMBOLS = [ "DeveloperToolbar", "loadCommands" ];
-
-XPCOMUtils.defineLazyGetter(this, "gcli", function () {
-  let obj = {};
-  Components.utils.import("resource:///modules/gcli.jsm", obj);
-  return obj.gcli;
-});
-
-let console = gcli._internal.console;
-
-/**
- * Load the various Command JSMs.
- * Should be called when the developer toolbar first opens.
- */
-function loadCommands()
-{
-  Components.utils.import("resource:///modules/GcliCommands.jsm", {});
-  Components.utils.import("resource:///modules/GcliTiltCommands.jsm", {});
-}
-
-
-
-let commandsLoaded = false;
-
-/**
- * A component to manage the global developer toolbar, which contains a GCLI
- * and buttons for various developer tools.
- * @param aChromeWindow The browser window to which this toolbar is attached
- * @param aToolbarElement See browser.xul:<toolbar id="developer-toolbar">
- */
-function DeveloperToolbar(aChromeWindow, aToolbarElement)
-{
-  if (!commandsLoaded) {
-    loadCommands();
-    commandsLoaded = true;
-  }
-
-  this._chromeWindow = aChromeWindow;
-
-  this._element = aToolbarElement;
-  this._element.hidden = true;
-  this._doc = this._element.ownerDocument;
-
-  this._command = this._doc.getElementById("Tools:DevToolbar");
-
-  aChromeWindow.getBrowser().tabContainer.addEventListener("TabSelect", this, false);
-}
-
-/**
- * Inspector notifications dispatched through the nsIObserverService
- */
-const NOTIFICATIONS = {
-  /** DeveloperToolbar.show() has been called */
-  SHOW: "developer-toolbar-show",
-
-  /** DeveloperToolbar.hide() has been called */
-  HIDE: "developer-toolbar-hide"
-};
-
-/**
- * Attach notification constants to the object prototype so tests etc can
- * use them without needing to import anything
- */
-DeveloperToolbar.prototype.NOTIFICATIONS = NOTIFICATIONS;
-
-/**
- * Is the toolbar open?
- */
-Object.defineProperty(DeveloperToolbar.prototype, 'visible', {
-  get: function DT_visible() {
-    return !this._element.hidden;
-  },
-  enumerable: true
-});
-
-/**
- * Called from browser.xul in response to menu-click or keyboard shortcut to
- * toggle the toolbar
- */
-DeveloperToolbar.prototype.toggle = function DT_toggle()
-{
-  if (this.visible) {
-    this.hide();
-  } else {
-    this.show();
-    this._input.focus();
-  }
-};
-
-/**
- * Even if the user has not clicked on 'Got it' in the intro, we only show it
- * once per session.
- * Warning this is slightly messed up because this.DeveloperToolbar is not the
- * same as this.DeveloperToolbar when in browser.js context.
- */
-DeveloperToolbar.introShownThisSession = false;
-
-/**
- * Show the developer toolbar
- */
-DeveloperToolbar.prototype.show = function DT_show()
-{
-  this._command.setAttribute("checked", "true");
-
-  this._input = this._doc.querySelector(".gclitoolbar-input-node");
-
-  this.tooltipPanel = new TooltipPanel(this._doc, this._input);
-  this.outputPanel = new OutputPanel(this._doc, this._input);
-
-  let contentDocument = this._chromeWindow.getBrowser().contentDocument;
-
-  this.display = gcli._internal.createDisplay({
-    contentDocument: contentDocument,
-    chromeDocument: this._doc,
-    chromeWindow: this._chromeWindow,
-
-    hintElement: this.tooltipPanel.hintElement,
-    inputElement: this._input,
-    completeElement: this._doc.querySelector(".gclitoolbar-complete-node"),
-    backgroundElement: this._doc.querySelector(".gclitoolbar-stack-node"),
-    outputDocument: this.outputPanel.document,
-
-    environment: {
-      chromeDocument: this._doc,
-      contentDocument: contentDocument
-    },
-
-    tooltipClass: 'gcliterm-tooltip',
-    eval: null,
-    scratchpad: null
-  });
-
-  this.display.onVisibilityChange.add(this.outputPanel._visibilityChanged, this.outputPanel);
-  this.display.onVisibilityChange.add(this.tooltipPanel._visibilityChanged, this.tooltipPanel);
-  this.display.onOutput.add(this.outputPanel._outputChanged, this.outputPanel);
-
-  this._element.hidden = false;
-  this._notify(NOTIFICATIONS.SHOW);
-
-  if (!DeveloperToolbar.introShownThisSession) {
-    this.display.maybeShowIntro();
-    DeveloperToolbar.introShownThisSession = true;
-  }
-};
-
-/**
- * Hide the developer toolbar
- */
-DeveloperToolbar.prototype.hide = function DT_hide()
-{
-  this._command.setAttribute("checked", "false");
-
-  this.display.onVisibilityChange.remove(this.outputPanel._visibilityChanged, this.outputPanel);
-  this.display.onVisibilityChange.remove(this.tooltipPanel._visibilityChanged, this.tooltipPanel);
-  this.display.onOutput.remove(this.outputPanel._outputChanged, this.outputPanel);
-  this.display.destroy();
-
-  // We could "delete this.display" etc if we have hard-to-track-down memory
-  // leaks as a belt-and-braces approach, however this prevents our DOM node
-  // hunter from looking in all the nooks and crannies, so it's better if we
-  // can be leak-free without
-
-  this.outputPanel.remove();
-  delete this.outputPanel;
-
-  this.tooltipPanel.remove();
-  delete this.tooltipPanel;
-
-  this._element.hidden = true;
-  this._notify(NOTIFICATIONS.HIDE);
-};
-
-/**
- * Utility for sending notifications
- * @param aTopic a NOTIFICATION constant
- */
-DeveloperToolbar.prototype._notify = function DT_notify(aTopic)
-{
-  let data = { toolbar: this };
-  data.wrappedJSObject = data;
-  Services.obs.notifyObservers(data, aTopic, null);
-};
-
-/**
- * Update various parts of the UI when the current tab changes
- * @param aEvent
- */
-DeveloperToolbar.prototype.handleEvent = function DT_handleEvent(aEvent)
-{
-  if (aEvent.type == "TabSelect") {
-    this._chromeWindow.HUDConsoleUI.refreshCommand();
-    this._chromeWindow.DebuggerUI.refreshCommand();
-
-    if (this.visible) {
-      let contentDocument = this._chromeWindow.getBrowser().contentDocument;
-
-      this.display.reattach({
-        contentDocument: contentDocument,
-        chromeWindow: this._chromeWindow,
-        environment: {
-          chromeDocument: this._doc,
-          contentDocument: contentDocument
-        },
-      });
-    }
-  }
-};
-
-/**
- * Add class="gcli-panel-inner-arrowcontent" to a panel's
- * |<xul:box class="panel-inner-arrowcontent">| so we can alter the styling
- * without complex CSS expressions.
- * @param aPanel The panel to affect
- */
-function getContentBox(aPanel)
-{
-  let container = aPanel.ownerDocument.getAnonymousElementByAttribute(
-          aPanel, "anonid", "container");
-  return container.querySelector(".panel-inner-arrowcontent");
-}
-
-/**
- * Helper function to calculate the sum of the vertical padding and margins
- * between a nested node |aNode| and an ancestor |aRoot|. Iff all of the
- * children of aRoot are 'only-childs' until you get to aNode then to avoid
- * scroll-bars, the 'correct' height of aRoot is verticalSpacing + aNode.height.
- * @param aNode The child node whose height is known.
- * @param aRoot The parent height whose height we can affect.
- * @return The sum of the vertical padding/margins in between aNode and aRoot.
- */
-function getVerticalSpacing(aNode, aRoot)
-{
-  let win = aNode.ownerDocument.defaultView;
-
-  function pxToNum(styles, property) {
-    return parseInt(styles.getPropertyValue(property).replace(/px$/, ''), 10);
-  }
-
-  let vertSpacing = 0;
-  do {
-    let styles = win.getComputedStyle(aNode);
-    vertSpacing += pxToNum(styles, "padding-top");
-    vertSpacing += pxToNum(styles, "padding-bottom");
-    vertSpacing += pxToNum(styles, "margin-top");
-    vertSpacing += pxToNum(styles, "margin-bottom");
-    vertSpacing += pxToNum(styles, "border-top-width");
-    vertSpacing += pxToNum(styles, "border-bottom-width");
-
-    let prev = aNode.previousSibling;
-    while (prev != null) {
-      vertSpacing += prev.clientHeight;
-      prev = prev.previousSibling;
-    }
-
-    let next = aNode.nextSibling;
-    while (next != null) {
-      vertSpacing += next.clientHeight;
-      next = next.nextSibling;
-    }
-
-    aNode = aNode.parentNode;
-  } while (aNode !== aRoot);
-
-  return vertSpacing + 9;
-}
-
-/**
- * Panel to handle command line output.
- * @param aChromeDoc document from which we can pull the parts we need.
- * @param aInput the input element that should get focus.
- */
-function OutputPanel(aChromeDoc, aInput)
-{
-  this._input = aInput;
-  this._panel = aChromeDoc.getElementById("gcli-output");
-  this._frame = aChromeDoc.getElementById("gcli-output-frame");
-  this._anchor = aChromeDoc.getElementById("developer-toolbar");
-
-  this._content = getContentBox(this._panel);
-  this._content.classList.add("gcli-panel-inner-arrowcontent");
-
-  this.document = this._frame.contentDocument;
-  this.document.body.classList.add("gclichrome-output");
-
-  this._div = this.document.querySelector("div");
-  this._div.classList.add('gcli-row-out');
-  this._div.setAttribute('aria-live', 'assertive');
-
-  this.displayedOutput = undefined;
-}
-
-/**
- * Display the OutputPanel.
- */
-OutputPanel.prototype.show = function OP_show()
-{
-  this._panel.ownerDocument.defaultView.setTimeout(function() {
-    this._resize();
-  }.bind(this), 0);
-
-  this._resize();
-  this._panel.openPopup(this._anchor, "before_end", -300, 0, false, false, null);
-
-  this._input.focus();
-};
-
-/**
- * Internal helper to set the height of the output panel to fit the available
- * content;
- */
-OutputPanel.prototype._resize = function CLP_resize()
-{
-  let vertSpacing = getVerticalSpacing(this._content, this._panel);
-  let idealHeight = this.document.body.scrollHeight + vertSpacing;
-  this._panel.sizeTo(400, Math.min(idealHeight, 500));
-};
-
-/**
- * Called by GCLI when a command is executed.
- */
-OutputPanel.prototype._outputChanged = function OP_outputChanged(aEvent)
-{
-  if (aEvent.output.hidden) {
-    return;
-  }
-
-  this.remove();
-
-  this.displayedOutput = aEvent.output;
-  this.update();
-
-  this.displayedOutput.onChange.add(this.update, this);
-  this.displayedOutput.onClose.add(this.remove, this);
-};
-
-/**
- * Called when displayed Output says it's changed or from outputChanged, which
- * happens when there is a new displayed Output.
- */
-OutputPanel.prototype.update = function OP_update()
-{
-  if (this.displayedOutput.data == null) {
-    while (this._div.hasChildNodes()) {
-      this._div.removeChild(this._div.firstChild);
-    }
-  } else {
-    this.displayedOutput.toDom(this._div);
-    this.show();
-  }
-};
-
-/**
- * Detach listeners from the currently displayed Output.
- */
-OutputPanel.prototype.remove = function OP_remove()
-{
-  this._panel.hidePopup();
-
-  if (this.displayedOutput) {
-    this.displayedOutput.onChange.remove(this.update, this);
-    this.displayedOutput.onClose.remove(this.remove, this);
-    delete this.displayedOutput;
-  }
-};
-
-/**
- * Called by GCLI to indicate that we should show or hide one either the
- * tooltip panel or the output panel.
- */
-OutputPanel.prototype._visibilityChanged = function OP_visibilityChanged(aEvent)
-{
-  if (aEvent.outputVisible === true) {
-    // this.show is called by _outputChanged
-  } else {
-    this._panel.hidePopup();
-  }
-};
-
-
-/**
- * Panel to handle tooltips.
- * @param aChromeDoc document from which we can pull the parts we need.
- * @param aInput the input element that should get focus.
- */
-function TooltipPanel(aChromeDoc, aInput)
-{
-  this._input = aInput;
-  this._panel = aChromeDoc.getElementById("gcli-tooltip");
-  this._frame = aChromeDoc.getElementById("gcli-tooltip-frame");
-  this._anchor = aChromeDoc.getElementById("developer-toolbar");
-
-  this._content = getContentBox(this._panel);
-  this._content.classList.add("gcli-panel-inner-arrowcontent");
-
-  this.document = this._frame.contentDocument;
-  this.document.body.classList.add("gclichrome-tooltip");
-
-  this.hintElement = this.document.querySelector("div");
-}
-
-/**
- * Display the TooltipPanel.
- */
-TooltipPanel.prototype.show = function TP_show()
-{
-  let vertSpacing = getVerticalSpacing(this._content, this._panel);
-  let idealHeight = this.document.body.scrollHeight + vertSpacing;
-  this._panel.sizeTo(350, Math.min(idealHeight, 500));
-  this._panel.openPopup(this._anchor, "before_start", 0, 0, false, false, null);
-
-  this._input.focus();
-};
-
-/**
- * Hide the TooltipPanel.
- */
-TooltipPanel.prototype.remove = function TP_remove()
-{
-  this._panel.hidePopup();
-};
-
-/**
- * Called by GCLI to indicate that we should show or hide one either the
- * tooltip panel or the output panel.
- */
-TooltipPanel.prototype._visibilityChanged = function TP_visibilityChanged(aEvent)
-{
-  if (aEvent.tooltipVisible === true) {
-    this.show();
-  } else {
-    this._panel.hidePopup();
-  }
-};
--- a/browser/devtools/shared/Templater.jsm
+++ b/browser/devtools/shared/Templater.jsm
@@ -37,64 +37,43 @@
  * ***** END LICENSE BLOCK ***** */
 
 
 var EXPORTED_SYMBOLS = [ "Templater", "template" ];
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 const Node = Components.interfaces.nsIDOMNode;
 
-/**
- * For full documentation, see:
- * https://github.com/mozilla/domtemplate/blob/master/README.md
- */
-
 // WARNING: do not 'use_strict' without reading the notes in _envEval();
 
 /**
  * Begin a new templating process.
  * @param node A DOM element or string referring to an element's id
  * @param data Data to use in filling out the template
  * @param options Options to customize the template processing. One of:
  * - allowEval: boolean (default false) Basic template interpolations are
- *   either property paths (e.g. ${a.b.c.d}), or if allowEval=true then we
- *   allow arbitrary JavaScript
- * - stack: string or array of strings (default empty array) The template
- *   engine maintains a stack of tasks to help debug where it is. This allows
- *   this stack to be prefixed with a template name
- * - blankNullUndefined: By default DOMTemplate exports null and undefined
- *   values using the strings 'null' and 'undefined', which can be helpful for
- *   debugging, but can introduce unnecessary extra logic in a template to
- *   convert null/undefined to ''. By setting blankNullUndefined:true, this
- *   conversion is handled by DOMTemplate
+ * either property paths (e.g. ${a.b.c.d}), however if allowEval=true then we
+ * allow arbitrary JavaScript
  */
 function template(node, data, options) {
   var template = new Templater(options || {});
   template.processNode(node, data);
   return template;
 }
 
 /**
  * Construct a Templater object. Use template() in preference to this ctor.
  * @deprecated Use template(node, data, options);
  */
 function Templater(options) {
   if (options == null) {
     options = { allowEval: true };
   }
   this.options = options;
-  if (options.stack && Array.isArray(options.stack)) {
-    this.stack = options.stack;
-  }
-  else if (typeof options.stack === 'string') {
-    this.stack = [ options.stack ];
-  }
-  else {
-    this.stack = [];
-  }
+  this.stack = [];
 }
 
 /**
  * Cached regex used to find ${...} sections in some text.
  * Performance note: This regex uses ( and ) to capture the 'script' for
  * further processing. Not all of the uses of this regex use this feature so
  * if use of the capturing group is a performance drain then we should split
  * this regex in two.
@@ -106,17 +85,17 @@ Templater.prototype._templateRegion = /\
  * See Templater._processTextNode() for details.
  */
 Templater.prototype._splitSpecial = /\uF001|\uF002/;
 
 /**
  * Cached regex used to detect if a script is capable of being interpreted
  * using Template._property() or if we need to use Template._envEval()
  */
-Templater.prototype._isPropertyScript = /^[_a-zA-Z0-9.]*$/;
+Templater.prototype._isPropertyScript = /^[a-zA-Z0-9.]*$/;
 
 /**
  * Recursive function to walk the tree processing the attributes as it goes.
  * @param node the node to process. If you pass a string in instead of a DOM
  * element, it is assumed to be an id for use with document.getElementById()
  * @param data the data to use for node processing.
  */
 Templater.prototype.processNode = function(node, data) {
@@ -169,21 +148,17 @@ Templater.prototype.processNode = functi
             var capture = node.hasAttribute('capture' + name.substring(2));
             node.addEventListener(name.substring(2), func, capture);
             if (capture) {
               node.removeAttribute('capture' + name.substring(2));
             }
           } else {
             // Replace references in all other attributes
             var newValue = value.replace(this._templateRegion, function(path) {
-              var insert = this._envEval(path.slice(2, -1), data, value);
-              if (this.options.blankNullUndefined && insert == null) {
-                insert = '';
-              }
-              return insert;
+              return this._envEval(path.slice(2, -1), data, value);
             }.bind(this));
             // Remove '_' prefix of attribute names so the DOM won't try
             // to use them before we've processed the template
             if (name.charAt(0) === '_') {
               node.removeAttribute(name);
               node.setAttribute(name.substring(1), newValue);
             } else if (value !== newValue) {
               attrs[i].value = newValue;
@@ -197,17 +172,17 @@ Templater.prototype.processNode = functi
 
     // Loop through our children calling processNode. First clone them, so the
     // set of nodes that we visit will be unaffected by additions or removals.
     var childNodes = Array.prototype.slice.call(node.childNodes);
     for (var j = 0; j < childNodes.length; j++) {
       this.processNode(childNodes[j], data);
     }
 
-    if (node.nodeType === 3 /*Node.TEXT_NODE*/) {
+    if (node.nodeType === Node.TEXT_NODE) {
       this._processTextNode(node, data);
     }
   } finally {
     delete data.__element;
     this.stack.pop();
   }
 };
 
@@ -367,51 +342,40 @@ Templater.prototype._processTextNode = f
     parts.forEach(function(part) {
       if (part === null || part === undefined || part === '') {
         return;
       }
       if (part.charAt(0) === '$') {
         part = this._envEval(part.slice(1), data, node.data);
       }
       this._handleAsync(part, node, function(reply, siblingNode) {
-        var doc = siblingNode.ownerDocument;
-        if (reply == null) {
-          reply = this.options.blankNullUndefined ? '' : '' + reply;
-        }
-        if (typeof reply.cloneNode === 'function') {
-          // i.e. if (reply instanceof Element) { ...
-          reply = this._maybeImportNode(reply, doc);
-          siblingNode.parentNode.insertBefore(reply, siblingNode);
-        } else if (typeof reply.item === 'function' && reply.length) {
-          // if thing is a NodeList, then import the children
-          for (var i = 0; i < reply.length; i++) {
-            var child = this._maybeImportNode(reply.item(i), doc);
-            siblingNode.parentNode.insertBefore(child, siblingNode);
-          }
-        }
-        else {
-          // if thing isn't a DOM element then wrap its string value in one
-          reply = doc.createTextNode(reply.toString());
-          siblingNode.parentNode.insertBefore(reply, siblingNode);
-        }
-
+        reply = this._toNode(reply, siblingNode.ownerDocument);
+        siblingNode.parentNode.insertBefore(reply, siblingNode);
       }.bind(this));
     }, this);
     node.parentNode.removeChild(node);
   }
 };
 
 /**
- * Return node or a import of node, if it's not in the given document
- * @param node The node that we want to be properly owned
- * @param doc The document that the given node should belong to
- * @return A node that belongs to the given document
+ * Helper to convert a 'thing' to a DOM Node.
+ * This is (obviously) a no-op for DOM Elements (which are detected using
+ * 'typeof thing.cloneNode !== "function"' (is there a better way that will
+ * work in all environments, including a .jsm?)
+ * Non DOM elements are converted to a string and wrapped in a TextNode.
  */
-Templater.prototype._maybeImportNode = function(node, doc) {
-  return node.ownerDocument === doc ? node : doc.importNode(node, true);
+Templater.prototype._toNode = function(thing, document) {
+  if (thing == null) {
+    thing = '' + thing;
+  }
+  // if thing isn't a DOM element then wrap its string value in one
+  if (typeof thing.cloneNode !== 'function') {
+    thing = document.createTextNode(thing.toString());
+  }
+  return thing;
 };
 
 /**
  * A function to handle the fact that some nodes can be promises, so we check
  * and resolve if needed using a marker node to keep our place before calling
  * an inserter function.
  * @param thing The object which could be real data or a promise of real data
  * we use it directly if it's not a promise, or resolve it if it is.
@@ -460,38 +424,38 @@ Templater.prototype._stripBraces = funct
  * a string to be cut into an array using <tt>split('.')</tt>
  * @param data the data to use for node processing
  * @param newValue (optional) If defined, this value will replace the
  * original value for the data at the path specified.
  * @return The value pointed to by <tt>path</tt> before any
  * <tt>newValue</tt> is applied.
  */
 Templater.prototype._property = function(path, data, newValue) {
+  this.stack.push(path);
   try {
     if (typeof path === 'string') {
       path = path.split('.');
     }
     var value = data[path[0]];
     if (path.length === 1) {
       if (newValue !== undefined) {
         data[path[0]] = newValue;
       }
       if (typeof value === 'function') {
         return value.bind(data);
       }
       return value;
     }
     if (!value) {
-      this._handleError('"' + path[0] + '" is undefined');
+      this._handleError('Can\'t find path=' + path);
       return null;
     }
     return this._property(path.slice(1), value, newValue);
-  } catch (ex) {
-    this._handleError('Path error with \'' + path + '\'', ex);
-    return '${' + path + '}';
+  } finally {
+    this.stack.pop();
   }
 };
 
 /**
  * Like eval, but that creates a context of the variables in <tt>env</tt> in
  * which the script is evaluated.
  * WARNING: This script uses 'with' which is generally regarded to be evil.
  * The alternative is to create a Function at runtime that takes X parameters
@@ -500,45 +464,47 @@ Templater.prototype._property = function
  * @param script The string to be evaluated.
  * @param data The environment in which to eval the script.
  * @param frame Optional debugging string in case of failure.
  * @return The return value of the script, or the error message if the script
  * execution failed.
  */
 Templater.prototype._envEval = function(script, data, frame) {
   try {
-    this.stack.push(frame.replace(/\s+/g, ' '));
+    this.stack.push(frame);
     if (this._isPropertyScript.test(script)) {
       return this._property(script, data);
     } else {
       if (!this.options.allowEval) {
         this._handleError('allowEval is not set, however \'' + script + '\'' +
             ' can not be resolved using a simple property path.');
         return '${' + script + '}';
       }
       with (data) {
         return eval(script);
       }
     }
   } catch (ex) {
-    this._handleError('Template error evaluating \'' + script + '\'', ex);
+    this._handleError('Template error evaluating \'' + script + '\'' +
+        ' environment=' + Object.keys(data).join(', '), ex);
     return '${' + script + '}';
   } finally {
     this.stack.pop();
   }
 };
 
 /**
  * A generic way of reporting errors, for easy overloading in different
  * environments.
  * @param message the error message to report.
  * @param ex optional associated exception.
  */
 Templater.prototype._handleError = function(message, ex) {
-  this._logError(message + ' (In: ' + this.stack.join(' > ') + ')');
+  this._logError(message);
+  this._logError('In: ' + this.stack.join(' > '));
   if (ex) {
     this._logError(ex);
   }
 };
 
 
 /**
  * A generic way of reporting errors, for easy overloading in different
--- a/browser/devtools/shared/test/Makefile.in
+++ b/browser/devtools/shared/test/Makefile.in
@@ -44,30 +44,20 @@ VPATH     = @srcdir@
 relativesrcdir  = browser/devtools/shared/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_TEST_FILES = \
   browser_promise_basic.js \
   browser_templater_basic.js \
-  browser_toolbar_basic.js \
-  browser_gcli_commands.js \
-  browser_gcli_inspect.js \
-  browser_gcli_integrate.js \
-  browser_gcli_require.js \
-  browser_gcli_web.js \
-  browser_gcli_break.js \
   head.js \
   $(NULL)
 
 _BROWSER_TEST_PAGES = \
   browser_templater_basic.html \
-  browser_toolbar_basic.html \
-  browser_gcli_inspect.html \
-  browser_gcli_break.html \
   $(NULL)
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
 
 libs:: $(_BROWSER_TEST_PAGES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
deleted file mode 100644
--- a/browser/devtools/shared/test/browser_gcli_break.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-  <head>
-    <meta charset="utf-8">
-    <title>Browser GCLI break command test</title>
-    <!-- Any copyright is dedicated to the Public Domain.
-         http://creativecommons.org/publicdomain/zero/1.0/ -->
-    <script type="text/javascript">
-      function firstCall() {
-        eval("window.line0 = Error().lineNumber; secondCall();");
-      }
-      function secondCall() {
-        eval("debugger;");
-      }
-    </script>
-  </head>
-  <body>
-  </body>
-</html>
deleted file mode 100644
--- a/browser/devtools/shared/test/browser_gcli_break.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Tests that the break command works as it should
-
-const TEST_URI = "http://example.com/browser/browser/devtools/shared/test/browser_gcli_break.html";
-
-function test() {
-  DeveloperToolbarTest.test(TEST_URI, function(browser, tab) {
-    testBreakCommands();
-  });
-}
-
-function testBreakCommands() {
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "brea",
-    directTabText: "k",
-    status: "ERROR"
-  });
-
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "break",
-    status: "ERROR"
-  });
-
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "break add",
-    status: "ERROR"
-  });
-
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "break add line",
-    emptyParameters: [ " <file>", " <line>" ],
-    status: "ERROR"
-  });
-
-  let pane = DebuggerUI.toggleDebugger();
-  pane._frame.addEventListener("Debugger:Connecting", function dbgConnected() {
-    pane._frame.removeEventListener("Debugger:Connecting", dbgConnected, true);
-
-    // Wait for the initial resume.
-    let client = pane.debuggerWindow.gClient;
-    client.addOneTimeListener("resumed", function() {
-      client.activeThread.addOneTimeListener("framesadded", function() {
-        DeveloperToolbarTest.checkInputStatus({
-          typed: "break add line " + TEST_URI + " " + content.wrappedJSObject.line0,
-          status: "VALID"
-        });
-        DeveloperToolbarTest.exec({
-          args: {
-            type: 'line',
-            file: TEST_URI,
-            line: content.wrappedJSObject.line0
-          },
-          completed: false
-        });
-
-        DeveloperToolbarTest.checkInputStatus({
-          typed: "break list",
-          status: "VALID"
-        });
-        DeveloperToolbarTest.exec();
-
-        client.activeThread.resume(function() {
-          DeveloperToolbarTest.checkInputStatus({
-            typed: "break del 0",
-            status: "VALID"
-          });
-          DeveloperToolbarTest.exec({
-            args: { breakid: 0 },
-            completed: false
-          });
-
-          finish();
-        });
-      });
-
-      // Trigger newScript notifications using eval.
-      content.wrappedJSObject.firstCall();
-    });
-  }, true);
-}
deleted file mode 100644
--- a/browser/devtools/shared/test/browser_gcli_commands.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test various GCLI commands
-
-let imported = {};
-Components.utils.import("resource:///modules/HUDService.jsm", imported);
-
-const TEST_URI = "data:text/html;charset=utf-8,gcli-commands";
-
-function test() {
-  DeveloperToolbarTest.test(TEST_URI, function(browser, tab) {
-    testEcho();
-    testConsoleClear();
-    testConsoleOpenClose(tab);
-
-    imported = undefined;
-    finish();
-  });
-}
-
-function testEcho() {
-  DeveloperToolbarTest.exec({
-    typed: "echo message",
-    args: { message: "message" },
-    outputMatch: /^message$/,
-  });
-}
-
-function testConsoleClear() {
-  DeveloperToolbarTest.exec({
-    typed: "console clear",
-    args: {},
-    blankOutput: true,
-  });
-}
-
-function testConsoleOpenClose(tab) {
-  DeveloperToolbarTest.exec({
-    typed: "console open",
-    args: {},
-    blankOutput: true,
-  });
-
-  let hud = imported.HUDService.getHudByWindow(content);
-  ok(hud.hudId in imported.HUDService.hudReferences, "console open");
-
-  DeveloperToolbarTest.exec({
-    typed: "console close",
-    args: {},
-    blankOutput: true,
-  });
-
-  ok(!(hud.hudId in imported.HUDService.hudReferences), "console closed");
-}
deleted file mode 100644
--- a/browser/devtools/shared/test/browser_gcli_inspect.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
-  <meta charset="utf-8">
-  <title>GCLI inspect command test</title>
-</head>
-<body>
-
-  <!-- This is a list of 0 h1 elements -->
-
-  <!-- This is a list of 1 div elements -->
-  <div>Hello, I'm a div</div>
-
-  <!-- This is a list of 2 span elements -->
-  <span>Hello, I'm a span</span>
-  <span>And me</span>
-
-  <!-- This is a collection of various things that match only once -->
-  <p class="someclass">.someclass</p>
-  <p id="someid">#someid</p>
-  <button disabled>button[disabled]</button>
-  <p><strong>p&gt;strong</strong></p>
-
-</body>
-</html>
deleted file mode 100644
--- a/browser/devtools/shared/test/browser_gcli_inspect.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Tests that the inspect command works as it should
-
-const TEST_URI = "http://example.com/browser/browser/devtools/shared/test/browser_gcli_inspect.html";
-
-function test() {
-  DeveloperToolbarTest.test(TEST_URI, function(browser, tab) {
-    testInspect();
-
-    finish();
-  });
-}
-
-function testInspect() {
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "inspec",
-    directTabText: "t",
-    status: "ERROR"
-  });
-
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "inspect",
-    emptyParameters: [ " <node>" ],
-    status: "ERROR"
-  });
-
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "inspect h1",
-    status: "ERROR"
-  });
-
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "inspect span",
-    status: "ERROR"
-  });
-
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "inspect div",
-    status: "VALID"
-  });
-
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "inspect .someclass",
-    status: "VALID"
-  });
-
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "inspect #someid",
-    status: "VALID"
-  });
-
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "inspect button[disabled]",
-    status: "VALID"
-  });
-
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "inspect p>strong",
-    status: "VALID"
-  });
-
-  DeveloperToolbarTest.checkInputStatus({
-    typed: "inspect :root",
-    status: "VALID"
-  });
-}
deleted file mode 100644
--- a/browser/devtools/shared/test/browser_gcli_integrate.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Tests that source URLs in the Web Console can be clicked to display the
-// standard View Source window.
-
-function test() {
-  testCreateCommands();
-  testRemoveCommands();
-}
-
-let tselarr = {
-  name: 'tselarr',
-  params: [
-    { name: 'num', type: { name: 'selection', data: [ '1', '2', '3' ] } },
-    { name: 'arr', type: { name: 'array', subtype: 'string' } },
-  ],
-  exec: function(args, env) {
-    return "flu " + args.num + "-" + args.arr.join("_");
-  }
-};
-
-function testCreateCommands() {
-  let gcliIndex = require("gcli/index");
-  gcliIndex.addCommand(tselarr);
-
-  let canon = require("gcli/canon");
-  let tselcmd = canon.getCommand("tselarr");
-  ok(tselcmd != null, "tselarr exists in the canon");
-  ok(tselcmd instanceof canon.Command, "canon storing commands");
-}
-
-function testRemoveCommands() {
-  let gcliIndex = require("gcli/index");
-  gcliIndex.removeCommand(tselarr);
-
-  let canon = require("gcli/canon");
-  let tselcmd = canon.getCommand("tselarr");
-  ok(tselcmd == null, "tselcmd removed from the canon");
-}
deleted file mode 100644
--- a/browser/devtools/shared/test/browser_gcli_require.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Tests that source URLs in the Web Console can be clicked to display the
-// standard View Source window.
-
-function test() {
-  define('gclitest/requirable', [], function(require, exports, module) {
-    exports.thing1 = 'thing1';
-    exports.thing2 = 2;
-
-    let status = 'initial';
-    exports.setStatus = function(aStatus) { status = aStatus; };
-    exports.getStatus = function() { return status; };
-  });
-
-  define('gclitest/unrequirable', [], function(require, exports, module) {
-    null.throwNPE();
-  });
-
-  define('gclitest/recurse', [], function(require, exports, module) {
-    require('gclitest/recurse');
-  });
-
-  testWorking();
-  testLeakage();
-  testMultiImport();
-  testRecursive();
-  testUncompilable();
-
-  delete define.modules['gclitest/requirable'];
-  delete define.globalDomain.modules['gclitest/requirable'];
-  delete define.modules['gclitest/unrequirable'];
-  delete define.globalDomain.modules['gclitest/unrequirable'];
-  delete define.modules['gclitest/recurse'];
-  delete define.globalDomain.modules['gclitest/recurse'];
-
-  finish();
-}
-
-function testWorking() {
-  // There are lots of requirement tests that we could be doing here
-  // The fact that we can get anything at all working is a testament to
-  // require doing what it should - we don't need to test the
-  let requireable = require('gclitest/requirable');
-  ok('thing1' == requireable.thing1, 'thing1 was required');
-  ok(2 == requireable.thing2, 'thing2 was required');
-  ok(requireable.thing3 === undefined, 'thing3 was not required');
-}
-
-function testDomains() {
-  let requireable = require('gclitest/requirable');
-  ok(requireable.status === undefined, 'requirable has no status');
-  requireable.setStatus(null);
-  ok(null === requireable.getStatus(), 'requirable.getStatus changed to null');
-  ok(requireable.status === undefined, 'requirable still has no status');
-  requireable.setStatus('42');
-  ok('42' == requireable.getStatus(), 'requirable.getStatus changed to 42');
-  ok(requireable.status === undefined, 'requirable *still* has no status');
-
-  let domain = new define.Domain();
-  let requireable2 = domain.require('gclitest/requirable');
-  ok(requireable2.status === undefined, 'requirable2 has no status');
-  ok('initial' === requireable2.getStatus(), 'requirable2.getStatus is initial');
-  requireable2.setStatus(999);
-  ok(999 === requireable2.getStatus(), 'requirable2.getStatus changed to 999');
-  ok(requireable2.status === undefined, 'requirable2 still has no status');
-
-  t.verifyEqual('42', requireable.getStatus());
-  ok(requireable.status === undefined, 'requirable has no status (as expected)');
-
-  delete domain.modules['gclitest/requirable'];
-}
-
-function testLeakage() {
-  let requireable = require('gclitest/requirable');
-  ok(requireable.setup == null, 'leakage of setup');
-  ok(requireable.shutdown == null, 'leakage of shutdown');
-  ok(requireable.testWorking == null, 'leakage of testWorking');
-}
-
-function testMultiImport() {
-  let r1 = require('gclitest/requirable');
-  let r2 = require('gclitest/requirable');
-  ok(r1 === r2, 'double require was strict equal');
-}
-
-function testUncompilable() {
-  // It's not totally clear how a module loader should perform with unusable
-  // modules, however at least it should go into a flat spin ...
-  // GCLI mini_require reports an error as it should
-  try {
-    let unrequireable = require('gclitest/unrequirable');
-    fail();
-  }
-  catch (ex) {
-    // an exception is expected
-  }
-}
-
-function testRecursive() {
-  // See Bug 658583
-  // require('gclitest/recurse');
-  // Also see the comments in the testRecursive() function
-}
deleted file mode 100644
--- a/browser/devtools/shared/test/browser_gcli_web.js
+++ /dev/null
@@ -1,2939 +0,0 @@
-/*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-
-/*
- *
- *
- *
- *
- *
- *
- *
- *********************************** WARNING ***********************************
- *
- * Do not edit this file without understanding where it comes from,
- * Your changes are likely to be overwritten without warning.
- *
- * This test file is generated using a level 25 wizard spell cast on the
- * test files that run in the browser as part of GCLI's test suite.
- * For details of how to cast the spell, see GCLI's gcli.js
- *
- * For more information on GCLI see:
- * - https://github.com/mozilla/gcli/blob/master/docs/index.md
- * - https://wiki.mozilla.org/DevTools/Features/GCLI
- *
- * The original source for this file is:
- *  https://github.com/mozilla/gcli/
- *
- *******************************************************************************
- *
- *
- *
- *
- *
- *
- *
- *
- *
- */
-
-///////////////////////////////////////////////////////////////////////////////
-/*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-
-define('gclitest/index', ['require', 'exports', 'module' , 'gclitest/suite'], function(require, exports, module) {
-
-  var examiner = require('gclitest/suite').examiner;
-
-  // A minimum fake dom to get us through the JS tests
-  var fakeWindow = {
-    isFake: true,
-    document: { title: 'Fake DOM' }
-  };
-  fakeWindow.window = fakeWindow;
-  examiner.defaultOptions = {
-    window: fakeWindow,
-    hideExec: true
-  };
-
-  /**
-   * A simple proxy to examiner.run, for convenience - this is run from the
-   * top level.
-   * @param options Lookup of options that customize test running. Includes:
-   * - window (default=undefined) A reference to the DOM window. If left
-   *   undefined then a reduced set of tests will run.
-   * - isNode (default=false) Are we running under NodeJS, specifically, are we
-   *   using JSDom, which isn't a 100% complete DOM implementation.
-   *   Some tests are skipped when using NodeJS.
-   * - display (default=undefined) A reference to a Display implementation.
-   *   A reduced set of tests will run if left undefined
-   * - detailedResultLog (default=false) do we output a test summary to
-   *   |console.log| on test completion.
-   * - hideExec (default=false) Set the |hidden| property in calls to
-   *   |requisition.exec()| which prevents the display from becoming messed up,
-   *   however use of hideExec restricts the set of tests that are run
-   */
-  exports.run = function(options) {
-    examiner.run(options || {});
-
-    // A better set of default than those specified above, come from the set
-    // that are passed to run().
-    examiner.defaultOptions = {
-      window: options.window,
-      display: options.display,
-      hideExec: options.hideExec
-    };
-  };
-
-});
-/*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-
-define('gclitest/suite', ['require', 'exports', 'module' , 'gcli/index', 'test/examiner', 'gclitest/testCli', 'gclitest/testCompletion', 'gclitest/testExec', 'gclitest/testHistory', 'gclitest/testJs', 'gclitest/testKeyboard', 'gclitest/testRequire', 'gclitest/testResource', 'gclitest/testScratchpad', 'gclitest/testSpell', 'gclitest/testSplit', 'gclitest/testTokenize', 'gclitest/testTooltip', 'gclitest/testTypes', 'gclitest/testUtil'], function(require, exports, module) {
-
-  // We need to make sure GCLI is initialized before we begin testing it
-  require('gcli/index');
-
-  var examiner = require('test/examiner');
-
-  // It's tempting to want to unify these strings and make addSuite() do the
-  // call to require(), however that breaks the build system which looks for
-  // the strings passed to require
-  examiner.addSuite('gclitest/testCli', require('gclitest/testCli'));
-  examiner.addSuite('gclitest/testCompletion', require('gclitest/testCompletion'));
-  examiner.addSuite('gclitest/testExec', require('gclitest/testExec'));
-  examiner.addSuite('gclitest/testHistory', require('gclitest/testHistory'));
-  examiner.addSuite('gclitest/testJs', require('gclitest/testJs'));
-  examiner.addSuite('gclitest/testKeyboard', require('gclitest/testKeyboard'));
-  examiner.addSuite('gclitest/testRequire', require('gclitest/testRequire'));
-  examiner.addSuite('gclitest/testResource', require('gclitest/testResource'));
-  examiner.addSuite('gclitest/testScratchpad', require('gclitest/testScratchpad'));
-  examiner.addSuite('gclitest/testSpell', require('gclitest/testSpell'));
-  examiner.addSuite('gclitest/testSplit', require('gclitest/testSplit'));
-  examiner.addSuite('gclitest/testTokenize', require('gclitest/testTokenize'));
-  examiner.addSuite('gclitest/testTooltip', require('gclitest/testTooltip'));
-  examiner.addSuite('gclitest/testTypes', require('gclitest/testTypes'));
-  examiner.addSuite('gclitest/testUtil', require('gclitest/testUtil'));
-
-  exports.examiner = examiner;
-});
-/*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-
-define('test/examiner', ['require', 'exports', 'module' ], function(require, exports, module) {
-var examiner = exports;
-
-
-/**
- * Test harness data
- */
-examiner.suites = {};
-
-/**
- * The gap between tests when running async
- */
-var delay = 10;
-
-var currentTest = null;
-
-var stati = {
-  notrun: { index: 0, name: 'Skipped' },
-  executing: { index: 1, name: 'Executing' },
-  asynchronous: { index: 2, name: 'Waiting' },
-  pass: { index: 3, name: 'Pass' },
-  fail: { index: 4, name: 'Fail' }
-};
-
-/**
- * Add a test suite. Generally used like:
- * test.addSuite('foo', require('path/to/foo'));
- */
-examiner.addSuite = function(name, suite) {
-  examiner.suites[name] = new Suite(name, suite);
-};
-
-/**
- * When run from an command, there are some options that we can't (and
- * shouldn't) specify, so we allow a set of default options, which are merged
- * with the specified options in |run()|.
- */
-examiner.defaultOptions = {};
-
-/**
- * Add properties to |options| from |examiner.defaultOptions| when |options|
- * does not have a value for a given name.
- */
-function mergeDefaultOptions(options) {
-  Object.keys(examiner.defaultOptions).forEach(function(name) {
-    if (options[name] == null) {
-      options[name] = examiner.defaultOptions[name];
-    }
-  });
-}
-
-/**
- * Run the tests defined in the test suite synchronously
- */
-examiner.run = function(options) {
-  mergeDefaultOptions(options);
-
-  Object.keys(examiner.suites).forEach(function(suiteName) {
-    var suite = examiner.suites[suiteName];
-    suite.run(options);
-  }.bind(this));
-
-  if (options.detailedResultLog) {
-    examiner.detailedResultLog();
-  }
-  else {
-    console.log('Completed test suite');
-  }
-
-  return examiner.suites;
-};
-
-/**
- * Run all the tests asynchronously
- */
-examiner.runAsync = function(options, callback) {
-  mergeDefaultOptions(options);
-  this._runAsyncInternal(0, options, callback);
-};
-
-/**
- * Run all the test suits asynchronously
- */
-examiner._runAsyncInternal = function(i, options, callback) {
-  if (i >= Object.keys(examiner.suites).length) {
-    if (typeof callback === 'function') {
-      callback();
-    }
-    return;
-  }
-
-  var suiteName = Object.keys(examiner.suites)[i];
-  examiner.suites[suiteName].runAsync(options, function() {
-    setTimeout(function() {
-      examiner._runAsyncInternal(i + 1, options, callback);
-    }.bind(this), delay);
-  }.bind(this));
-};
-
-/**
- * Create a JSON object suitable for serialization
- */
-examiner.toRemote = function() {
-  return {
-    suites: Object.keys(examiner.suites).map(function(suiteName) {
-      return examiner.suites[suiteName].toRemote();
-    }.bind(this)),
-    summary: {
-      checks: this.checks,
-      status: this.status
-    }
-  };
-};
-
-/**
- * The number of checks in this set of test suites is the sum of the checks in
- * the test suites.
- */
-Object.defineProperty(examiner, 'checks', {
-  get: function() {
-    return  Object.keys(examiner.suites).reduce(function(current, suiteName) {
-      return current + examiner.suites[suiteName].checks;
-    }.bind(this), 0);
-  },
-  enumerable: true
-});
-
-/**
- * The status of this set of test suites is the worst of the statuses of the
- * contained test suites.
- */
-Object.defineProperty(examiner, 'status', {
-  get: function() {
-    return Object.keys(examiner.suites).reduce(function(status, suiteName) {
-      var suiteStatus = examiner.suites[suiteName].status;
-      return status.index > suiteStatus.index ? status : suiteStatus;
-    }.bind(this), stati.notrun);
-  },
-  enumerable: true
-});
-
-/**
- * Output a test summary to console.log
- */
-examiner.detailedResultLog = function() {
-  Object.keys(this.suites).forEach(function(suiteName) {
-    var suite = examiner.suites[suiteName];
-
-    console.log(suite.name + ': ' + suite.status.name + ' (funcs=' +
-            Object.keys(suite.tests).length +
-            ', checks=' + suite.checks + ')');
-
-    Object.keys(suite.tests).forEach(function(testName) {
-      var test = suite.tests[testName];
-      if (test.status !== stati.pass || test.failures.length !== 0) {
-        console.log('- ' + test.name + ': ' + test.status.name);
-        test.failures.forEach(function(failure) {
-          console.log('  - ' + failure.message);
-          if (failure.expected) {
-            console.log('    - Expected: ' + failure.expected);
-            console.log('    -   Actual: ' + failure.actual);
-          }
-        }.bind(this));
-      }
-    }.bind(this));
-  }.bind(this));
-
-  console.log();
-  console.log('Summary: ' + this.status.name + ' (' + this.checks + ' checks)');
-};
-
-/**
- * Used by assert to record a failure against the current test
- * @param failure A set of properties describing the failure. Properties include:
- * - message (string, required) A message describing the test
- * - expected (optional) The expected data
- * - actual (optional) The actual data
- */
-examiner.recordFailure = function(failure) {
-  if (!currentTest) {
-    console.error('No currentTest for ' + failure.message);
-    return;
-  }
-
-  currentTest.status = stati.fail;
-  currentTest.failures.push(failure);
-};
-
-/**
- * Used by assert to record a check pass
- */
-examiner.recordPass = function() {
-  if (!currentTest) {
-    console.error('No currentTest');
-    return;
-  }
-
-  currentTest.checks++;
-};
-
-/**
- * When we want to note something alongside a test
- */
-examiner.log = function(message) {
-  currentTest.failures.push({ message: message });
-};
-
-/**
- * A suite is a group of tests
- */
-function Suite(suiteName, suite) {
-  this.name = suiteName.replace(/gclitest\//, '');
-  this.suite = suite;
-
-  this.tests = {};
-  Object.keys(suite).forEach(function(testName) {
-    if (testName !== 'setup' && testName !== 'shutdown') {
-      var test = new Test(this, testName, suite[testName]);
-      this.tests[testName] = test;
-    }
-  }.bind(this));
-}
-
-/**
- * Run all the tests in this suite synchronously
- */
-Suite.prototype.run = function(options) {
-  if (!this._setup(options)) {
-    return;
-  }
-
-  Object.keys(this.tests).forEach(function(testName) {
-    var test = this.tests[testName];
-    test.run(options);
-  }.bind(this));
-
-  this._shutdown(options);
-};
-
-/**
- * Run all the tests in this suite asynchronously
- */
-Suite.prototype.runAsync = function(options, callback) {
-  if (!this._setup(options)) {
-    if (typeof callback === 'function') {
-      callback();
-    }
-    return;
-  }
-
-  this._runAsyncInternal(0, options, function() {
-    this._shutdown(options);
-
-    if (typeof callback === 'function') {
-      callback();
-    }
-  }.bind(this));
-};
-
-/**
- * Function used by the async runners that can handle async recursion.
- */
-Suite.prototype._runAsyncInternal = function(i, options, callback) {
-  if (i >= Object.keys(this.tests).length) {
-    if (typeof callback === 'function') {
-      callback();
-    }
-    return;
-  }
-
-  var testName = Object.keys(this.tests)[i];
-  this.tests[testName].runAsync(options, function() {
-    setTimeout(function() {
-      this._runAsyncInternal(i + 1, options, callback);
-    }.bind(this), delay);
-  }.bind(this));
-};
-
-/**
- * Create a JSON object suitable for serialization
- */
-Suite.prototype.toRemote = function() {
-  return {
-    name: this.name,
-    tests: Object.keys(this.tests).map(function(testName) {
-      return this.tests[testName].toRemote();
-    }.bind(this))
-  };
-};
-
-/**
- * The number of checks in this suite is the sum of the checks in the contained
- * tests.
- */
-Object.defineProperty(Suite.prototype, 'checks', {
-  get: function() {
-    return Object.keys(this.tests).reduce(function(prevChecks, testName) {
-      return prevChecks + this.tests[testName].checks;
-    }.bind(this), 0);
-  },
-  enumerable: true
-});
-
-/**
- * The status of a test suite is the worst of the statuses of the contained
- * tests.
- */
-Object.defineProperty(Suite.prototype, 'status', {
-  get: function() {
-    return Object.keys(this.tests).reduce(function(prevStatus, testName) {
-      var suiteStatus = this.tests[testName].status;
-      return prevStatus.index > suiteStatus.index ? prevStatus : suiteStatus;
-    }.bind(this), stati.notrun);
-  },
-  enumerable: true
-});
-
-/**
- * Defensively setup the test suite
- */
-Suite.prototype._setup = function(options) {
-  if (typeof this.suite.setup !== 'function') {
-    return true;
-  }
-
-  try {
-    this.suite.setup(options);
-    return true;
-  }
-  catch (ex) {
-    this._logToAllTests(stati.notrun, '' + ex);
-    console.error(ex);
-    if (ex.stack) {
-      console.error(ex.stack);
-    }
-    return false;
-  }
-};
-
-/**
- * Defensively shutdown the test suite
- */
-Suite.prototype._shutdown = function(options) {
-  if (typeof this.suite.shutdown !== 'function') {
-    return true;
-  }
-
-  try {
-    this.suite.shutdown(options);
-    return true;
-  }
-  catch (ex) {
-    this._logToAllTests(stati.fail, '' + ex);
-    console.error(ex);
-    if (ex.stack) {
-      console.error(ex.stack);
-    }
-    return false;
-  }
-};
-
-/**
- * Something has gone wrong that affects all tests in this Suite
- */
-Suite.prototype._logToAllTests = function(status, message) {
-  Object.keys(this.tests).forEach(function(testName) {
-    var test = this.tests[testName];
-    test.status = status;
-    test.failures.push({ message: message });
-  }.bind(this));
-};
-
-
-/**
- * A test represents data about a single test function
- */
-function Test(suite, name, func) {
-  this.suite = suite;
-  this.name = name;
-  this.func = func;
-  this.title = name.replace(/^test/, '').replace(/([A-Z])/g, ' $1');
-
-  this.failures = [];
-  this.status = stati.notrun;
-  this.checks = 0;
-}
-
-/**
- * Run just a single test
- */
-Test.prototype.run = function(options) {
-  currentTest = this;
-  this.status = stati.executing;
-  this.failures = [];
-  this.checks = 0;
-
-  try {
-    this.func.apply(this.suite, [ options ]);
-  }
-  catch (ex) {
-    this.status = stati.fail;
-    this.failures.push({ message: '' + ex });
-    console.error(ex);
-    if (ex.stack) {
-      console.error(ex.stack);
-    }
-  }
-
-  if (this.status === stati.executing) {
-    this.status = stati.pass;
-  }
-
-  currentTest = null;
-};
-
-/**
- * Run all the tests in this suite asynchronously
- */
-Test.prototype.runAsync = function(options, callback) {
-  setTimeout(function() {
-    this.run(options);
-    if (typeof callback === 'function') {
-      callback();
-    }
-  }.bind(this), delay);
-};
-
-/**
- * Create a JSON object suitable for serialization
- */
-Test.prototype.toRemote = function() {
-  return {
-    name: this.name,
-    title: this.title,
-    status: this.status,
-    failures: this.failures,
-    checks: this.checks
-  };
-};
-
-
-});
-/*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-
-define('gclitest/testCli', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/types', 'gclitest/commands', 'test/assert'], function(require, exports, module) {
-
-
-var Requisition = require('gcli/cli').Requisition;
-var Status = require('gcli/types').Status;
-var commands = require('gclitest/commands');
-
-var test = require('test/assert');
-
-exports.setup = function() {
-  commands.setup();
-};
-
-exports.shutdown = function() {
-  commands.shutdown();
-};
-
-
-var assign1;
-var assign2;
-var assignC;
-var requ;
-var debug = false;
-var status;
-var statuses;
-
-function update(input) {
-  if (!requ) {
-    requ = new Requisition();
-  }
-  requ.update(input.typed);
-
-  if (debug) {
-    console.log('####### TEST: typed="' + input.typed +
-        '" cur=' + input.cursor.start +
-        ' cli=', requ);
-  }
-
-  status = requ.getStatus();
-  assignC = requ.getAssignmentAt(input.cursor.start);
-  statuses = requ.getInputStatusMarkup(input.cursor.start).map(function(s) {
-    return Array(s.string.length + 1).join(s.status.toString()[0]);
-  }).join('');
-
-  if (requ.commandAssignment.value) {
-    assign1 = requ.getAssignment(0);
-    assign2 = requ.getAssignment(1);
-  }
-  else {
-    assign1 = undefined;
-    assign2 = undefined;
-  }
-}
-
-function verifyPredictionsContains(name, predictions) {
-  return predictions.every(function(prediction) {
-    return name === prediction.name;
-  }, this);
-}
-
-
-exports.testBlank = function() {
-  update({ typed: '', cursor: { start: 0, end: 0 } });
-  test.is(        '', statuses);
-  test.is(Status.ERROR, status);
-  test.is(-1, assignC.paramIndex);
-  test.is(undefined, requ.commandAssignment.value);
-
-  update({ typed: ' ', cursor: { start: 1, end: 1 } });
-  test.is(        'V', statuses);
-  test.is(Status.ERROR, status);
-  test.is(-1, assignC.paramIndex);
-  test.is(undefined, requ.commandAssignment.value);
-
-  update({ typed: ' ', cursor: { start: 0, end: 0 } });
-  test.is(        'V', statuses);
-  test.is(Status.ERROR, status);
-  test.is(-1, assignC.paramIndex);
-  test.is(undefined, requ.commandAssignment.value);
-};
-
-exports.testIncompleteMultiMatch = function() {
-  update({ typed: 't', cursor: { start: 1, end: 1 } });
-  test.is(        'I', statuses);
-  test.is(Status.ERROR, status);
-  test.is(-1, assignC.paramIndex);
-  test.ok(assignC.getPredictions().length > 0);
-  verifyPredictionsContains('tsv', assignC.getPredictions());
-  verifyPredictionsContains('tsr', assignC.getPredictions());
-  test.is(undefined, requ.commandAssignment.value);
-};
-
-exports.testIncompleteSingleMatch = function() {
-  update({ typed: 'tselar', cursor: { start: 6, end: 6 } });
-  test.is(        'IIIIII', statuses);
-  test.is(Status.ERROR, status);
-  test.is(-1, assignC.paramIndex);
-  test.is(1, assignC.getPredictions().length);
-  test.is('tselarr', assignC.getPredictions()[0].name);
-  test.is(undefined, requ.commandAssignment.value);
-};
-
-exports.testTsv = function() {
-  update({ typed: 'tsv', cursor: { start: 3, end: 3 } });
-  test.is(        'VVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is(-1, assignC.paramIndex);
-  test.is('tsv', requ.commandAssignment.value.name);
-
-  update({ typed: 'tsv ', cursor: { start: 4, end: 4 } });
-  test.is(        'VVVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is(0, assignC.paramIndex);
-  test.is('tsv', requ.commandAssignment.value.name);
-
-  update({ typed: 'tsv ', cursor: { start: 2, end: 2 } });
-  test.is(        'VVVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is(-1, assignC.paramIndex);
-  test.is('tsv', requ.commandAssignment.value.name);
-
-  update({ typed: 'tsv o', cursor: { start: 5, end: 5 } });
-  test.is(        'VVVVI', statuses);
-  test.is(Status.ERROR, status);
-  test.is(0, assignC.paramIndex);
-  test.ok(assignC.getPredictions().length >= 2);
-  test.is(commands.option1, assignC.getPredictions()[0].value);
-  test.is(commands.option2, assignC.getPredictions()[1].value);
-  test.is('tsv', requ.commandAssignment.value.name);
-  test.is('o', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tsv option', cursor: { start: 10, end: 10 } });
-  test.is(        'VVVVIIIIII', statuses);
-  test.is(Status.ERROR, status);
-  test.is(0, assignC.paramIndex);
-  test.ok(assignC.getPredictions().length >= 2);
-  test.is(commands.option1, assignC.getPredictions()[0].value);
-  test.is(commands.option2, assignC.getPredictions()[1].value);
-  test.is('tsv', requ.commandAssignment.value.name);
-  test.is('option', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tsv option', cursor: { start: 1, end: 1 } });
-  test.is(        'VVVVEEEEEE', statuses);
-  test.is(Status.ERROR, status);
-  test.is(-1, assignC.paramIndex);
-  test.is('tsv', requ.commandAssignment.value.name);
-  test.is('option', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tsv option ', cursor: { start: 11, end: 11 } });
-  test.is(        'VVVVEEEEEEV', statuses);
-  test.is(Status.ERROR, status);
-  test.is(1, assignC.paramIndex);
-  test.is(0, assignC.getPredictions().length);
-  test.is('tsv', requ.commandAssignment.value.name);
-  test.is('option', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tsv option1', cursor: { start: 11, end: 11 } });
-  test.is(        'VVVVVVVVVVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsv', requ.commandAssignment.value.name);
-  test.is('option1', assign1.arg.text);
-  test.is(commands.option1, assign1.value);
-  test.is(0, assignC.paramIndex);
-
-  update({ typed: 'tsv option1 ', cursor: { start: 12, end: 12 } });
-  test.is(        'VVVVVVVVVVVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsv', requ.commandAssignment.value.name);
-  test.is('option1', assign1.arg.text);
-  test.is(commands.option1, assign1.value);
-  test.is(1, assignC.paramIndex);
-
-  update({ typed: 'tsv option1 6', cursor: { start: 13, end: 13 } });
-  test.is(        'VVVVVVVVVVVVV', statuses);
-  test.is(Status.VALID, status);
-  test.is('tsv', requ.commandAssignment.value.name);
-  test.is('option1', assign1.arg.text);
-  test.is(commands.option1, assign1.value);
-  test.is('6', assign2.arg.text);
-  test.is('6', assign2.value);
-  test.is('string', typeof assign2.value);
-  test.is(1, assignC.paramIndex);
-
-  update({ typed: 'tsv option2 6', cursor: { start: 13, end: 13 } });
-  test.is(        'VVVVVVVVVVVVV', statuses);
-  test.is(Status.VALID, status);
-  test.is('tsv', requ.commandAssignment.value.name);
-  test.is('option2', assign1.arg.text);
-  test.is(commands.option2, assign1.value);
-  test.is('6', assign2.arg.text);
-  test.is(6, assign2.value);
-  test.is('number', typeof assign2.value);
-  test.is(1, assignC.paramIndex);
-};
-
-exports.testInvalid = function() {
-  update({ typed: 'zxjq', cursor: { start: 4, end: 4 } });
-  test.is(        'EEEE', statuses);
-  test.is('zxjq', requ.commandAssignment.arg.text);
-  test.is('', requ._unassigned.arg.text);
-  test.is(-1, assignC.paramIndex);
-
-  update({ typed: 'zxjq ', cursor: { start: 5, end: 5 } });
-  test.is(        'EEEEV', statuses);
-  test.is('zxjq', requ.commandAssignment.arg.text);
-  test.is('', requ._unassigned.arg.text);
-  test.is(-1, assignC.paramIndex);
-
-  update({ typed: 'zxjq one', cursor: { start: 8, end: 8 } });
-  test.is(        'EEEEVEEE', statuses);
-  test.is('zxjq', requ.commandAssignment.arg.text);
-  test.is('one', requ._unassigned.arg.text);
-};
-
-exports.testSingleString = function() {
-  update({ typed: 'tsr', cursor: { start: 3, end: 3 } });
-  test.is(        'VVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsr', requ.commandAssignment.value.name);
-  test.ok(assign1.arg.isBlank());
-  test.is(undefined, assign1.value);
-  test.is(undefined, assign2);
-
-  update({ typed: 'tsr ', cursor: { start: 4, end: 4 } });
-  test.is(        'VVVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsr', requ.commandAssignment.value.name);
-  test.ok(assign1.arg.isBlank());
-  test.is(undefined, assign1.value);
-  test.is(undefined, assign2);
-
-  update({ typed: 'tsr h', cursor: { start: 5, end: 5 } });
-  test.is(        'VVVVV', statuses);
-  test.is(Status.VALID, status);
-  test.is('tsr', requ.commandAssignment.value.name);
-  test.is('h', assign1.arg.text);
-  test.is('h', assign1.value);
-
-  update({ typed: 'tsr "h h"', cursor: { start: 9, end: 9 } });
-  test.is(        'VVVVVVVVV', statuses);
-  test.is(Status.VALID, status);
-  test.is('tsr', requ.commandAssignment.value.name);
-  test.is('h h', assign1.arg.text);
-  test.is('h h', assign1.value);
-
-  update({ typed: 'tsr h h h', cursor: { start: 9, end: 9 } });
-  test.is(        'VVVVVVVVV', statuses);
-  test.is('tsr', requ.commandAssignment.value.name);
-  test.is('h h h', assign1.arg.text);
-  test.is('h h h', assign1.value);
-};
-
-exports.testSingleNumber = function() {
-  update({ typed: 'tsu', cursor: { start: 3, end: 3 } });
-  test.is(        'VVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsu', requ.commandAssignment.value.name);
-  test.is('', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tsu ', cursor: { start: 4, end: 4 } });
-  test.is(        'VVVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsu', requ.commandAssignment.value.name);
-  test.is('', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tsu 1', cursor: { start: 5, end: 5 } });
-  test.is(        'VVVVV', statuses);
-  test.is(Status.VALID, status);
-  test.is('tsu', requ.commandAssignment.value.name);
-  test.is('1', assign1.arg.text);
-  test.is(1, assign1.value);
-  test.is('number', typeof assign1.value);
-
-  update({ typed: 'tsu x', cursor: { start: 5, end: 5 } });
-  test.is(        'VVVVE', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsu', requ.commandAssignment.value.name);
-  test.is('x', assign1.arg.text);
-  test.is(undefined, assign1.value);
-};
-
-exports.testElement = function(options) {
-  update({ typed: 'tse', cursor: { start: 3, end: 3 } });
-  test.is(        'VVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tse', requ.commandAssignment.value.name);
-  test.ok(assign1.arg.isBlank());
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tse :root', cursor: { start: 9, end: 9 } });
-  test.is(        'VVVVVVVVV', statuses);
-  test.is(Status.VALID, status);
-  test.is('tse', requ.commandAssignment.value.name);
-  test.is(':root', assign1.arg.text);
-  if (!options.window.isFake) {
-    test.is(options.window.document.documentElement, assign1.value);
-  }
-
-  if (!options.window.isFake) {
-    var inputElement = options.window.document.getElementById('gcli-input');
-    if (inputElement) {
-      update({ typed: 'tse #gcli-input', cursor: { start: 15, end: 15 } });
-      test.is(        'VVVVVVVVVVVVVVV', statuses);
-      test.is(Status.VALID, status);
-      test.is('tse', requ.commandAssignment.value.name);
-      test.is('#gcli-input', assign1.arg.text);
-      test.is(inputElement, assign1.value);
-    }
-    else {
-      test.log('Skipping test that assumes gcli on the web');
-    }
-  }
-
-  update({ typed: 'tse #gcli-nomatch', cursor: { start: 17, end: 17 } });
-  // This is somewhat debatable because this input can't be corrected simply
-  // by typing so it's and error rather than incomplete, however without
-  // digging into the CSS engine we can't tell that so we default to incomplete
-  test.is(        'VVVVIIIIIIIIIIIII', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tse', requ.commandAssignment.value.name);
-  test.is('#gcli-nomatch', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tse #', cursor: { start: 5, end: 5 } });
-  test.is(        'VVVVE', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tse', requ.commandAssignment.value.name);
-  test.is('#', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tse .', cursor: { start: 5, end: 5 } });
-  test.is(        'VVVVE', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tse', requ.commandAssignment.value.name);
-  test.is('.', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tse *', cursor: { start: 5, end: 5 } });
-  test.is(        'VVVVE', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tse', requ.commandAssignment.value.name);
-  test.is('*', assign1.arg.text);
-  test.is(undefined, assign1.value);
-};
-
-exports.testNestedCommand = function() {
-  update({ typed: 'tsn', cursor: { start: 3, end: 3 } });
-  test.is(        'III', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsn', requ.commandAssignment.arg.text);
-  test.is(undefined, assign1);
-
-  update({ typed: 'tsn ', cursor: { start: 4, end: 4 } });
-  test.is(        'IIIV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsn', requ.commandAssignment.arg.text);
-  test.is(undefined, assign1);
-
-  update({ typed: 'tsn x', cursor: { start: 5, end: 5 } });
-  // Commented out while we try out fuzzy matching
-  // test.is(        'EEEVE', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsn x', requ.commandAssignment.arg.text);
-  test.is(undefined, assign1);
-
-  update({ typed: 'tsn dif', cursor: { start: 7, end: 7 } });
-  test.is(        'VVVVVVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsn dif', requ.commandAssignment.value.name);
-  test.is('', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tsn dif ', cursor: { start: 8, end: 8 } });
-  test.is(        'VVVVVVVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsn dif', requ.commandAssignment.value.name);
-  test.is('', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tsn dif x', cursor: { start: 9, end: 9 } });
-  test.is(        'VVVVVVVVV', statuses);
-  test.is(Status.VALID, status);
-  test.is('tsn dif', requ.commandAssignment.value.name);
-  test.is('x', assign1.arg.text);
-  test.is('x', assign1.value);
-
-  update({ typed: 'tsn ext', cursor: { start: 7, end: 7 } });
-  test.is(        'VVVVVVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsn ext', requ.commandAssignment.value.name);
-  test.is('', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tsn exte', cursor: { start: 8, end: 8 } });
-  test.is(        'VVVVVVVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsn exte', requ.commandAssignment.value.name);
-  test.is('', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tsn exten', cursor: { start: 9, end: 9 } });
-  test.is(        'VVVVVVVVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsn exten', requ.commandAssignment.value.name);
-  test.is('', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'tsn extend', cursor: { start: 10, end: 10 } });
-  test.is(        'VVVVVVVVVV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsn extend', requ.commandAssignment.value.name);
-  test.is('', assign1.arg.text);
-  test.is(undefined, assign1.value);
-
-  update({ typed: 'ts ', cursor: { start: 3, end: 3 } });
-  test.is(        'EEV', statuses);
-  test.is(Status.ERROR, status);
-  test.is('ts', requ.commandAssignment.arg.text);
-  test.is(undefined, assign1);
-};
-
-// From Bug 664203
-exports.testDeeplyNested = function() {
-  update({ typed: 'tsn deep down nested cmd', cursor: { start: 24, end: 24 } });
-  test.is(        'VVVVVVVVVVVVVVVVVVVVVVVV', statuses);
-  test.is(Status.VALID, status);
-  test.is('tsn deep down nested cmd', requ.commandAssignment.value.name);
-  test.is(undefined, assign1);
-
-  update({ typed: 'tsn deep down nested', cursor: { start: 20, end: 20 } });
-  test.is(        'IIIVIIIIVIIIIVIIIIII', statuses);
-  test.is(Status.ERROR, status);
-  test.is('tsn deep down nested', requ.commandAssignment.value.name);
-  test.is(undefined, assign1);
-};
-
-
-});
-/*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-
-define('gclitest/commands', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/util', 'gcli/types/selection', 'gcli/types/basic', 'gcli/types'], function(require, exports, module) {
-var commands = exports;
-
-
-var canon = require('gcli/canon');
-var util = require('gcli/util');
-
-var SelectionType = require('gcli/types/selection').SelectionType;
-var DeferredType = require('gcli/types/basic').DeferredType;
-var types = require('gcli/types');
-
-/**
- * Registration and de-registration.
- */
-commands.setup = function() {
-  // setup/shutdown need to register/unregister types, however that means we
-  // need to re-initialize commands.option1 and commands.option2 with the
-  // actual types
-  commands.option1.type = types.getType('string');
-  commands.option2.type = types.getType('number');
-
-  types.registerType(commands.optionType);
-  types.registerType(commands.optionValue);
-
-  canon.addCommand(commands.tsv);
-  canon.addCommand(commands.tsr);
-  canon.addCommand(commands.tse);
-  canon.addCommand(commands.tsj);
-  canon.addCommand(commands.tsb);
-  canon.addCommand(commands.tss);
-  canon.addCommand(commands.tsu);
-  canon.addCommand(commands.tsn);
-  canon.addCommand(commands.tsnDif);
-  canon.addCommand(commands.tsnExt);
-  canon.addCommand(commands.tsnExte);
-  canon.addCommand(commands.tsnExten);
-  canon.addCommand(commands.tsnExtend);
-  canon.addCommand(commands.tsnDeep);
-  canon.addCommand(commands.tsnDeepDown);
-  canon.addCommand(commands.tsnDeepDownNested);
-  canon.addCommand(commands.tsnDeepDownNestedCmd);
-  canon.addCommand(commands.tselarr);
-  canon.addCommand(commands.tsm);
-  canon.addCommand(commands.tsg);
-};
-
-commands.shutdown = function() {
-  canon.removeCommand(commands.tsv);
-  canon.removeCommand(commands.tsr);
-  canon.removeCommand(commands.tse);
-  canon.removeCommand(commands.tsj);
-  canon.removeCommand(commands.tsb);
-  canon.removeCommand(commands.tss);
-  canon.removeCommand(commands.tsu);
-  canon.removeCommand(commands.tsn);
-  canon.removeCommand(commands.tsnDif);
-  canon.removeCommand(commands.tsnExt);
-  canon.removeCommand(commands.tsnExte);
-  canon.removeCommand(commands.tsnExten);
-  canon.removeCommand(commands.tsnExtend);
-  canon.removeCommand(commands.tsnDeep);
-  canon.removeCommand(commands.tsnDeepDown);
-  canon.removeCommand(commands.tsnDeepDownNested);
-  canon.removeCommand(commands.tsnDeepDownNestedCmd);
-  canon.removeCommand(commands.tselarr);
-  canon.removeCommand(commands.tsm);
-  canon.removeCommand(commands.tsg);
-
-  types.deregisterType(commands.optionType);
-  types.deregisterType(commands.optionValue);
-};
-
-
-commands.option1 = { type: types.getType('string') };
-commands.option2 = { type: types.getType('number') };
-
-var lastOption = undefined;
-
-commands.optionType = new SelectionType({
-  name: 'optionType',
-  lookup: [
-    { name: 'option1', value: commands.option1 },
-    { name: 'option2', value: commands.option2 }
-  ],
-  noMatch: function() {
-    lastOption = undefined;
-  },
-  stringify: function(option) {
-    lastOption = option;
-    return SelectionType.prototype.stringify.call(this, option);
-  },
-  parse: function(arg) {
-    var conversion = SelectionType.prototype.parse.call(this, arg);
-    lastOption = conversion.value;
-    return conversion;
-  }
-});
-
-commands.optionValue = new DeferredType({
-  name: 'optionValue',
-  defer: function() {
-    if (lastOption && lastOption.type) {
-      return lastOption.type;
-    }
-    else {
-      return types.getType('blank');
-    }
-  }
-});
-
-commands.onCommandExec = util.createEvent('commands.onCommandExec');
-
-function createExec(name) {
-  return function(args, context) {
-    var data = {
-      command: commands[name],
-      args: args,
-      context: context
-    };
-    commands.onCommandExec(data);
-    return data;
-  };
-}
-
-commands.tsv = {
-  name: 'tsv',
-  params: [
-    { name: 'optionType', type: 'optionType' },
-    { name: 'optionValue', type: 'optionValue' }
-  ],
-  exec: createExec('tsv')
-};
-
-commands.tsr = {
-  name: 'tsr',
-  params: [ { name: 'text', type: 'string' } ],
-  exec: createExec('tsr')
-};
-
-commands.tse = {
-  name: 'tse',
-  params: [ { name: 'node', type: 'node' } ],
-  exec: createExec('tse')
-};
-
-commands.tsj = {
-  name: 'tsj',
-  params: [ { name: 'javascript', type: 'javascript' } ],
-  exec: createExec('tsj')
-};
-
-commands.tsb = {
-  name: 'tsb',
-  params: [ { name: 'toggle', type: 'boolean' } ],
-  exec: createExec('tsb')
-};
-
-commands.tss = {
-  name: 'tss',
-  exec: createExec('tss')
-};
-
-commands.tsu = {
-  name: 'tsu',
-  params: [ { name: 'num', type: { name: 'number', max: 10, min: -5, step: 3 } } ],
-  exec: createExec('tsu')
-};
-
-commands.tsn = {
-  name: 'tsn'
-};
-
-commands.tsnDif = {
-  name: 'tsn dif',
-  params: [ { name: 'text', type: 'string' } ],
-  exec: createExec('tsnDif')
-};
-
-commands.tsnExt = {
-  name: 'tsn ext',
-  params: [ { name: 'text', type: 'string' } ],
-  exec: createExec('tsnExt')
-};
-
-commands.tsnExte = {
-  name: 'tsn exte',
-  params: [ { name: 'text', type: 'string' } ],
-  exec: createExec('')
-};
-
-commands.tsnExten = {
-  name: 'tsn exten',
-  params: [ { name: 'text', type: 'string' } ],
-  exec: createExec('tsnExte')
-};
-
-commands.tsnExtend = {
-  name: 'tsn extend',
-  params: [ { name: 'text', type: 'string' } ],
-  exec: createExec('tsnExtend')
-};
-
-commands.tsnDeep = {
-  name: 'tsn deep',
-};
-
-commands.tsnDeepDown = {
-  name: 'tsn deep down',
-};
-
-commands.tsnDeepDownNested = {
-  name: 'tsn deep down nested',
-};
-
-commands.tsnDeepDownNestedCmd = {
-  name: 'tsn deep down nested cmd',
-  exec: createExec('tsnDeepDownNestedCmd')
-};
-
-commands.tselarr = {
-  name: 'tselarr',
-  params: [
-    { name: 'num', type: { name: 'selection', data: [ '1', '2', '3' ] } },
-    { name: 'arr', type: { name: 'array', subtype: 'string' } },
-  ],
-  exec: createExec('tselarr')
-};
-
-commands.tsm = {
-  name: 'tsm',
-  description: 'a 3-param test selection|string|number',
-  params: [
-    { name: 'abc', type: { name: 'selection', data: [ 'a', 'b', 'c' ] } },
-    { name: 'txt', type: 'string' },
-    { name: 'num', type: { name: 'number', max: 42, min: 0 } },
-  ],
-  exec: createExec('tsm')
-};
-
-commands.tsg = {
-  name: 'tsg',
-  description: 'a param group test',
-  params: [
-    { name: 'solo', type: { name: 'selection', data: [ 'aaa', 'bbb', 'ccc' ] } },
-    {
-      group: 'First',
-      params: [
-        { name: 'txt1', type: 'string', defaultValue: null },
-        { name: 'bool', type: 'boolean' }
-      ]
-    },
-    {
-      group: 'Second',
-      params: [
-        { name: 'txt2', type: 'string', defaultValue: 'd' },
-        { name: 'num', type: { name: 'number', min: 40 }, defaultValue: 42 }
-      ]
-    }
-  ],
-  exec: createExec('tsg')
-};
-
-
-});
-/*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-
-define('test/assert', ['require', 'exports', 'module' ], function(require, exports, module) {
-
-  exports.ok = ok;
-  exports.is = is;
-  exports.log = info;
-
-});
-/*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-
-define('gclitest/testCompletion', ['require', 'exports', 'module' , 'test/assert', 'gclitest/commands'], function(require, exports, module) {
-
-
-var test = require('test/assert');
-var commands = require('gclitest/commands');
-
-
-exports.setup = function() {
-  commands.setup();
-};
-
-exports.shutdown = function() {
-  commands.shutdown();
-};
-
-
-function type(typed, tests, options) {
-  var inputter = options.display.inputter;
-  var completer = options.display.completer;
-
-  inputter.setInput(typed);
-
-  if (tests.cursor) {
-    inputter.setCursor({ start: tests.cursor, end: tests.cursor });
-  }
-
-  if (tests.emptyParameters == null) {
-    tests.emptyParameters = [];
-  }
-
-  var realParams = completer.emptyParameters;
-  test.is(tests.emptyParameters.length, realParams.length,
-          'emptyParameters.length for \'' + typed + '\'');
-
-  if (realParams.length === tests.emptyParameters.length) {
-    for (var i = 0; i < realParams.length; i++) {
-      test.is(tests.emptyParameters[i], realParams[i].replace(/\u00a0/g, ' '),
-              'emptyParameters[' + i + '] for \'' + typed + '\'');
-    }
-  }
-
-  if (tests.directTabText) {
-    test.is(tests.directTabText, completer.directTabText,
-            'directTabText for \'' + typed + '\'');
-  }
-  else {
-    test.is('', completer.directTabText,
-            'directTabText for \'' + typed + '\'');
-  }
-
-  if (tests.arrowTabText) {
-    test.is(' \u00a0\u21E5 ' + tests.arrowTabText,
-            completer.arrowTabText,
-            'arrowTabText for \'' + typed + '\'');
-  }
-  else {
-    test.is('', completer.arrowTabText,
-            'arrowTabText for \'' + typed + '\'');
-  }
-}
-
-exports.testActivate = function(options) {
-  if (!options.display) {
-    test.log('No display. Skipping activate tests');
-    return;
-  }
-
-  type('', { }, options);
-
-  type(' ', { }, options);
-
-  type('tsr', {
-    emptyParameters: [ ' <text>' ]
-  }, options);
-
-  type('tsr ', {
-    emptyParameters: [ '<text>' ]
-  }, options);
-
-  type('tsr b', { }, options);
-
-  type('tsb', {
-    emptyParameters: [ ' [toggle]' ]
-  }, options);
-
-  type('tsm', {
-    emptyParameters: [ ' <abc>', ' <txt>', ' <num>' ]
-  }, options);
-
-  type('tsm ', {
-    emptyParameters: [ ' <txt>', ' <num>' ],
-    directTabText: 'a'
-  }, options);
-
-  type('tsm a', {
-    emptyParameters: [ ' <txt>', ' <num>' ]
-  }, options);
-
-  type('tsm a ', {
-    emptyParameters: [ '<txt>', ' <num>' ]
-  }, options);
-
-  type('tsm a  ', {
-    emptyParameters: [ '<txt>', ' <num>' ]
-  }, options);
-
-  type('tsm a  d', {
-    emptyParameters: [ ' <num>' ]
-  }, options);
-
-  type('tsm a "d d"', {
-    emptyParameters: [ ' <num>' ]
-  }, options);
-
-  type('tsm a "d ', {
-    emptyParameters: [ ' <num>' ]
-  }, options);
-
-  type('tsm a "d d" ', {
-    emptyParameters: [ '<num>' ]
-  }, options);
-
-  type('tsm a "d d ', {
-    emptyParameters: [ ' <num>' ]
-  }, options);
-
-  type('tsm d r', {
-    emptyParameters: [ ' <num>' ]
-  }, options);
-
-  type('tsm a d ', {
-    emptyParameters: [ '<num>' ]
-  }, options);
-
-  type('tsm a d 4', { }, options);
-
-  type('tsg', {
-    emptyParameters: [ ' <solo>' ]
-  }, options);
-
-  type('tsg ', {
-    directTabText: 'aaa'
-  }, options);
-
-  type('tsg a', {
-    directTabText: 'aa'
-  }, options);
-
-  type('tsg b', {
-    directTabText: 'bb'
-  }, options);
-
-  type('tsg d', { }, options);
-
-  type('tsg aa', {
-    directTabText: 'a'
-  }, options);
-
-  type('tsg aaa', { }, options);
-
-  type('tsg aaa ', { }, options);
-
-  type('tsg aaa d', { }, options);
-
-  type('tsg aaa dddddd', { }, options);
-
-  type('tsg aaa dddddd ', { }, options);
-
-  type('tsg aaa "d', { }, options);
-
-  type('tsg aaa "d d', { }, options);
-
-  type('tsg aaa "d d"', { }, options);
-
-  type('tsn ex ', { }, options);
-
-  type('selarr', {
-    arrowTabText: 'tselarr'
-  }, options);
-
-  type('tselar 1', { }, options);
-
-  type('tselar 1', {
-    cursor: 7
-  }, options);
-
-  type('tselar 1', {
-    cursor: 6,
-    arrowTabText: 'tselarr'
-  }, options);
-
-  type('tselar 1', {
-    cursor: 5,
-    arrowTabText: 'tselarr'
-  }, options);
-};
-
-
-});
-/*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-
-define('gclitest/testExec', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/canon', 'gclitest/commands', 'gcli/types/node', 'test/assert'], function(require, exports, module) {
-
-
-var Requisition = require('gcli/cli').Requisition;
-var canon = require('gcli/canon');
-var commands = require('gclitest/commands');
-var nodetype = require('gcli/types/node');
-
-var test = require('test/assert');
-
-var actualExec;
-var actualOutput;
-var hideExec = false;
-
-exports.setup = function() {
-  commands.setup();
-  commands.onCommandExec.add(commandExeced);
-  canon.commandOutputManager.onOutput.add(commandOutputed);
-};
-
-exports.shutdown = function() {
-  commands.shutdown();
-  commands.onCommandExec.remove(commandExeced);
-  canon.commandOutputManager.onOutput.remove(commandOutputed);
-};
-
-function commandExeced(ev) {
-  actualExec = ev;
-}
-
-function commandOutputed(ev) {
-  actualOutput = ev.output;
-}
-
-function exec(command, expectedArgs) {
-  var environment = {};
-
-  var requisition = new Requisition(environment);
-  var outputObject = requisition.exec({ typed: command, hidden: hideExec });
-
-  test.is(command.indexOf(actualExec.command.name), 0, 'Command name: ' + command);
-
-  test.is(command, outputObject.typed, 'outputObject.command for: ' + command);
-  test.ok(outputObject.completed, 'outputObject.completed false for: ' + command);
-
-  if (expectedArgs == null) {
-    test.ok(false, 'expectedArgs == null for ' + command);
-    return;
-  }
-  if (actualExec.args == null) {
-    test.ok(false, 'actualExec.args == null for ' + command);
-    return;
-  }
-
-  test.is(Object.keys(expectedArgs).length, Object.keys(actualExec.args).length,
-          'Arg count: ' + command);
-  Object.keys(expectedArgs).forEach(function(arg) {
-    var expectedArg = expectedArgs[arg];
-    var actualArg = actualExec.args[arg];
-
-    if (Array.isArray(expectedArg)) {
-      if (!Array.isArray(actualArg)) {
-        test.ok(false, 'actual is not an array. ' + command + '/' + arg);
-        return;
-      }
-
-      test.is(expectedArg.length, actualArg.length,
-              'Array length: ' + command + '/' + arg);
-      for (var i = 0; i < expectedArg.length; i++) {
-        test.is(expectedArg[i], actualArg[i],
-                'Member: "' + command + '/' + arg + '/' + i);
-      }
-    }
-    else {
-      test.is(expectedArg, actualArg, 'Command: "' + command + '" arg: ' + arg);
-    }
-  });
-
-  test.is(environment, actualExec.context.environment, 'Environment');
-
-  if (!hideExec) {
-    test.is(false, actualOutput.error, 'output error is false');
-    test.is(command, actualOutput.typed, 'command is typed');
-    test.ok(typeof actualOutput.canonical === 'string', 'canonical exists');
-
-    test.is(actualExec.args, actualOutput.args, 'actualExec.args is actualOutput.args');
-  }
-}
-
-
-exports.testExec = function(options) {
-  hideExec = options.hideExec;
-
-  exec('tss', {});
-
-  // Bug 707008 - GCLI deferred types don't work properly
-  exec('tsv option1 10', { optionType: commands.option1, optionValue: '10' });
-  exec('tsv option2 10', { optionType: commands.option2, optionValue: 10 });
-
-  exec('tsr fred', { text: 'fred' });
-  exec('tsr fred bloggs', { text: 'fred bloggs' });
-  exec('tsr "fred bloggs"', { text: 'fred bloggs' });
-
-  exec('tsb', { toggle: false });
-  exec('tsb --toggle', { toggle: true });
-
-  exec('tsu 10', { num: 10 });
-  exec('tsu --num 10', { num: 10 });
-
-  // Bug 704829 - Enable GCLI Javascript parameters
-  // The answer to this should be 2
-  exec('tsj { 1 + 1 }', { javascript: '1 + 1' });
-
-  var origDoc = nodetype.getDocument();
-  nodetype.setDocument(mockDoc);
-  exec('tse :root', { node: mockBody });
-  nodetype.setDocument(origDoc);
-
-  exec('tsn dif fred', { text: 'fred' });
-  exec('tsn exten fred', { text: 'fred' });
-  exec('tsn extend fred', { text: 'fred' });
-
-  exec('tselarr 1', { num: '1', arr: [ ] });
-  exec('tselarr 1 a', { num: '1', arr: [ 'a' ] });
-  exec('tselarr 1 a b', { num: '1', arr: [ 'a', 'b' ] });
-
-  exec('tsm a 10 10', { abc: 'a', txt: '10', num: 10 });
-
-  // Bug 707009 - GCLI doesn't always fill in default parameters properly
-  exec('tsg aaa', { solo: 'aaa', txt1: null, bool: false, txt2: 'd', num: 42 });
-};
-
-var mockBody = {
-  style: {}
-};
-
-var mockDoc = {
-  querySelectorAll: function(css) {
-    if (css === ':root') {
-      return {
-        length: 1,
-        item: function(i) {
-          return mockBody;
-        }
-      };
-    }
-    throw new Error('mockDoc.querySelectorAll(\'' + css + '\') error');
-  }
-};
-
-
-});
-/*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-
-define('gclitest/testHistory', ['require', 'exports', 'module' , 'test/assert', 'gcli/history'], function(require, exports, module) {
-
-var test = require('test/assert');
-var History = require('gcli/history').History;
-
-exports.setup = function() {
-};
-
-exports.shutdown = function() {
-};
-
-exports.testSimpleHistory = function () {
-  var history = new History({});
-  history.add('foo');
-  history.add('bar');
-  test.is('bar', history.backward());
-  test.is('foo', history.backward());
-
-  // Adding to the history again moves us back to the start of the history.
-  history.add('quux');
-  test.is('quux', history.backward());
-  test.is('bar', history.backward());
-  test.is('foo', history.backward());
-};
-
-exports.testBackwardsPastIndex = function () {
-  var history = new History({});
-  history.add('foo');
-  history.add('bar');
-  test.is('bar', history.backward());
-  test.is('foo', history.backward());
-
-  // Moving backwards past recorded history just keeps giving you the last
-  // item.
-  test.is('foo', history.backward());
-};
-
-exports.testForwardsPastIndex = function () {
-  var history = new History({});
-  history.add('foo');
-  history.add('bar');
-  test.is('bar', history.backward());
-  test.is('foo', history.backward());
-
-  // Going forward through the history again.
-  test.is('bar', history.forward());
-
-  // 'Present' time.
-  test.is('', history.forward());
-
-  // Going to the 'future' just keeps giving us the empty string.
-  test.is('', history.forward());
-};
-
-});
-/*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-
-define('gclitest/testJs', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/types', 'gcli/types/javascript', 'gcli/canon', 'test/assert'], function(require, exports, module) {
-
-
-var Requisition = require('gcli/cli').Requisition;
-var Status = require('gcli/types').Status;
-var javascript = require('gcli/types/javascript');
-var canon = require('gcli/canon');
-
-var test = require('test/assert');
-
-var debug = false;
-var requ;
-
-var assign;
-var status;
-var statuses;
-var tempWindow;
-
-
-exports.setup = function(options) {
-  tempWindow = javascript.getGlobalObject();
-  javascript.setGlobalObject(options.window);
-
-  Object.defineProperty(options.window, 'donteval', {
-    get: function() {
-      test.ok(false, 'donteval should not be used');
-      return { cant: '', touch: '', 'this': '' };
-    },
-    enumerable: true,
-    configurable : true
-  });
-};
-
-exports.shutdown = function(options) {
-  delete options.window.donteval;
-
-  javascript.setGlobalObject(tempWindow);
-  tempWindow = undefined;
-};
-
-function input(typed) {
-  if (!requ) {
-    requ = new Requisition();
-  }
-  var cursor = { start: typed.length, end: typed.length };
-  requ.update(typed);
-
-  if (debug) {
-    console.log('####### TEST: typed="' + typed +
-        '" cur=' + cursor.start +
-        ' cli=', requ);
-  }
-
-  status = requ.getStatus();
-  statuses = requ.getInputStatusMarkup(cursor.start).map(function(s) {
-    return Array(s.string.length + 1).join(s.status.toString()[0]);
-  }).join('');
-
-  if (requ.commandAssignment.value) {
-    assign = requ.getAssignment(0);
-  }
-  else {
-    assign = undefined;
-  }
-}
-
-function predictionsHas(name) {
-  return assign.getPredictions().some(function(prediction) {
-    return name === prediction.name;
-  }, this);
-}
-
-function check(expStatuses, expStatus, expAssign, expPredict) {
-  test.is('{', requ.commandAssignment.value.name, 'is exec');
-
-  test.is(expStatuses, statuses, 'unexpected status markup');
-  test.is(expStatus.toString(), status.toString(), 'unexpected status');
-  test.is(expAssign, assign.value, 'unexpected assignment');
-
-  if (expPredict != null) {
-    var contains;
-    if (Array.isArray(expPredict)) {
-      expPredict.forEach(function(p) {
-        contains = predictionsHas(p);
-        test.ok(contains, 'missing prediction ' + p);
-      });
-    }
-    else if (typeof expPredict === 'number') {
-      contains = true;
-      test.is(assign.getPredictions().length, expPredict, 'prediction count');
-      if (assign.getPredictions().length !== expPredict) {
-        assign.getPredictions().forEach(function(prediction) {
-          test.log('actual prediction: ', prediction);
-        });
-      }
-    }
-    else {
-      contains = predictionsHas(expPredict);
-      test.ok(contains, 'missing prediction ' + expPredict);
-    }
-
-    if (!contains) {
-      test.log('Predictions: ' + assign.getPredictions().map(function(p) {
-        return p.name;
-      }).join(', '));
-    }
-  }
-}
-
-exports.testBasic = function(options) {
-  if (!canon.getCommand('{')) {
-    test.log('Skipping exec tests because { is not registered');
-    return;
-  }
-
-  input('{');
-  check('V', Status.ERROR, undefined);
-
-  input('{ ');
-  check('VV', Status.ERROR, undefined);
-
-  input('{ w');
-  check('VVI', Status.ERROR, 'w', 'window');
-
-  input('{ windo');
-  check('VVIIIII', Status.ERROR, 'windo', 'window');
-
-  input('{ window');
-  check('VVVVVVVV', Status.VALID, 'window');
-
-  input('{ window.d');
-  check('VVIIIIIIII', Status.ERROR, 'window.d', 'window.document');
-
-  input('{ window.document.title');
-  check('VVVVVVVVVVVVVVVVVVVVVVV', Status.VALID, 'window.document.title', 0);
-
-  input('{ d');
-  check('VVI', Status.ERROR, 'd', 'document');
-
-  input('{ document.title');
-  check('VVVVVVVVVVVVVVVV', Status.VALID, 'document.title', 0);
-
-  test.ok('donteval' in options.window, 'donteval exists');
-
-  input('{ don');
-  check('VVIII', Status.ERROR, 'don', 'donteval');
-
-  input('{ donteval');
-  check('VVVVVVVVVV', Status.VALID, 'donteval', 0);
-
-  /*
-  // This is a controversial test - technically we can tell that it's an error
-  // because 'donteval.' is a syntax error, however donteval is unsafe so we
-  // are playing safe by bailing out early. It's enough of a corner case that
-  // I don't think it warrants fixing
-  input('{ donteval.');
-  check('VVIIIIIIIII', Status.ERROR, 'donteval.', 0);
-  */
-
-  input('{ donteval.cant');
-  check('VVVVVVVVVVVVVVV', Status.VALID, 'donteval.cant', 0);
-
-  input('{ donteval.xxx');
-  check('VVVVVVVVVVVVVV', Status.VALID, 'donteval.xxx', 0);
-};
-
-
-});
-/*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-
-define('gclitest/testKeyboard', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/canon', 'gclitest/commands', 'gcli/types/javascript', 'test/assert'], function(require, exports, module) {
-
-
-var Requisition = require('gcli/cli').Requisition;
-var canon = require('gcli/canon');
-var commands = require('gclitest/commands');
-var javascript = require('gcli/types/javascript');
-
-var test = require('test/assert');
-
-var tempWindow;
-var inputter;
-
-exports.setup = function(options) {
-  tempWindow = javascript.getGlobalObject();
-  javascript.setGlobalObject(options.window);
-
-  if (options.display) {
-    inputter = options.display.inputter;
-  }
-
-  commands.setup();
-};
-
-exports.shutdown = function(options) {
-  commands.shutdown();
-
-  inputter = undefined;
-  javascript.setGlobalObject(tempWindow);
-  tempWindow = undefined;
-};
-
-var COMPLETES_TO = 'complete';
-var KEY_UPS_TO = 'keyup';
-var KEY_DOWNS_TO = 'keydown';
-
-function check(initial, action, after, choice, cursor, expectedCursor) {
-  var requisition;
-  if (inputter) {
-    requisition = inputter.requisition;
-    inputter.setInput(initial);
-  }
-  else {
-    requisition = new Requisition();
-    requisition.update(initial);
-  }
-
-  if (cursor == null) {
-    cursor = initial.length;
-  }
-  var assignment = requisition.getAssignmentAt(cursor);
-  switch (action) {
-    case COMPLETES_TO:
-      requisition.complete({ start: cursor, end: cursor }, choice);
-      break;
-
-    case KEY_UPS_TO:
-      assignment.increment();