diff --git a/Source/WebCore/inspector/CommandLineAPIModuleSource.js b/Source/WebCore/inspector/CommandLineAPIModuleSource.js
new file mode 100644
index 0000000..7a2c5ae
--- /dev/null
+++ b/Source/WebCore/inspector/CommandLineAPIModuleSource.js
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2007 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @param {InjectedScriptHost} InjectedScriptHost
+ * @param {Window} inspectedWindow
+ * @param {number} injectedScriptId
+ */
+(function (InjectedScriptHost, inspectedWindow, injectedScriptId, injectedScript) {
+
+/**
+ * @param {Arguments} array
+ * @param {number=} index
+ * @return {Array.<*>}
+ */
+function slice(array, index)
+{
+    var result = [];
+    for (var i = index || 0; i < array.length; ++i)
+        result.push(array[i]);
+    return result;
+}
+
+/**
+ * Please use this bind, not the one from Function.prototype
+ * @param {function(...)} func
+ * @param {Object} thisObject
+ * @param {...number} var_args
+ */
+function bind(func, thisObject, var_args)
+{
+    var args = slice(arguments, 2);
+
+    /**
+     * @param {...number} var_args
+     */
+    function bound(var_args)
+    {
+        return func.apply(thisObject, args.concat(slice(arguments)));
+    }
+    bound.toString = function() {
+        return "bound: " + func;
+    };
+    return bound;
+}
+
+/**
+ * @constructor
+ * @param {CommandLineAPIImpl} commandLineAPIImpl
+ * @param {Object} callFrame
+ */
+function CommandLineAPI(commandLineAPIImpl, callFrame)
+{
+    /**
+     * @param {string} member
+     * @return {boolean}
+     */
+    function inScopeVariables(member)
+    {
+        if (!callFrame)
+            return false;
+
+        var scopeChain = callFrame.scopeChain;
+        for (var i = 0; i < scopeChain.length; ++i) {
+            if (member in scopeChain[i])
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * @param {string} name The name of the method for which a toString method should be generated.
+     * @return {function():string}
+     */
+    function customToStringMethod(name)
+    {
+        return function () { return "function " + name + "() { [Command Line API] }"; };
+    }
+
+    for (var i = 0; i < CommandLineAPI.members_.length; ++i) {
+        var member = CommandLineAPI.members_[i];
+        if (member in inspectedWindow || inScopeVariables(member))
+            continue;
+
+        this[member] = bind(commandLineAPIImpl[member], commandLineAPIImpl);
+        this[member].toString = customToStringMethod(member);
+    }
+
+    for (var i = 0; i < 5; ++i) {
+        var member = "$" + i;
+        if (member in inspectedWindow || inScopeVariables(member))
+            continue;
+
+        this.__defineGetter__("$" + i, bind(commandLineAPIImpl._inspectedObject, commandLineAPIImpl, i));
+    }
+
+    this.$_ = injectedScript._lastResult;
+}
+
+/**
+ * @type {Array.<string>}
+ * @const
+ */
+CommandLineAPI.members_ = [
+    "$", "$$", "$x", "dir", "dirxml", "keys", "values", "profile", "profileEnd",
+    "monitorEvents", "unmonitorEvents", "inspect", "copy", "clear", "getEventListeners"
+];
+
+/**
+ * @constructor
+ */
+function CommandLineAPIImpl()
+{
+}
+
+CommandLineAPIImpl.prototype = {
+    /**
+     * @param {string} selector
+     * @param {Node=} start
+     */
+    $: function (selector, start)
+    {
+        if (this._canQuerySelectorOnNode(start))
+            return start.querySelector(selector);
+
+        var result = inspectedWindow.document.querySelector(selector);
+        if (result)
+            return result;
+        if (selector && selector[0] !== "#") {
+            result = inspectedWindow.document.getElementById(selector);
+            if (result) {
+                inspectedWindow.console.warn("The console function $() has changed from $=getElementById(id) to $=querySelector(selector). You might try $(\"#%s\")", selector );
+                return null;
+            }
+        }
+        return result;
+    },
+
+    /**
+     * @param {string} selector
+     * @param {Node=} start
+     */
+    $$: function (selector, start)
+    {
+        if (this._canQuerySelectorOnNode(start))
+            return start.querySelectorAll(selector);
+        return inspectedWindow.document.querySelectorAll(selector);
+    },
+
+    /**
+     * @param {Node=} node
+     * @return {boolean}
+     */
+    _canQuerySelectorOnNode: function(node)
+    {
+        return !!node && InjectedScriptHost.type(node) === "node" && (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE);
+    },
+
+    /**
+     * @param {string} xpath
+     * @param {Node=} context
+     */
+    $x: function(xpath, context)
+    {
+        var doc = (context && context.ownerDocument) || inspectedWindow.document;
+        var result = doc.evaluate(xpath, context || doc, null, XPathResult.ANY_TYPE, null);
+        switch (result.resultType) {
+        case XPathResult.NUMBER_TYPE:
+            return result.numberValue;
+        case XPathResult.STRING_TYPE:
+            return result.stringValue;
+        case XPathResult.BOOLEAN_TYPE:
+            return result.booleanValue;
+        default:
+            var nodes = [];
+            var node;
+            while (node = result.iterateNext())
+                nodes.push(node);
+            return nodes;
+        }
+    },
+
+    dir: function()
+    {
+        return inspectedWindow.console.dir.apply(inspectedWindow.console, arguments)
+    },
+
+    dirxml: function()
+    {
+        return inspectedWindow.console.dirxml.apply(inspectedWindow.console, arguments)
+    },
+
+    keys: function(object)
+    {
+        return Object.keys(object);
+    },
+
+    values: function(object)
+    {
+        var result = [];
+        for (var key in object)
+            result.push(object[key]);
+        return result;
+    },
+
+    profile: function()
+    {
+        return inspectedWindow.console.profile.apply(inspectedWindow.console, arguments)
+    },
+
+    profileEnd: function()
+    {
+        return inspectedWindow.console.profileEnd.apply(inspectedWindow.console, arguments)
+    },
+
+    /**
+     * @param {Object} object
+     * @param {Array.<string>|string=} types
+     */
+    monitorEvents: function(object, types)
+    {
+        if (!object || !object.addEventListener || !object.removeEventListener)
+            return;
+        types = this._normalizeEventTypes(types);
+        for (var i = 0; i < types.length; ++i) {
+            object.removeEventListener(types[i], this._logEvent, false);
+            object.addEventListener(types[i], this._logEvent, false);
+        }
+    },
+
+    /**
+     * @param {Object} object
+     * @param {Array.<string>|string=} types
+     */
+    unmonitorEvents: function(object, types)
+    {
+        if (!object || !object.addEventListener || !object.removeEventListener)
+            return;
+        types = this._normalizeEventTypes(types);
+        for (var i = 0; i < types.length; ++i)
+            object.removeEventListener(types[i], this._logEvent, false);
+    },
+
+    /**
+     * @param {*} object
+     * @return {*}
+     */
+    inspect: function(object)
+    {
+        return injectedScript._inspect(object);
+    },
+
+    copy: function(object)
+    {
+        if (injectedScript._subtype(object) === "node")
+            object = object.outerHTML;
+        InjectedScriptHost.copyText(object);
+    },
+
+    clear: function()
+    {
+        InjectedScriptHost.clearConsoleMessages();
+    },
+
+    /**
+     * @param {Node} node
+     */
+    getEventListeners: function(node)
+    {
+        return InjectedScriptHost.getEventListeners(node);
+    },
+
+    /**
+     * @param {number} num
+     */
+    _inspectedObject: function(num)
+    {
+        return InjectedScriptHost.inspectedObject(num);
+    },
+
+    /**
+     * @param {Array.<string>|string=} types
+     * @return {Array.<string>}
+     */
+    _normalizeEventTypes: function(types)
+    {
+        if (typeof types === "undefined")
+            types = [ "mouse", "key", "touch", "control", "load", "unload", "abort", "error", "select", "change", "submit", "reset", "focus", "blur", "resize", "scroll", "search", "devicemotion", "deviceorientation" ];
+        else if (typeof types === "string")
+            types = [ types ];
+
+        var result = [];
+        for (var i = 0; i < types.length; i++) {
+            if (types[i] === "mouse")
+                result.splice(0, 0, "mousedown", "mouseup", "click", "dblclick", "mousemove", "mouseover", "mouseout", "mousewheel");
+            else if (types[i] === "key")
+                result.splice(0, 0, "keydown", "keyup", "keypress", "textInput");
+            else if (types[i] === "touch")
+                result.splice(0, 0, "touchstart", "touchmove", "touchend", "touchcancel");
+            else if (types[i] === "control")
+                result.splice(0, 0, "resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset");
+            else
+                result.push(types[i]);
+        }
+        return result;
+    },
+
+    /**
+     * @param {Event} event
+     */
+    _logEvent: function(event)
+    {
+        inspectedWindow.console.log(event.type, event);
+    }
+}
+
+injectedScript.CommandLineAPI = CommandLineAPI;
+injectedScript._commandLineAPIImpl = new CommandLineAPIImpl();
+
+// This Module doesn't expose an object, it just adds an extension that InjectedScript uses.
+// However, we return an empty object, so that InjectedScript knows this module has been loaded.
+return {};
+
+})
