/*
 * Copyright (C) 2007 Apple Inc.  All rights reserved.
 * Copyright (C) 2013 Google 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.
 */

"use strict";

/**
 * @param {!InjectedScriptHostClass} InjectedScriptHost
 * @param {!Window|!WorkerGlobalScope} inspectedGlobalObject
 * @param {number} injectedScriptId
 * @suppress {uselessCode}
 */
(function (InjectedScriptHost, inspectedGlobalObject, injectedScriptId) {

/**
 * @param {!Array.<T>} array
 * @param {...} var_args
 * @template T
 */
function push(array, var_args)
{
    for (var i = 1; i < arguments.length; ++i)
        array[array.length] = arguments[i];
}

/**
 * @param {*} obj
 * @return {string}
 * @suppress {uselessCode}
 */
function toString(obj)
{
    // We don't use String(obj) because String could be overridden.
    // Also the ("" + obj) expression may throw.
    try {
        return "" + obj;
    } catch (e) {
        var name = InjectedScriptHost.internalConstructorName(obj) || InjectedScriptHost.subtype(obj) || (typeof obj);
        return "#<" + name + ">";
    }
}

/**
 * @param {*} obj
 * @return {string}
 */
function toStringDescription(obj)
{
    if (typeof obj === "number" && obj === 0 && 1 / obj < 0)
        return "-0"; // Negative zero.
    return toString(obj);
}

/**
 * FireBug's array detection.
 * @param {*} obj
 * @return {boolean}
 */
function isArrayLike(obj)
{
    if (typeof obj !== "object")
        return false;
    var splice = InjectedScriptHost.getProperty(obj, "splice");
    if (typeof splice === "function") {
        if (!InjectedScriptHost.objectHasOwnProperty(/** @type {!Object} */ (obj), "length"))
            return false;
        var len = InjectedScriptHost.getProperty(obj, "length");
        // is len uint32?
        return typeof len === "number" && len >>> 0 === len && (len > 0 || 1 / len > 0);
    }
    return false;
}

/**
 * @param {number} a
 * @param {number} b
 * @return {number}
 */
function max(a, b)
{
    return a > b ? a : b;
}

/**
 * FIXME: Remove once ES6 is supported natively by JS compiler.
 * @param {*} obj
 * @return {boolean}
 */
function isSymbol(obj)
{
    var type = typeof obj;
    return (type === "symbol");
}

/**
 * DOM Attributes which have observable side effect on getter, in the form of
 *   {interfaceName1: {attributeName1: true,
 *                     attributeName2: true,
 *                     ...},
 *    interfaceName2: {...},
 *    ...}
 * @type {!Object<string, !Object<string, boolean>>}
 * @const
 */
var domAttributesWithObservableSideEffectOnGet = {
    Request: { body: true, __proto__: null },
    Response: { body: true, __proto__: null },
    __proto__: null
}

/**
 * @param {!Object} object
 * @param {string} attribute
 * @return {boolean}
 */
function doesAttributeHaveObservableSideEffectOnGet(object, attribute)
{
    for (var interfaceName in domAttributesWithObservableSideEffectOnGet) {
        var interfaceFunction = inspectedGlobalObject[interfaceName];
        // Call to instanceOf looks safe after typeof check.
        var isInstance = typeof interfaceFunction === "function" && /* suppressBlacklist */ object instanceof interfaceFunction;
        if (isInstance)
            return attribute in domAttributesWithObservableSideEffectOnGet[interfaceName];
    }
    return false;
}

/**
 * @constructor
 */
var InjectedScript = function()
{
}
InjectedScriptHost.nullifyPrototype(InjectedScript);

/**
 * @type {!Object<string, boolean>}
 * @const
 */
InjectedScript.primitiveTypes = {
    "undefined": true,
    "boolean": true,
    "number": true,
    "string": true,
    __proto__: null
}

/**
 * @type {!Object<string, string>}
 * @const
 */
InjectedScript.closureTypes = {
    "local": "Local",
    "closure": "Closure",
    "catch": "Catch",
    "block": "Block",
    "script": "Script",
    "with": "With Block",
    "global": "Global",
    "eval": "Eval",
    "module": "Module",
    __proto__: null
};

InjectedScript.prototype = {
    /**
     * @param {*} object
     * @return {boolean}
     */
    isPrimitiveValue: function(object)
    {
        // FIXME(33716): typeof document.all is always 'undefined'.
        return InjectedScript.primitiveTypes[typeof object] && !this._isHTMLAllCollection(object);
    },

    /**
     * @param {*} object
     * @return {boolean}
     */
    _shouldPassByValue: function(object)
    {
        return typeof object === "object" && InjectedScriptHost.subtype(object) === "internal#location";
    },

    /**
     * @param {*} object
     * @param {string} groupName
     * @param {boolean} forceValueType
     * @param {boolean} generatePreview
     * @return {!RuntimeAgent.RemoteObject}
     */
    wrapObject: function(object, groupName, forceValueType, generatePreview)
    {
        return this._wrapObject(object, groupName, forceValueType, generatePreview);
    },

    /**
     * @param {!Array<!Object>} array
     * @param {string} property
     * @param {string} groupName
     * @param {boolean} forceValueType
     * @param {boolean} generatePreview
     */
    wrapPropertyInArray: function(array, property, groupName, forceValueType, generatePreview)
    {
        for (var i = 0; i < array.length; ++i) {
            if (typeof array[i] === "object" && property in array[i])
                array[i][property] = this.wrapObject(array[i][property], groupName, forceValueType, generatePreview);
        }
    },

    /**
     * @param {!Object} table
     * @param {!Array.<string>|string|boolean} columns
     * @return {!RuntimeAgent.RemoteObject}
     */
    wrapTable: function(table, columns)
    {
        var columnNames = null;
        if (typeof columns === "string")
            columns = [columns];
        if (InjectedScriptHost.subtype(columns) === "array") {
            columnNames = [];
            InjectedScriptHost.nullifyPrototype(columnNames);
            for (var i = 0; i < columns.length; ++i)
                columnNames[i] = toString(columns[i]);
        }
        return this._wrapObject(table, "console", false, true, columnNames, true);
    },

    /**
     * This method cannot throw.
     * @param {*} object
     * @param {string=} objectGroupName
     * @param {boolean=} forceValueType
     * @param {boolean=} generatePreview
     * @param {?Array.<string>=} columnNames
     * @param {boolean=} isTable
     * @param {boolean=} doNotBind
     * @param {*=} customObjectConfig
     * @return {!RuntimeAgent.RemoteObject}
     * @suppress {checkTypes}
     */
    _wrapObject: function(object, objectGroupName, forceValueType, generatePreview, columnNames, isTable, doNotBind, customObjectConfig)
    {
        try {
            return new InjectedScript.RemoteObject(object, objectGroupName, doNotBind, forceValueType, generatePreview, columnNames, isTable, undefined, customObjectConfig);
        } catch (e) {
            try {
                var description = injectedScript._describe(e);
            } catch (ex) {
                var description = "<failed to convert exception to string>";
            }
            return new InjectedScript.RemoteObject(description);
        }
    },

    /**
     * @param {!Object|symbol} object
     * @param {string=} objectGroupName
     * @return {string}
     */
    _bind: function(object, objectGroupName)
    {
        var id = InjectedScriptHost.bind(object, objectGroupName || "");
        return "{\"injectedScriptId\":" + injectedScriptId + ",\"id\":" + id + "}";
    },

    /**
     * @param {!Object} object
     * @param {string} objectGroupName
     * @param {boolean} ownProperties
     * @param {boolean} accessorPropertiesOnly
     * @param {boolean} generatePreview
     * @return {!Array<!RuntimeAgent.PropertyDescriptor>|boolean}
     */
    getProperties: function(object, objectGroupName, ownProperties, accessorPropertiesOnly, generatePreview)
    {
        var subtype = this._subtype(object);
        if (subtype === "internal#scope") {
            // Internally, scope contains object with scope variables and additional information like type,
            // we use additional information for preview and would like to report variables as scope
            // properties.
            object = object.object;
        }

        // Go over properties, wrap object values.
        var descriptors = this._propertyDescriptors(object, addPropertyIfNeeded, ownProperties, accessorPropertiesOnly);
        for (var i = 0; i < descriptors.length; ++i) {
            var descriptor = descriptors[i];
            if ("get" in descriptor)
                descriptor.get = this._wrapObject(descriptor.get, objectGroupName);
            if ("set" in descriptor)
                descriptor.set = this._wrapObject(descriptor.set, objectGroupName);
            if ("value" in descriptor)
                descriptor.value = this._wrapObject(descriptor.value, objectGroupName, false, generatePreview);
            if (!("configurable" in descriptor))
                descriptor.configurable = false;
            if (!("enumerable" in descriptor))
                descriptor.enumerable = false;
            if ("symbol" in descriptor)
                descriptor.symbol = this._wrapObject(descriptor.symbol, objectGroupName);
        }
        return descriptors;

        /**
         * @param {!Array<!Object>} descriptors
         * @param {!Object} descriptor
         * @return {boolean}
         */
        function addPropertyIfNeeded(descriptors, descriptor) {
            push(descriptors, descriptor);
            return true;
        }
    },

    /**
     * @param {!Object} object
     * @return {?Object}
     */
    _objectPrototype: function(object)
    {
        if (InjectedScriptHost.subtype(object) === "proxy")
            return null;
        try {
            return InjectedScriptHost.getPrototypeOf(object);
        } catch (e) {
            return null;
        }
    },

    /**
     * @param {!Object} object
     * @param {!function(!Array<!Object>, !Object)} addPropertyIfNeeded
     * @param {boolean=} ownProperties
     * @param {boolean=} accessorPropertiesOnly
     * @param {?Array<string>=} propertyNamesOnly
     * @return {!Array<!Object>}
     */
    _propertyDescriptors: function(object, addPropertyIfNeeded, ownProperties, accessorPropertiesOnly, propertyNamesOnly)
    {
        var descriptors = [];
        InjectedScriptHost.nullifyPrototype(descriptors);
        var propertyProcessed = { __proto__: null };
        var subtype = InjectedScriptHost.subtype(object);

        /**
         * @param {!Object} o
         * @param {!Array<string|number|symbol>=} properties
         * @param {number=} objectLength
         * @return {boolean}
         */
        function process(o, properties, objectLength)
        {
            // When properties is not provided, iterate over the object's indices.
            var length = properties ? properties.length : objectLength;
            for (var i = 0; i < length; ++i) {
                var property = properties ? properties[i] : ("" + i);
                if (propertyProcessed[property])
                    continue;
                propertyProcessed[property] = true;
                var name;
                if (isSymbol(property))
                    name = /** @type {string} */ (injectedScript._describe(property));
                else
                    name = typeof property === "number" ? ("" + property) : /** @type {string} */(property);

                if (subtype === "internal#scopeList" && name === "length")
                    continue;

                var descriptor;
                try {
                    descriptor = InjectedScriptHost.getOwnPropertyDescriptor(o, property);
                    if (descriptor) {
                        InjectedScriptHost.nullifyPrototype(descriptor);
                    }
                    var isAccessorProperty = descriptor && ("get" in descriptor || "set" in descriptor);
                    if (accessorPropertiesOnly && !isAccessorProperty)
                        continue;
                    if (descriptor && "get" in descriptor && "set" in descriptor && name !== "__proto__" &&
                            InjectedScriptHost.formatAccessorsAsProperties(object, descriptor.get) &&
                            !doesAttributeHaveObservableSideEffectOnGet(object, name)) {
                        descriptor.value = object[property];
                        descriptor.isOwn = true;
                        delete descriptor.get;
                        delete descriptor.set;
                    }
                } catch (e) {
                    if (accessorPropertiesOnly)
                        continue;
                    descriptor = { value: e, wasThrown: true, __proto__: null };
                }

                // Not all bindings provide proper descriptors. Fall back to the non-configurable, non-enumerable,
                // non-writable property.
                if (!descriptor) {
                    try {
                        descriptor = { value: o[property], writable: false, __proto__: null };
                    } catch (e) {
                        // Silent catch.
                        continue;
                    }
                }

                descriptor.name = name;
                if (o === object)
                    descriptor.isOwn = true;
                if (isSymbol(property))
                    descriptor.symbol = property;
                if (!addPropertyIfNeeded(descriptors, descriptor))
                    return false;
            }
            return true;
        }

        if (propertyNamesOnly) {
            for (var i = 0; i < propertyNamesOnly.length; ++i) {
                var name = propertyNamesOnly[i];
                for (var o = object; this._isDefined(o); o = this._objectPrototype(/** @type {!Object} */ (o))) {
                    o = /** @type {!Object} */ (o);
                    if (InjectedScriptHost.objectHasOwnProperty(o, name)) {
                        if (!process(o, [name]))
                            return descriptors;
                        break;
                    }
                    if (ownProperties)
                        break;
                }
            }
            return descriptors;
        }

        var skipGetOwnPropertyNames;
        try {
            skipGetOwnPropertyNames = subtype === "typedarray" && object.length > 500000;
        } catch (e) {
        }

        for (var o = object; this._isDefined(o); o = this._objectPrototype(/** @type {!Object} */ (o))) {
            o = /** @type {!Object} */ (o);
            if (InjectedScriptHost.subtype(o) === "proxy")
                continue;

            try {
                if (skipGetOwnPropertyNames && o === object) {
                    if (!process(o, undefined, o.length))
                        return descriptors;
                } else {
                    // First call Object.keys() to enforce ordering of the property descriptors.
                    if (!process(o, InjectedScriptHost.keys(o)))
                        return descriptors;
                    if (!process(o, InjectedScriptHost.getOwnPropertyNames(o)))
                        return descriptors;
                }
                if (!process(o, InjectedScriptHost.getOwnPropertySymbols(o)))
                    return descriptors;

                if (ownProperties) {
                    var proto = this._objectPrototype(o);
                    if (proto && !accessorPropertiesOnly) {
                        var descriptor = { name: "__proto__", value: proto, writable: true, configurable: true, enumerable: false, isOwn: true, __proto__: null };
                        if (!addPropertyIfNeeded(descriptors, descriptor))
                            return descriptors;
                    }
                }
            } catch (e) {
            }

            if (ownProperties)
                break;
        }
        return descriptors;
    },

    /**
     * @param {string|undefined} objectGroupName
     * @param {*} jsonMLObject
     * @throws {string} error message
     */
    _substituteObjectTagsInCustomPreview: function(objectGroupName, jsonMLObject)
    {
        var maxCustomPreviewRecursionDepth = 20;
        this._customPreviewRecursionDepth = (this._customPreviewRecursionDepth || 0) + 1
        try {
            if (this._customPreviewRecursionDepth >= maxCustomPreviewRecursionDepth)
                throw new Error("Too deep hierarchy of inlined custom previews");

            if (!isArrayLike(jsonMLObject))
                return;

            if (jsonMLObject[0] === "object") {
                var attributes = jsonMLObject[1];
                var originObject = attributes["object"];
                var config = attributes["config"];
                if (typeof originObject === "undefined")
                    throw new Error("Illegal format: obligatory attribute \"object\" isn't specified");

                jsonMLObject[1] = this._wrapObject(originObject, objectGroupName, false, false, null, false, false, config);
                return;
            }

            for (var i = 0; i < jsonMLObject.length; ++i)
                this._substituteObjectTagsInCustomPreview(objectGroupName, jsonMLObject[i]);
        } finally {
            this._customPreviewRecursionDepth--;
        }
    },

    /**
     * @param {*} object
     * @return {boolean}
     */
    _isDefined: function(object)
    {
        return !!object || this._isHTMLAllCollection(object);
    },

    /**
     * @param {*} object
     * @return {boolean}
     */
    _isHTMLAllCollection: function(object)
    {
        // document.all is reported as undefined, but we still want to process it.
        return (typeof object === "undefined") && !!InjectedScriptHost.subtype(object);
    },

    /**
     * @param {*} obj
     * @return {?string}
     */
    _subtype: function(obj)
    {
        if (obj === null)
            return "null";

        if (this.isPrimitiveValue(obj))
            return null;

        var subtype = InjectedScriptHost.subtype(obj);
        if (subtype)
            return subtype;

        if (isArrayLike(obj))
            return "array";

        // If owning frame has navigated to somewhere else window properties will be undefined.
        return null;
    },

    /**
     * @param {*} obj
     * @return {?string}
     */
    _describe: function(obj)
    {
        if (this.isPrimitiveValue(obj))
            return null;

        var subtype = this._subtype(obj);

        if (subtype === "regexp")
            return toString(obj);

        if (subtype === "date")
            return toString(obj);

        if (subtype === "node") {
            var description = "";
            if (obj.nodeName)
                description = obj.nodeName.toLowerCase();
            else if (obj.constructor)
                description = obj.constructor.name.toLowerCase();

            switch (obj.nodeType) {
            case 1 /* Node.ELEMENT_NODE */:
                description += obj.id ? "#" + obj.id : "";
                var className = obj.className;
                description += (className && typeof className === "string") ? "." + className.trim().replace(/\s+/g, ".") : "";
                break;
            case 10 /*Node.DOCUMENT_TYPE_NODE */:
                description = "<!DOCTYPE " + description + ">";
                break;
            }
            return description;
        }

        if (subtype === "proxy")
            return "Proxy";

        var className = InjectedScriptHost.internalConstructorName(obj);
        if (subtype === "array" || subtype === "typedarray") {
            if (typeof obj.length === "number")
                return className + "(" + obj.length + ")";
            return className;
        }

        if (subtype === "map" || subtype === "set" || subtype === "blob") {
            if (typeof obj.size === "number")
                return className + "(" + obj.size + ")";
            return className;
        }

        if (subtype === "arraybuffer" || subtype === "dataview") {
            if (typeof obj.byteLength === "number")
                return className + "(" + obj.byteLength + ")";
            return className;
        }

        if (typeof obj === "function")
            return toString(obj);

        if (isSymbol(obj)) {
            try {
                // It isn't safe, because Symbol.prototype.toString can be overriden.
                return /* suppressBlacklist */ obj.toString() || "Symbol";
            } catch (e) {
                return "Symbol";
            }
        }

        if (InjectedScriptHost.subtype(obj) === "error") {
            try {
                var stack = obj.stack;
                var message = obj.message && obj.message.length ? ": " + obj.message : "";
                var firstCallFrame = /^\s+at\s/m.exec(stack);
                var stackMessageEnd = firstCallFrame ? firstCallFrame.index : -1;
                if (stackMessageEnd !== -1) {
                    var stackTrace = stack.substr(stackMessageEnd);
                    return className + message + "\n" + stackTrace;
                }
                return className + message;
            } catch(e) {
            }
        }

        if (subtype === "internal#entry") {
            if ("key" in obj)
                return "{" + this._describeIncludingPrimitives(obj.key) + " => " + this._describeIncludingPrimitives(obj.value) + "}";
            return this._describeIncludingPrimitives(obj.value);
        }

        if (subtype === "internal#scopeList")
            return "Scopes[" + obj.length + "]";

        if (subtype === "internal#scope")
            return (InjectedScript.closureTypes[obj.type] || "Unknown") + (obj.name ? " (" + obj.name + ")" : "");

        return className;
    },

    /**
     * @param {*} value
     * @return {string}
     */
    _describeIncludingPrimitives: function(value)
    {
        if (typeof value === "string")
            return "\"" + value.replace(/\n/g, "\u21B5") + "\"";
        if (value === null)
            return "" + value;
        return this.isPrimitiveValue(value) ? toStringDescription(value) : (this._describe(value) || "");
    },

    /**
     * @param {boolean} enabled
     */
    setCustomObjectFormatterEnabled: function(enabled)
    {
        this._customObjectFormatterEnabled = enabled;
    }
}

/**
 * @type {!InjectedScript}
 * @const
 */
var injectedScript = new InjectedScript();

/**
 * @constructor
 * @param {*} object
 * @param {string=} objectGroupName
 * @param {boolean=} doNotBind
 * @param {boolean=} forceValueType
 * @param {boolean=} generatePreview
 * @param {?Array.<string>=} columnNames
 * @param {boolean=} isTable
 * @param {boolean=} skipEntriesPreview
 * @param {*=} customObjectConfig
 */
InjectedScript.RemoteObject = function(object, objectGroupName, doNotBind, forceValueType, generatePreview, columnNames, isTable, skipEntriesPreview, customObjectConfig)
{
    this.type = typeof object;
    if (this.type === "undefined" && injectedScript._isHTMLAllCollection(object))
        this.type = "object";

    if (injectedScript.isPrimitiveValue(object) || object === null || forceValueType) {
        // We don't send undefined values over JSON.
        if (this.type !== "undefined")
            this.value = object;

        // Null object is object with 'null' subtype.
        if (object === null)
            this.subtype = "null";

        // Provide user-friendly number values.
        if (this.type === "number") {
            this.description = toStringDescription(object);
            switch (this.description) {
            case "NaN":
            case "Infinity":
            case "-Infinity":
            case "-0":
                delete this.value;
                this.unserializableValue = this.description;
                break;
            }
        }

        return;
    }

    if (injectedScript._shouldPassByValue(object)) {
        this.value = object;
        this.subtype = injectedScript._subtype(object);
        this.description = injectedScript._describeIncludingPrimitives(object);
        return;
    }

    object = /** @type {!Object} */ (object);

    if (!doNotBind)
        this.objectId = injectedScript._bind(object, objectGroupName);
    var subtype = injectedScript._subtype(object);
    if (subtype)
        this.subtype = subtype;
    var className = InjectedScriptHost.internalConstructorName(object);
    if (className)
        this.className = className;
    this.description = injectedScript._describe(object);

    if (generatePreview && this.type === "object") {
        if (this.subtype === "proxy")
            this.preview = this._generatePreview(InjectedScriptHost.proxyTargetValue(object), undefined, columnNames, isTable, skipEntriesPreview);
        else if (this.subtype !== "node")
            this.preview = this._generatePreview(object, undefined, columnNames, isTable, skipEntriesPreview);
    }

    if (injectedScript._customObjectFormatterEnabled) {
        var customPreview = this._customPreview(object, objectGroupName, customObjectConfig);
        if (customPreview)
            this.customPreview = customPreview;
    }
}

InjectedScript.RemoteObject.prototype = {

    /**
     * @param {*} object
     * @param {string=} objectGroupName
     * @param {*=} customObjectConfig
     * @return {?RuntimeAgent.CustomPreview}
     */
    _customPreview: function(object, objectGroupName, customObjectConfig)
    {
        /**
         * @param {!Error} error
         */
        function logError(error)
        {
            // We use user code to generate custom output for object, we can use user code for reporting error too.
            Promise.resolve().then(/* suppressBlacklist */ inspectedGlobalObject.console.error.bind(inspectedGlobalObject.console, "Custom Formatter Failed: " + error.message));
        }

        /**
         * @param {*} object
         * @param {*=} customObjectConfig
         * @return {*}
         */
        function wrap(object, customObjectConfig)
        {
            return injectedScript._wrapObject(object, objectGroupName, false, false, null, false, false, customObjectConfig);
        }

        try {
            var formatters = inspectedGlobalObject["devtoolsFormatters"];
            if (!formatters || !isArrayLike(formatters))
                return null;

            for (var i = 0; i < formatters.length; ++i) {
                try {
                    var formatted = formatters[i].header(object, customObjectConfig);
                    if (!formatted)
                        continue;

                    var hasBody = formatters[i].hasBody(object, customObjectConfig);
                    injectedScript._substituteObjectTagsInCustomPreview(objectGroupName, formatted);
                    var formatterObjectId = injectedScript._bind(formatters[i], objectGroupName);
                    var bindRemoteObjectFunctionId = injectedScript._bind(wrap, objectGroupName);
                    var result = {header: JSON.stringify(formatted), hasBody: !!hasBody, formatterObjectId: formatterObjectId, bindRemoteObjectFunctionId: bindRemoteObjectFunctionId};
                    if (customObjectConfig)
                        result["configObjectId"] = injectedScript._bind(customObjectConfig, objectGroupName);
                    return result;
                } catch (e) {
                    logError(e);
                }
            }
        } catch (e) {
            logError(e);
        }
        return null;
    },

    /**
     * @return {!RuntimeAgent.ObjectPreview} preview
     */
    _createEmptyPreview: function()
    {
        var preview = {
            type: /** @type {!RuntimeAgent.ObjectPreviewType.<string>} */ (this.type),
            description: this.description || toStringDescription(this.value),
            overflow: false,
            properties: [],
            __proto__: null
        };
        InjectedScriptHost.nullifyPrototype(preview.properties);
        if (this.subtype)
            preview.subtype = /** @type {!RuntimeAgent.ObjectPreviewSubtype.<string>} */ (this.subtype);
        return preview;
    },

    /**
     * @param {!Object} object
     * @param {?Array.<string>=} firstLevelKeys
     * @param {?Array.<string>=} secondLevelKeys
     * @param {boolean=} isTable
     * @param {boolean=} skipEntriesPreview
     * @return {!RuntimeAgent.ObjectPreview} preview
     */
    _generatePreview: function(object, firstLevelKeys, secondLevelKeys, isTable, skipEntriesPreview)
    {
        var preview = this._createEmptyPreview();
        var firstLevelKeysCount = firstLevelKeys ? firstLevelKeys.length : 0;
        var propertiesThreshold = {
            properties: isTable ? 1000 : max(5, firstLevelKeysCount),
            indexes: isTable ? 1000 : max(100, firstLevelKeysCount),
            __proto__: null
        };
        var subtype = this.subtype;
        var primitiveString;

        try {
            var descriptors = [];
            InjectedScriptHost.nullifyPrototype(descriptors);

            // Add internal properties to preview.
            var rawInternalProperties = InjectedScriptHost.getInternalProperties(object) || [];
            var internalProperties = [];
            InjectedScriptHost.nullifyPrototype(rawInternalProperties);
            InjectedScriptHost.nullifyPrototype(internalProperties);
            var entries = null;
            for (var i = 0; i < rawInternalProperties.length; i += 2) {
                if (rawInternalProperties[i] === "[[Entries]]") {
                    entries = /** @type {!Array<*>} */(rawInternalProperties[i + 1]);
                    continue;
                }
                if (rawInternalProperties[i] === "[[PrimitiveValue]]" && typeof rawInternalProperties[i + 1] === 'string')
                    primitiveString = rawInternalProperties[i + 1];
                var internalPropertyDescriptor = {
                    name: rawInternalProperties[i],
                    value: rawInternalProperties[i + 1],
                    isOwn: true,
                    enumerable: true,
                    __proto__: null
                };
                push(descriptors, internalPropertyDescriptor);
            }
            var naturalDescriptors = injectedScript._propertyDescriptors(object, addPropertyIfNeeded, false /* ownProperties */, undefined /* accessorPropertiesOnly */, firstLevelKeys);
            for (var i = 0; i < naturalDescriptors.length; i++)
                push(descriptors, naturalDescriptors[i]);

            this._appendPropertyPreviewDescriptors(preview, descriptors, secondLevelKeys, isTable);

            if (subtype === "map" || subtype === "set" || subtype === "weakmap" || subtype === "weakset" || subtype === "iterator")
                this._appendEntriesPreview(entries, preview, skipEntriesPreview);

        } catch (e) {}

        return preview;

        /**
         * @param {!Array<!Object>} descriptors
         * @param {!Object} descriptor
         * @return {boolean}
         */
        function addPropertyIfNeeded(descriptors, descriptor) {
            if (descriptor.wasThrown)
                return true;

            // Ignore __proto__ property.
            if (descriptor.name === "__proto__")
                return true;

            // Ignore length property of array.
            if ((subtype === "array" || subtype === "typedarray") && descriptor.name === "length")
                return true;

            // Ignore size property of map, set.
            if ((subtype === "map" || subtype === "set") && descriptor.name === "size")
                return true;

            // Never preview prototype properties.
            if (!descriptor.isOwn)
                return true;

            // Ignore computed properties unless they have getters.
            if (!("value" in descriptor) && !descriptor.get)
                return true;

            // Ignore index properties when there is a primitive string.
            if (primitiveString && primitiveString[descriptor.name] === descriptor.value)
                return true;

            if (toString(descriptor.name >>> 0) === descriptor.name)
                propertiesThreshold.indexes--;
            else
                propertiesThreshold.properties--;

            var canContinue = propertiesThreshold.indexes >= 0 && propertiesThreshold.properties >= 0;
            if (!canContinue) {
                preview.overflow = true;
                return false;
            }
            push(descriptors, descriptor);
            return true;
        }
    },

    /**
     * @param {!RuntimeAgent.ObjectPreview} preview
     * @param {!Array.<*>|!Iterable.<*>} descriptors
     * @param {?Array.<string>=} secondLevelKeys
     * @param {boolean=} isTable
     */
    _appendPropertyPreviewDescriptors: function(preview, descriptors, secondLevelKeys, isTable)
    {
        for (var i = 0; i < descriptors.length; ++i) {
            var descriptor = descriptors[i];
            var name = descriptor.name;
            var value = descriptor.value;
            var type = typeof value;

            // Special-case HTMLAll.
            if (type === "undefined" && injectedScript._isHTMLAllCollection(value))
                type = "object";

            // Ignore computed properties unless they have getters.
            if (descriptor.get && !("value" in descriptor)) {
                push(preview.properties, { name: name, type: "accessor", __proto__: null });
                continue;
            }

            // Render own properties.
            if (value === null) {
                push(preview.properties, { name: name, type: "object", subtype: "null", value: "null", __proto__: null });
                continue;
            }

            var maxLength = 100;
            if (InjectedScript.primitiveTypes[type]) {
                if (type === "string" && value.length > maxLength)
                    value = this._abbreviateString(value, maxLength, true);
                push(preview.properties, { name: name, type: type, value: toStringDescription(value), __proto__: null });
                continue;
            }

            var property = { name: name, type: type, __proto__: null };
            var subtype = injectedScript._subtype(value);
            if (subtype)
                property.subtype = subtype;

            if (secondLevelKeys === null || secondLevelKeys) {
                var subPreview = this._generatePreview(value, secondLevelKeys || undefined, undefined, isTable);
                property.valuePreview = subPreview;
                if (subPreview.overflow)
                    preview.overflow = true;
            } else {
                var description = "";
                if (type !== "function")
                    description = this._abbreviateString(/** @type {string} */ (injectedScript._describe(value)), maxLength, subtype === "regexp");
                property.value = description;
            }
            push(preview.properties, property);
        }
    },

    /**
     * @param {?Array<*>} entries
     * @param {!RuntimeAgent.ObjectPreview} preview
     * @param {boolean=} skipEntriesPreview
     */
    _appendEntriesPreview: function(entries, preview, skipEntriesPreview)
    {
        if (!entries)
            return;
        if (skipEntriesPreview) {
            if (entries.length)
                preview.overflow = true;
            return;
        }
        preview.entries = [];
        InjectedScriptHost.nullifyPrototype(preview.entries);
        var entriesThreshold = 5;
        for (var i = 0; i < entries.length; ++i) {
            if (preview.entries.length >= entriesThreshold) {
                preview.overflow = true;
                break;
            }
            var entry = entries[i];
            InjectedScriptHost.nullifyPrototype(entry);
            var previewEntry = {
                value: generateValuePreview(entry.value),
                __proto__: null
            };
            if ("key" in entry)
                previewEntry.key = generateValuePreview(entry.key);
            push(preview.entries, previewEntry);
        }

        /**
         * @param {*} value
         * @return {!RuntimeAgent.ObjectPreview}
         */
        function generateValuePreview(value)
        {
            var remoteObject = new InjectedScript.RemoteObject(value, undefined, true, undefined, true, undefined, undefined, true);
            var valuePreview = remoteObject.preview || remoteObject._createEmptyPreview();
            return valuePreview;
        }
    },

    /**
     * @param {string} string
     * @param {number} maxLength
     * @param {boolean=} middle
     * @return {string}
     */
    _abbreviateString: function(string, maxLength, middle)
    {
        if (string.length <= maxLength)
            return string;
        if (middle) {
            var leftHalf = maxLength >> 1;
            var rightHalf = maxLength - leftHalf - 1;
            return string.substr(0, leftHalf) + "\u2026" + string.substr(string.length - rightHalf, rightHalf);
        }
        return string.substr(0, maxLength) + "\u2026";
    },

    __proto__: null
}

return injectedScript;
})
