Backed out changeset 57755fd703c9 (bug 768096)
authorMihai Sucan <mihai.sucan@gmail.com>
Fri, 28 Sep 2012 13:19:40 +0100
changeset 108512 3a07399169df233ccb80c11c0b8bf3fe2fc1fb30
parent 108511 954d1a3b410b781460af7aa829d77261e226f911
child 108513 b07d095ad2f47545ecd821d84bbc89209c75a549
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
bugs768096
milestone18.0a1
backs out57755fd703c94281ec731ffcbce136e2172e28bc
Backed out changeset 57755fd703c9 (bug 768096)
browser/devtools/webconsole/HUDService.jsm
browser/devtools/webconsole/PropertyPanel.jsm
browser/devtools/webconsole/test/browser_webconsole_bug_632347_iterators_generators.js
browser/devtools/webconsole/test/browser_webconsole_bug_659907_console_dir.js
browser/devtools/webconsole/test/browser_webconsole_jsterm.js
browser/devtools/webconsole/webconsole.js
toolkit/devtools/debugger/dbg-client.jsm
toolkit/devtools/webconsole/WebConsoleClient.jsm
toolkit/devtools/webconsole/WebConsoleUtils.jsm
toolkit/devtools/webconsole/dbg-webconsole-actors.js
--- a/browser/devtools/webconsole/HUDService.jsm
+++ b/browser/devtools/webconsole/HUDService.jsm
@@ -531,18 +531,22 @@ WebConsole.prototype = {
 
   /**
    * Message names that the HUD listens for. These messages come from the remote
    * Web Console content script.
    *
    * @private
    * @type array
    */
-  _messageListeners: ["WebConsole:Initialized", "WebConsole:NetworkActivity",
-    "WebConsole:FileActivity", "WebConsole:LocationChange"],
+  _messageListeners: ["JSTerm:EvalObject", "WebConsole:ConsoleAPI",
+    "WebConsole:CachedMessages", "WebConsole:Initialized", "JSTerm:EvalResult",
+    "JSTerm:AutocompleteProperties", "JSTerm:ClearOutput",
+    "JSTerm:InspectObject", "WebConsole:NetworkActivity",
+    "WebConsole:FileActivity", "WebConsole:LocationChange",
+    "JSTerm:NonNativeConsoleAPI"],
 
   /**
    * The xul:panel that holds the Web Console when it is positioned as a window.
    * @type nsIDOMElement
    */
   consolePanel: null,
 
   /**
@@ -892,20 +896,20 @@ WebConsole.prototype = {
   {
     HUDService.animate(this.hudId, ANIMATE_OUT, function() {
       HUDService.deactivateHUDForContext(this.tab, true);
     }.bind(this));
   },
 
   /**
    * The clear output button handler.
-   * @private
    */
-  _onClearButton: function WC__onClearButton()
+  onClearButton: function WC_onClearButton()
   {
+    this.ui.jsterm.clearOutput(true);
     this.chromeWindow.DeveloperToolbar.resetErrorsCount(this.tab);
   },
 
   /**
    * Setup the message manager used to communicate with the Web Console content
    * script. This method loads the content script, adds the message listeners
    * and initializes the connection to the content script.
    *
@@ -915,18 +919,20 @@ WebConsole.prototype = {
   {
     this.messageManager.loadFrameScript(CONTENT_SCRIPT_URL, true);
 
     this._messageListeners.forEach(function(aName) {
       this.messageManager.addMessageListener(aName, this.ui);
     }, this);
 
     let message = {
-      features: ["NetworkMonitor", "LocationChange"],
+      features: ["ConsoleAPI", "JSTerm", "NetworkMonitor", "LocationChange"],
+      cachedMessages: ["ConsoleAPI", "PageError"],
       NetworkMonitor: { monitorFileActivity: true },
+      JSTerm: { notifyNonNativeConsoleAPI: true },
       preferences: {
         "NetworkMonitor.saveRequestAndResponseBodies":
           this.ui.saveRequestAndResponseBodies,
       },
     };
 
     this.sendMessageToContent("WebConsole:Init", message);
   },
--- a/browser/devtools/webconsole/PropertyPanel.jsm
+++ b/browser/devtools/webconsole/PropertyPanel.jsm
@@ -22,102 +22,95 @@ var EXPORTED_SYMBOLS = ["PropertyPanel",
 
 /**
  * This is an implementation of the nsITreeView interface. For comments on the
  * interface properties, see the documentation:
  * https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsITreeView
  */
 var PropertyTreeView = function() {
   this._rows = [];
-  this._objectActors = [];
+  this._objectCache = {};
 };
 
 PropertyTreeView.prototype = {
   /**
    * Stores the visible rows of the tree.
    * @private
    */
   _rows: null,
 
   /**
    * Stores the nsITreeBoxObject for this tree.
    * @private
    */
   _treeBox: null,
 
   /**
-   * Track known object actor IDs. We clean these when the panel is
-   * destroyed/cleaned up.
-   *
+   * Stores cached information about local objects being inspected.
    * @private
-   * @type array
    */
-  _objectActors: null,
-
-  /**
-   * Map fake object actors to their IDs. This is used when we inspect local
-   * objects.
-   * @private
-   * @type Object
-   */
-  _localObjectActors: null,
-
-  _releaseObject: null,
-  _objectPropertiesProvider: null,
+  _objectCache: null,
 
   /**
    * Use this setter to update the content of the tree.
    *
    * @param object aData
    *        A meta object that holds information about the object you want to
    *        display in the property panel. Object properties:
    *        - object:
    *        This is the raw object you want to display. You can only provide
    *        this object if you want the property panel to work in sync mode.
-   *        - objectProperties:
+   *        - remoteObject:
    *        An array that holds information on the remote object being
    *        inspected. Each element in this array describes each property in the
-   *        remote object. See WebConsoleUtils.inspectObject() for details.
-   *        - objectPropertiesProvider:
+   *        remote object. See WebConsoleUtils.namesAndValuesOf() for details.
+   *        - rootCacheId:
+   *        The cache ID where the objects referenced in remoteObject are found.
+   *        - panelCacheId:
+   *        The cache ID where any object retrieved by this property panel
+   *        instance should be stored into.
+   *        - remoteObjectProvider:
    *        A function that is invoked when a new object is needed. This is
    *        called when the user tries to expand an inspectable property. The
    *        callback must take four arguments:
-   *          - actorID:
-   *          The object actor ID from which we request the properties.
+   *          - fromCacheId:
+   *          Tells from where to retrieve the object the user picked (from
+   *          which cache ID).
+   *          - objectId:
+   *          The object ID the user wants.
+   *          - panelCacheId:
+   *          Tells in which cache ID to store the objects referenced by
+   *          objectId so they can be retrieved later.
    *          - callback:
    *          The callback function to be invoked when the remote object is
-   *          received. This function takes one argument: the array of
-   *          descriptors for each property in the object represented by the
-   *          actor.
-   *        - releaseObject:
-   *        Function to invoke when an object actor should be released. The
-   *        function must take one argument: the object actor ID.
+   *          received. This function takes one argument: the raw message
+   *          received from the Web Console content script.
    */
   set data(aData) {
     let oldLen = this._rows.length;
 
-    this.cleanup();
+    this._cleanup();
 
     if (!aData) {
       return;
     }
 
-    if (aData.objectPropertiesProvider) {
-      this._objectPropertiesProvider = aData.objectPropertiesProvider;
-      this._releaseObject = aData.releaseObject;
-      this._propertiesToRows(aData.objectProperties, 0);
-      this._rows = aData.objectProperties;
+    if (aData.remoteObject) {
+      this._rootCacheId = aData.rootCacheId;
+      this._panelCacheId = aData.panelCacheId;
+      this._remoteObjectProvider = aData.remoteObjectProvider;
+      this._rows = [].concat(aData.remoteObject);
+      this._updateRemoteObject(this._rows, 0);
     }
     else if (aData.object) {
-      this._localObjectActors = Object.create(null);
       this._rows = this._inspectObject(aData.object);
     }
     else {
-      throw new Error("First argument must have an objectActor or an " +
-                      "object property!");
+      throw new Error("First argument must have a .remoteObject or " +
+                      "an .object property!");
     }
 
     if (this._treeBox) {
       this._treeBox.beginUpdateBatch();
       if (oldLen) {
         this._treeBox.rowCountChanged(0, -oldLen);
       }
       this._treeBox.rowCountChanged(0, this._rows.length);
@@ -130,109 +123,87 @@ PropertyTreeView.prototype = {
    * adds properties to each array element.
    *
    * @private
    * @param array aObject
    *        The remote object you want prepared for use with the tree view.
    * @param number aLevel
    *        The level you want to give to each property in the remote object.
    */
-  _propertiesToRows: function PTV__propertiesToRows(aObject, aLevel)
+  _updateRemoteObject: function PTV__updateRemoteObject(aObject, aLevel)
   {
-    aObject.forEach(function(aItem) {
-      aItem._level = aLevel;
-      aItem._open = false;
-      aItem._children = null;
-
-      if (this._releaseObject) {
-        ["value", "get", "set"].forEach(function(aProp) {
-          let val = aItem[aProp];
-          if (val && val.actor) {
-            this._objectActors.push(val.actor);
-          }
-        }, this);
-      }
-    }, this);
+    aObject.forEach(function(aElement) {
+      aElement.level = aLevel;
+      aElement.isOpened = false;
+      aElement.children = null;
+    });
   },
 
   /**
    * Inspect a local object.
    *
    * @private
    * @param object aObject
    *        The object you want to inspect.
-   * @return array
-   *         The array of properties, each being described in a way that is
-   *         usable by the tree view.
    */
   _inspectObject: function PTV__inspectObject(aObject)
   {
-    this._objectPropertiesProvider = this._localPropertiesProvider.bind(this);
-    let children =
-      WebConsoleUtils.inspectObject(aObject, this._localObjectGrip.bind(this));
-    this._propertiesToRows(children, 0);
+    this._objectCache = {};
+    this._remoteObjectProvider = this._localObjectProvider.bind(this);
+    let children = WebConsoleUtils.namesAndValuesOf(aObject, this._objectCache);
+    this._updateRemoteObject(children, 0);
     return children;
   },
 
   /**
-   * Make a local fake object actor for the given object.
-   *
-   * @private
-   * @param object aObject
-   *        The object to make an actor for.
-   * @return object
-   *         The fake actor grip that represents the given object.
-   */
-  _localObjectGrip: function PTV__localObjectGrip(aObject)
-  {
-    let grip = WebConsoleUtils.getObjectGrip(aObject);
-    grip.actor = "obj" + gSequenceId();
-    this._localObjectActors[grip.actor] = aObject;
-    return grip;
-  },
-
-  /**
-   * A properties provider for when the user inspects local objects (not remote
+   * An object provider for when the user inspects local objects (not remote
    * ones).
    *
    * @private
-   * @param string aActor
-   *        The ID of the object actor you want.
+   * @param string aFromCacheId
+   *        The cache ID from where to retrieve the desired object.
+   * @param string aObjectId
+   *        The ID of the object you want.
+   * @param string aDestCacheId
+   *        The ID of the cache where to store any objects referenced by the
+   *        desired object.
    * @param function aCallback
-   *        The function you want to receive the list of properties.
+   *        The function you want to receive the object.
    */
-  _localPropertiesProvider:
-  function PTV__localPropertiesProvider(aActor, aCallback)
+  _localObjectProvider:
+  function PTV__localObjectProvider(aFromCacheId, aObjectId, aDestCacheId,
+                                    aCallback)
   {
-    let object = this._localObjectActors[aActor];
-    let properties =
-      WebConsoleUtils.inspectObject(object, this._localObjectGrip.bind(this));
-    aCallback(properties);
+    let object = WebConsoleUtils.namesAndValuesOf(this._objectCache[aObjectId],
+                                                  this._objectCache);
+    aCallback({cacheId: aFromCacheId,
+               objectId: aObjectId,
+               object: object,
+               childrenCacheId: aDestCacheId || aFromCacheId,
+    });
   },
 
   /** nsITreeView interface implementation **/
 
   selection: null,
 
   get rowCount()                     { return this._rows.length; },
   setTree: function(treeBox)         { this._treeBox = treeBox;  },
-  getCellText: function PTV_getCellText(idx, column)
-  {
+  getCellText: function(idx, column) {
     let row = this._rows[idx];
-    return row.name + ": " + WebConsoleUtils.getPropertyPanelValue(row);
+    return row.name + ": " + row.value;
   },
   getLevel: function(idx) {
-    return this._rows[idx]._level;
+    return this._rows[idx].level;
   },
   isContainer: function(idx) {
-    return typeof this._rows[idx].value == "object" && this._rows[idx].value &&
-           this._rows[idx].value.inspectable;
+    return !!this._rows[idx].inspectable;
   },
   isContainerOpen: function(idx) {
-    return this._rows[idx]._open;
+    return this._rows[idx].isOpened;
   },
   isContainerEmpty: function(idx)    { return false; },
   isSeparator: function(idx)         { return false; },
   isSorted: function()               { return false; },
   isEditable: function(idx, column)  { return false; },
   isSelectable: function(row, col)   { return true; },
 
   getParentIndex: function(idx)
@@ -245,67 +216,71 @@ PropertyTreeView.prototype = {
         return t;
       }
     }
     return -1;
   },
 
   hasNextSibling: function(idx, after)
   {
-    let thisLevel = this.getLevel(idx);
-    return this._rows.slice(after + 1).some(function (r) r._level == thisLevel);
+    var thisLevel = this.getLevel(idx);
+    return this._rows.slice(after + 1).some(function (r) r.level == thisLevel);
   },
 
   toggleOpenState: function(idx)
   {
     let item = this._rows[idx];
-    if (!this.isContainer(idx)) {
+    if (!item.inspectable) {
       return;
     }
 
-    if (item._open) {
+    if (item.isOpened) {
       this._treeBox.beginUpdateBatch();
-      item._open = false;
+      item.isOpened = false;
 
-      var thisLevel = item._level;
+      var thisLevel = item.level;
       var t = idx + 1, deleteCount = 0;
       while (t < this._rows.length && this.getLevel(t++) > thisLevel) {
         deleteCount++;
       }
 
       if (deleteCount) {
         this._rows.splice(idx + 1, deleteCount);
         this._treeBox.rowCountChanged(idx + 1, -deleteCount);
       }
       this._treeBox.invalidateRow(idx);
       this._treeBox.endUpdateBatch();
     }
     else {
       let levelUpdate = true;
-      let callback = function _onRemoteResponse(aProperties) {
+      let callback = function _onRemoteResponse(aResponse) {
         this._treeBox.beginUpdateBatch();
+        item.isOpened = true;
+
         if (levelUpdate) {
-          this._propertiesToRows(aProperties, item._level + 1);
-          item._children = aProperties;
+          this._updateRemoteObject(aResponse.object, item.level + 1);
+          item.children = aResponse.object;
         }
 
-        this._rows.splice.apply(this._rows, [idx + 1, 0].concat(item._children));
+        this._rows.splice.apply(this._rows, [idx + 1, 0].concat(item.children));
 
-        this._treeBox.rowCountChanged(idx + 1, item._children.length);
+        this._treeBox.rowCountChanged(idx + 1, item.children.length);
         this._treeBox.invalidateRow(idx);
         this._treeBox.endUpdateBatch();
-        item._open = true;
       }.bind(this);
 
-      if (!item._children) {
-        this._objectPropertiesProvider(item.value.actor, callback);
+      if (!item.children) {
+        let fromCacheId = item.level > 0 ? this._panelCacheId :
+                                           this._rootCacheId;
+        this._remoteObjectProvider(fromCacheId, item.objectId,
+                                   this._panelCacheId, callback);
       }
       else {
         levelUpdate = false;
-        callback(item._children);
+        callback({object: item.children});
       }
     }
   },
 
   getImageSrc: function(idx, column) { },
   getProgressMode : function(idx,column) { },
   getCellValue: function(idx, column) { },
   cycleHeader: function(col, elem) { },
@@ -318,33 +293,28 @@ PropertyTreeView.prototype = {
   getCellProperties: function(idx, column, prop) { },
   getColumnProperties: function(column, element, prop) { },
 
   setCellValue: function(row, col, value)               { },
   setCellText: function(row, col, value)                { },
   drop: function(index, orientation, dataTransfer)      { },
   canDrop: function(index, orientation, dataTransfer)   { return false; },
 
-  /**
-   * Cleanup the property tree view.
-   */
-  cleanup: function PTV_cleanup()
+  _cleanup: function PTV__cleanup()
   {
-    if (this._releaseObject) {
-      this._objectActors.forEach(this._releaseObject);
-      delete this._objectPropertiesProvider;
-      delete this._releaseObject;
-    }
-    if (this._localObjectActors) {
-      delete this._localObjectActors;
-      delete this._objectPropertiesProvider;
+    if (this._rows.length) {
+      // Reset the existing _rows children to the initial state.
+      this._updateRemoteObject(this._rows, 0);
+      this._rows = [];
     }
 
-    this._rows = [];
-    this._objectActors = [];
+    delete this._objectCache;
+    delete this._rootCacheId;
+    delete this._panelCacheId;
+    delete this._remoteObjectProvider;
   },
 };
 
 ///////////////////////////////////////////////////////////////////////////
 //// Helper for creating the panel.
 
 /**
  * Creates a DOMNode and sets all the attributes of aAttributes on the created
@@ -484,14 +454,8 @@ PropertyPanel.prototype.destroy = functi
 {
   this.treeView.data = null;
   this.panel.parentNode.removeChild(this.panel);
   this.treeView = null;
   this.panel = null;
   this.tree = null;
 }
 
-
-function gSequenceId()
-{
-  return gSequenceId.n++;
-}
-gSequenceId.n = 0;
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_632347_iterators_generators.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_632347_iterators_generators.js
@@ -112,13 +112,13 @@ function testPropertyPanel(aPanel) {
      "gen1 is correctly displayed in the Property Panel");
 
   ok(find("gen2: Generator", false),
      "gen2 is correctly displayed in the Property Panel");
 
   ok(find("iter1: Iterator", false),
      "iter1 is correctly displayed in the Property Panel");
 
-  ok(find("iter2: Object", false),
+  ok(find("iter2: Iterator", false),
      "iter2 is correctly displayed in the Property Panel");
 
   executeSoon(finishTest);
 }
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_659907_console_dir.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_659907_console_dir.js
@@ -36,17 +36,17 @@ function testConsoleDir(outputNode) {
   let foundQSA = false;
   let foundLocation = false;
   let foundWrite = false;
   for (let i = 0; i < view.rowCount; i++) {
     let text = view.getCellText(i);
     if (text == "querySelectorAll: function querySelectorAll()") {
       foundQSA = true;
     }
-    else if (text  == "location: Location") {
+    else if (text  == "location: Object") {
       foundLocation = true;
     }
     else if (text  == "write: function write()") {
       foundWrite = true;
     }
   }
   ok(foundQSA, "found document.querySelectorAll");
   ok(foundLocation, "found document.location");
--- a/browser/devtools/webconsole/test/browser_webconsole_jsterm.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_jsterm.js
@@ -106,32 +106,30 @@ function testJSTerm(hud)
   ok(!output, "help worked");
 
   jsterm.execute("?");
   output = jsterm.outputNode.querySelector(".webconsole-msg-output");
   ok(!output, "? worked");
 
   let foundTab = null;
   waitForSuccess({
-    name: "help tabs opened",
+    name: "help tab opened",
     validatorFn: function()
     {
-      let newTabOpen = gBrowser.tabs.length == tabs + 3;
+      let newTabOpen = gBrowser.tabs.length == tabs + 1;
       if (!newTabOpen) {
         return false;
       }
 
       foundTab = gBrowser.tabs[tabs];
       return true;
     },
     successFn: function()
     {
-      gBrowser.removeTab(gBrowser.tabs[gBrowser.tabs.length - 1]);
-      gBrowser.removeTab(gBrowser.tabs[gBrowser.tabs.length - 1]);
-      gBrowser.removeTab(gBrowser.tabs[gBrowser.tabs.length - 1]);
+      gBrowser.removeTab(foundTab);
       nextTest();
     },
     failureFn: nextTest,
   });
   yield;
 
   jsterm.clearOutput();
   jsterm.execute("pprint({b:2, a:1})");
@@ -173,17 +171,17 @@ function testJSTerm(hud)
   jsterm.execute("pprint('hi')");
   checkResult('0: "h"\n  1: "i"', "pprint('hi')", 1);
   yield;
 
   // check that pprint(function) shows function source, bug 618344
   jsterm.clearOutput();
   jsterm.execute("pprint(print)");
   checkResult(function(nodes) {
-    return nodes[0].textContent.indexOf("aOwner.helperResult") > -1;
+    return nodes[0].textContent.indexOf("aJSTerm.") > -1;
   }, "pprint(function) shows source", 1);
   yield;
 
   // check that an evaluated null produces "null", bug 650780
   jsterm.clearOutput();
   jsterm.execute("null");
   checkResult("null", "null is null", 1);
   yield;
--- a/browser/devtools/webconsole/webconsole.js
+++ b/browser/devtools/webconsole/webconsole.js
@@ -44,18 +44,16 @@ const STRINGS_URI = "chrome://browser/lo
 let l10n = new WebConsoleUtils.l10n(STRINGS_URI);
 
 
 // The XUL namespace.
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
 const MIXED_CONTENT_LEARN_MORE = "https://developer.mozilla.org/en/Security/MixedContent";
 
-const HELP_URL = "https://developer.mozilla.org/docs/Tools/Web_Console/Helpers";
-
 // The amount of time in milliseconds that must pass between messages to
 // trigger the display of a new group.
 const NEW_GROUP_DELAY = 5000;
 
 // The amount of time in milliseconds that we wait before performing a live
 // search.
 const SEARCH_DELAY = 200;
 
@@ -304,22 +302,16 @@ WebConsoleFrame.prototype = {
   outputNode: null,
 
   /**
    * The input element that allows the user to filter messages by string.
    * @type nsIDOMElement
    */
   filterBox: null,
 
-  /**
-   * Getter for the debugger WebConsoleClient.
-   * @type object
-   */
-  get webConsoleClient() this.proxy ? this.proxy.webConsoleClient : null,
-
   _saveRequestAndResponseBodies: false,
 
   /**
    * Tells whether to save the bodies of network requests and responses.
    * Disabled by default to save memory.
    * @type boolean
    */
   get saveRequestAndResponseBodies() this._saveRequestAndResponseBodies,
@@ -416,20 +408,18 @@ WebConsoleFrame.prototype = {
                                        !this.getFilterState("network");
     }.bind(this));
 
     this.closeButton = doc.getElementById("webconsole-close-button");
     this.closeButton.addEventListener("command",
                                       this.owner.onCloseButton.bind(this.owner));
 
     let clearButton = doc.getElementsByClassName("webconsole-clear-console-button")[0];
-    clearButton.addEventListener("command", function WCF__onClearButton() {
-      this.owner._onClearButton();
-      this.jsterm.clearOutput(true);
-    }.bind(this));
+    clearButton.addEventListener("command",
+                                 this.owner.onClearButton.bind(this.owner));
   },
 
   /**
    * Initialize the default filter preferences.
    * @private
    */
   _initDefaultFilterPrefs: function WCF__initDefaultFilterPrefs()
   {
@@ -662,29 +652,50 @@ WebConsoleFrame.prototype = {
    */
   receiveMessage: function WCF_receiveMessage(aMessage)
   {
     if (!aMessage.json || aMessage.json.hudId != this.hudId) {
       return;
     }
 
     switch (aMessage.name) {
+      case "JSTerm:EvalResult":
+      case "JSTerm:EvalObject":
+      case "JSTerm:AutocompleteProperties":
+        this.owner._receiveMessageWithCallback(aMessage.json);
+        break;
+      case "JSTerm:ClearOutput":
+        this.jsterm.clearOutput();
+        break;
+      case "JSTerm:InspectObject":
+        this.jsterm.handleInspectObject(aMessage.json);
+        break;
+      case "WebConsole:ConsoleAPI":
+        this.outputMessage(CATEGORY_WEBDEV, this.logConsoleAPIMessage,
+                           [aMessage.json]);
+        break;
       case "WebConsole:Initialized":
         this._onMessageManagerInitComplete();
         break;
+      case "WebConsole:CachedMessages":
+        this._displayCachedConsoleMessages(aMessage.json.messages);
+        break;
       case "WebConsole:NetworkActivity":
         this.handleNetworkActivity(aMessage.json);
         break;
       case "WebConsole:FileActivity":
         this.outputMessage(CATEGORY_NETWORK, this.logFileActivity,
                            [aMessage.json.uri]);
         break;
       case "WebConsole:LocationChange":
         this.owner.onLocationChange(aMessage.json);
         break;
+      case "JSTerm:NonNativeConsoleAPI":
+        this.outputMessage(CATEGORY_JS, this.logWarningAboutReplacedAPI);
+        break;
     }
   },
 
   /**
    * Callback method used to track the Web Console initialization via message
    * manager.
    *
    * @private
@@ -1017,21 +1028,23 @@ WebConsoleFrame.prototype = {
 
     return false;
   },
 
   /**
    * Display cached messages that may have been collected before the UI is
    * displayed.
    *
+   * @private
    * @param array aRemoteMessages
    *        Array of cached messages coming from the remote Web Console
    *        content instance.
    */
-  displayCachedMessages: function WCF_displayCachedMessages(aRemoteMessages)
+  _displayCachedConsoleMessages:
+  function WCF__displayCachedConsoleMessages(aRemoteMessages)
   {
     if (!aRemoteMessages.length) {
       return;
     }
 
     aRemoteMessages.forEach(function(aMessage) {
       switch (aMessage._type) {
         case "PageError": {
@@ -1044,70 +1057,59 @@ WebConsoleFrame.prototype = {
           this.outputMessage(CATEGORY_WEBDEV, this.logConsoleAPIMessage,
                              [aMessage]);
           break;
       }
     }, this);
   },
 
   /**
-   * Logs a message to the Web Console that originates from the Web Console
-   * server.
+   * Logs a message to the Web Console that originates from the remote Web
+   * Console instance.
    *
    * @param object aMessage
-   *        The message received from the server.
+   *        The message received from the remote Web Console instance.
+   *        console service. This object needs to hold:
+   *          - hudId - the Web Console ID.
+   *          - apiMessage - a representation of the object sent by the console
+   *          storage service. This object holds the console message level, the
+   *          arguments that were passed to the console method and other
+   *          information.
+   *          - argumentsToString - the array of arguments passed to the console
+   *          method, each converted to a string.
    * @return nsIDOMElement|undefined
    *         The message element to display in the Web Console output.
    */
   logConsoleAPIMessage: function WCF_logConsoleAPIMessage(aMessage)
   {
     let body = null;
     let clipboardText = null;
     let sourceURL = null;
     let sourceLine = 0;
-    let level = aMessage.level;
-    let args = aMessage.arguments;
-    let objectActors = [];
+    let level = aMessage.apiMessage.level;
+    let args = aMessage.apiMessage.arguments;
+    let argsToString = aMessage.argumentsToString;
 
     switch (level) {
       case "log":
       case "info":
       case "warn":
       case "error":
       case "debug":
-      case "dir":
-      case "groupEnd": {
-        body = { arguments: args };
-        let clipboardArray = [];
-        args.forEach(function(aValue) {
-          clipboardArray.push(WebConsoleUtils.objectActorGripToString(aValue));
-          if (aValue && typeof aValue == "object" && aValue.actor) {
-            objectActors.push(aValue.actor);
-          }
-        }, this);
-        clipboardText = clipboardArray.join(" ");
-        sourceURL = aMessage.filename;
-        sourceLine = aMessage.lineNumber;
-
-        if (level == "dir") {
-          body.objectProperties = aMessage.objectProperties;
-        }
-        else if (level == "groupEnd") {
-          objectActors.forEach(this._releaseObject, this);
-
-          if (this.groupDepth > 0) {
-            this.groupDepth--;
-          }
-          return; // no need to continue
-        }
-
+        body = {
+          cacheId: aMessage.objectsCacheId,
+          remoteObjects: args,
+          argsToString: argsToString,
+        };
+        clipboardText = argsToString.join(" ");
+        sourceURL = aMessage.apiMessage.filename;
+        sourceLine = aMessage.apiMessage.lineNumber;
         break;
-      }
-
-      case "trace": {
+
+      case "trace":
         let filename = WebConsoleUtils.abbreviateSourceURL(args[0].filename);
         let functionName = args[0].functionName ||
                            l10n.getStr("stacktrace.anonymousFunction");
         let lineNumber = args[0].lineNumber;
 
         body = l10n.getFormatStr("stacktrace.outputMessage",
                                  [filename, functionName, lineNumber]);
 
@@ -1119,63 +1121,77 @@ WebConsoleFrame.prototype = {
         args.forEach(function(aFrame) {
           clipboardText += aFrame.filename + " :: " +
                            aFrame.functionName + " :: " +
                            aFrame.lineNumber + "\n";
         });
 
         clipboardText = clipboardText.trimRight();
         break;
-      }
+
+      case "dir":
+        body = {
+          cacheId: aMessage.objectsCacheId,
+          resultString: argsToString[0],
+          remoteObject: args[0],
+          remoteObjectProvider:
+            this.jsterm.remoteObjectProvider.bind(this.jsterm),
+        };
+        clipboardText = body.resultString;
+        sourceURL = aMessage.apiMessage.filename;
+        sourceLine = aMessage.apiMessage.lineNumber;
+        break;
 
       case "group":
       case "groupCollapsed":
         clipboardText = body = args;
-        sourceURL = aMessage.filename;
-        sourceLine = aMessage.lineNumber;
+        sourceURL = aMessage.apiMessage.filename;
+        sourceLine = aMessage.apiMessage.lineNumber;
         this.groupDepth++;
         break;
 
+      case "groupEnd":
+        if (this.groupDepth > 0) {
+          this.groupDepth--;
+        }
+        return;
+
       case "time":
         if (!args) {
           return;
         }
         if (args.error) {
           Cu.reportError(l10n.getStr(args.error));
           return;
         }
         body = l10n.getFormatStr("timerStarted", [args.name]);
         clipboardText = body;
-        sourceURL = aMessage.filename;
-        sourceLine = aMessage.lineNumber;
+        sourceURL = aMessage.apiMessage.filename;
+        sourceLine = aMessage.apiMessage.lineNumber;
         break;
 
       case "timeEnd":
         if (!args) {
           return;
         }
         body = l10n.getFormatStr("timeEnd", [args.name, args.duration]);
         clipboardText = body;
-        sourceURL = aMessage.filename;
-        sourceLine = aMessage.lineNumber;
+        sourceURL = aMessage.apiMessage.filename;
+        sourceLine = aMessage.apiMessage.lineNumber;
         break;
 
       default:
         Cu.reportError("Unknown Console API log level: " + level);
         return;
     }
 
     let node = this.createMessageNode(CATEGORY_WEBDEV, LEVELS[level], body,
                                       sourceURL, sourceLine, clipboardText,
                                       level, aMessage.timeStamp);
 
-    if (objectActors.length) {
-      node._objectActors = objectActors;
-    }
-
     // Make the node bring up the property panel, to allow the user to inspect
     // the stack trace.
     if (level == "trace") {
       node._stacktrace = args;
 
       this.makeOutputMessageLink(node, function _traceNodeClickCallback() {
         if (node._panelOpen) {
           return;
@@ -1187,87 +1203,80 @@ WebConsoleFrame.prototype = {
         };
 
         let propPanel = this.jsterm.openPropertyPanel(options);
         propPanel.panel.setAttribute("hudId", this.hudId);
       }.bind(this));
     }
 
     if (level == "dir") {
+      // Make sure the cached evaluated object will be purged when the node is
+      // removed.
+      node._evalCacheId = aMessage.objectsCacheId;
+
       // Initialize the inspector message node, by setting the PropertyTreeView
       // object on the tree view. This has to be done *after* the node is
       // shown, because the tree binding must be attached first.
       node._onOutput = function _onMessageOutput() {
         node.querySelector("tree").view = node.propertyTreeView;
       };
     }
 
     return node;
   },
 
   /**
-   * Handle ConsoleAPICall objects received from the server. This method outputs
-   * the window.console API call.
-   *
-   * @param object aMessage
-   *        The console API message received from the server.
-   */
-  handleConsoleAPICall: function WCF_handleConsoleAPICall(aMessage)
-  {
-    this.outputMessage(CATEGORY_WEBDEV, this.logConsoleAPIMessage, [aMessage]);
-  },
-
-  /**
    * The click event handler for objects shown inline coming from the
    * window.console API.
    *
    * @private
    * @param nsIDOMNode aMessage
    *        The message element this handler corresponds to.
    * @param nsIDOMNode aAnchor
    *        The object inspector anchor element. This is the clickable element
    *        in the console.log message we display.
-   * @param object aObjectActor
-   *        The object actor grip.
+   * @param array aRemoteObject
+   *        The remote object representation.
    */
   _consoleLogClick:
-  function WCF__consoleLogClick(aMessage, aAnchor, aObjectActor)
+  function WCF__consoleLogClick(aMessage, aAnchor, aRemoteObject)
   {
     if (aAnchor._panelOpen) {
       return;
     }
 
     let options = {
       title: aAnchor.textContent,
       anchor: aAnchor,
 
       // Data to inspect.
       data: {
-        objectPropertiesProvider: this.objectPropertiesProvider.bind(this),
-        releaseObject: this._releaseObject.bind(this),
+        // This is where the resultObject children are cached.
+        rootCacheId: aMessage._evalCacheId,
+        remoteObject: aRemoteObject,
+        // This is where all objects retrieved by the panel will be cached.
+        panelCacheId: "HUDPanel-" + gSequenceId(),
+        remoteObjectProvider: this.jsterm.remoteObjectProvider.bind(this.jsterm),
       },
     };
 
-    let propPanel;
-    let onPopupHide = function _onPopupHide() {
+    let propPanel = this.jsterm.openPropertyPanel(options);
+    propPanel.panel.setAttribute("hudId", this.hudId);
+
+    let onPopupHide = function JST__evalInspectPopupHide() {
       propPanel.panel.removeEventListener("popuphiding", onPopupHide, false);
 
-      if (!aMessage.parentNode && aMessage._objectActors) {
-        aMessage._objectActors.forEach(this._releaseObject, this);
-        aMessage._objectActors = null;
+      this.jsterm.clearObjectCache(options.data.panelCacheId);
+
+      if (!aMessage.parentNode && aMessage._evalCacheId) {
+        this.jsterm.clearObjectCache(aMessage._evalCacheId);
       }
     }.bind(this);
 
-    this.objectPropertiesProvider(aObjectActor.actor,
-      function _onObjectProperties(aProperties) {
-        options.data.objectProperties = aProperties;
-        propPanel = this.jsterm.openPropertyPanel(options);
-        propPanel.panel.setAttribute("hudId", this.hudId);
-        propPanel.panel.addEventListener("popuphiding", onPopupHide, false);
-      }.bind(this));
+    propPanel.panel.addEventListener("popuphiding", onPopupHide, false);
   },
 
   /**
    * Reports an error in the page source, either JavaScript or CSS.
    *
    * @param nsIScriptError aScriptError
    *        The error message to report.
    * @return nsIDOMElement|undefined
@@ -1439,22 +1448,24 @@ WebConsoleFrame.prototype = {
     }.bind(this));
 
     return outputNode;
   },
 
   /**
    * Inform user that the Web Console API has been replaced by a script
    * in a content page.
+   *
+   * @return nsIDOMElement|undefined
+   *         The message element to display in the Web Console output.
    */
   logWarningAboutReplacedAPI: function WCF_logWarningAboutReplacedAPI()
   {
-    let node = this.createMessageNode(CATEGORY_JS, SEVERITY_WARNING,
-                                      l10n.getStr("ConsoleAPIDisabled"));
-    this.outputMessage(CATEGORY_JS, node);
+    return this.createMessageNode(CATEGORY_JS, SEVERITY_WARNING,
+                                  l10n.getStr("ConsoleAPIDisabled"));
   },
 
   /**
    * Handle the "WebConsole:NetworkActivity" message coming from the remote Web
    * Console.
    *
    * @param object aMessage
    *        The HTTP activity object. This object needs to hold two properties:
@@ -1836,57 +1847,37 @@ WebConsoleFrame.prototype = {
    * @private
    * @param array aItem
    *        The item you want to remove from the output queue.
    */
   _pruneItemFromQueue: function WCF__pruneItemFromQueue(aItem)
   {
     let [category, methodOrNode, args] = aItem;
     if (typeof methodOrNode != "function" &&
-        methodOrNode._objectActors && !methodOrNode._panelOpen) {
-      methodOrNode._objectActors.forEach(this._releaseObject, this);
+        methodOrNode._evalCacheId && !methodOrNode._panelOpen) {
+      this.jsterm.clearObjectCache(methodOrNode._evalCacheId);
     }
 
     if (category == CATEGORY_NETWORK) {
       let connectionId = null;
       if (methodOrNode == this.logNetActivity) {
         connectionId = args[0];
       }
       else if (typeof methodOrNode != "function") {
         connectionId = methodOrNode._connectionId;
       }
       if (connectionId && connectionId in this._networkRequests) {
         delete this._networkRequests[connectionId];
       }
     }
     else if (category == CATEGORY_WEBDEV &&
              methodOrNode == this.logConsoleAPIMessage) {
-      let level = args[0].level;
-      let releaseObject = function _releaseObject(aValue) {
-        if (aValue && typeof aValue == "object" && aValue.actor) {
-          this._releaseObject(aValue.actor);
-        }
-      }.bind(this);
-      switch (level) {
-        case "log":
-        case "info":
-        case "warn":
-        case "error":
-        case "debug":
-        case "dir":
-        case "groupEnd": {
-          args[0].arguments.forEach(releaseObject);
-          if (level == "dir") {
-            args[0].objectProperties.forEach(function(aObject) {
-              ["value", "get", "set"].forEach(function(aProp) {
-                releaseObject(aObject[aProp]);
-              });
-            });
-          }
-        }
+      let level = args[0].apiMessage.level;
+      if (level == "dir") {
+        this.jsterm.clearObjectCache(args[0].objectsCacheId);
       }
     }
   },
 
   /**
    * Ensures that the number of message nodes of type aCategory don't exceed that
    * category's line limit by removing old messages as needed.
    *
@@ -1920,31 +1911,33 @@ WebConsoleFrame.prototype = {
   pruneConsoleDirNode: function WCF_pruneConsoleDirNode(aMessageNode)
   {
     if (aMessageNode.parentNode) {
       aMessageNode.parentNode.removeChild(aMessageNode);
     }
 
     let tree = aMessageNode.querySelector("tree");
     tree.parentNode.removeChild(tree);
-    aMessageNode.propertyTreeView.data = null;
     aMessageNode.propertyTreeView = null;
+    if (tree.view) {
+      tree.view.data = null;
+    }
     tree.view = null;
   },
 
   /**
    * Remove a given message from the output.
    *
    * @param nsIDOMNode aNode
    *        The message node you want to remove.
    */
   removeOutputMessage: function WCF_removeOutputMessage(aNode)
   {
-    if (aNode._objectActors && !aNode._panelOpen) {
-      aNode._objectActors.forEach(this._releaseObject, this);
+    if (aNode._evalCacheId && !aNode._panelOpen) {
+      this.jsterm.clearObjectCache(aNode._evalCacheId);
     }
 
     if (aNode.classList.contains("webconsole-msg-cssparser")) {
       let desc = aNode.childNodes[2].textContent;
       let location = "";
       if (aNode.childNodes[4]) {
         location = aNode.childNodes[4].getAttribute("title");
       }
@@ -2059,17 +2052,17 @@ WebConsoleFrame.prototype = {
     let node = this.document.createElementNS(XUL_NS, "richlistitem");
 
     if (aBody instanceof Ci.nsIDOMNode) {
       bodyNode.appendChild(aBody);
     }
     else {
       let str = undefined;
       if (aLevel == "dir") {
-        str = WebConsoleUtils.objectActorGripToString(aBody.arguments[0]);
+        str = aBody.resultString;
       }
       else if (["log", "info", "warn", "error", "debug"].indexOf(aLevel) > -1 &&
                typeof aBody == "object") {
         this._makeConsoleLogMessageBody(node, bodyNode, aBody);
       }
       else {
         str = aBody;
       }
@@ -2134,19 +2127,20 @@ WebConsoleFrame.prototype = {
 
       bodyContainer.appendChild(tree);
       node.appendChild(bodyContainer);
       node.classList.add("webconsole-msg-inspector");
       // Create the treeView object.
       let treeView = node.propertyTreeView = new PropertyTreeView();
 
       treeView.data = {
-        objectPropertiesProvider: this.objectPropertiesProvider.bind(this),
-        releaseObject: this._releaseObject.bind(this),
-        objectProperties: body.objectProperties,
+        rootCacheId: body.cacheId,
+        panelCacheId: body.cacheId,
+        remoteObject: Array.isArray(body.remoteObject) ? body.remoteObject : [],
+        remoteObjectProvider: body.remoteObjectProvider,
       };
 
       tree.setAttribute("rows", treeView.rowCount);
     }
     else {
       node.appendChild(bodyNode);
     }
     node.appendChild(repeatContainer);
@@ -2165,46 +2159,45 @@ WebConsoleFrame.prototype = {
    * @private
    * @param nsIDOMElement aMessage
    *        The message element that holds the output for the given call.
    * @param nsIDOMElement aContainer
    *        The specific element that will hold each part of the console.log
    *        output.
    * @param object aBody
    *        The object given by this.logConsoleAPIMessage(). This object holds
-   *        the call information that we need to display - mainly the arguments
-   *        array of the given API call.
+   *        the call information that we need to display.
    */
   _makeConsoleLogMessageBody:
   function WCF__makeConsoleLogMessageBody(aMessage, aContainer, aBody)
   {
+    aMessage._evalCacheId = aBody.cacheId;
+
     Object.defineProperty(aMessage, "_panelOpen", {
       get: function() {
         let nodes = aContainer.querySelectorAll(".hud-clickable");
         return Array.prototype.some.call(nodes, function(aNode) {
           return aNode._panelOpen;
         });
       },
       enumerable: true,
       configurable: false
     });
 
-    aBody.arguments.forEach(function(aItem) {
+    aBody.remoteObjects.forEach(function(aItem, aIndex) {
       if (aContainer.firstChild) {
         aContainer.appendChild(this.document.createTextNode(" "));
       }
 
-      let text = WebConsoleUtils.objectActorGripToString(aItem);
-
-      if (aItem && typeof aItem != "object" || !aItem.inspectable) {
+      let text = aBody.argsToString[aIndex];
+      if (!Array.isArray(aItem)) {
         aContainer.appendChild(this.document.createTextNode(text));
         return;
       }
 
-      // For inspectable objects.
       let elem = this.document.createElement("description");
       elem.classList.add("hud-clickable");
       elem.setAttribute("aria-haspopup", "true");
       elem.appendChild(this.document.createTextNode(text));
 
       this._addMessageLinkCallback(elem,
         this._consoleLogClick.bind(this, aMessage, elem, aItem));
 
@@ -2396,51 +2389,16 @@ WebConsoleFrame.prototype = {
         }
       }
     }
 
     clipboardHelper.copyString(strings.join("\n"), this.document);
   },
 
   /**
-   * Object properties provider. This function gives you the properties of the
-   * remote object you want.
-   *
-   * @param string aActor
-   *        The object actor ID from which you want the properties.
-   * @param function aCallback
-   *        Function you want invoked once the properties are received.
-   */
-  objectPropertiesProvider:
-  function WCF_objectPropertiesProvider(aActor, aCallback)
-  {
-    this.webConsoleClient.inspectObjectProperties(aActor,
-      function(aResponse) {
-        if (aResponse.error) {
-          Cu.reportError("Failed to retrieve the object properties from the " +
-                         "server. Error: " + aResponse.error);
-          return;
-        }
-        aCallback(aResponse.properties);
-      });
-  },
-
-  /**
-   * Release an object actor.
-   *
-   * @private
-   * @param string aActor
-   *        The object actor ID you want to release.
-   */
-  _releaseObject: function WCF__releaseObject(aActor)
-  {
-    this.proxy.releaseActor(aActor);
-  },
-
-  /**
    * Open the selected item's URL in a new tab.
    */
   openSelectedItemInTab: function WCF_openSelectedItemInTab()
   {
     let item = this.outputNode.selectedItem;
 
     if (!item || !item.url) {
       return;
@@ -2515,22 +2473,16 @@ JSTerm.prototype = {
   history: null,
 
   /**
    * Getter for the element that holds the messages we display.
    * @type nsIDOMElement
    */
   get outputNode() this.hud.outputNode,
 
-  /**
-   * Getter for the debugger WebConsoleClient.
-   * @type object
-   */
-  get webConsoleClient() this.hud.webConsoleClient,
-
   COMPLETE_FORWARD: 0,
   COMPLETE_BACKWARD: 1,
   COMPLETE_HINT_ONLY: 2,
 
   /**
    * Initialize the JSTerminal UI.
    * @private
    */
@@ -2542,97 +2494,92 @@ JSTerm.prototype = {
     this.inputNode.addEventListener("keypress", this._keyPress, false);
     this.inputNode.addEventListener("input", this._inputEventHandler, false);
     this.inputNode.addEventListener("keyup", this._inputEventHandler, false);
 
     this.lastInputValue && this.setInputValue(this.lastInputValue);
   },
 
   /**
-   * The JavaScript evaluation response handler.
+   * Asynchronously evaluate a string in the content process sandbox.
+   *
+   * @param string aString
+   *        String to evaluate in the content process JavaScript sandbox.
+   * @param function [aCallback]
+   *        Optional function to be invoked when the evaluation result is
+   *        received.
+   */
+  evalInContentSandbox: function JST_evalInContentSandbox(aString, aCallback)
+  {
+    let message = {
+      str: aString,
+      resultCacheId: "HUDEval-" + gSequenceId(),
+    };
+
+    this.hud.owner.sendMessageToContent("JSTerm:EvalRequest", message, aCallback);
+
+    return message;
+  },
+
+  /**
+   * The "JSTerm:EvalResult" message handler. This is the JSTerm execution
+   * result callback which is invoked whenever JavaScript code evaluation
+   * results come from the content process.
    *
    * @private
-   * @param nsIDOMElement [aAfterNode]
-   *        Optional DOM element after which the evaluation result will be
-   *        inserted.
    * @param function [aCallback]
    *        Optional function to invoke when the evaluation result is added to
    *        the output.
    * @param object aResponse
-   *        The message received from the server.
+   *        The JSTerm:EvalResult message received from the content process. See
+   *        JSTerm.handleEvalRequest() in HUDService-content.js for further
+   *        details.
+   * @param object aRequest
+   *        The JSTerm:EvalRequest message we sent to the content process.
+   * @see JSTerm.handleEvalRequest() in HUDService-content.js
    */
   _executeResultCallback:
-  function JST__executeResultCallback(aAfterNode, aCallback, aResponse)
+  function JST__executeResultCallback(aCallback, aResponse, aRequest)
   {
     let errorMessage = aResponse.errorMessage;
-    let result = aResponse.result;
-    let inspectable = result && typeof result == "object" && result.inspectable;
-    let helperResult = aResponse.helperResult;
-    let helperHasRawOutput = !!(helperResult || {}).rawOutput;
-    let resultString =
-      WebConsoleUtils.objectActorGripToString(result,
-                                              !helperHasRawOutput);
-
-    if (helperResult && helperResult.type) {
-      switch (helperResult.type) {
-        case "clearOutput":
-          this.clearOutput();
-          break;
-        case "inspectObject":
-          this.handleInspectObject(helperResult.input, helperResult.object);
-          break;
-        case "error":
-          try {
-            errorMessage = l10n.getStr(helperResult.message);
-          }
-          catch (ex) {
-            errorMessage = helperResult.message;
-          }
-          break;
-        case "help":
-          this.hud.owner.openLink(HELP_URL);
-          break;
-      }
-    }
+    let resultString = aResponse.resultString;
 
     // Hide undefined results coming from JSTerm helper functions.
-    if (!errorMessage && result && typeof result == "object" &&
-        result.type == "undefined" &&
-        helperResult && !helperHasRawOutput) {
-      aCallback && aCallback();
+    if (!errorMessage &&
+        resultString == "undefined" &&
+        aResponse.helperResult &&
+        !aResponse.inspectable &&
+        !aResponse.helperRawOutput) {
       return;
     }
 
+    let afterNode = aRequest.outputNode;
+
     if (aCallback) {
       let oldFlushCallback = this.hud._flushCallback;
       this.hud._flushCallback = function() {
         aCallback();
         oldFlushCallback && oldFlushCallback();
         this.hud._flushCallback = oldFlushCallback;
       }.bind(this);
     }
 
-    let node;
-
-    if (errorMessage) {
-      node = this.writeOutput(errorMessage, CATEGORY_OUTPUT, SEVERITY_ERROR,
-                              aAfterNode, aResponse.timestamp);
+    if (aResponse.errorMessage) {
+      this.writeOutput(aResponse.errorMessage, CATEGORY_OUTPUT, SEVERITY_ERROR,
+                       afterNode, aResponse.timestamp);
     }
-    else if (inspectable) {
-      node = this.writeOutputJS(resultString,
-                                this._evalOutputClick.bind(this, aResponse),
-                                aAfterNode, aResponse.timestamp);
+    else if (aResponse.inspectable) {
+      let node = this.writeOutputJS(aResponse.resultString,
+                                    this._evalOutputClick.bind(this, aResponse),
+                                    afterNode, aResponse.timestamp);
+      node._evalCacheId = aResponse.childrenCacheId;
     }
     else {
-      node = this.writeOutput(resultString, CATEGORY_OUTPUT, SEVERITY_LOG,
-                              aAfterNode, aResponse.timestamp);
-    }
-
-    if (result && typeof result == "object" && result.actor) {
-      node._objectActors = [result.actor];
+      this.writeOutput(aResponse.resultString, CATEGORY_OUTPUT, SEVERITY_LOG,
+                       afterNode, aResponse.timestamp);
     }
   },
 
   /**
    * Execute a string. Execution happens asynchronously in the content process.
    *
    * @param string [aExecuteString]
    *        The string you want to execute. If this is not provided, the current
@@ -2645,19 +2592,20 @@ JSTerm.prototype = {
     // attempt to execute the content of the inputNode
     aExecuteString = aExecuteString || this.inputNode.value;
     if (!aExecuteString) {
       this.writeOutput("no value to execute", CATEGORY_OUTPUT, SEVERITY_LOG);
       return;
     }
 
     let node = this.writeOutput(aExecuteString, CATEGORY_INPUT, SEVERITY_LOG);
-    let onResult = this._executeResultCallback.bind(this, node, aCallback);
-
-    this.webConsoleClient.evaluateJS(aExecuteString, onResult);
+
+    let onResult = this._executeResultCallback.bind(this, aCallback);
+    let messageToContent = this.evalInContentSandbox(aExecuteString, onResult);
+    messageToContent.outputNode = node;
 
     this.history.push(aExecuteString);
     this.historyIndex++;
     this.historyPlaceHolder = this.history.length;
     this.setInputValue("");
     this.clearCompletion();
   },
 
@@ -2798,17 +2746,17 @@ JSTerm.prototype = {
 
     hud.groupDepth = 0;
     hud._outputQueue.forEach(hud._pruneItemFromQueue, hud);
     hud._outputQueue = [];
     hud._networkRequests = {};
     hud._cssNodes = {};
 
     if (aClearStorage) {
-      this.webConsoleClient.clearMessagesCache();
+      hud.owner.sendMessageToContent("ConsoleAPI:ClearCache", {});
     }
   },
 
   /**
    * Updates the size of the input field (command line) to fit its contents.
    *
    * @returns void
    */
@@ -3125,53 +3073,49 @@ JSTerm.prototype = {
    */
   _updateCompletionResult:
   function JST__updateCompletionResult(aType, aCallback)
   {
     if (this.lastCompletion.value == this.inputNode.value) {
       return;
     }
 
-    let requestId = gSequenceId();
-    let input = this.inputNode.value;
-    let cursor = this.inputNode.selectionStart;
-
-    // TODO: Bug 787986 - throttle/disable updates, deal with slow/high latency
-    // network connections.
+    let message = {
+      id: "HUDComplete-" + gSequenceId(),
+      input: this.inputNode.value,
+    };
+
     this.lastCompletion = {
-      requestId: requestId,
+      requestId: message.id,
       completionType: aType,
       value: null,
     };
-
-    let callback = this._receiveAutocompleteProperties.bind(this, requestId,
-                                                            aCallback);
-    this.webConsoleClient.autocomplete(input, cursor, callback);
+    let callback = this._receiveAutocompleteProperties.bind(this, aCallback);
+    this.hud.owner.sendMessageToContent("JSTerm:Autocomplete", message, callback);
   },
 
   /**
-   * Handler for the autocompletion results. This method takes
-   * the completion result received from the server and updates the UI
+   * Handler for the "JSTerm:AutocompleteProperties" message. This method takes
+   * the completion result received from the content process and updates the UI
    * accordingly.
    *
-   * @param number aRequestId
-   *        Request ID.
    * @param function [aCallback=null]
    *        Optional, function to invoke when the completion result is received.
    * @param object aMessage
    *        The JSON message which holds the completion results received from
    *        the content process.
    */
   _receiveAutocompleteProperties:
-  function JST__receiveAutocompleteProperties(aRequestId, aCallback, aMessage)
+  function JST__receiveAutocompleteProperties(aCallback, aMessage)
   {
     let inputNode = this.inputNode;
     let inputValue = inputNode.value;
-    if (this.lastCompletion.value == inputValue ||
-        aRequestId != this.lastCompletion.requestId) {
+    if (aMessage.input != inputValue ||
+        this.lastCompletion.value == inputValue ||
+        aMessage.id != this.lastCompletion.requestId) {
       return;
     }
 
     let matches = aMessage.matches;
     if (!matches.length) {
       this.clearCompletion();
       return;
     }
@@ -3317,102 +3261,99 @@ JSTerm.prototype = {
       objectId: aObjectId,
       resultCacheId: aResultCacheId,
     };
 
     this.hud.owner.sendMessageToContent("JSTerm:GetEvalObject", message, aCallback);
   },
 
   /**
-   * The JSTerm InspectObject remote message handler. This allows the remote
+   * The "JSTerm:InspectObject" remote message handler. This allows the content
    * process to open the Property Panel for a given object.
    *
    * @param object aRequest
    *        The request message from the content process. This message includes
    *        the user input string that was evaluated to inspect an object and
    *        the result object which is to be inspected.
    */
-  handleInspectObject: function JST_handleInspectObject(aInput, aActor)
+  handleInspectObject: function JST_handleInspectObject(aRequest)
   {
     let options = {
-      title: aInput,
+      title: aRequest.input,
 
       data: {
-        objectPropertiesProvider: this.hud.objectPropertiesProvider.bind(this.hud),
-        releaseObject: this.hud._releaseObject.bind(this.hud),
+        rootCacheId: aRequest.objectCacheId,
+        panelCacheId: aRequest.objectCacheId,
+        remoteObject: aRequest.resultObject,
+        remoteObjectProvider: this.remoteObjectProvider.bind(this),
       },
     };
 
-    let propPanel;
+    let propPanel = this.openPropertyPanel(options);
+    propPanel.panel.setAttribute("hudId", this.hudId);
 
     let onPopupHide = function JST__onPopupHide() {
       propPanel.panel.removeEventListener("popuphiding", onPopupHide, false);
-      this.hud._releaseObject(aActor.actor);
+
+      this.clearObjectCache(options.data.panelCacheId);
     }.bind(this);
 
-    this.hud.objectPropertiesProvider(aActor.actor,
-      function _onObjectProperties(aProperties) {
-        options.data.objectProperties = aProperties;
-        propPanel = this.openPropertyPanel(options);
-        propPanel.panel.setAttribute("hudId", this.hudId);
-        propPanel.panel.addEventListener("popuphiding", onPopupHide, false);
-      }.bind(this));
+    propPanel.panel.addEventListener("popuphiding", onPopupHide, false);
   },
 
   /**
    * The click event handler for evaluation results in the output.
    *
    * @private
    * @param object aResponse
-   *        The JavaScript evaluation response received from the server.
+   *        The JSTerm:EvalResult message received from the content process.
    * @param nsIDOMNode aLink
    *        The message node for which we are handling events.
    */
   _evalOutputClick: function JST__evalOutputClick(aResponse, aLinkNode)
   {
     if (aLinkNode._panelOpen) {
       return;
     }
 
     let options = {
       title: aResponse.input,
       anchor: aLinkNode,
 
       // Data to inspect.
       data: {
-        objectPropertiesProvider: this.hud.objectPropertiesProvider.bind(this.hud),
-        releaseObject: this.hud._releaseObject.bind(this.hud),
+        // This is where the resultObject children are cached.
+        rootCacheId: aResponse.childrenCacheId,
+        remoteObject: aResponse.resultObject,
+        // This is where all objects retrieved by the panel will be cached.
+        panelCacheId: "HUDPanel-" + gSequenceId(),
+        remoteObjectProvider: this.remoteObjectProvider.bind(this),
       },
     };
 
-    let propPanel;
-
     options.updateButtonCallback = function JST__evalUpdateButton() {
-      let onResult =
+      this.evalInContentSandbox(aResponse.input,
         this._evalOutputUpdatePanelCallback.bind(this, options, propPanel,
-                                                 aResponse);
-      this.webConsoleClient.evaluateJS(aResponse.input, onResult);
+                                                 aResponse));
     }.bind(this);
 
+    let propPanel = this.openPropertyPanel(options);
+    propPanel.panel.setAttribute("hudId", this.hudId);
+
     let onPopupHide = function JST__evalInspectPopupHide() {
       propPanel.panel.removeEventListener("popuphiding", onPopupHide, false);
 
-      if (!aLinkNode.parentNode && aLinkNode._objectActors) {
-        aLinkNode._objectActors.forEach(this.hud._releaseObject, this.hud);
-        aLinkNode._objectActors = null;
+      this.clearObjectCache(options.data.panelCacheId);
+
+      if (!aLinkNode.parentNode && aLinkNode._evalCacheId) {
+        this.clearObjectCache(aLinkNode._evalCacheId);
       }
     }.bind(this);
 
-    this.hud.objectPropertiesProvider(aResponse.result.actor,
-      function _onObjectProperties(aProperties) {
-        options.data.objectProperties = aProperties;
-        propPanel = this.openPropertyPanel(options);
-        propPanel.panel.setAttribute("hudId", this.hudId);
-        propPanel.panel.addEventListener("popuphiding", onPopupHide, false);
-      }.bind(this));
+    propPanel.panel.addEventListener("popuphiding", onPopupHide, false);
   },
 
   /**
    * The callback used for updating the Property Panel when the user clicks the
    * Update button.
    *
    * @private
    * @param object aOptions
@@ -3431,50 +3372,42 @@ JSTerm.prototype = {
                                     aNewResponse)
   {
     if (aNewResponse.errorMessage) {
       this.writeOutput(aNewResponse.errorMessage, CATEGORY_OUTPUT,
                        SEVERITY_ERROR);
       return;
     }
 
-    let result = aNewResponse.result;
-    let inspectable = result && typeof result == "object" && result.inspectable;
-    let newActor = result && typeof result == "object" ? result.actor : null;
-
-    let anchor = aOptions.anchor;
-    if (anchor && newActor) {
-      if (!anchor._objectActors) {
-        anchor._objectActors = [];
-      }
-      if (anchor._objectActors.indexOf(newActor) == -1) {
-        anchor._objectActors.push(newActor);
-      }
-    }
-
-    if (!inspectable) {
+    if (!aNewResponse.inspectable) {
       this.writeOutput(l10n.getStr("JSTerm.updateNotInspectable"), CATEGORY_OUTPUT, SEVERITY_ERROR);
       return;
     }
 
+    this.clearObjectCache(aOptions.data.panelCacheId);
+    this.clearObjectCache(aOptions.data.rootCacheId);
+
+    if (aOptions.anchor && aOptions.anchor._evalCacheId) {
+      aOptions.anchor._evalCacheId = aNewResponse.childrenCacheId;
+    }
+
     // Update the old response object such that when the panel is reopen, the
     // user sees the new response.
-    aOldResponse.result = aNewResponse.result;
-    aOldResponse.error = aNewResponse.error;
-    aOldResponse.errorMessage = aNewResponse.errorMessage;
-    aOldResponse.timestamp = aNewResponse.timestamp;
-
-    this.hud.objectPropertiesProvider(newActor,
-      function _onObjectProperties(aProperties) {
-        aOptions.data.objectProperties = aProperties;
-        // TODO: This updates the value of the tree.
-        // However, the states of open nodes is not saved.
-        // See bug 586246.
-        aPropPanel.treeView.data = aOptions.data;
-      }.bind(this));
+    aOldResponse.id = aNewResponse.id;
+    aOldResponse.childrenCacheId = aNewResponse.childrenCacheId;
+    aOldResponse.resultObject = aNewResponse.resultObject;
+    aOldResponse.resultString = aNewResponse.resultString;
+
+    aOptions.data.rootCacheId = aNewResponse.childrenCacheId;
+    aOptions.data.remoteObject = aNewResponse.resultObject;
+
+    // TODO: This updates the value of the tree.
+    // However, the states of open nodes is not saved.
+    // See bug 586246.
+    aPropPanel.treeView.data = aOptions.data;
   },
 
   /**
    * Destroy the JSTerm object. Call this method to avoid memory leaks.
    */
   destroy: function JST_destroy()
   {
     this.clearCompletion();
@@ -3695,17 +3628,16 @@ CommandController.prototype = {
  * @param object aWebConsole
  *        The Web Console instance that owns this connection proxy.
  */
 function WebConsoleConnectionProxy(aWebConsole)
 {
   this.owner = aWebConsole;
 
   this._onPageError = this._onPageError.bind(this);
-  this._onConsoleAPICall = this._onConsoleAPICall.bind(this);
 }
 
 WebConsoleConnectionProxy.prototype = {
   /**
    * The owning Web Console instance.
    *
    * @see WebConsoleFrame
    * @type object
@@ -3730,24 +3662,16 @@ WebConsoleConnectionProxy.prototype = {
    * The WebConsoleActor ID.
    *
    * @private
    * @type string
    */
   _consoleActor: null,
 
   /**
-   * Tells if the window.console object of the remote web page is the native
-   * object or not.
-   * @private
-   * @type boolean
-   */
-  _hasNativeConsoleAPI: false,
-
-  /**
    * Initialize the debugger server.
    */
   initServer: function WCCP_initServer()
   {
     if (!DebuggerServer.initialized) {
       DebuggerServer.init();
       DebuggerServer.addBrowserActors();
     }
@@ -3760,19 +3684,18 @@ WebConsoleConnectionProxy.prototype = {
    *        Optional function to invoke when connection is established.
    */
   connect: function WCCP_connect(aCallback)
   {
     let transport = DebuggerServer.connectPipe();
     let client = this.client = new DebuggerClient(transport);
 
     client.addListener("pageError", this._onPageError);
-    client.addListener("consoleAPICall", this._onConsoleAPICall);
-
-    let listeners = ["PageError", "ConsoleAPI"];
+
+    let listeners = ["PageError"];
 
     client.connect(function(aType, aTraits) {
       client.listTabs(function(aResponse) {
         let tab = aResponse.tabs[aResponse.selected];
         this._consoleActor = tab.consoleActor;
         client.attachConsole(tab.consoleActor, listeners,
                              this._onAttachConsole.bind(this, aCallback));
       }.bind(this));
@@ -3797,46 +3720,16 @@ WebConsoleConnectionProxy.prototype = {
     if (aResponse.error) {
       Cu.reportError("attachConsole failed: " + aResponse.error + " " +
                      aResponse.message);
       return;
     }
 
     this.webConsoleClient = aWebConsoleClient;
 
-    this._hasNativeConsoleAPI = aResponse.nativeConsoleAPI;
-
-    let msgs = ["PageError", "ConsoleAPI"];
-    this.webConsoleClient.getCachedMessages(msgs,
-      this._onCachedMessages.bind(this, aCallback));
-  },
-
-  /**
-   * The "cachedMessages" response handler.
-   *
-   * @private
-   * @param function [aCallback]
-   *        Optional function to invoke once the connection is established.
-   * @param object aResponse
-   *        The JSON response object received from the server.
-   */
-  _onCachedMessages: function WCCP__onCachedMessages(aCallback, aResponse)
-  {
-    if (aResponse.error) {
-      Cu.reportError("Web Console getCachedMessages error: " + aResponse.error +
-                     " " + aResponse.message);
-      return;
-    }
-
-    this.owner.displayCachedMessages(aResponse.messages);
-
-    if (!this._hasNativeConsoleAPI) {
-      this.owner.logWarningAboutReplacedAPI();
-    }
-
     this.connected = true;
     aCallback && aCallback();
   },
 
   /**
    * The "pageError" message type handler. We redirect any page errors to the UI
    * for displaying.
    *
@@ -3849,60 +3742,29 @@ WebConsoleConnectionProxy.prototype = {
   _onPageError: function WCCP__onPageError(aType, aPacket)
   {
     if (this.owner && aPacket.from == this._consoleActor) {
       this.owner.handlePageError(aPacket.pageError);
     }
   },
 
   /**
-   * The "consoleAPICall" message type handler. We redirect any message to
-   * the UI for displaying.
-   *
-   * @private
-   * @param string aType
-   *        Message type.
-   * @param object aPacket
-   *        The message received from the server.
-   */
-  _onConsoleAPICall: function WCCP__onConsoleAPICall(aType, aPacket)
-  {
-    if (this.owner && aPacket.from == this._consoleActor) {
-      this.owner.handleConsoleAPICall(aPacket.message);
-    }
-  },
-
-  /**
-   * Release an object actor.
-   *
-   * @param string aActor
-   *        The actor ID to send the request to.
-   */
-  releaseActor: function WCCP_releaseActor(aActor)
-  {
-    if (this.client) {
-      this.client.release(aActor);
-    }
-  },
-
-  /**
    * Disconnect the Web Console from the remote server.
    *
    * @param function [aOnDisconnect]
    *        Optional function to invoke when the connection is dropped.
    */
   disconnect: function WCCP_disconnect(aOnDisconnect)
   {
     if (!this.client) {
       aOnDisconnect && aOnDisconnect();
       return;
     }
 
     this.client.removeListener("pageError", this._onPageError);
-    this.client.removeListener("consoleAPICall", this._onConsoleAPICall);
     this.client.close(aOnDisconnect);
 
     this.client = null;
     this.webConsoleClient = null;
     this.connected = false;
   },
 };
 
--- a/toolkit/devtools/debugger/dbg-client.jsm
+++ b/toolkit/devtools/debugger/dbg-client.jsm
@@ -162,17 +162,16 @@ const ThreadStateTypes = {
   "detached": "detached"
 };
 
 /**
  * Set of protocol messages that are sent by the server without a prior request
  * by the client.
  */
 const UnsolicitedNotifications = {
-  "consoleAPICall": "consoleAPICall",
   "newScript": "newScript",
   "tabDetached": "tabDetached",
   "tabNavigated": "tabNavigated",
   "pageError": "pageError",
   "profilerStateChanged": "profilerStateChanged"
 };
 
 /**
@@ -368,30 +367,16 @@ DebuggerClient.prototype = {
         self._threadClients[aThreadActor] = threadClient;
         self.activeThread = threadClient;
       }
       aOnResponse(aResponse, threadClient);
     });
   },
 
   /**
-   * Release an object actor.
-   *
-   * @param string aActor
-   *        The actor ID to send the request to.
-   */
-  release: function DC_release(aActor) {
-    let packet = {
-      to: aActor,
-      type: "release",
-    };
-    this.request(packet);
-  },
-
-  /**
    * Send a request to the debugging server.
    *
    * @param aRequest object
    *        A JSON packet to send to the debugging server.
    * @param aOnResponse function
    *        If specified, will be called with the response packet when
    *        debugging server responds.
    */
--- a/toolkit/devtools/webconsole/WebConsoleClient.jsm
+++ b/toolkit/devtools/webconsole/WebConsoleClient.jsm
@@ -44,85 +44,16 @@ WebConsoleClient.prototype = {
       to: this._actor,
       type: "getCachedMessages",
       messageTypes: aTypes,
     };
     this._client.request(packet, aOnResponse);
   },
 
   /**
-   * Inspect the properties of an object.
-   *
-   * @param string aActor
-   *        The WebConsoleObjectActor ID to send the request to.
-   * @param function aOnResponse
-   *        The function invoked when the response is received.
-   */
-  inspectObjectProperties:
-  function WCC_inspectObjectProperties(aActor, aOnResponse)
-  {
-    let packet = {
-      to: aActor,
-      type: "inspectProperties",
-    };
-    this._client.request(packet, aOnResponse);
-  },
-
-  /**
-   * Evaluate a JavaScript expression.
-   *
-   * @param string aString
-   *        The code you want to evaluate.
-   * @param function aOnResponse
-   *        The function invoked when the response is received.
-   */
-  evaluateJS: function WCC_evaluateJS(aString, aOnResponse)
-  {
-    let packet = {
-      to: this._actor,
-      type: "evaluateJS",
-      text: aString,
-    };
-    this._client.request(packet, aOnResponse);
-  },
-
-  /**
-   * Autocomplete a JavaScript expression.
-   *
-   * @param string aString
-   *        The code you want to autocomplete.
-   * @param number aCursor
-   *        Cursor location inside the string. Index starts from 0.
-   * @param function aOnResponse
-   *        The function invoked when the response is received.
-   */
-  autocomplete: function WCC_autocomplete(aString, aCursor, aOnResponse)
-  {
-    let packet = {
-      to: this._actor,
-      type: "autocomplete",
-      text: aString,
-      cursor: aCursor,
-    };
-    this._client.request(packet, aOnResponse);
-  },
-
-  /**
-   * Clear the cache of messages (page errors and console API calls).
-   */
-  clearMessagesCache: function WCC_clearMessagesCache()
-  {
-    let packet = {
-      to: this._actor,
-      type: "clearMessagesCache",
-    };
-    this._client.request(packet);
-  },
-
-  /**
    * Start the given Web Console listeners.
    *
    * @see this.LISTENERS
    * @param array aListeners
    *        Array of listeners you want to start. See this.LISTENERS for
    *        known listeners.
    * @param function aOnResponse
    *        Function to invoke when the server response is received.
--- a/toolkit/devtools/webconsole/WebConsoleUtils.jsm
+++ b/toolkit/devtools/webconsole/WebConsoleUtils.jsm
@@ -10,32 +10,18 @@ const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
                                   "resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, "ConsoleAPIStorage",
-                                  "resource://gre/modules/ConsoleAPIStorage.jsm");
-
-var EXPORTED_SYMBOLS = ["WebConsoleUtils", "JSPropertyProvider", "JSTermHelpers",
-                        "PageErrorListener", "ConsoleAPIListener"];
-
-// Match the function name from the result of toString() or toSource().
-//
-// Examples:
-// (function foobar(a, b) { ...
-// function foobar2(a) { ...
-// function() { ...
-const REGEX_MATCH_FUNCTION_NAME = /^\(?function\s+([^(\s]+)\s*\(/;
-
-// Match the function arguments from the result of toString() or toSource().
-const REGEX_MATCH_FUNCTION_ARGS = /^\(?function\s*[^\s(]*\s*\((.+?)\)/;
+var EXPORTED_SYMBOLS = ["WebConsoleUtils", "JSPropertyProvider",
+                        "PageErrorListener"];
 
 const TYPES = { OBJECT: 0,
                 FUNCTION: 1,
                 ARRAY: 2,
                 OTHER: 3,
                 ITERATOR: 4,
                 GETTER: 5,
                 GENERATOR: 6,
@@ -222,22 +208,17 @@ var WebConsoleUtils = {
       case "string":
         output = this.formatResultString(aResult);
         break;
       case "boolean":
       case "date":
       case "error":
       case "number":
       case "regexp":
-        try {
-          output = aResult + "";
-        }
-        catch (ex) {
-          output = ex;
-        }
+        output = aResult.toString();
         break;
       case "null":
       case "undefined":
         output = type;
         break;
       default:
         try {
           if (aResult.toSource) {
@@ -323,25 +304,18 @@ var WebConsoleUtils = {
    *        The evaluation result object you want to check.
    * @return string
    *         Constructor name or type: string, number, boolean, regexp, date,
    *         function, object, null, undefined...
    */
   getResultType: function WCU_getResultType(aResult)
   {
     let type = aResult === null ? "null" : typeof aResult;
-    try {
-      if (type == "object" && aResult.constructor && aResult.constructor.name) {
-        type = aResult.constructor.name + "";
-      }
-    }
-    catch (ex) {
-      // Prevent potential exceptions in page-provided objects from taking down
-      // the Web Console. If the constructor.name is a getter that throws, or
-      // something else bad happens.
+    if (type == "object" && aResult.constructor && aResult.constructor.name) {
+      type = aResult.constructor.name;
     }
 
     return type.toLowerCase();
   },
 
   /**
    * Figures out the type of aObject and the string to display as the object
    * value.
@@ -463,53 +437,37 @@ var WebConsoleUtils = {
    * @return boolean
    *         True if the given property is a getter, false otherwise.
    */
   isNonNativeGetter: function WCU_isNonNativeGetter(aObject, aProp)
   {
     if (typeof aObject != "object") {
       return false;
     }
-    let desc = this.getPropertyDescriptor(aObject, aProp);
-    return desc && desc.get && !this.isNativeFunction(desc.get);
-  },
-
-  /**
-   * Get the property descriptor for the given object.
-   *
-   * @param object aObject
-   *        The object that contains the property.
-   * @param string aProp
-   *        The property you want to get the descriptor for.
-   * @return object
-   *         Property descriptor.
-   */
-  getPropertyDescriptor: function WCU_getPropertyDescriptor(aObject, aProp)
-  {
-    let desc = null;
+    let desc;
     while (aObject) {
       try {
         if (desc = Object.getOwnPropertyDescriptor(aObject, aProp)) {
           break;
         }
       }
-      catch (ex if (ex.name == "NS_ERROR_XPC_BAD_CONVERT_JS" ||
-                    ex.name == "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO" ||
-                    ex.name == "TypeError")) {
+      catch (ex) {
         // Native getters throw here. See bug 520882.
-        // null throws TypeError.
+        if (ex.name == "NS_ERROR_XPC_BAD_CONVERT_JS" ||
+            ex.name == "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO") {
+          return false;
+        }
+        throw ex;
       }
-      try {
-        aObject = Object.getPrototypeOf(aObject);
-      }
-      catch (ex if (ex.name == "TypeError")) {
-        return desc;
-      }
+      aObject = Object.getPrototypeOf(aObject);
     }
-    return desc;
+    if (desc && desc.get && !this.isNativeFunction(desc.get)) {
+      return true;
+    }
+    return false;
   },
 
   /**
    * Get an array that describes the properties of the given object.
    *
    * @param object aObject
    *        The object to get the properties from.
    * @param object aObjectCache
@@ -586,220 +544,48 @@ var WebConsoleUtils = {
       if (pair.inspectable && aObjectCache) {
         pair.objectId = ++gObjectId;
         aObjectCache[pair.objectId] = value;
       }
 
       pairs.push(pair);
     }
 
-    pairs.sort(this.propertiesSort);
+    pairs.sort(function(a, b)
+    {
+      // Convert the pair.name to a number for later sorting.
+      let aNumber = parseFloat(a.name);
+      let bNumber = parseFloat(b.name);
+
+      // Sort numbers.
+      if (!isNaN(aNumber) && isNaN(bNumber)) {
+        return -1;
+      }
+      else if (isNaN(aNumber) && !isNaN(bNumber)) {
+        return 1;
+      }
+      else if (!isNaN(aNumber) && !isNaN(bNumber)) {
+        return aNumber - bNumber;
+      }
+      // Sort string.
+      else if (a.name < b.name) {
+        return -1;
+      }
+      else if (a.name > b.name) {
+        return 1;
+      }
+      else {
+        return 0;
+      }
+    });
 
     return pairs;
   },
 
   /**
-   * Sort function for object properties.
-   *
-   * @param object a
-   *        Property descriptor.
-   * @param object b
-   *        Property descriptor.
-   * @return integer
-   *         -1 if a.name < b.name,
-   *         1 if a.name > b.name,
-   *         0 otherwise.
-   */
-  propertiesSort: function WCU_propertiesSort(a, b)
-  {
-    // Convert the pair.name to a number for later sorting.
-    let aNumber = parseFloat(a.name);
-    let bNumber = parseFloat(b.name);
-
-    // Sort numbers.
-    if (!isNaN(aNumber) && isNaN(bNumber)) {
-      return -1;
-    }
-    else if (isNaN(aNumber) && !isNaN(bNumber)) {
-      return 1;
-    }
-    else if (!isNaN(aNumber) && !isNaN(bNumber)) {
-      return aNumber - bNumber;
-    }
-    // Sort string.
-    else if (a.name < b.name) {
-      return -1;
-    }
-    else if (a.name > b.name) {
-      return 1;
-    }
-    else {
-      return 0;
-    }
-  },
-
-  /**
-   * Inspect the properties of the given object. For each property a descriptor
-   * object is created. The descriptor gives you information about the property
-   * name, value, type, getter and setter. When the property value references
-   * another object you get a wrapper that holds information about that object.
-   *
-   * @see this.inspectObjectProperty
-   * @param object aObject
-   *        The object you want to inspect.
-   * @param function aObjectWrapper
-   *        The function that creates wrappers for property values which
-   *        reference other objects. This function must take one argument, the
-   *        object to wrap, and it must return an object grip that gives
-   *        information about the referenced object.
-   * @return array
-   *         An array of property descriptors.
-   */
-  inspectObject: function WCU_inspectObject(aObject, aObjectWrapper)
-  {
-    let properties = [];
-    let isDOMDocument = aObject instanceof Ci.nsIDOMDocument;
-    let deprecated = ["width", "height", "inputEncoding"];
-
-    for (let name in aObject) {
-      // See bug 632275: skip deprecated properties.
-      if (isDOMDocument && deprecated.indexOf(name) > -1) {
-        continue;
-      }
-
-      properties.push(this.inspectObjectProperty(aObject, name, aObjectWrapper));
-    }
-
-    return properties.sort(this.propertiesSort);
-  },
-
-  /**
-   * A helper method that creates a property descriptor for the provided object,
-   * properly formatted for sending in a protocol response.
-   *
-   * The property value can reference other objects. Since actual objects cannot
-   * be sent to the client, we need to send simple object grips - descriptors
-   * for those objects. This is why you need to give an object wrapper function
-   * that creates object grips.
-   *
-   * @param string aProperty
-   *        Property name for which we have the descriptor.
-   * @param object aObject
-   *        The object that the descriptor is generated for.
-   * @param function aObjectWrapper
-   *        This function is given the property value. Whatever the function
-   *        returns is used as the representation of the property value.
-   * @return object
-   *         The property descriptor formatted for sending to the client.
-   */
-  inspectObjectProperty:
-  function WCU_inspectObjectProperty(aObject, aProperty, aObjectWrapper)
-  {
-    let descriptor = this.getPropertyDescriptor(aObject, aProperty) || {};
-
-    let result = { name: aProperty };
-    result.configurable = descriptor.configurable;
-    result.enumerable = descriptor.enumerable;
-    result.writable = descriptor.writable;
-    if (descriptor.value !== undefined) {
-      result.value = this.createValueGrip(descriptor.value, aObjectWrapper);
-    }
-    else if (descriptor.get) {
-      if (this.isNativeFunction(descriptor.get)) {
-        result.value = this.createValueGrip(aObject[aProperty], aObjectWrapper);
-      }
-      else {
-        result.get = this.createValueGrip(descriptor.get, aObjectWrapper);
-        result.set = this.createValueGrip(descriptor.set, aObjectWrapper);
-      }
-    }
-
-    // There are cases with properties that have no value and no getter. For
-    // example window.screen.width.
-    if (result.value === undefined && result.get === undefined) {
-      result.value = this.createValueGrip(aObject[aProperty], aObjectWrapper);
-    }
-
-    return result;
-  },
-
-  /**
-   * Make an object grip for the given object. An object grip of the simplest
-   * form with minimal information about the given object is returned. This
-   * method is usually combined with other functions that add further state
-   * information and object ID such that, later, the client is able to retrieve
-   * more information about the object being represented by this grip.
-   *
-   * @param object aObject
-   *        The object you want to create a grip for.
-   * @return object
-   *         The object grip.
-   */
-  getObjectGrip: function WCU_getObjectGrip(aObject)
-  {
-    let className = null;
-    let type = typeof aObject;
-
-    let result = {
-      "type": type,
-      "className": this.getObjectClassName(aObject),
-      "displayString": this.formatResult(aObject),
-      "inspectable": this.isObjectInspectable(aObject),
-    };
-
-    if (type == "function") {
-      result.functionName = this.getFunctionName(aObject);
-      result.functionArguments = this.getFunctionArguments(aObject);
-    }
-
-    return result;
-  },
-
-  /**
-   * Create a grip for the given value. If the value is an object,
-   * an object wrapper will be created.
-   *
-   * @param mixed aValue
-   *        The value you want to create a grip for, before sending it to the
-   *        client.
-   * @param function aObjectWrapper
-   *        If the value is an object then the aObjectWrapper function is
-   *        invoked to give us an object grip. See this.getObjectGrip().
-   * @return mixed
-   *         The value grip.
-   */
-  createValueGrip: function WCU_createValueGrip(aValue, aObjectWrapper)
-  {
-    let type = typeof(aValue);
-    switch (type) {
-      case "boolean":
-      case "string":
-      case "number":
-        return aValue;
-      case "object":
-      case "function":
-        if (aValue) {
-          return aObjectWrapper(aValue);
-        }
-      default:
-        if (aValue === null) {
-          return { type: "null" };
-        }
-
-        if (aValue === undefined) {
-          return { type: "undefined" };
-        }
-
-        Cu.reportError("Failed to provide a grip for value of " + type + ": " +
-                       aValue);
-        return null;
-    }
-  },
-
-  /**
    * Check if the given object is an iterator or a generator.
    *
    * @param object aObject
    *        The object you want to check.
    * @return boolean
    *         True if the given object is an iterator or a generator, otherwise
    *         false is returned.
    */
@@ -847,169 +633,16 @@ var WebConsoleUtils = {
       let requestURI = Services.io.newURI(aRequest, null, null);
       let contentURI = Services.io.newURI(aLocation, null, null);
       return (contentURI.scheme == "https" && requestURI.scheme != "https");
     }
     catch (ex) {
       return false;
     }
   },
-
-  /**
-   * Make a string representation for an object actor grip.
-   *
-   * @param object aGrip
-   *        The object grip received from the server.
-   * @param boolean [aFormatString=false]
-   *        Optional boolean that tells if you want strings to be unevaled or
-   *        not.
-   * @return string
-   *         The object grip converted to a string.
-   */
-  objectActorGripToString: function WCU_objectActorGripToString(aGrip, aFormatString)
-  {
-    // Primitives like strings and numbers are not sent as objects.
-    // But null and undefined are sent as objects with the type property
-    // telling which type of value we have.
-    let type = typeof(aGrip);
-    if (aGrip && type == "object") {
-      return aGrip.displayString || aGrip.className || aGrip.type || type;
-    }
-    return type == "string" && aFormatString ?
-           this.formatResultString(aGrip) : aGrip + "";
-  },
-
-  /**
-   * Helper function to deduce the name of the provided function.
-   *
-   * @param funtion aFunction
-   *        The function whose name will be returned.
-   * @return string
-   *         Function name.
-   */
-  getFunctionName: function WCF_getFunctionName(aFunction)
-  {
-    let name = null;
-    if (aFunction.name) {
-      name = aFunction.name;
-    }
-    else {
-      let desc;
-      try {
-        desc = aFunction.getOwnPropertyDescriptor("displayName");
-      }
-      catch (ex) { }
-      if (desc && typeof desc.value == "string") {
-        name = desc.value;
-      }
-    }
-    if (!name) {
-      try {
-        let str = (aFunction.toString() || aFunction.toSource()) + "";
-        name = (str.match(REGEX_MATCH_FUNCTION_NAME) || [])[1];
-      }
-      catch (ex) { }
-    }
-    return name;
-  },
-
-  /**
-   * Helper function to deduce the arguments of the provided function.
-   *
-   * @param funtion aFunction
-   *        The function whose name will be returned.
-   * @return array
-   *         Function arguments.
-   */
-  getFunctionArguments: function WCF_getFunctionArguments(aFunction)
-  {
-    let args = [];
-    try {
-      let str = (aFunction.toString() || aFunction.toSource()) + "";
-      let argsString = (str.match(REGEX_MATCH_FUNCTION_ARGS) || [])[1];
-      if (argsString) {
-        args = argsString.split(/\s*,\s*/);
-      }
-    }
-    catch (ex) { }
-    return args;
-  },
-
-  /**
-   * Get the object class name. For example, the |window| object has the Window
-   * class name (based on [object Window]).
-   *
-   * @param object aObject
-   *        The object you want to get the class name for.
-   * @return string
-   *         The object class name.
-   */
-  getObjectClassName: function WCF_getObjectClassName(aObject)
-  {
-    if (aObject === null) {
-      return "null";
-    }
-    if (aObject === undefined) {
-      return "undefined";
-    }
-
-    let type = typeof aObject;
-    if (type != "object") {
-      return type;
-    }
-
-    let className;
-
-    try {
-      className = ((aObject + "").match(/^\[object (\S+)\]$/) || [])[1];
-      if (!className) {
-        className = ((aObject.constructor + "").match(/^\[object (\S+)\]$/) || [])[1];
-      }
-      if (!className && typeof aObject.constructor == "function") {
-        className = this.getFunctionName(aObject.constructor);
-      }
-    }
-    catch (ex) { }
-
-    return className;
-  },
-
-  /**
-   * Determine the string to display as a property value in the property panel.
-   *
-   * @param object aActor
-   *        Object actor grip.
-   * @return string
-   *         Property value as suited for the property panel.
-   */
-  getPropertyPanelValue: function WCU_getPropertyPanelValue(aActor)
-  {
-    if (aActor.get) {
-      return "Getter";
-    }
-
-    let val = aActor.value;
-    if (typeof val == "string") {
-      return this.formatResultString(val);
-    }
-
-    if (typeof val != "object" || !val) {
-      return val;
-    }
-
-    if (val.type == "function" && val.functionName) {
-      return "function " + val.functionName + "(" +
-             val.functionArguments.join(", ") + ")";
-    }
-    if (val.type == "object" && val.className) {
-      return val.className;
-    }
-
-    return val.displayString || val.type;
-  },
 };
 
 //////////////////////////////////////////////////////////////////////////
 // Localization
 //////////////////////////////////////////////////////////////////////////
 
 WebConsoleUtils.l10n = function WCU_l10n(aBundleURI)
 {
@@ -1525,332 +1158,8 @@ PageErrorListener.prototype =
    * Remove the nsIConsoleService listener.
    */
   destroy: function PEL_destroy()
   {
     Services.console.unregisterListener(this);
     this.listener = this.window = null;
   },
 };
-
-
-///////////////////////////////////////////////////////////////////////////////
-// The window.console API observer
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * The window.console API observer. This allows the window.console API messages
- * to be sent to the remote Web Console instance.
- *
- * @constructor
- * @param nsIDOMWindow aWindow
- *        The window object for which we are created.
- * @param object aOwner
- *        The owner object must have the following methods:
- *        - onConsoleAPICall(). This method is invoked with one argument, the
- *        Console API message that comes from the observer service, whenever
- *        a relevant console API call is received.
- */
-function ConsoleAPIListener(aWindow, aOwner)
-{
-  this.window = aWindow;
-  this.owner = aOwner;
-}
-
-ConsoleAPIListener.prototype =
-{
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
-
-  /**
-   * The content window for which we listen to window.console API calls.
-   * @type nsIDOMWindow
-   */
-  window: null,
-
-  /**
-   * The owner object which is notified of window.console API calls. It must
-   * have a onConsoleAPICall method which is invoked with one argument: the
-   * console API call object that comes from the observer service.
-   *
-   * @type object
-   * @see WebConsoleActor
-   */
-  owner: null,
-
-  /**
-   * Initialize the window.console API observer.
-   */
-  init: function CAL_init()
-  {
-    // Note that the observer is process-wide. We will filter the messages as
-    // needed, see CAL_observe().
-    Services.obs.addObserver(this, "console-api-log-event", false);
-  },
-
-  /**
-   * The console API message observer. When messages are received from the
-   * observer service we forward them to the remote Web Console instance.
-   *
-   * @param object aMessage
-   *        The message object receives from the observer service.
-   * @param string aTopic
-   *        The message topic received from the observer service.
-   */
-  observe: function CAL_observe(aMessage, aTopic)
-  {
-    if (!this.owner || !this.window) {
-      return;
-    }
-
-    let apiMessage = aMessage.wrappedJSObject;
-    let msgWindow = WebConsoleUtils.getWindowByOuterId(apiMessage.ID,
-                                                       this.window);
-    if (!msgWindow || msgWindow.top != this.window) {
-      // Not the same window!
-      return;
-    }
-
-    this.owner.onConsoleAPICall(apiMessage);
-  },
-
-  /**
-   * Get the cached messages for the current inner window.
-   *
-   * @return array
-   *         The array of cached messages. Each element is a Console API
-   *         prepared to be sent to the remote Web Console instance.
-   */
-  getCachedMessages: function CAL_getCachedMessages()
-  {
-    let innerWindowId = WebConsoleUtils.getInnerWindowId(this.window);
-    let messages = ConsoleAPIStorage.getEvents(innerWindowId);
-    return messages;
-  },
-
-  /**
-   * Destroy the console API listener.
-   */
-  destroy: function CAL_destroy()
-  {
-    Services.obs.removeObserver(this, "console-api-log-event");
-    this.window = this.owner = null;
-  },
-};
-
-
-
-/**
- * JSTerm helper functions.
- *
- * Defines a set of functions ("helper functions") that are available from the
- * Web Console but not from the web page.
- *
- * A list of helper functions used by Firebug can be found here:
- *   http://getfirebug.com/wiki/index.php/Command_Line_API
- *
- * @param object aOwner
- *        The owning object.
- */
-function JSTermHelpers(aOwner)
-{
-  /**
-   * Find a node by ID.
-   *
-   * @param string aId
-   *        The ID of the element you want.
-   * @return nsIDOMNode or null
-   *         The result of calling document.querySelector(aSelector).
-   */
-  aOwner.sandbox.$ = function JSTH_$(aSelector)
-  {
-    return aOwner.window.document.querySelector(aSelector);
-  };
-
-  /**
-   * Find the nodes matching a CSS selector.
-   *
-   * @param string aSelector
-   *        A string that is passed to window.document.querySelectorAll.
-   * @return nsIDOMNodeList
-   *         Returns the result of document.querySelectorAll(aSelector).
-   */
-  aOwner.sandbox.$$ = function JSTH_$$(aSelector)
-  {
-    return aOwner.window.document.querySelectorAll(aSelector);
-  };
-
-  /**
-   * Runs an xPath query and returns all matched nodes.
-   *
-   * @param string aXPath
-   *        xPath search query to execute.
-   * @param [optional] nsIDOMNode aContext
-   *        Context to run the xPath query on. Uses window.document if not set.
-   * @return array of nsIDOMNode
-   */
-  aOwner.sandbox.$x = function JSTH_$x(aXPath, aContext)
-  {
-    let nodes = [];
-    let doc = aOwner.window.document;
-    let aContext = aContext || doc;
-
-    try {
-      let results = doc.evaluate(aXPath, aContext, null,
-                                 Ci.nsIDOMXPathResult.ANY_TYPE, null);
-      let node;
-      while (node = results.iterateNext()) {
-        nodes.push(node);
-      }
-    }
-    catch (ex) {
-      aOwner.window.console.error(ex.message);
-    }
-
-    return nodes;
-  };
-
-  /**
-   * Returns the currently selected object in the highlighter.
-   *
-   * TODO: this implementation crosses the client/server boundaries! This is not
-   * usable within a remote browser. To implement this feature correctly we need
-   * support for remote inspection capabilities within the Inspector as well.
-   * See bug 787975.
-   *
-   * @return nsIDOMElement|null
-   *         The DOM element currently selected in the highlighter.
-   */
-  Object.defineProperty(aOwner.sandbox, "$0", {
-    get: function() {
-      try {
-        return aOwner.chromeWindow().InspectorUI.selection;
-      }
-      catch (ex) {
-        aOwner.window.console.error(ex.message);
-      }
-    },
-    enumerable: true,
-    configurable: false
-  });
-
-  /**
-   * Clears the output of the JSTerm.
-   */
-  aOwner.sandbox.clear = function JSTH_clear()
-  {
-    aOwner.helperResult = {
-      type: "clearOutput",
-    };
-  };
-
-  /**
-   * Returns the result of Object.keys(aObject).
-   *
-   * @param object aObject
-   *        Object to return the property names from.
-   * @return array of strings
-   */
-  aOwner.sandbox.keys = function JSTH_keys(aObject)
-  {
-    return Object.keys(WebConsoleUtils.unwrap(aObject));
-  };
-
-  /**
-   * Returns the values of all properties on aObject.
-   *
-   * @param object aObject
-   *        Object to display the values from.
-   * @return array of string
-   */
-  aOwner.sandbox.values = function JSTH_values(aObject)
-  {
-    let arrValues = [];
-    let obj = WebConsoleUtils.unwrap(aObject);
-
-    try {
-      for (let prop in obj) {
-        arrValues.push(obj[prop]);
-      }
-    }
-    catch (ex) {
-      aOwner.window.console.error(ex.message);
-    }
-
-    return arrValues;
-  };
-
-  /**
-   * Opens a help window in MDN.
-   */
-  aOwner.sandbox.help = function JSTH_help()
-  {
-    aOwner.helperResult = { type: "help" };
-  };
-
-  /**
-   * Inspects the passed aObject. This is done by opening the PropertyPanel.
-   *
-   * @param object aObject
-   *        Object to inspect.
-   */
-  aOwner.sandbox.inspect = function JSTH_inspect(aObject)
-  {
-    let obj = WebConsoleUtils.unwrap(aObject);
-    if (!WebConsoleUtils.isObjectInspectable(obj)) {
-      return aObject;
-    }
-
-    aOwner.helperResult = {
-      type: "inspectObject",
-      input: aOwner.evalInput,
-      object: aOwner.createValueGrip(obj),
-    };
-  };
-
-  /**
-   * Prints aObject to the output.
-   *
-   * @param object aObject
-   *        Object to print to the output.
-   * @return string
-   */
-  aOwner.sandbox.pprint = function JSTH_pprint(aObject)
-  {
-    if (aObject === null || aObject === undefined || aObject === true ||
-        aObject === false) {
-      aOwner.helperResult = {
-        type: "error",
-        message: "helperFuncUnsupportedTypeError",
-      };
-      return;
-    }
-
-    aOwner.helperResult = { rawOutput: true };
-
-    if (typeof aObject == "function") {
-      return aObject + "\n";
-    }
-
-    let output = [];
-    let getObjectGrip = WebConsoleUtils.getObjectGrip.bind(WebConsoleUtils);
-    let obj = WebConsoleUtils.unwrap(aObject);
-    let props = WebConsoleUtils.inspectObject(obj, getObjectGrip);
-    props.forEach(function(aProp) {
-      output.push(aProp.name + ": " +
-                  WebConsoleUtils.getPropertyPanelValue(aProp));
-    });
-
-    return "  " + output.join("\n  ");
-  };
-
-  /**
-   * Print a string to the output, as-is.
-   *
-   * @param string aString
-   *        A string you want to output.
-   * @return void
-   */
-  aOwner.sandbox.print = function JSTH_print(aString)
-  {
-    aOwner.helperResult = { rawOutput: true };
-    return String(aString);
-  };
-}
--- a/toolkit/devtools/webconsole/dbg-webconsole-actors.js
+++ b/toolkit/devtools/webconsole/dbg-webconsole-actors.js
@@ -10,87 +10,45 @@ let Cc = Components.classes;
 let Ci = Components.interfaces;
 let Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
                                   "resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, "WebConsoleUtils",
-                                  "resource://gre/modules/devtools/WebConsoleUtils.jsm");
-
 XPCOMUtils.defineLazyModuleGetter(this, "PageErrorListener",
                                   "resource://gre/modules/devtools/WebConsoleUtils.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, "ConsoleAPIListener",
-                                  "resource://gre/modules/devtools/WebConsoleUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "JSTermHelpers",
-                                  "resource://gre/modules/devtools/WebConsoleUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "JSPropertyProvider",
-                                  "resource://gre/modules/devtools/WebConsoleUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "ConsoleAPIStorage",
-                                  "resource://gre/modules/ConsoleAPIStorage.jsm");
-
-
 /**
  * The WebConsoleActor implements capabilities needed for the Web Console
  * feature.
  *
  * @constructor
  * @param object aConnection
  *        The connection to the client, DebuggerServerConnection.
  * @param object aTabActor
  *        The parent tab actor.
  */
 function WebConsoleActor(aConnection, aTabActor)
 {
   this.conn = aConnection;
   this._browser = aTabActor.browser;
-
-  this._objectActorsPool = new ActorPool(this.conn);
-  this.conn.addActorPool(this._objectActorsPool);
 }
 
 WebConsoleActor.prototype =
 {
   /**
    * The xul:browser we work with.
    * @private
    * @type nsIDOMElement
    */
   _browser: null,
 
   /**
-   * Actor pool for all of the object actors for objects we send to the client.
-   * @private
-   * @type object
-   * @see ActorPool
-   * @see this.objectGrip()
-   */
-  _objectActorsPool: null,
-
-  /**
-   * Tells the current page location associated to the sandbox. When the page
-   * location is changed, we recreate the sandbox.
-   * @private
-   * @type object
-   */
-  _sandboxLocation: null,
-
-  /**
-   * The JavaScript Sandbox where code is evaluated.
-   * @type object
-   */
-  sandbox: null,
-
-  /**
    * The debugger server connection instance.
    * @type object
    */
   conn: null,
 
   /**
    * The content window we work with.
    * @type nsIDOMWindow
@@ -98,119 +56,36 @@ WebConsoleActor.prototype =
   get window() this._browser.contentWindow,
 
   /**
    * The PageErrorListener instance.
    * @type object
    */
   pageErrorListener: null,
 
-  /**
-   * The ConsoleAPIListener instance.
-   */
-  consoleAPIListener: null,
-
   actorPrefix: "console",
 
   grip: function WCA_grip()
   {
     return { actor: this.actorID };
   },
 
   /**
-   * Tells if the window.console object is native or overwritten by script in
-   * the page.
-   *
-   * @return boolean
-   *         True if the window.console object is native, or false otherwise.
-   */
-  hasNativeConsoleAPI: function WCA_hasNativeConsoleAPI()
-  {
-    let isNative = false;
-    try {
-      let consoleObject = WebConsoleUtils.unwrap(this.window).console;
-      isNative = "__mozillaConsole__" in consoleObject;
-    }
-    catch (ex) { }
-    return isNative;
-  },
-
-  /**
    * Destroy the current WebConsoleActor instance.
    */
   disconnect: function WCA_disconnect()
   {
     if (this.pageErrorListener) {
       this.pageErrorListener.destroy();
       this.pageErrorListener = null;
     }
-    if (this.consoleAPIListener) {
-      this.consoleAPIListener.destroy();
-      this.consoleAPIListener = null;
-    }
-    this.conn.removeActorPool(this._objectActorsPool);
-    this._objectActorsPool = null;
-    this._sandboxLocation = this.sandbox = null;
     this.conn = this._browser = null;
   },
 
   /**
-   * Create a grip for the given value. If the value is an object,
-   * a WebConsoleObjectActor will be created.
-   *
-   * @param mixed aValue
-   * @return object
-   */
-  createValueGrip: function WCA_createValueGrip(aValue)
-  {
-    return WebConsoleUtils.createValueGrip(aValue,
-                                           this.createObjectActor.bind(this));
-  },
-
-  /**
-   * Create a grip for the given object.
-   *
-   * @param object aObject
-   *        The object you want.
-   * @param object
-   *        The object grip.
-   */
-  createObjectActor: function WCA_createObjectActor(aObject)
-  {
-    // We need to unwrap the object, otherwise we cannot access the properties
-    // and methods added by the content scripts.
-    let obj = WebConsoleUtils.unwrap(aObject);
-    let actor = new WebConsoleObjectActor(obj, this);
-    this._objectActorsPool.addActor(actor);
-    return actor.grip();
-  },
-
-  /**
-   * Get an object actor by its ID.
-   *
-   * @param string aActorID
-   * @return object
-   */
-  getObjectActorByID: function WCA_getObjectActorByID(aActorID)
-  {
-    return this._objectActorsPool.get(aActorID);
-  },
-
-  /**
-   * Release an object grip for the given object actor.
-   *
-   * @param object aActor
-   *        The WebConsoleObjectActor instance you want to release.
-   */
-  releaseObject: function WCA_releaseObject(aActor)
-  {
-    this._objectActorsPool.removeActor(aActor.actorID);
-  },
-
-  /**
    * Handler for the "startListeners" request.
    *
    * @param object aRequest
    *        The JSON request object received from the Web Console client.
    * @return object
    *         The response object which holds the startedListeners array.
    */
   onStartListeners: function WCA_onStartListeners(aRequest)
@@ -223,30 +98,19 @@ WebConsoleActor.prototype =
         case "PageError":
           if (!this.pageErrorListener) {
             this.pageErrorListener =
               new PageErrorListener(this.window, this);
             this.pageErrorListener.init();
           }
           startedListeners.push(listener);
           break;
-        case "ConsoleAPI":
-          if (!this.consoleAPIListener) {
-            this.consoleAPIListener =
-              new ConsoleAPIListener(this.window, this);
-            this.consoleAPIListener.init();
-          }
-          startedListeners.push(listener);
-          break;
       }
     }
-    return {
-      startedListeners: startedListeners,
-      nativeConsoleAPI: this.hasNativeConsoleAPI(),
-    };
+    return { startedListeners: startedListeners };
   },
 
   /**
    * Handler for the "stopListeners" request.
    *
    * @param object aRequest
    *        The JSON request object received from the Web Console client.
    * @return object
@@ -254,232 +118,35 @@ WebConsoleActor.prototype =
    *         stoppedListeners array.
    */
   onStopListeners: function WCA_onStopListeners(aRequest)
   {
     let stoppedListeners = [];
 
     // If no specific listeners are requested to be detached, we stop all
     // listeners.
-    let toDetach = aRequest.listeners || ["PageError", "ConsoleAPI"];
+    let toDetach = aRequest.listeners || ["PageError"];
 
     while (toDetach.length > 0) {
       let listener = toDetach.shift();
       switch (listener) {
         case "PageError":
           if (this.pageErrorListener) {
             this.pageErrorListener.destroy();
             this.pageErrorListener = null;
           }
           stoppedListeners.push(listener);
           break;
-        case "ConsoleAPI":
-          if (this.consoleAPIListener) {
-            this.consoleAPIListener.destroy();
-            this.consoleAPIListener = null;
-          }
-          stoppedListeners.push(listener);
-          break;
       }
     }
 
     return { stoppedListeners: stoppedListeners };
   },
 
   /**
-   * Handler for the "getCachedMessages" request. This method sends the cached
-   * error messages and the window.console API calls to the client.
-   *
-   * @param object aRequest
-   *        The JSON request object received from the Web Console client.
-   * @return object
-   *         The response packet to send to the client: it holds the cached
-   *         messages array.
-   */
-  onGetCachedMessages: function WCA_onGetCachedMessages(aRequest)
-  {
-    let types = aRequest.messageTypes;
-    if (!types) {
-      return {
-        error: "missingParameter",
-        message: "The messageTypes parameter is missing.",
-      };
-    }
-
-    let messages = [];
-
-    while (types.length > 0) {
-      let type = types.shift();
-      switch (type) {
-        case "ConsoleAPI":
-          if (this.consoleAPIListener) {
-            let cache = this.consoleAPIListener.getCachedMessages();
-            cache.forEach(function(aMessage) {
-              let message = this.prepareConsoleMessageForRemote(aMessage);
-              message._type = type;
-              messages.push(message);
-            }, this);
-          }
-          break;
-        case "PageError":
-          if (this.pageErrorListener) {
-            let cache = this.pageErrorListener.getCachedMessages();
-            cache.forEach(function(aMessage) {
-              let message = this.preparePageErrorForRemote(aMessage);
-              message._type = type;
-              messages.push(message);
-            }, this);
-          }
-          break;
-      }
-    }
-
-    messages.sort(function(a, b) { return a.timeStamp - b.timeStamp; });
-
-    return {
-      from: this.actorID,
-      messages: messages,
-    };
-  },
-
-  /**
-   * Handler for the "evaluateJS" request. This method evaluates the given
-   * JavaScript string and sends back the result.
-   *
-   * @param object aRequest
-   *        The JSON request object received from the Web Console client.
-   * @return object
-   *         The evaluation response packet.
-   */
-  onEvaluateJS: function WCA_onEvaluateJS(aRequest)
-  {
-    let input = aRequest.text;
-    let result, error = null;
-    let timestamp;
-
-    this.helperResult = null;
-    this.evalInput = input;
-    try {
-      timestamp = Date.now();
-      result = this.evalInSandbox(input);
-    }
-    catch (ex) {
-      error = ex;
-    }
-
-    let helperResult = this.helperResult;
-    delete this.helperResult;
-    delete this.evalInput;
-
-    return {
-      from: this.actorID,
-      input: input,
-      result: this.createValueGrip(result),
-      timestamp: timestamp,
-      error: error,
-      errorMessage: error ? String(error) : null,
-      helperResult: helperResult,
-    };
-  },
-
-  /**
-   * The Autocomplete request handler.
-   *
-   * @param object aRequest
-   *        The request message - what input to autocomplete.
-   * @return object
-   *         The response message - matched properties.
-   */
-  onAutocomplete: function WCA_onAutocomplete(aRequest)
-  {
-    let result = JSPropertyProvider(this.window, aRequest.text) || {};
-    return {
-      from: this.actorID,
-      matches: result.matches || [],
-      matchProp: result.matchProp,
-    };
-  },
-
-  /**
-   * The "clearMessagesCache" request handler.
-   */
-  onClearMessagesCache: function WCA_onClearMessagesCache()
-  {
-    // TODO: Bug 717611 - Web Console clear button does not clear cached errors
-    let windowId = WebConsoleUtils.getInnerWindowId(this.window);
-    ConsoleAPIStorage.clearEvents(windowId);
-    return {};
-  },
-
-  /**
-   * Create the JavaScript sandbox where user input is evaluated.
-   * @private
-   */
-  _createSandbox: function WCA__createSandbox()
-  {
-    this._sandboxLocation = this.window.location;
-    this.sandbox = new Cu.Sandbox(this.window, {
-      sandboxPrototype: this.window,
-      wantXrays: false,
-    });
-
-    this.sandbox.console = this.window.console;
-
-    JSTermHelpers(this);
-  },
-
-  /**
-   * Evaluates a string in the sandbox.
-   *
-   * @param string aString
-   *        String to evaluate in the sandbox.
-   * @return mixed
-   *         The result of the evaluation.
-   */
-  evalInSandbox: function WCA_evalInSandbox(aString)
-  {
-    // If the user changed to a different location, we need to update the
-    // sandbox.
-    if (this._sandboxLocation !== this.window.location) {
-      this._createSandbox();
-    }
-
-    // The help function needs to be easy to guess, so we make the () optional
-    if (aString.trim() == "help" || aString.trim() == "?") {
-      aString = "help()";
-    }
-
-    let window = WebConsoleUtils.unwrap(this.sandbox.window);
-    let $ = null, $$ = null;
-
-    // We prefer to execute the page-provided implementations for the $() and
-    // $$() functions.
-    if (typeof window.$ == "function") {
-      $ = this.sandbox.$;
-      delete this.sandbox.$;
-    }
-    if (typeof window.$$ == "function") {
-      $$ = this.sandbox.$$;
-      delete this.sandbox.$$;
-    }
-
-    let result = Cu.evalInSandbox(aString, this.sandbox, "1.8",
-                                  "Web Console", 1);
-
-    if ($) {
-      this.sandbox.$ = $;
-    }
-    if ($$) {
-      this.sandbox.$$ = $$;
-    }
-
-    return result;
-  },
-
-  /**
    * Handler for page errors received from the PageErrorListener. This method
    * sends the nsIScriptError to the remote Web Console client.
    *
    * @param nsIScriptError aPageError
    *        The page error we need to send to the client.
    */
   onPageError: function WCA_onPageError(aPageError)
   {
@@ -511,170 +178,16 @@ WebConsoleActor.prototype =
       category: aPageError.category,
       timeStamp: aPageError.timeStamp,
       warning: !!(aPageError.flags & aPageError.warningFlag),
       error: !!(aPageError.flags & aPageError.errorFlag),
       exception: !!(aPageError.flags & aPageError.exceptionFlag),
       strict: !!(aPageError.flags & aPageError.strictFlag),
     };
   },
-
-  /**
-   * Handler for window.console API calls received from the ConsoleAPIListener.
-   * This method sends the object to the remote Web Console client.
-   *
-   * @param object aMessage
-   *        The console API call we need to send to the remote client.
-   */
-  onConsoleAPICall: function WCA_onConsoleAPICall(aMessage)
-  {
-    let packet = {
-      from: this.actorID,
-      type: "consoleAPICall",
-      message: this.prepareConsoleMessageForRemote(aMessage),
-    };
-    this.conn.send(packet);
-  },
-
-  /**
-   * Prepare a message from the console API to be sent to the remote Web Console
-   * instance.
-   *
-   * @param object aMessage
-   *        The original message received from console-api-log-event.
-   * @return object
-   *         The object that can be sent to the remote client.
-   */
-  prepareConsoleMessageForRemote:
-  function WCA_prepareConsoleMessageForRemote(aMessage)
-  {
-    let result = {
-      level: aMessage.level,
-      filename: aMessage.filename,
-      lineNumber: aMessage.lineNumber,
-      functionName: aMessage.functionName,
-      timeStamp: aMessage.timeStamp,
-    };
-
-    switch (result.level) {
-      case "trace":
-      case "group":
-      case "groupCollapsed":
-      case "time":
-      case "timeEnd":
-        result.arguments = aMessage.arguments;
-        break;
-      default:
-        result.arguments = Array.map(aMessage.arguments || [],
-          function(aObj) {
-            return this.createValueGrip(aObj);
-          }, this);
-
-        if (result.level == "dir") {
-          result.objectProperties = [];
-          let first = result.arguments[0];
-          if (typeof first == "object" && first && first.inspectable) {
-            let actor = this.getObjectActorByID(first.actor);
-            result.objectProperties = actor.onInspectProperties().properties;
-          }
-        }
-        break;
-    }
-
-    return result;
-  },
-
-  /**
-   * Find the XUL window that owns the content window.
-   *
-   * @return Window
-   *         The XUL window that owns the content window.
-   */
-  chromeWindow: function WCA_chromeWindow()
-  {
-    return this.window.QueryInterface(Ci.nsIInterfaceRequestor)
-           .getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell)
-           .chromeEventHandler.ownerDocument.defaultView;
-  },
 };
 
 WebConsoleActor.prototype.requestTypes =
 {
   startListeners: WebConsoleActor.prototype.onStartListeners,
   stopListeners: WebConsoleActor.prototype.onStopListeners,
-  getCachedMessages: WebConsoleActor.prototype.onGetCachedMessages,
-  evaluateJS: WebConsoleActor.prototype.onEvaluateJS,
-  autocomplete: WebConsoleActor.prototype.onAutocomplete,
-  clearMessagesCache: WebConsoleActor.prototype.onClearMessagesCache,
 };
 
-/**
- * Creates an actor for the specified object.
- *
- * @constructor
- * @param object aObj
- *        The object you want.
- * @param object aWebConsoleActor
- *        The parent WebConsoleActor instance for this object.
- */
-function WebConsoleObjectActor(aObj, aWebConsoleActor)
-{
-  this.obj = aObj;
-  this.parent = aWebConsoleActor;
-}
-
-WebConsoleObjectActor.prototype =
-{
-  actorPrefix: "consoleObj",
-
-  /**
-   * Returns a grip for this actor for returning in a protocol message.
-   */
-  grip: function WCOA_grip()
-  {
-    let grip = WebConsoleUtils.getObjectGrip(this.obj);
-    grip.actor = this.actorID;
-    return grip;
-  },
-
-  /**
-   * Releases this actor from the pool.
-   */
-  release: function WCOA_release()
-  {
-    this.parent.releaseObject(this);
-    this.parent = this.obj = null;
-  },
-
-  /**
-   * Handle a protocol request to inspect the properties of the object.
-   *
-   * @return object
-   *         Message to send to the client. This holds the 'properties' property
-   *         - an array with a descriptor for each property in the object.
-   */
-  onInspectProperties: function WCOA_onInspectProperties()
-  {
-    // TODO: Bug 787981 - use LongStringActor for strings that are too long.
-    let createObjectActor = this.parent.createObjectActor.bind(this.parent);
-    let props = WebConsoleUtils.inspectObject(this.obj, createObjectActor);
-    return {
-      from: this.actorID,
-      properties: props,
-    };
-  },
-
-  /**
-   * Handle a protocol request to release a grip.
-   */
-  onRelease: function WCOA_onRelease()
-  {
-    this.release();
-    return {};
-  },
-};
-
-WebConsoleObjectActor.prototype.requestTypes =
-{
-  "inspectProperties": WebConsoleObjectActor.prototype.onInspectProperties,
-  "release": WebConsoleObjectActor.prototype.onRelease,
-};
-