/*
 * 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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 {InjectedScriptHostClass} InjectedScriptHost
 * @param {Window} inspectedWindow
 * @param {number} injectedScriptId
 * @param {!InjectedScript} injectedScript
 */
(function (InjectedScriptHost, inspectedWindow, injectedScriptId, injectedScript) {

var TypeUtils = {
    /**
     * http://www.khronos.org/registry/typedarray/specs/latest/#7
     * @const
     * @type {!Array.<function(new:ArrayBufferView, ArrayBufferView)>}
     */
    _typedArrayClasses: (function(typeNames) {
        var result = [];
        for (var i = 0, n = typeNames.length; i < n; ++i) {
            if (inspectedWindow[typeNames[i]])
                result.push(inspectedWindow[typeNames[i]]);
        }
        return result;
    })(["Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "Float32Array", "Float64Array"]),

    /**
     * @const
     * @type {!Array.<string>}
     */
    _supportedPropertyPrefixes: ["webkit"],

    /**
     * @param {*} array
     * @return {function(new:ArrayBufferView, ArrayBufferView)|null}
     */
    typedArrayClass: function(array)
    {
        var classes = TypeUtils._typedArrayClasses;
        for (var i = 0, n = classes.length; i < n; ++i) {
            if (array instanceof classes[i])
                return classes[i];
        }
        return null;
    },

    /**
     * @param {*} obj
     * @return {*}
     */
    clone: function(obj)
    {
        if (!obj)
            return obj;

        var type = typeof obj;
        if (type !== "object" && type !== "function")
            return obj;

        // Handle Array and ArrayBuffer instances.
        if (typeof obj.slice === "function") {
            console.assert(obj instanceof Array || obj instanceof ArrayBuffer);
            return obj.slice(0);
        }

        var typedArrayClass = TypeUtils.typedArrayClass(obj);
        if (typedArrayClass)
            return new typedArrayClass(/** @type {ArrayBufferView} */ (obj));

        if (obj instanceof HTMLImageElement) {
            var img = /** @type {HTMLImageElement} */ (obj);
            // Special case for Images with Blob URIs: cloneNode will fail if the Blob URI has already been revoked.
            // FIXME: Maybe this is a bug in WebKit core?
            if (/^blob:/.test(img.src))
                return TypeUtils.cloneIntoCanvas(img);
            return img.cloneNode(true);
        }

        if (obj instanceof HTMLCanvasElement)
            return TypeUtils.cloneIntoCanvas(obj);

        if (obj instanceof HTMLVideoElement)
            return TypeUtils.cloneIntoCanvas(obj, obj.videoWidth, obj.videoHeight);

        if (obj instanceof ImageData) {
            var context = TypeUtils._dummyCanvas2dContext();
            // FIXME: suppress type checks due to outdated builtin externs for createImageData.
            var result = (/** @type {?} */ (context)).createImageData(obj);
            for (var i = 0, n = obj.data.length; i < n; ++i)
              result.data[i] = obj.data[i];
            return result;
        }

        console.error("ASSERT_NOT_REACHED: failed to clone object: ", obj);
        return obj;
    },

    /**
     * @param {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} obj
     * @param {number=} width
     * @param {number=} height
     * @return {HTMLCanvasElement}
     */
    cloneIntoCanvas: function(obj, width, height)
    {
        var canvas = /** @type {HTMLCanvasElement} */ (inspectedWindow.document.createElement("canvas"));
        canvas.width = width || +obj.width;
        canvas.height = height || +obj.height;
        var context = /** @type {CanvasRenderingContext2D} */ (Resource.wrappedObject(canvas.getContext("2d")));
        context.drawImage(obj, 0, 0);
        return canvas;
    },

    /**
     * @param {Object=} obj
     * @return {Object}
     */
    cloneObject: function(obj)
    {
        if (!obj)
            return null;
        var result = {};
        for (var key in obj)
            result[key] = obj[key];
        return result;
    },

    /**
     * @param {!Array.<string>} names
     * @return {!Object.<string, boolean>}
     */
    createPrefixedPropertyNamesSet: function(names)
    {
        var result = Object.create(null);
        for (var i = 0, name; name = names[i]; ++i) {
            result[name] = true;
            var suffix = name.substr(0, 1).toUpperCase() + name.substr(1);
            for (var j = 0, prefix; prefix = TypeUtils._supportedPropertyPrefixes[j]; ++j)
                result[prefix + suffix] = true;
        }
        return result;
    },

    /**
     * @return {number}
     */
    now: function()
    {
        try {
            return inspectedWindow.performance.now();
        } catch(e) {
            try {
                return Date.now();
            } catch(ex) {
            }
        }
        return 0;
    },

    /**
     * @param {string} property
     * @param {!Object} obj
     * @return {boolean}
     */
    isEnumPropertyName: function(property, obj)
    {
        return (/^[A-Z][A-Z0-9_]+$/.test(property) && typeof obj[property] === "number");
    },

    /**
     * @return {CanvasRenderingContext2D}
     */
    _dummyCanvas2dContext: function()
    {
        var context = TypeUtils._dummyCanvas2dContextInstance;
        if (!context) {
            var canvas = /** @type {HTMLCanvasElement} */ (inspectedWindow.document.createElement("canvas"));
            context = /** @type {CanvasRenderingContext2D} */ (Resource.wrappedObject(canvas.getContext("2d")));
            TypeUtils._dummyCanvas2dContextInstance = context;
        }
        return context;
    }
}

/** @typedef {{name:string, valueIsEnum:(boolean|undefined), value:*, values:(!Array.<TypeUtils.InternalResourceStateDescriptor>|undefined), isArray:(boolean|undefined)}} */
TypeUtils.InternalResourceStateDescriptor;

/**
 * @interface
 */
function StackTrace()
{
}

StackTrace.prototype = {
    /**
     * @param {number} index
     * @return {{sourceURL: string, lineNumber: number, columnNumber: number}|undefined}
     */
    callFrame: function(index)
    {
    }
}

/**
 * @param {number=} stackTraceLimit
 * @param {Function=} topMostFunctionToIgnore
 * @return {StackTrace}
 */
StackTrace.create = function(stackTraceLimit, topMostFunctionToIgnore)
{
    if (typeof Error.captureStackTrace === "function")
        return new StackTraceV8(stackTraceLimit, topMostFunctionToIgnore || arguments.callee);
    // FIXME: Support JSC, and maybe other browsers.
    return null;
}

/**
 * @constructor
 * @implements {StackTrace}
 * @param {number=} stackTraceLimit
 * @param {Function=} topMostFunctionToIgnore
 * @see http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
 */
function StackTraceV8(stackTraceLimit, topMostFunctionToIgnore)
{
    StackTrace.call(this);

    var oldPrepareStackTrace = Error.prepareStackTrace;
    var oldStackTraceLimit = Error.stackTraceLimit;
    if (typeof stackTraceLimit === "number")
        Error.stackTraceLimit = stackTraceLimit;

    /**
     * @param {Object} error
     * @param {Array.<CallSite>} structuredStackTrace
     * @return {Array.<{sourceURL: string, lineNumber: number, columnNumber: number}>}
     */
    Error.prepareStackTrace = function(error, structuredStackTrace)
    {
        return structuredStackTrace.map(function(callSite) {
            return {
                sourceURL: callSite.getFileName(),
                lineNumber: callSite.getLineNumber(),
                columnNumber: callSite.getColumnNumber()
            };
        });
    }

    var holder = /** @type {{stack: Array.<{sourceURL: string, lineNumber: number, columnNumber: number}>}} */ ({});
    Error.captureStackTrace(holder, topMostFunctionToIgnore || arguments.callee);
    this._stackTrace = holder.stack;

    Error.stackTraceLimit = oldStackTraceLimit;
    Error.prepareStackTrace = oldPrepareStackTrace;
}

StackTraceV8.prototype = {
    /**
     * @override
     * @param {number} index
     * @return {{sourceURL: string, lineNumber: number, columnNumber: number}|undefined}
     */
    callFrame: function(index)
    {
        return this._stackTrace[index];
    },

    __proto__: StackTrace.prototype
}

/**
 * @constructor
 * @template T
 */
function Cache()
{
    this.reset();
}

Cache.prototype = {
    /**
     * @return {number}
     */
    size: function()
    {
        return this._size;
    },

    reset: function()
    {
        /** @type {!Object.<number, !T>} */
        this._items = Object.create(null);
        /** @type {number} */
        this._size = 0;
    },

    /**
     * @param {number} key
     * @return {boolean}
     */
    has: function(key)
    {
        return key in this._items;
    },

    /**
     * @param {number} key
     * @return {T|undefined}
     */
    get: function(key)
    {
        return this._items[key];
    },

    /**
     * @param {number} key
     * @param {!T} item
     */
    put: function(key, item)
    {
        if (!this.has(key))
            ++this._size;
        this._items[key] = item;
    }
}

/**
 * @constructor
 * @param {Resource|Object} thisObject
 * @param {string} functionName
 * @param {Array|Arguments} args
 * @param {Resource|*=} result
 * @param {StackTrace=} stackTrace
 */
function Call(thisObject, functionName, args, result, stackTrace)
{
    this._thisObject = thisObject;
    this._functionName = functionName;
    this._args = Array.prototype.slice.call(args, 0);
    this._result = result;
    this._stackTrace = stackTrace || null;

    if (!this._functionName)
        console.assert(this._args.length === 2 && typeof this._args[0] === "string");
}

Call.prototype = {
    /**
     * @return {Resource}
     */
    resource: function()
    {
        return Resource.forObject(this._thisObject);
    },

    /**
     * @return {string}
     */
    functionName: function()
    {
        return this._functionName;
    },

    /**
     * @return {boolean}
     */
    isPropertySetter: function()
    {
        return !this._functionName;
    },
    
    /**
     * @return {!Array}
     */
    args: function()
    {
        return this._args;
    },

    /**
     * @return {*}
     */
    result: function()
    {
        return this._result;
    },

    /**
     * @return {StackTrace}
     */
    stackTrace: function()
    {
        return this._stackTrace;
    },

    /**
     * @param {StackTrace} stackTrace
     */
    setStackTrace: function(stackTrace)
    {
        this._stackTrace = stackTrace;
    },

    /**
     * @param {*} result
     */
    setResult: function(result)
    {
        this._result = result;
    },

    /**
     * @param {string} name
     * @param {Object} attachment
     */
    setAttachment: function(name, attachment)
    {
        if (attachment) {
            /** @type {Object.<string, Object>} */
            this._attachments = this._attachments || Object.create(null);
            this._attachments[name] = attachment;
        } else if (this._attachments)
            delete this._attachments[name];
    },

    /**
     * @param {string} name
     * @return {Object}
     */
    attachment: function(name)
    {
        return this._attachments && this._attachments[name];
    },

    freeze: function()
    {
        if (this._freezed)
            return;
        this._freezed = true;
        for (var i = 0, n = this._args.length; i < n; ++i) {
            // FIXME: freeze the Resources also!
            if (!Resource.forObject(this._args[i]))
                this._args[i] = TypeUtils.clone(this._args[i]);
        }
    },

    /**
     * @param {!Cache.<ReplayableResource>} cache
     * @return {!ReplayableCall}
     */
    toReplayable: function(cache)
    {
        this.freeze();
        var thisObject = /** @type {ReplayableResource} */ (Resource.toReplayable(this._thisObject, cache));
        var result = Resource.toReplayable(this._result, cache);
        var args = this._args.map(function(obj) {
            return Resource.toReplayable(obj, cache);
        });
        var attachments = TypeUtils.cloneObject(this._attachments);
        return new ReplayableCall(thisObject, this._functionName, args, result, this._stackTrace, attachments);
    },

    /**
     * @param {!ReplayableCall} replayableCall
     * @param {!Cache.<Resource>} cache
     * @return {!Call}
     */
    replay: function(replayableCall, cache)
    {
        var replayableResult = replayableCall.result();
        if (replayableResult instanceof ReplayableResource && !cache.has(replayableResult.id())) {
            var resource = replayableResult.replay(cache);
            console.assert(resource.calls().length > 0, "Expected create* call for the Resource");
            return resource.calls()[0];
        }

        var replayObject = ReplayableResource.replay(replayableCall.replayableResource(), cache);
        var replayArgs = replayableCall.args().map(function(obj) {
            return ReplayableResource.replay(obj, cache);
        });
        var replayResult = undefined;

        if (replayableCall.isPropertySetter())
            replayObject[replayArgs[0]] = replayArgs[1];
        else {
            var replayFunction = replayObject[replayableCall.functionName()];
            console.assert(typeof replayFunction === "function", "Expected a function to replay");
            replayResult = replayFunction.apply(replayObject, replayArgs);

            if (replayableResult instanceof ReplayableResource) {
                var resource = replayableResult.replay(cache);
                if (!resource.wrappedObject())
                    resource.setWrappedObject(replayResult);
            }
        }
    
        this._thisObject = replayObject;
        this._functionName = replayableCall.functionName();
        this._args = replayArgs;
        this._result = replayResult;
        this._stackTrace = replayableCall.stackTrace();
        this._freezed = true;
        var attachments = replayableCall.attachments();
        if (attachments)
            this._attachments = TypeUtils.cloneObject(attachments);

        var thisResource = Resource.forObject(replayObject);
        if (thisResource)
            thisResource.onCallReplayed(this);

        return this;
    }
}

/**
 * @constructor
 * @param {ReplayableResource} thisObject
 * @param {string} functionName
 * @param {Array.<ReplayableResource|*>} args
 * @param {ReplayableResource|*} result
 * @param {StackTrace} stackTrace
 * @param {Object.<string, Object>} attachments
 */
function ReplayableCall(thisObject, functionName, args, result, stackTrace, attachments)
{
    this._thisObject = thisObject;
    this._functionName = functionName;
    this._args = args;
    this._result = result;
    this._stackTrace = stackTrace;
    if (attachments)
        this._attachments = attachments;
}

ReplayableCall.prototype = {
    /**
     * @return {ReplayableResource}
     */
    replayableResource: function()
    {
        return this._thisObject;
    },

    /**
     * @return {string}
     */
    functionName: function()
    {
        return this._functionName;
    },

    /**
     * @return {boolean}
     */
    isPropertySetter: function()
    {
        return !this._functionName;
    },

    /**
     * @return {string}
     */
    propertyName: function()
    {
        console.assert(this.isPropertySetter());
        return /** @type {string} */ (this._args[0]);
    },

    /**
     * @return {*}
     */
    propertyValue: function()
    {
        console.assert(this.isPropertySetter());
        return this._args[1];
    },

    /**
     * @return {Array.<ReplayableResource|*>}
     */
    args: function()
    {
        return this._args;
    },

    /**
     * @return {ReplayableResource|*}
     */
    result: function()
    {
        return this._result;
    },

    /**
     * @return {StackTrace}
     */
    stackTrace: function()
    {
        return this._stackTrace;
    },

    /**
     * @return {Object.<string, Object>}
     */
    attachments: function()
    {
        return this._attachments;
    },

    /**
     * @param {string} name
     * @return {Object}
     */
    attachment: function(name)
    {
        return this._attachments && this._attachments[name];
    },

    /**
     * @param {!Cache.<Resource>} cache
     * @return {!Call}
     */
    replay: function(cache)
    {
        var call = /** @type {!Call} */ (Object.create(Call.prototype));
        return call.replay(this, cache);
    }
}

/**
 * @constructor
 * @param {!Object} wrappedObject
 * @param {string} name
 */
function Resource(wrappedObject, name)
{
    /** @type {number} */
    this._id = ++Resource._uniqueId;
    /** @type {string} */
    this._name = name || "Resource";
    /** @type {number} */
    this._kindId = Resource._uniqueKindIds[this._name] = (Resource._uniqueKindIds[this._name] || 0) + 1;
    /** @type {ResourceTrackingManager} */
    this._resourceManager = null;
    /** @type {!Array.<Call>} */
    this._calls = [];
    /**
     * This is to prevent GC from collecting associated resources.
     * Otherwise, for example in WebGL, subsequent calls to gl.getParameter()
     * may return a recently created instance that is no longer bound to a
     * Resource object (thus, no history to replay it later).
     *
     * @type {!Object.<string, Resource>}
     */
    this._boundResources = Object.create(null);
    this.setWrappedObject(wrappedObject);
}

/**
 * @type {number}
 */
Resource._uniqueId = 0;

/**
 * @type {!Object.<string, number>}
 */
Resource._uniqueKindIds = {};

/**
 * @param {*} obj
 * @return {Resource}
 */
Resource.forObject = function(obj)
{
    if (!obj)
        return null;
    if (obj instanceof Resource)
        return obj;
    if (typeof obj === "object")
        return obj["__resourceObject"];
    return null;
}

/**
 * @param {Resource|*} obj
 * @return {*}
 */
Resource.wrappedObject = function(obj)
{
    var resource = Resource.forObject(obj);
    return resource ? resource.wrappedObject() : obj;
}

/**
 * @param {Resource|*} obj
 * @param {!Cache.<ReplayableResource>} cache
 * @return {ReplayableResource|*}
 */
Resource.toReplayable = function(obj, cache)
{
    var resource = Resource.forObject(obj);
    return resource ? resource.toReplayable(cache) : obj;
}

Resource.prototype = {
    /**
     * @return {number}
     */
    id: function()
    {
        return this._id;
    },

    /**
     * @return {string}
     */
    name: function()
    {
        return this._name;
    },

    /**
     * @return {string}
     */
    description: function()
    {
        return this._name + "@" + this._kindId;
    },

    /**
     * @return {Object}
     */
    wrappedObject: function()
    {
        return this._wrappedObject;
    },

    /**
     * @param {!Object} value
     */
    setWrappedObject: function(value)
    {
        console.assert(value, "wrappedObject should not be NULL");
        console.assert(!(value instanceof Resource), "Binding a Resource object to another Resource object?");
        this._wrappedObject = value;
        this._bindObjectToResource(value);
    },

    /**
     * @return {Object}
     */
    proxyObject: function()
    {
        if (!this._proxyObject)
            this._proxyObject = this._wrapObject();
        return this._proxyObject;
    },

    /**
     * @return {ResourceTrackingManager}
     */
    manager: function()
    {
        return this._resourceManager;
    },

    /**
     * @param {ResourceTrackingManager} value
     */
    setManager: function(value)
    {
        this._resourceManager = value;
    },

    /**
     * @return {!Array.<!Call>}
     */
    calls: function()
    {
        return this._calls;
    },

    /**
     * @return {ContextResource}
     */
    contextResource: function()
    {
        if (this instanceof ContextResource)
            return /** @type {ContextResource} */ (this);

        if (this._calculatingContextResource)
            return null;

        this._calculatingContextResource = true;
        var result = null;
        for (var i = 0, n = this._calls.length; i < n; ++i) {
            result = this._calls[i].resource().contextResource();
            if (result)
                break;
        }
        delete this._calculatingContextResource;
        console.assert(result, "Failed to find context resource for " + this._name + "@" + this._kindId);
        return result;
    },

    /**
     * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
     */
    currentState: function()
    {
        var result = [];
        var proxyObject = this.proxyObject();
        if (!proxyObject)
            return result;
        var statePropertyNames = this._proxyStatePropertyNames || [];
        for (var i = 0, n = statePropertyNames.length; i < n; ++i) {
            var pname = statePropertyNames[i];
            result.push({ name: pname, value: proxyObject[pname] });
        }
        result.push({ name: "context", value: this.contextResource() });
        return result;
    },

    /**
     * @return {string}
     */
    toDataURL: function()
    {
        return "";
    },

    /**
     * @param {!Cache.<ReplayableResource>} cache
     * @return {!ReplayableResource}
     */
    toReplayable: function(cache)
    {
        var result = cache.get(this._id);
        if (result)
            return result;
        var data = {
            id: this._id,
            name: this._name,
            kindId: this._kindId
        };
        result = new ReplayableResource(this, data);
        cache.put(this._id, result); // Put into the cache early to avoid loops.
        data.calls = this._calls.map(function(call) {
            return call.toReplayable(cache);
        });
        this._populateReplayableData(data, cache);
        var contextResource = this.contextResource();
        if (contextResource !== this)
            data.contextResource = Resource.toReplayable(contextResource, cache);
        return result;
    },

    /**
     * @param {!Object} data
     * @param {!Cache.<ReplayableResource>} cache
     */
    _populateReplayableData: function(data, cache)
    {
        // Do nothing. Should be overridden by subclasses.
    },

    /**
     * @param {!Object} data
     * @param {!Cache.<Resource>} cache
     * @return {!Resource}
     */
    replay: function(data, cache)
    {
        var resource = cache.get(data.id);
        if (resource)
            return resource;
        this._id = data.id;
        this._name = data.name;
        this._kindId = data.kindId;
        this._resourceManager = null;
        this._calls = [];
        this._boundResources = Object.create(null);
        this._wrappedObject = null;
        cache.put(data.id, this); // Put into the cache early to avoid loops.
        this._doReplayCalls(data, cache);
        console.assert(this._wrappedObject, "Resource should be reconstructed!");
        return this;
    },

    /**
     * @param {!Object} data
     * @param {!Cache.<Resource>} cache
     */
    _doReplayCalls: function(data, cache)
    {
        for (var i = 0, n = data.calls.length; i < n; ++i)
            this._calls.push(data.calls[i].replay(cache));
    },

    /**
     * @param {!Call} call
     */
    pushCall: function(call)
    {
        call.freeze();
        this._calls.push(call);
    },

    /**
     * @param {!Call} call
     */
    onCallReplayed: function(call)
    {
        // Ignore by default.
    },

    /**
     * @param {!Object} object
     */
    _bindObjectToResource: function(object)
    {
        Object.defineProperty(object, "__resourceObject", {
            value: this,
            writable: false,
            enumerable: false,
            configurable: true
        });
    },

    /**
     * @param {string} key
     * @param {*} obj
     */
    _registerBoundResource: function(key, obj)
    {
        var resource = Resource.forObject(obj);
        if (resource)
            this._boundResources[key] = resource;
        else
            delete this._boundResources[key];
    },

    /**
     * @return {Object}
     */
    _wrapObject: function()
    {
        var wrappedObject = this.wrappedObject();
        if (!wrappedObject)
            return null;
        var proxy = Object.create(wrappedObject.__proto__); // In order to emulate "instanceof".

        var customWrapFunctions = this._customWrapFunctions();
        /** @type {Array.<string>} */
        this._proxyStatePropertyNames = [];

        /**
         * @param {string} property
         */
        function processProperty(property)
        {
            if (typeof wrappedObject[property] === "function") {
                var customWrapFunction = customWrapFunctions[property];
                if (customWrapFunction)
                    proxy[property] = this._wrapCustomFunction(this, wrappedObject, wrappedObject[property], property, customWrapFunction);
                else
                    proxy[property] = this._wrapFunction(this, wrappedObject, wrappedObject[property], property);
            } else if (TypeUtils.isEnumPropertyName(property, wrappedObject)) {
                // Fast access to enums and constants.
                proxy[property] = wrappedObject[property];
            } else {
                this._proxyStatePropertyNames.push(property);
                Object.defineProperty(proxy, property, {
                    get: function()
                    {
                        var obj = wrappedObject[property];
                        var resource = Resource.forObject(obj);
                        return resource ? resource : obj;
                    },
                    set: this._wrapPropertySetter(this, wrappedObject, property),
                    enumerable: true
                });
            }
        }

        var isEmpty = true;
        for (var property in wrappedObject) {
            isEmpty = false;
            processProperty.call(this, property);
        }
        if (isEmpty)
            return wrappedObject; // Nothing to proxy.

        this._bindObjectToResource(proxy);
        return proxy;
    },

    /**
     * @param {!Resource} resource
     * @param {!Object} originalObject
     * @param {!Function} originalFunction
     * @param {string} functionName
     * @param {!Function} customWrapFunction
     * @return {!Function}
     */
    _wrapCustomFunction: function(resource, originalObject, originalFunction, functionName, customWrapFunction)
    {
        return function()
        {
            var manager = resource.manager();
            var isCapturing = manager && manager.capturing();
            if (isCapturing)
                manager.captureArguments(resource, arguments);
            var wrapFunction = new Resource.WrapFunction(originalObject, originalFunction, functionName, arguments);
            customWrapFunction.apply(wrapFunction, arguments);
            if (isCapturing) {
                var call = wrapFunction.call();
                call.setStackTrace(StackTrace.create(1, arguments.callee));
                manager.captureCall(call);
            }
            return wrapFunction.result();
        };
    },

    /**
     * @param {!Resource} resource
     * @param {!Object} originalObject
     * @param {!Function} originalFunction
     * @param {string} functionName
     * @return {!Function}
     */
    _wrapFunction: function(resource, originalObject, originalFunction, functionName)
    {
        return function()
        {
            var manager = resource.manager();
            if (!manager || !manager.capturing())
                return originalFunction.apply(originalObject, arguments);
            manager.captureArguments(resource, arguments);
            var result = originalFunction.apply(originalObject, arguments);
            var stackTrace = StackTrace.create(1, arguments.callee);
            var call = new Call(resource, functionName, arguments, result, stackTrace);
            manager.captureCall(call);
            return result;
        };
    },

    /**
     * @param {!Resource} resource
     * @param {!Object} originalObject
     * @param {string} propertyName
     * @return {function(*)}
     */
    _wrapPropertySetter: function(resource, originalObject, propertyName)
    {
        return function(value)
        {
            resource._registerBoundResource(propertyName, value);
            var manager = resource.manager();
            if (!manager || !manager.capturing()) {
                originalObject[propertyName] = Resource.wrappedObject(value);
                return;
            }
            var args = [propertyName, value];
            manager.captureArguments(resource, args);
            originalObject[propertyName] = Resource.wrappedObject(value);
            var stackTrace = StackTrace.create(1, arguments.callee);
            var call = new Call(resource, "", args, undefined, stackTrace);
            manager.captureCall(call);
        };
    },

    /**
     * @return {!Object.<string, Function>}
     */
    _customWrapFunctions: function()
    {
        return Object.create(null); // May be overridden by subclasses.
    }
}

/**
 * @constructor
 * @param {Object} originalObject
 * @param {Function} originalFunction
 * @param {string} functionName
 * @param {Array|Arguments} args
 */
Resource.WrapFunction = function(originalObject, originalFunction, functionName, args)
{
    this._originalObject = originalObject;
    this._originalFunction = originalFunction;
    this._functionName = functionName;
    this._args = args;
    this._resource = Resource.forObject(originalObject);
    console.assert(this._resource, "Expected a wrapped call on a Resource object.");
}

Resource.WrapFunction.prototype = {
    /**
     * @return {*}
     */
    result: function()
    {
        if (!this._executed) {
            this._executed = true;
            this._result = this._originalFunction.apply(this._originalObject, this._args);
        }
        return this._result;
    },

    /**
     * @return {!Call}
     */
    call: function()
    {
        if (!this._call)
            this._call = new Call(this._resource, this._functionName, this._args, this.result());
        return this._call;
    },

    /**
     * @param {*} result
     */
    overrideResult: function(result)
    {
        var call = this.call();
        call.setResult(result);
        this._result = result;
    }
}

/**
 * @param {function(new:Resource, !Object, string)} resourceConstructor
 * @param {string} resourceName
 * @return {function(this:Resource.WrapFunction)}
 */
Resource.WrapFunction.resourceFactoryMethod = function(resourceConstructor, resourceName)
{
    /** @this Resource.WrapFunction */
    return function()
    {
        var wrappedObject = /** @type {Object} */ (this.result());
        if (!wrappedObject)
            return;
        var resource = new resourceConstructor(wrappedObject, resourceName);
        var manager = this._resource.manager();
        if (manager)
            manager.registerResource(resource);
        this.overrideResult(resource.proxyObject());
        resource.pushCall(this.call());
    }
}

/**
 * @constructor
 * @param {!Resource} originalResource
 * @param {!Object} data
 */
function ReplayableResource(originalResource, data)
{
    this._proto = originalResource.__proto__;
    this._data = data;
}

ReplayableResource.prototype = {
    /**
     * @return {number}
     */
    id: function()
    {
        return this._data.id;
    },

    /**
     * @return {string}
     */
    name: function()
    {
        return this._data.name;
    },

    /**
     * @return {string}
     */
    description: function()
    {
        return this._data.name + "@" + this._data.kindId;
    },

    /**
     * @return {!ReplayableResource}
     */
    contextResource: function()
    {
        return this._data.contextResource || this;
    },

    /**
     * @param {!Cache.<Resource>} cache
     * @return {!Resource}
     */
    replay: function(cache)
    {
        var result = /** @type {!Resource} */ (Object.create(this._proto));
        result = result.replay(this._data, cache)
        console.assert(result.__proto__ === this._proto, "Wrong type of a replay result");
        return result;
    }
}

/**
 * @param {ReplayableResource|*} obj
 * @param {!Cache.<Resource>} cache
 * @return {*}
 */
ReplayableResource.replay = function(obj, cache)
{
    return (obj instanceof ReplayableResource) ? obj.replay(cache).wrappedObject() : obj;
}

/**
 * @constructor
 * @extends {Resource}
 * @param {!Object} wrappedObject
 * @param {string} name
 */
function ContextResource(wrappedObject, name)
{
    Resource.call(this, wrappedObject, name);
}

ContextResource.prototype = {
    __proto__: Resource.prototype
}

/**
 * @constructor
 * @extends {Resource}
 * @param {!Object} wrappedObject
 * @param {string} name
 */
function LogEverythingResource(wrappedObject, name)
{
    Resource.call(this, wrappedObject, name);
}

LogEverythingResource.prototype = {
    /**
     * @override
     * @return {!Object.<string, Function>}
     */
    _customWrapFunctions: function()
    {
        var wrapFunctions = Object.create(null);
        var wrappedObject = this.wrappedObject();
        if (wrappedObject) {
            for (var property in wrappedObject) {
                /** @this Resource.WrapFunction */
                wrapFunctions[property] = function()
                {
                    this._resource.pushCall(this.call());
                }
            }
        }
        return wrapFunctions;
    },

    __proto__: Resource.prototype
}

////////////////////////////////////////////////////////////////////////////////
// WebGL
////////////////////////////////////////////////////////////////////////////////

/**
 * @constructor
 * @extends {Resource}
 * @param {!Object} wrappedObject
 * @param {string} name
 */
function WebGLBoundResource(wrappedObject, name)
{
    Resource.call(this, wrappedObject, name);
    /** @type {!Object.<string, *>} */
    this._state = {};
}

WebGLBoundResource.prototype = {
    /**
     * @override
     * @param {!Object} data
     * @param {!Cache.<ReplayableResource>} cache
     */
    _populateReplayableData: function(data, cache)
    {
        var state = this._state;
        data.state = {};
        Object.keys(state).forEach(function(parameter) {
            data.state[parameter] = Resource.toReplayable(state[parameter], cache);
        });
    },

    /**
     * @override
     * @param {!Object} data
     * @param {!Cache.<Resource>} cache
     */
    _doReplayCalls: function(data, cache)
    {
        var gl = this._replayContextResource(data, cache).wrappedObject();

        /** @type {!Object.<string, Array.<string>>} */
        var bindingsData = {
            TEXTURE_2D: ["bindTexture", "TEXTURE_BINDING_2D"],
            TEXTURE_CUBE_MAP: ["bindTexture", "TEXTURE_BINDING_CUBE_MAP"],
            ARRAY_BUFFER: ["bindBuffer", "ARRAY_BUFFER_BINDING"],
            ELEMENT_ARRAY_BUFFER: ["bindBuffer", "ELEMENT_ARRAY_BUFFER_BINDING"],
            FRAMEBUFFER: ["bindFramebuffer", "FRAMEBUFFER_BINDING"],
            RENDERBUFFER: ["bindRenderbuffer", "RENDERBUFFER_BINDING"]
        };
        var originalBindings = {};
        Object.keys(bindingsData).forEach(function(bindingTarget) {
            var bindingParameter = bindingsData[bindingTarget][1];
            originalBindings[bindingTarget] = gl.getParameter(gl[bindingParameter]);
        });

        var state = {};
        Object.keys(data.state).forEach(function(parameter) {
            state[parameter] = ReplayableResource.replay(data.state[parameter], cache);
        });
        this._state = state;
        Resource.prototype._doReplayCalls.call(this, data, cache);

        Object.keys(bindingsData).forEach(function(bindingTarget) {
            var bindMethodName = bindingsData[bindingTarget][0];
            gl[bindMethodName].call(gl, gl[bindingTarget], originalBindings[bindingTarget]);
        });
    },

    /**
     * @param {!Object} data
     * @param {!Cache.<Resource>} cache
     * @return {WebGLRenderingContextResource}
     */
    _replayContextResource: function(data, cache)
    {
        var calls = /** @type {!Array.<ReplayableCall>} */ (data.calls);
        for (var i = 0, n = calls.length; i < n; ++i) {
            var resource = ReplayableResource.replay(calls[i].replayableResource(), cache);
            var contextResource = WebGLRenderingContextResource.forObject(resource);
            if (contextResource)
                return contextResource;
        }
        return null;
    },

    /**
     * @param {number} target
     * @param {string} bindMethodName
     */
    pushBinding: function(target, bindMethodName)
    {
        if (this._state.bindTarget !== target) {
            this._state.bindTarget = target;
            this.pushCall(new Call(WebGLRenderingContextResource.forObject(this), bindMethodName, [target, this]));
        }
    },

    __proto__: Resource.prototype
}

/**
 * @constructor
 * @extends {WebGLBoundResource}
 * @param {!Object} wrappedObject
 * @param {string} name
 */
function WebGLTextureResource(wrappedObject, name)
{
    WebGLBoundResource.call(this, wrappedObject, name);
}

WebGLTextureResource.prototype = {
    /**
     * @override (overrides @return type)
     * @return {WebGLTexture}
     */
    wrappedObject: function()
    {
        return this._wrappedObject;
    },

    /**
     * @override
     * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
     */
    currentState: function()
    {
        var result = [];
        var glResource = WebGLRenderingContextResource.forObject(this);
        var gl = glResource.wrappedObject();
        var texture = this.wrappedObject();
        if (!gl || !texture)
            return result;
        result.push({ name: "isTexture", value: gl.isTexture(texture) });
        result.push({ name: "context", value: this.contextResource() });

        var target = this._state.bindTarget;
        if (typeof target !== "number")
            return result;

        var bindingParameter;
        switch (target) {
        case gl.TEXTURE_2D:
            bindingParameter = gl.TEXTURE_BINDING_2D;
            break;
        case gl.TEXTURE_CUBE_MAP:
            bindingParameter = gl.TEXTURE_BINDING_CUBE_MAP;
            break;
        default:
            console.error("ASSERT_NOT_REACHED: unknown texture target " + target);
            return result;
        }
        result.push({ name: "target", value: target, valueIsEnum: true });

        var oldTexture = /** @type {WebGLTexture} */ (gl.getParameter(bindingParameter));
        if (oldTexture !== texture)
            gl.bindTexture(target, texture);

        var textureParameters = [
            "TEXTURE_MAG_FILTER",
            "TEXTURE_MIN_FILTER",
            "TEXTURE_WRAP_S",
            "TEXTURE_WRAP_T",
            "TEXTURE_MAX_ANISOTROPY_EXT" // EXT_texture_filter_anisotropic extension
        ];
        glResource.queryStateValues(gl.getTexParameter, target, textureParameters, result);

        if (oldTexture !== texture)
            gl.bindTexture(target, oldTexture);
        return result;
    },

    /**
     * @override
     * @param {!Object} data
     * @param {!Cache.<Resource>} cache
     */
    _doReplayCalls: function(data, cache)
    {
        var gl = this._replayContextResource(data, cache).wrappedObject();

        var state = {};
        WebGLRenderingContextResource.PixelStoreParameters.forEach(function(parameter) {
            state[parameter] = gl.getParameter(gl[parameter]);
        });

        WebGLBoundResource.prototype._doReplayCalls.call(this, data, cache);

        WebGLRenderingContextResource.PixelStoreParameters.forEach(function(parameter) {
            gl.pixelStorei(gl[parameter], state[parameter]);
        });
    },

    /**
     * @override
     * @param {!Call} call
     */
    pushCall: function(call)
    {
        var gl = WebGLRenderingContextResource.forObject(call.resource()).wrappedObject();
        WebGLRenderingContextResource.PixelStoreParameters.forEach(function(parameter) {
            var value = gl.getParameter(gl[parameter]);
            if (this._state[parameter] !== value) {
                this._state[parameter] = value;
                var pixelStoreCall = new Call(gl, "pixelStorei", [gl[parameter], value]);
                WebGLBoundResource.prototype.pushCall.call(this, pixelStoreCall);
            }
        }, this);

        // FIXME: remove any older calls that no longer contribute to the resource state.
        // FIXME: optimize memory usage: maybe it's more efficient to store one texImage2D call instead of many texSubImage2D.
        WebGLBoundResource.prototype.pushCall.call(this, call);
    },

    /**
     * Handles: texParameteri, texParameterf
     * @param {!Call} call
     */
    pushCall_texParameter: function(call)
    {
        var args = call.args();
        var pname = args[1];
        var param = args[2];
        if (this._state[pname] !== param) {
            this._state[pname] = param;
            WebGLBoundResource.prototype.pushCall.call(this, call);
        }
    },

    /**
     * Handles: copyTexImage2D, copyTexSubImage2D
     * copyTexImage2D and copyTexSubImage2D define a texture image with pixels from the current framebuffer.
     * @param {!Call} call
     */
    pushCall_copyTexImage2D: function(call)
    {
        var glResource = WebGLRenderingContextResource.forObject(call.resource());
        var gl = glResource.wrappedObject();
        var framebufferResource = /** @type {WebGLFramebufferResource} */ (glResource.currentBinding(gl.FRAMEBUFFER));
        if (framebufferResource)
            this.pushCall(new Call(glResource, "bindFramebuffer", [gl.FRAMEBUFFER, framebufferResource]));
        else {
            // FIXME: Implement this case.
            console.error("ASSERT_NOT_REACHED: Could not properly process a gl." + call.functionName() + " call while the DRAWING BUFFER is bound.");
        }
        this.pushCall(call);
    },

    __proto__: WebGLBoundResource.prototype
}

/**
 * @constructor
 * @extends {Resource}
 * @param {!Object} wrappedObject
 * @param {string} name
 */
function WebGLProgramResource(wrappedObject, name)
{
    Resource.call(this, wrappedObject, name);
}

WebGLProgramResource.prototype = {
    /**
     * @override (overrides @return type)
     * @return {WebGLProgram}
     */
    wrappedObject: function()
    {
        return this._wrappedObject;
    },

    /**
     * @override
     * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
     */
    currentState: function()
    {
        /**
         * @param {!Object} obj
         * @param {!Array.<TypeUtils.InternalResourceStateDescriptor>} output
         */
        function convertToStateDescriptors(obj, output)
        {
            for (var pname in obj)
                output.push({ name: pname, value: obj[pname], valueIsEnum: (pname === "type") });
        }

        var result = [];
        var program = this.wrappedObject();
        if (!program)
            return result;
        var glResource = WebGLRenderingContextResource.forObject(this);
        var gl = glResource.wrappedObject();
        var programParameters = ["DELETE_STATUS", "LINK_STATUS", "VALIDATE_STATUS"];
        glResource.queryStateValues(gl.getProgramParameter, program, programParameters, result);
        result.push({ name: "getProgramInfoLog", value: gl.getProgramInfoLog(program) });
        result.push({ name: "isProgram", value: gl.isProgram(program) });
        result.push({ name: "context", value: this.contextResource() });

        // ATTACHED_SHADERS
        var callFormatter = CallFormatter.forResource(this);
        var shaders = gl.getAttachedShaders(program) || [];
        var shaderDescriptors = [];
        for (var i = 0, n = shaders.length; i < n; ++i) {
            var shaderResource = Resource.forObject(shaders[i]);
            var pname = callFormatter.enumNameForValue(shaderResource.type());
            shaderDescriptors.push({ name: pname, value: shaderResource });
        }
        result.push({ name: "ATTACHED_SHADERS", values: shaderDescriptors, isArray: true });

        // ACTIVE_UNIFORMS
        var uniformDescriptors = [];
        var uniforms = this._activeUniforms(true);
        for (var i = 0, n = uniforms.length; i < n; ++i) {
            var pname = "" + i;
            var values = [];
            convertToStateDescriptors(uniforms[i], values);
            uniformDescriptors.push({ name: pname, values: values });
        }
        result.push({ name: "ACTIVE_UNIFORMS", values: uniformDescriptors, isArray: true });

        // ACTIVE_ATTRIBUTES
        var attributesCount = /** @type {number} */ (gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES));
        var attributeDescriptors = [];
        for (var i = 0; i < attributesCount; ++i) {
            var activeInfo = gl.getActiveAttrib(program, i);
            if (!activeInfo)
                continue;
            var pname = "" + i;
            var values = [];
            convertToStateDescriptors(activeInfo, values);
            attributeDescriptors.push({ name: pname, values: values });
        }
        result.push({ name: "ACTIVE_ATTRIBUTES", values: attributeDescriptors, isArray: true });

        return result;
    },

    /**
     * @param {boolean=} includeAllInfo
     * @return {!Array.<{name:string, type:number, value:*, size:(number|undefined)}>}
     */
    _activeUniforms: function(includeAllInfo)
    {
        var uniforms = [];
        var program = this.wrappedObject();
        if (!program)
            return uniforms;

        var gl = WebGLRenderingContextResource.forObject(this).wrappedObject();
        var uniformsCount = /** @type {number} */ (gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS));
        for (var i = 0; i < uniformsCount; ++i) {
            var activeInfo = gl.getActiveUniform(program, i);
            if (!activeInfo)
                continue;
            var uniformLocation = gl.getUniformLocation(program, activeInfo.name);
            if (!uniformLocation)
                continue;
            var value = gl.getUniform(program, uniformLocation);
            var item = Object.create(null);
            item.name = activeInfo.name;
            item.type = activeInfo.type;
            item.value = value;
            if (includeAllInfo)
                item.size = activeInfo.size;
            uniforms.push(item);
        }
        return uniforms;
    },

    /**
     * @override
     * @param {!Object} data
     * @param {!Cache.<ReplayableResource>} cache
     */
    _populateReplayableData: function(data, cache)
    {
        var glResource = WebGLRenderingContextResource.forObject(this);
        var originalErrors = glResource.getAllErrors();
        data.uniforms = this._activeUniforms();
        glResource.restoreErrors(originalErrors);
    },

    /**
     * @override
     * @param {!Object} data
     * @param {!Cache.<Resource>} cache
     */
    _doReplayCalls: function(data, cache)
    {
        Resource.prototype._doReplayCalls.call(this, data, cache);
        var gl = WebGLRenderingContextResource.forObject(this).wrappedObject();
        var program = this.wrappedObject();

        var originalProgram = /** @type {WebGLProgram} */ (gl.getParameter(gl.CURRENT_PROGRAM));
        var currentProgram = originalProgram;
        
        data.uniforms.forEach(function(uniform) {
            var uniformLocation = gl.getUniformLocation(program, uniform.name);
            if (!uniformLocation)
                return;
            if (currentProgram !== program) {
                currentProgram = program;
                gl.useProgram(program);
            }
            var methodName = this._uniformMethodNameByType(gl, uniform.type);
            if (methodName.indexOf("Matrix") === -1)
                gl[methodName].call(gl, uniformLocation, uniform.value);
            else
                gl[methodName].call(gl, uniformLocation, false, uniform.value);
        }.bind(this));

        if (currentProgram !== originalProgram)
            gl.useProgram(originalProgram);
    },

    /**
     * @param {WebGLRenderingContext} gl
     * @param {number} type
     * @return {string}
     */
    _uniformMethodNameByType: function(gl, type)
    {
        var uniformMethodNames = WebGLProgramResource._uniformMethodNames;
        if (!uniformMethodNames) {
            uniformMethodNames = {};
            uniformMethodNames[gl.FLOAT] = "uniform1f";
            uniformMethodNames[gl.FLOAT_VEC2] = "uniform2fv";
            uniformMethodNames[gl.FLOAT_VEC3] = "uniform3fv";
            uniformMethodNames[gl.FLOAT_VEC4] = "uniform4fv";
            uniformMethodNames[gl.INT] = "uniform1i";
            uniformMethodNames[gl.BOOL] = "uniform1i";
            uniformMethodNames[gl.SAMPLER_2D] = "uniform1i";
            uniformMethodNames[gl.SAMPLER_CUBE] = "uniform1i";
            uniformMethodNames[gl.INT_VEC2] = "uniform2iv";
            uniformMethodNames[gl.BOOL_VEC2] = "uniform2iv";
            uniformMethodNames[gl.INT_VEC3] = "uniform3iv";
            uniformMethodNames[gl.BOOL_VEC3] = "uniform3iv";
            uniformMethodNames[gl.INT_VEC4] = "uniform4iv";
            uniformMethodNames[gl.BOOL_VEC4] = "uniform4iv";
            uniformMethodNames[gl.FLOAT_MAT2] = "uniformMatrix2fv";
            uniformMethodNames[gl.FLOAT_MAT3] = "uniformMatrix3fv";
            uniformMethodNames[gl.FLOAT_MAT4] = "uniformMatrix4fv";
            WebGLProgramResource._uniformMethodNames = uniformMethodNames;
        }
        console.assert(uniformMethodNames[type], "Unknown uniform type " + type);
        return uniformMethodNames[type];
    },

    /**
     * @override
     * @param {!Call} call
     */
    pushCall: function(call)
    {
        // FIXME: remove any older calls that no longer contribute to the resource state.
        // FIXME: handle multiple attachShader && detachShader.
        Resource.prototype.pushCall.call(this, call);
    },

    __proto__: Resource.prototype
}

/**
 * @constructor
 * @extends {Resource}
 * @param {!Object} wrappedObject
 * @param {string} name
 */
function WebGLShaderResource(wrappedObject, name)
{
    Resource.call(this, wrappedObject, name);
}

WebGLShaderResource.prototype = {
    /**
     * @override (overrides @return type)
     * @return {WebGLShader}
     */
    wrappedObject: function()
    {
        return this._wrappedObject;
    },

    /**
     * @return {number}
     */
    type: function()
    {
        var call = this._calls[0];
        if (call && call.functionName() === "createShader")
            return call.args()[0];
        console.error("ASSERT_NOT_REACHED: Failed to restore shader type from the log.", call);
        return 0;
    },

    /**
     * @override
     * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
     */
    currentState: function()
    {
        var result = [];
        var shader = this.wrappedObject();
        if (!shader)
            return result;
        var glResource = WebGLRenderingContextResource.forObject(this);
        var gl = glResource.wrappedObject();
        var shaderParameters = ["SHADER_TYPE", "DELETE_STATUS", "COMPILE_STATUS"];
        glResource.queryStateValues(gl.getShaderParameter, shader, shaderParameters, result);
        result.push({ name: "getShaderInfoLog", value: gl.getShaderInfoLog(shader) });
        result.push({ name: "getShaderSource", value: gl.getShaderSource(shader) });
        result.push({ name: "isShader", value: gl.isShader(shader) });
        result.push({ name: "context", value: this.contextResource() });

        // getShaderPrecisionFormat
        var shaderType = this.type();
        var precisionValues = [];
        var precisionParameters = ["LOW_FLOAT", "MEDIUM_FLOAT", "HIGH_FLOAT", "LOW_INT", "MEDIUM_INT", "HIGH_INT"];
        for (var i = 0, pname; pname = precisionParameters[i]; ++i)
            precisionValues.push({ name: pname, value: gl.getShaderPrecisionFormat(shaderType, gl[pname]) });
        result.push({ name: "getShaderPrecisionFormat", values: precisionValues });

        return result;
    },

    /**
     * @override
     * @param {!Call} call
     */
    pushCall: function(call)
    {
        // FIXME: remove any older calls that no longer contribute to the resource state.
        // FIXME: handle multiple shaderSource calls.
        Resource.prototype.pushCall.call(this, call);
    },

    __proto__: Resource.prototype
}

/**
 * @constructor
 * @extends {WebGLBoundResource}
 * @param {!Object} wrappedObject
 * @param {string} name
 */
function WebGLBufferResource(wrappedObject, name)
{
    WebGLBoundResource.call(this, wrappedObject, name);
}

WebGLBufferResource.prototype = {
    /**
     * @override (overrides @return type)
     * @return {WebGLBuffer}
     */
    wrappedObject: function()
    {
        return this._wrappedObject;
    },

    /**
     * @override
     * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
     */
    currentState: function()
    {
        var result = [];
        var glResource = WebGLRenderingContextResource.forObject(this);
        var gl = glResource.wrappedObject();
        var buffer = this.wrappedObject();
        if (!gl || !buffer)
            return result;
        result.push({ name: "isBuffer", value: gl.isBuffer(buffer) });
        result.push({ name: "context", value: this.contextResource() });

        var target = this._state.bindTarget;
        if (typeof target !== "number")
            return result;

        var bindingParameter;
        switch (target) {
        case gl.ARRAY_BUFFER:
            bindingParameter = gl.ARRAY_BUFFER_BINDING;
            break;
        case gl.ELEMENT_ARRAY_BUFFER:
            bindingParameter = gl.ELEMENT_ARRAY_BUFFER_BINDING;
            break;
        default:
            console.error("ASSERT_NOT_REACHED: unknown buffer target " + target);
            return result;
        }
        result.push({ name: "target", value: target, valueIsEnum: true });

        var oldBuffer = /** @type {WebGLBuffer} */ (gl.getParameter(bindingParameter));
        if (oldBuffer !== buffer)
            gl.bindBuffer(target, buffer);

        var bufferParameters = ["BUFFER_SIZE", "BUFFER_USAGE"];
        glResource.queryStateValues(gl.getBufferParameter, target, bufferParameters, result);

        if (oldBuffer !== buffer)
            gl.bindBuffer(target, oldBuffer);
        return result;
    },

    /**
     * @override
     * @param {!Call} call
     */
    pushCall: function(call)
    {
        // FIXME: remove any older calls that no longer contribute to the resource state.
        // FIXME: Optimize memory for bufferSubData.
        WebGLBoundResource.prototype.pushCall.call(this, call);
    },

    __proto__: WebGLBoundResource.prototype
}

/**
 * @constructor
 * @extends {WebGLBoundResource}
 * @param {!Object} wrappedObject
 * @param {string} name
 */
function WebGLFramebufferResource(wrappedObject, name)
{
    WebGLBoundResource.call(this, wrappedObject, name);
}

WebGLFramebufferResource.prototype = {
    /**
     * @override (overrides @return type)
     * @return {WebGLFramebuffer}
     */
    wrappedObject: function()
    {
        return this._wrappedObject;
    },

    /**
     * @override
     * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
     */
    currentState: function()
    {
        var result = [];
        var framebuffer = this.wrappedObject();
        if (!framebuffer)
            return result;
        var gl = WebGLRenderingContextResource.forObject(this).wrappedObject();

        var oldFramebuffer = /** @type {WebGLFramebuffer} */ (gl.getParameter(gl.FRAMEBUFFER_BINDING));
        if (oldFramebuffer !== framebuffer)
            gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);

        var attachmentParameters = ["COLOR_ATTACHMENT0", "DEPTH_ATTACHMENT", "STENCIL_ATTACHMENT"];
        var framebufferParameters = ["FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE", "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME", "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL", "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE"];
        for (var i = 0, attachment; attachment = attachmentParameters[i]; ++i) {
            var values = [];
            for (var j = 0, pname; pname = framebufferParameters[j]; ++j) {
                var value = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl[attachment], gl[pname]);
                value = Resource.forObject(value) || value;
                values.push({ name: pname, value: value, valueIsEnum: WebGLRenderingContextResource.GetResultIsEnum[pname] });
            }
            result.push({ name: attachment, values: values });
        }
        result.push({ name: "isFramebuffer", value: gl.isFramebuffer(framebuffer) });
        result.push({ name: "context", value: this.contextResource() });

        if (oldFramebuffer !== framebuffer)
            gl.bindFramebuffer(gl.FRAMEBUFFER, oldFramebuffer);
        return result;
    },

    /**
     * @override
     * @param {!Call} call
     */
    pushCall: function(call)
    {
        // FIXME: remove any older calls that no longer contribute to the resource state.
        WebGLBoundResource.prototype.pushCall.call(this, call);
    },

    __proto__: WebGLBoundResource.prototype
}

/**
 * @constructor
 * @extends {WebGLBoundResource}
 * @param {!Object} wrappedObject
 * @param {string} name
 */
function WebGLRenderbufferResource(wrappedObject, name)
{
    WebGLBoundResource.call(this, wrappedObject, name);
}

WebGLRenderbufferResource.prototype = {
    /**
     * @override (overrides @return type)
     * @return {WebGLRenderbuffer}
     */
    wrappedObject: function()
    {
        return this._wrappedObject;
    },

    /**
     * @override
     * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
     */
    currentState: function()
    {
        var result = [];
        var renderbuffer = this.wrappedObject();
        if (!renderbuffer)
            return result;
        var glResource = WebGLRenderingContextResource.forObject(this);
        var gl = glResource.wrappedObject();

        var oldRenderbuffer = /** @type {WebGLRenderbuffer} */ (gl.getParameter(gl.RENDERBUFFER_BINDING));
        if (oldRenderbuffer !== renderbuffer)
            gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);

        var renderbufferParameters = ["RENDERBUFFER_WIDTH", "RENDERBUFFER_HEIGHT", "RENDERBUFFER_INTERNAL_FORMAT", "RENDERBUFFER_RED_SIZE", "RENDERBUFFER_GREEN_SIZE", "RENDERBUFFER_BLUE_SIZE", "RENDERBUFFER_ALPHA_SIZE", "RENDERBUFFER_DEPTH_SIZE", "RENDERBUFFER_STENCIL_SIZE"];
        glResource.queryStateValues(gl.getRenderbufferParameter, gl.RENDERBUFFER, renderbufferParameters, result);
        result.push({ name: "isRenderbuffer", value: gl.isRenderbuffer(renderbuffer) });
        result.push({ name: "context", value: this.contextResource() });

        if (oldRenderbuffer !== renderbuffer)
            gl.bindRenderbuffer(gl.RENDERBUFFER, oldRenderbuffer);
        return result;
    },

    /**
     * @override
     * @param {!Call} call
     */
    pushCall: function(call)
    {
        // FIXME: remove any older calls that no longer contribute to the resource state.
        WebGLBoundResource.prototype.pushCall.call(this, call);
    },

    __proto__: WebGLBoundResource.prototype
}

/**
 * @constructor
 * @extends {Resource}
 * @param {!Object} wrappedObject
 * @param {string} name
 */
function WebGLUniformLocationResource(wrappedObject, name)
{
    Resource.call(this, wrappedObject, name);
}

WebGLUniformLocationResource.prototype = {
    /**
     * @override (overrides @return type)
     * @return {WebGLUniformLocation}
     */
    wrappedObject: function()
    {
        return this._wrappedObject;
    },

    /**
     * @return {WebGLProgramResource}
     */
    program: function()
    {
        var call = this._calls[0];
        if (call && call.functionName() === "getUniformLocation")
            return /** @type {WebGLProgramResource} */ (Resource.forObject(call.args()[0]));
        console.error("ASSERT_NOT_REACHED: Failed to restore WebGLUniformLocation from the log.", call);
        return null;
    },

    /**
     * @return {string}
     */
    name: function()
    {
        var call = this._calls[0];
        if (call && call.functionName() === "getUniformLocation")
            return call.args()[1];
        console.error("ASSERT_NOT_REACHED: Failed to restore WebGLUniformLocation from the log.", call);
        return "";
    },

    /**
     * @override
     * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
     */
    currentState: function()
    {
        var result = [];
        var location = this.wrappedObject();
        if (!location)
            return result;
        var programResource = this.program();
        var program = programResource && programResource.wrappedObject();
        if (!program)
            return result;
        var gl = WebGLRenderingContextResource.forObject(this).wrappedObject();
        var uniformValue = gl.getUniform(program, location);
        var name = this.name();
        result.push({ name: "name", value: name });
        result.push({ name: "program", value: programResource });
        result.push({ name: "value", value: uniformValue });
        result.push({ name: "context", value: this.contextResource() });

        if (typeof this._type !== "number") {
            var altName = name + "[0]";
            var uniformsCount = /** @type {number} */ (gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS));
            for (var i = 0; i < uniformsCount; ++i) {
                var activeInfo = gl.getActiveUniform(program, i);
                if (!activeInfo)
                    continue;
                if (activeInfo.name === name || activeInfo.name === altName) {
                    this._type = activeInfo.type;
                    this._size = activeInfo.size;
                    if (activeInfo.name === name)
                        break;
                }
            }
        }
        if (typeof this._type === "number")
            result.push({ name: "type", value: this._type, valueIsEnum: true });
        if (typeof this._size === "number")
            result.push({ name: "size", value: this._size });

        return result;
    },

    /**
     * @override
     * @param {!Object} data
     * @param {!Cache.<ReplayableResource>} cache
     */
    _populateReplayableData: function(data, cache)
    {
        data.type = this._type;
        data.size = this._size;
    },

    /**
     * @override
     * @param {!Object} data
     * @param {!Cache.<Resource>} cache
     */
    _doReplayCalls: function(data, cache)
    {
        this._type = data.type;
        this._size = data.size;
        Resource.prototype._doReplayCalls.call(this, data, cache);
    },

    __proto__: Resource.prototype
}

/**
 * @constructor
 * @extends {ContextResource}
 * @param {!WebGLRenderingContext} glContext
 */
function WebGLRenderingContextResource(glContext)
{
    ContextResource.call(this, glContext, "WebGLRenderingContext");
    /** @type {Object.<number, boolean>} */
    this._customErrors = null;
    /** @type {!Object.<string, string>} */
    this._extensions = {};
    /** @type {!Object.<string, number>} */
    this._extensionEnums = {};
}

/**
 * @const
 * @type {!Array.<string>}
 */
WebGLRenderingContextResource.GLCapabilities = [
    "BLEND",
    "CULL_FACE",
    "DEPTH_TEST",
    "DITHER",
    "POLYGON_OFFSET_FILL",
    "SAMPLE_ALPHA_TO_COVERAGE",
    "SAMPLE_COVERAGE",
    "SCISSOR_TEST",
    "STENCIL_TEST"
];

/**
 * @const
 * @type {!Array.<string>}
 */
WebGLRenderingContextResource.PixelStoreParameters = [
    "PACK_ALIGNMENT",
    "UNPACK_ALIGNMENT",
    "UNPACK_COLORSPACE_CONVERSION_WEBGL",
    "UNPACK_FLIP_Y_WEBGL",
    "UNPACK_PREMULTIPLY_ALPHA_WEBGL"
];

/**
 * @const
 * @type {!Array.<string>}
 */
WebGLRenderingContextResource.StateParameters = [
    "ACTIVE_TEXTURE",
    "ARRAY_BUFFER_BINDING",
    "BLEND_COLOR",
    "BLEND_DST_ALPHA",
    "BLEND_DST_RGB",
    "BLEND_EQUATION_ALPHA",
    "BLEND_EQUATION_RGB",
    "BLEND_SRC_ALPHA",
    "BLEND_SRC_RGB",
    "COLOR_CLEAR_VALUE",
    "COLOR_WRITEMASK",
    "CULL_FACE_MODE",
    "CURRENT_PROGRAM",
    "DEPTH_CLEAR_VALUE",
    "DEPTH_FUNC",
    "DEPTH_RANGE",
    "DEPTH_WRITEMASK",
    "ELEMENT_ARRAY_BUFFER_BINDING",
    "FRAGMENT_SHADER_DERIVATIVE_HINT_OES", // OES_standard_derivatives extension
    "FRAMEBUFFER_BINDING",
    "FRONT_FACE",
    "GENERATE_MIPMAP_HINT",
    "LINE_WIDTH",
    "PACK_ALIGNMENT",
    "POLYGON_OFFSET_FACTOR",
    "POLYGON_OFFSET_UNITS",
    "RENDERBUFFER_BINDING",
    "SAMPLE_COVERAGE_INVERT",
    "SAMPLE_COVERAGE_VALUE",
    "SCISSOR_BOX",
    "STENCIL_BACK_FAIL",
    "STENCIL_BACK_FUNC",
    "STENCIL_BACK_PASS_DEPTH_FAIL",
    "STENCIL_BACK_PASS_DEPTH_PASS",
    "STENCIL_BACK_REF",
    "STENCIL_BACK_VALUE_MASK",
    "STENCIL_BACK_WRITEMASK",
    "STENCIL_CLEAR_VALUE",
    "STENCIL_FAIL",
    "STENCIL_FUNC",
    "STENCIL_PASS_DEPTH_FAIL",
    "STENCIL_PASS_DEPTH_PASS",
    "STENCIL_REF",
    "STENCIL_VALUE_MASK",
    "STENCIL_WRITEMASK",
    "UNPACK_ALIGNMENT",
    "UNPACK_COLORSPACE_CONVERSION_WEBGL",
    "UNPACK_FLIP_Y_WEBGL",
    "UNPACK_PREMULTIPLY_ALPHA_WEBGL",
    "VERTEX_ARRAY_BINDING_OES", // OES_vertex_array_object extension
    "VIEWPORT"
];

/**
 * True for those enums that return also an enum via a getter API method (e.g. getParameter, getShaderParameter, etc.).
 * @const
 * @type {!Object.<string, boolean>}
 */
WebGLRenderingContextResource.GetResultIsEnum = TypeUtils.createPrefixedPropertyNamesSet([
    // gl.getParameter()
    "ACTIVE_TEXTURE",
    "BLEND_DST_ALPHA",
    "BLEND_DST_RGB",
    "BLEND_EQUATION_ALPHA",
    "BLEND_EQUATION_RGB",
    "BLEND_SRC_ALPHA",
    "BLEND_SRC_RGB",
    "CULL_FACE_MODE",
    "DEPTH_FUNC",
    "FRONT_FACE",
    "GENERATE_MIPMAP_HINT",
    "FRAGMENT_SHADER_DERIVATIVE_HINT_OES",
    "STENCIL_BACK_FAIL",
    "STENCIL_BACK_FUNC",
    "STENCIL_BACK_PASS_DEPTH_FAIL",
    "STENCIL_BACK_PASS_DEPTH_PASS",
    "STENCIL_FAIL",
    "STENCIL_FUNC",
    "STENCIL_PASS_DEPTH_FAIL",
    "STENCIL_PASS_DEPTH_PASS",
    "UNPACK_COLORSPACE_CONVERSION_WEBGL",
    // gl.getBufferParameter()
    "BUFFER_USAGE",
    // gl.getFramebufferAttachmentParameter()
    "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",
    // gl.getRenderbufferParameter()
    "RENDERBUFFER_INTERNAL_FORMAT",
    // gl.getTexParameter()
    "TEXTURE_MAG_FILTER",
    "TEXTURE_MIN_FILTER",
    "TEXTURE_WRAP_S",
    "TEXTURE_WRAP_T",
    // gl.getShaderParameter()
    "SHADER_TYPE",
    // gl.getVertexAttrib()
    "VERTEX_ATTRIB_ARRAY_TYPE"
]);

/**
 * @const
 * @type {!Object.<string, boolean>}
 */
WebGLRenderingContextResource.DrawingMethods = TypeUtils.createPrefixedPropertyNamesSet([
    "clear",
    "drawArrays",
    "drawElements"
]);

/**
 * @param {*} obj
 * @return {WebGLRenderingContextResource}
 */
WebGLRenderingContextResource.forObject = function(obj)
{
    var resource = Resource.forObject(obj);
    if (!resource)
        return null;
    resource = resource.contextResource();
    return (resource instanceof WebGLRenderingContextResource) ? resource : null;
}

WebGLRenderingContextResource.prototype = {
    /**
     * @override (overrides @return type)
     * @return {WebGLRenderingContext}
     */
    wrappedObject: function()
    {
        return this._wrappedObject;
    },

    /**
     * @override
     * @return {string}
     */
    toDataURL: function()
    {
        return this.wrappedObject().canvas.toDataURL();
    },

    /**
     * @return {Array.<number>}
     */
    getAllErrors: function()
    {
        var errors = [];
        var gl = this.wrappedObject();
        if (gl) {
            while (true) {
                var error = gl.getError();
                if (error === gl.NO_ERROR)
                    break;
                this.clearError(error);
                errors.push(error);
            }
        }
        if (this._customErrors) {
            for (var key in this._customErrors) {
                var error = Number(key);
                errors.push(error);
            }
            delete this._customErrors;
        }
        return errors;
    },

    /**
     * @param {Array.<number>} errors
     */
    restoreErrors: function(errors)
    {
        var gl = this.wrappedObject();
        if (gl) {
            var wasError = false;
            while (gl.getError() !== gl.NO_ERROR)
                wasError = true;
            console.assert(!wasError, "Error(s) while capturing current WebGL state.");
        }
        if (!errors.length)
            delete this._customErrors;
        else {
            this._customErrors = {};
            for (var i = 0, n = errors.length; i < n; ++i)
                this._customErrors[errors[i]] = true;
        }
    },

    /**
     * @param {number} error
     */
    clearError: function(error)
    {
        if (this._customErrors)
            delete this._customErrors[error];
    },

    /**
     * @return {number}
     */
    nextError: function()
    {
        if (this._customErrors) {
            for (var key in this._customErrors) {
                var error = Number(key);
                delete this._customErrors[error];
                return error;
            }
        }
        delete this._customErrors;
        var gl = this.wrappedObject();
        return gl ? gl.NO_ERROR : 0;
    },

    /**
     * @param {string} name
     * @param {Object} obj
     */
    registerWebGLExtension: function(name, obj)
    {
        // FIXME: Wrap OES_vertex_array_object extension.
        var lowerName = name.toLowerCase();
        if (obj && !this._extensions[lowerName]) {
            this._extensions[lowerName] = name;
            for (var property in obj) {
                if (TypeUtils.isEnumPropertyName(property, obj))
                    this._extensionEnums[property] = /** @type {number} */ (obj[property]);
            }
        }
    },

    /**
     * @param {string} name
     * @return {number|undefined}
     */
    _enumValueForName: function(name)
    {
        if (typeof this._extensionEnums[name] === "number")
            return this._extensionEnums[name];
        var gl = this.wrappedObject();
        return (typeof gl[name] === "number" ? gl[name] : undefined);
    },

    /**
     * @param {function(this:WebGLRenderingContext, T, number):*} func
     * @param {T} targetOrWebGLObject
     * @param {!Array.<string>} pnames
     * @param {!Array.<TypeUtils.InternalResourceStateDescriptor>} output
     * @template T
     */
    queryStateValues: function(func, targetOrWebGLObject, pnames, output)
    {
        var gl = this.wrappedObject();
        for (var i = 0, pname; pname = pnames[i]; ++i) {
            var enumValue = this._enumValueForName(pname);
            if (typeof enumValue !== "number")
                continue;
            var value = func.call(gl, targetOrWebGLObject, enumValue);
            value = Resource.forObject(value) || value;
            output.push({ name: pname, value: value, valueIsEnum: WebGLRenderingContextResource.GetResultIsEnum[pname] });
        }
    },

    /**
     * @override
     * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
     */
    currentState: function()
    {
        /**
         * @param {!Object} obj
         * @param {!Array.<TypeUtils.InternalResourceStateDescriptor>} output
         */
        function convertToStateDescriptors(obj, output)
        {
            for (var pname in obj)
                output.push({ name: pname, value: obj[pname], valueIsEnum: WebGLRenderingContextResource.GetResultIsEnum[pname] });
        }

        var gl = this.wrappedObject();
        var glState = this._internalCurrentState(null);

        // VERTEX_ATTRIB_ARRAYS
        var vertexAttribStates = [];
        for (var i = 0, n = glState.VERTEX_ATTRIB_ARRAYS.length; i < n; ++i) {
            var pname = "" + i;
            var values = [];
            convertToStateDescriptors(glState.VERTEX_ATTRIB_ARRAYS[i], values);
            vertexAttribStates.push({ name: pname, values: values });
        }
        delete glState.VERTEX_ATTRIB_ARRAYS;

        // TEXTURE_UNITS
        var textureUnits = [];
        for (var i = 0, n = glState.TEXTURE_UNITS.length; i < n; ++i) {
            var pname = "TEXTURE" + i;
            var values = [];
            convertToStateDescriptors(glState.TEXTURE_UNITS[i], values);
            textureUnits.push({ name: pname, values: values });
        }
        delete glState.TEXTURE_UNITS;

        var result = [];
        convertToStateDescriptors(glState, result);
        result.push({ name: "VERTEX_ATTRIB_ARRAYS", values: vertexAttribStates, isArray: true });
        result.push({ name: "TEXTURE_UNITS", values: textureUnits, isArray: true });

        var textureBindingParameters = ["TEXTURE_BINDING_2D", "TEXTURE_BINDING_CUBE_MAP"];
        for (var i = 0, pname; pname = textureBindingParameters[i]; ++i) {
            var value = gl.getParameter(gl[pname]);
            value = Resource.forObject(value) || value;
            result.push({ name: pname, value: value });
        }

        // ENABLED_EXTENSIONS
        var enabledExtensions = [];
        for (var lowerName in this._extensions) {
            var pname = this._extensions[lowerName];
            var value = gl.getExtension(pname);
            value = Resource.forObject(value) || value;
            enabledExtensions.push({ name: pname, value: value });
        }
        result.push({ name: "ENABLED_EXTENSIONS", values: enabledExtensions, isArray: true });

        return result;
    },

    /**
     * @param {?Cache.<ReplayableResource>} cache
     * @return {!Object.<string, *>}
     */
    _internalCurrentState: function(cache)
    {
        /**
         * @param {Resource|*} obj
         * @return {Resource|ReplayableResource|*}
         */
        function maybeToReplayable(obj)
        {
            return cache ? Resource.toReplayable(obj, cache) : (Resource.forObject(obj) || obj);
        }

        var gl = this.wrappedObject();
        var originalErrors = this.getAllErrors();

        // Take a full GL state snapshot.
        var glState = Object.create(null);
        WebGLRenderingContextResource.GLCapabilities.forEach(function(parameter) {
            glState[parameter] = gl.isEnabled(gl[parameter]);
        });
        for (var i = 0, pname; pname = WebGLRenderingContextResource.StateParameters[i]; ++i) {
            var enumValue = this._enumValueForName(pname);
            if (typeof enumValue === "number")
                glState[pname] = maybeToReplayable(gl.getParameter(enumValue));
        }

        // VERTEX_ATTRIB_ARRAYS
        var maxVertexAttribs = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
        var vertexAttribParameters = [
            "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",
            "VERTEX_ATTRIB_ARRAY_ENABLED",
            "VERTEX_ATTRIB_ARRAY_SIZE",
            "VERTEX_ATTRIB_ARRAY_STRIDE",
            "VERTEX_ATTRIB_ARRAY_TYPE",
            "VERTEX_ATTRIB_ARRAY_NORMALIZED",
            "CURRENT_VERTEX_ATTRIB",
            "VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE" // ANGLE_instanced_arrays extension
        ];
        var vertexAttribStates = [];
        for (var index = 0; index < maxVertexAttribs; ++index) {
            var state = Object.create(null);
            for (var i = 0, pname; pname = vertexAttribParameters[i]; ++i) {
                var enumValue = this._enumValueForName(pname);
                if (typeof enumValue === "number")
                    state[pname] = maybeToReplayable(gl.getVertexAttrib(index, enumValue));
            }
            state.VERTEX_ATTRIB_ARRAY_POINTER = gl.getVertexAttribOffset(index, gl.VERTEX_ATTRIB_ARRAY_POINTER);
            vertexAttribStates.push(state);
        }
        glState.VERTEX_ATTRIB_ARRAYS = vertexAttribStates;

        // TEXTURE_UNITS
        var savedActiveTexture = /** @type {number} */ (gl.getParameter(gl.ACTIVE_TEXTURE));
        var maxTextureImageUnits = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS));
        var textureUnits = [];
        for (var i = 0; i < maxTextureImageUnits; ++i) {
            gl.activeTexture(gl.TEXTURE0 + i);
            var state = Object.create(null);
            state.TEXTURE_2D = maybeToReplayable(gl.getParameter(gl.TEXTURE_BINDING_2D));
            state.TEXTURE_CUBE_MAP = maybeToReplayable(gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP));
            textureUnits.push(state);
        }
        glState.TEXTURE_UNITS = textureUnits;
        gl.activeTexture(savedActiveTexture);

        this.restoreErrors(originalErrors);
        return glState;
    },

    /**
     * @override
     * @param {!Object} data
     * @param {!Cache.<ReplayableResource>} cache
     */
    _populateReplayableData: function(data, cache)
    {
        var gl = this.wrappedObject();
        data.originalCanvas = gl.canvas;
        data.originalContextAttributes = gl.getContextAttributes();
        data.extensions = TypeUtils.cloneObject(this._extensions);
        data.extensionEnums = TypeUtils.cloneObject(this._extensionEnums);
        data.glState = this._internalCurrentState(cache);
    },

    /**
     * @override
     * @param {!Object} data
     * @param {!Cache.<Resource>} cache
     */
    _doReplayCalls: function(data, cache)
    {
        this._customErrors = null;
        this._extensions = TypeUtils.cloneObject(data.extensions) || {};
        this._extensionEnums = TypeUtils.cloneObject(data.extensionEnums) || {};

        var canvas = data.originalCanvas.cloneNode(true);
        var replayContext = null;
        var contextIds = ["experimental-webgl", "webkit-3d", "3d"];
        for (var i = 0, contextId; contextId = contextIds[i]; ++i) {
            replayContext = canvas.getContext(contextId, data.originalContextAttributes);
            if (replayContext)
                break;
        }

        console.assert(replayContext, "Failed to create a WebGLRenderingContext for the replay.");

        var gl = /** @type {!WebGLRenderingContext} */ (Resource.wrappedObject(replayContext));
        this.setWrappedObject(gl);

        // Enable corresponding WebGL extensions.
        for (var name in this._extensions)
            gl.getExtension(name);

        var glState = data.glState;
        gl.bindFramebuffer(gl.FRAMEBUFFER, /** @type {WebGLFramebuffer} */ (ReplayableResource.replay(glState.FRAMEBUFFER_BINDING, cache)));
        gl.bindRenderbuffer(gl.RENDERBUFFER, /** @type {WebGLRenderbuffer} */ (ReplayableResource.replay(glState.RENDERBUFFER_BINDING, cache)));

        // Enable or disable server-side GL capabilities.
        WebGLRenderingContextResource.GLCapabilities.forEach(function(parameter) {
            console.assert(parameter in glState);
            if (glState[parameter])
                gl.enable(gl[parameter]);
            else
                gl.disable(gl[parameter]);
        });

        gl.blendColor(glState.BLEND_COLOR[0], glState.BLEND_COLOR[1], glState.BLEND_COLOR[2], glState.BLEND_COLOR[3]);
        gl.blendEquationSeparate(glState.BLEND_EQUATION_RGB, glState.BLEND_EQUATION_ALPHA);
        gl.blendFuncSeparate(glState.BLEND_SRC_RGB, glState.BLEND_DST_RGB, glState.BLEND_SRC_ALPHA, glState.BLEND_DST_ALPHA);
        gl.clearColor(glState.COLOR_CLEAR_VALUE[0], glState.COLOR_CLEAR_VALUE[1], glState.COLOR_CLEAR_VALUE[2], glState.COLOR_CLEAR_VALUE[3]);
        gl.clearDepth(glState.DEPTH_CLEAR_VALUE);
        gl.clearStencil(glState.STENCIL_CLEAR_VALUE);
        gl.colorMask(glState.COLOR_WRITEMASK[0], glState.COLOR_WRITEMASK[1], glState.COLOR_WRITEMASK[2], glState.COLOR_WRITEMASK[3]);
        gl.cullFace(glState.CULL_FACE_MODE);
        gl.depthFunc(glState.DEPTH_FUNC);
        gl.depthMask(glState.DEPTH_WRITEMASK);
        gl.depthRange(glState.DEPTH_RANGE[0], glState.DEPTH_RANGE[1]);
        gl.frontFace(glState.FRONT_FACE);
        gl.hint(gl.GENERATE_MIPMAP_HINT, glState.GENERATE_MIPMAP_HINT);
        gl.lineWidth(glState.LINE_WIDTH);

        var enumValue = this._enumValueForName("FRAGMENT_SHADER_DERIVATIVE_HINT_OES");
        if (typeof enumValue === "number")
            gl.hint(enumValue, glState.FRAGMENT_SHADER_DERIVATIVE_HINT_OES);

        WebGLRenderingContextResource.PixelStoreParameters.forEach(function(parameter) {
            gl.pixelStorei(gl[parameter], glState[parameter]);
        });

        gl.polygonOffset(glState.POLYGON_OFFSET_FACTOR, glState.POLYGON_OFFSET_UNITS);
        gl.sampleCoverage(glState.SAMPLE_COVERAGE_VALUE, glState.SAMPLE_COVERAGE_INVERT);
        gl.stencilFuncSeparate(gl.FRONT, glState.STENCIL_FUNC, glState.STENCIL_REF, glState.STENCIL_VALUE_MASK);
        gl.stencilFuncSeparate(gl.BACK, glState.STENCIL_BACK_FUNC, glState.STENCIL_BACK_REF, glState.STENCIL_BACK_VALUE_MASK);
        gl.stencilOpSeparate(gl.FRONT, glState.STENCIL_FAIL, glState.STENCIL_PASS_DEPTH_FAIL, glState.STENCIL_PASS_DEPTH_PASS);
        gl.stencilOpSeparate(gl.BACK, glState.STENCIL_BACK_FAIL, glState.STENCIL_BACK_PASS_DEPTH_FAIL, glState.STENCIL_BACK_PASS_DEPTH_PASS);
        gl.stencilMaskSeparate(gl.FRONT, glState.STENCIL_WRITEMASK);
        gl.stencilMaskSeparate(gl.BACK, glState.STENCIL_BACK_WRITEMASK);

        gl.scissor(glState.SCISSOR_BOX[0], glState.SCISSOR_BOX[1], glState.SCISSOR_BOX[2], glState.SCISSOR_BOX[3]);
        gl.viewport(glState.VIEWPORT[0], glState.VIEWPORT[1], glState.VIEWPORT[2], glState.VIEWPORT[3]);

        gl.useProgram(/** @type {WebGLProgram} */ (ReplayableResource.replay(glState.CURRENT_PROGRAM, cache)));

        // VERTEX_ATTRIB_ARRAYS
        var maxVertexAttribs = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
        for (var i = 0; i < maxVertexAttribs; ++i) {
            var state = glState.VERTEX_ATTRIB_ARRAYS[i] || {};
            if (state.VERTEX_ATTRIB_ARRAY_ENABLED)
                gl.enableVertexAttribArray(i);
            else
                gl.disableVertexAttribArray(i);
            if (state.CURRENT_VERTEX_ATTRIB)
                gl.vertexAttrib4fv(i, state.CURRENT_VERTEX_ATTRIB);
            var buffer = /** @type {WebGLBuffer} */ (ReplayableResource.replay(state.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, cache));
            if (buffer) {
                gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
                gl.vertexAttribPointer(i, state.VERTEX_ATTRIB_ARRAY_SIZE, state.VERTEX_ATTRIB_ARRAY_TYPE, state.VERTEX_ATTRIB_ARRAY_NORMALIZED, state.VERTEX_ATTRIB_ARRAY_STRIDE, state.VERTEX_ATTRIB_ARRAY_POINTER);
            }
        }
        gl.bindBuffer(gl.ARRAY_BUFFER, /** @type {WebGLBuffer} */ (ReplayableResource.replay(glState.ARRAY_BUFFER_BINDING, cache)));
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, /** @type {WebGLBuffer} */ (ReplayableResource.replay(glState.ELEMENT_ARRAY_BUFFER_BINDING, cache)));

        // TEXTURE_UNITS
        var maxTextureImageUnits = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS));
        for (var i = 0; i < maxTextureImageUnits; ++i) {
            gl.activeTexture(gl.TEXTURE0 + i);
            var state = glState.TEXTURE_UNITS[i] || {};
            gl.bindTexture(gl.TEXTURE_2D, /** @type {WebGLTexture} */ (ReplayableResource.replay(state.TEXTURE_2D, cache)));
            gl.bindTexture(gl.TEXTURE_CUBE_MAP, /** @type {WebGLTexture} */ (ReplayableResource.replay(state.TEXTURE_CUBE_MAP, cache)));
        }
        gl.activeTexture(glState.ACTIVE_TEXTURE);

        ContextResource.prototype._doReplayCalls.call(this, data, cache);
    },

    /**
     * @param {Object|number} target
     * @return {Resource}
     */
    currentBinding: function(target)
    {
        var resource = Resource.forObject(target);
        if (resource)
            return resource;
        var gl = this.wrappedObject();
        var bindingParameter;
        var bindMethodName;
        var bindMethodTarget = target;
        switch (target) {
        case gl.ARRAY_BUFFER:
            bindingParameter = gl.ARRAY_BUFFER_BINDING;
            bindMethodName = "bindBuffer";
            break;
        case gl.ELEMENT_ARRAY_BUFFER:
            bindingParameter = gl.ELEMENT_ARRAY_BUFFER_BINDING;
            bindMethodName = "bindBuffer";
            break;
        case gl.TEXTURE_2D:
            bindingParameter = gl.TEXTURE_BINDING_2D;
            bindMethodName = "bindTexture";
            break;
        case gl.TEXTURE_CUBE_MAP:
        case gl.TEXTURE_CUBE_MAP_POSITIVE_X:
        case gl.TEXTURE_CUBE_MAP_NEGATIVE_X:
        case gl.TEXTURE_CUBE_MAP_POSITIVE_Y:
        case gl.TEXTURE_CUBE_MAP_NEGATIVE_Y:
        case gl.TEXTURE_CUBE_MAP_POSITIVE_Z:
        case gl.TEXTURE_CUBE_MAP_NEGATIVE_Z:
            bindingParameter = gl.TEXTURE_BINDING_CUBE_MAP;
            bindMethodTarget = gl.TEXTURE_CUBE_MAP;
            bindMethodName = "bindTexture";
            break;
        case gl.FRAMEBUFFER:
            bindingParameter = gl.FRAMEBUFFER_BINDING;
            bindMethodName = "bindFramebuffer";
            break;
        case gl.RENDERBUFFER:
            bindingParameter = gl.RENDERBUFFER_BINDING;
            bindMethodName = "bindRenderbuffer";
            break;
        default:
            console.error("ASSERT_NOT_REACHED: unknown binding target " + target);
            return null;
        }
        resource = Resource.forObject(gl.getParameter(bindingParameter));
        if (resource)
            resource.pushBinding(bindMethodTarget, bindMethodName);
        return resource;
    },

    /**
     * @override
     * @param {!Call} call
     */
    onCallReplayed: function(call)
    {
        var functionName = call.functionName();
        var args = call.args();
        switch (functionName) {
        case "bindBuffer":
        case "bindFramebuffer":
        case "bindRenderbuffer":
        case "bindTexture":
            // Update BINDING state for Resources in the replay world.
            var resource = Resource.forObject(args[1]);
            if (resource)
                resource.pushBinding(args[0], functionName);
            break;
        case "getExtension":
            this.registerWebGLExtension(args[0], /** @type {Object} */ (call.result()));
            break;
        }
    },

    /**
     * @override
     * @return {!Object.<string, Function>}
     */
    _customWrapFunctions: function()
    {
        var wrapFunctions = WebGLRenderingContextResource._wrapFunctions;
        if (!wrapFunctions) {
            wrapFunctions = Object.create(null);

            wrapFunctions["createBuffer"] = Resource.WrapFunction.resourceFactoryMethod(WebGLBufferResource, "WebGLBuffer");
            wrapFunctions["createShader"] = Resource.WrapFunction.resourceFactoryMethod(WebGLShaderResource, "WebGLShader");
            wrapFunctions["createProgram"] = Resource.WrapFunction.resourceFactoryMethod(WebGLProgramResource, "WebGLProgram");
            wrapFunctions["createTexture"] = Resource.WrapFunction.resourceFactoryMethod(WebGLTextureResource, "WebGLTexture");
            wrapFunctions["createFramebuffer"] = Resource.WrapFunction.resourceFactoryMethod(WebGLFramebufferResource, "WebGLFramebuffer");
            wrapFunctions["createRenderbuffer"] = Resource.WrapFunction.resourceFactoryMethod(WebGLRenderbufferResource, "WebGLRenderbuffer");
            wrapFunctions["getUniformLocation"] = Resource.WrapFunction.resourceFactoryMethod(WebGLUniformLocationResource, "WebGLUniformLocation");

            /**
             * @param {string} methodName
             * @param {function(this:Resource, !Call)=} pushCallFunc
             */
            function stateModifyingWrapFunction(methodName, pushCallFunc)
            {
                if (pushCallFunc) {
                    /**
                     * @param {Object|number} target
                     * @this Resource.WrapFunction
                     */
                    wrapFunctions[methodName] = function(target)
                    {
                        var resource = this._resource.currentBinding(target);
                        if (resource)
                            pushCallFunc.call(resource, this.call());
                    }
                } else {
                    /**
                     * @param {Object|number} target
                     * @this Resource.WrapFunction
                     */
                    wrapFunctions[methodName] = function(target)
                    {
                        var resource = this._resource.currentBinding(target);
                        if (resource)
                            resource.pushCall(this.call());
                    }
                }
            }
            stateModifyingWrapFunction("bindAttribLocation");
            stateModifyingWrapFunction("compileShader");
            stateModifyingWrapFunction("detachShader");
            stateModifyingWrapFunction("linkProgram");
            stateModifyingWrapFunction("shaderSource");
            stateModifyingWrapFunction("bufferData");
            stateModifyingWrapFunction("bufferSubData");
            stateModifyingWrapFunction("compressedTexImage2D");
            stateModifyingWrapFunction("compressedTexSubImage2D");
            stateModifyingWrapFunction("copyTexImage2D", WebGLTextureResource.prototype.pushCall_copyTexImage2D);
            stateModifyingWrapFunction("copyTexSubImage2D", WebGLTextureResource.prototype.pushCall_copyTexImage2D);
            stateModifyingWrapFunction("generateMipmap");
            stateModifyingWrapFunction("texImage2D");
            stateModifyingWrapFunction("texSubImage2D");
            stateModifyingWrapFunction("texParameterf", WebGLTextureResource.prototype.pushCall_texParameter);
            stateModifyingWrapFunction("texParameteri", WebGLTextureResource.prototype.pushCall_texParameter);
            stateModifyingWrapFunction("renderbufferStorage");

            /** @this Resource.WrapFunction */
            wrapFunctions["getError"] = function()
            {
                var gl = /** @type {WebGLRenderingContext} */ (this._originalObject);
                var error = this.result();
                if (error !== gl.NO_ERROR)
                    this._resource.clearError(error);
                else {
                    error = this._resource.nextError();
                    if (error !== gl.NO_ERROR)
                        this.overrideResult(error);
                }
            }

            /**
             * @param {string} name
             * @this Resource.WrapFunction
             */
            wrapFunctions["getExtension"] = function(name)
            {
                this._resource.registerWebGLExtension(name, this.result());
            }

            //
            // Register bound WebGL resources.
            //

            /**
             * @param {WebGLProgram} program
             * @param {WebGLShader} shader
             * @this Resource.WrapFunction
             */
            wrapFunctions["attachShader"] = function(program, shader)
            {
                var resource = this._resource.currentBinding(program);
                if (resource) {
                    resource.pushCall(this.call());
                    var shaderResource = /** @type {WebGLShaderResource} */ (Resource.forObject(shader));
                    if (shaderResource) {
                        var shaderType = shaderResource.type();
                        resource._registerBoundResource("__attachShader_" + shaderType, shaderResource);
                    }
                }
            }
            /**
             * @param {number} target
             * @param {number} attachment
             * @param {number} objectTarget
             * @param {WebGLRenderbuffer|WebGLTexture} obj
             * @this Resource.WrapFunction
             */
            wrapFunctions["framebufferRenderbuffer"] = wrapFunctions["framebufferTexture2D"] = function(target, attachment, objectTarget, obj)
            {
                var resource = this._resource.currentBinding(target);
                if (resource) {
                    resource.pushCall(this.call());
                    resource._registerBoundResource("__framebufferAttachmentObjectName", obj);
                }
            }
            /**
             * @param {number} target
             * @param {Object} obj
             * @this Resource.WrapFunction
             */
            wrapFunctions["bindBuffer"] = wrapFunctions["bindFramebuffer"] = wrapFunctions["bindRenderbuffer"] = function(target, obj)
            {
                this._resource.currentBinding(target); // To call WebGLBoundResource.prototype.pushBinding().
                this._resource._registerBoundResource("__bindBuffer_" + target, obj);
            }
            /**
             * @param {number} target
             * @param {WebGLTexture} obj
             * @this Resource.WrapFunction
             */
            wrapFunctions["bindTexture"] = function(target, obj)
            {
                this._resource.currentBinding(target); // To call WebGLBoundResource.prototype.pushBinding().
                var gl = /** @type {WebGLRenderingContext} */ (this._originalObject);
                var currentTextureBinding = /** @type {number} */ (gl.getParameter(gl.ACTIVE_TEXTURE));
                this._resource._registerBoundResource("__bindTexture_" + target + "_" + currentTextureBinding, obj);
            }
            /**
             * @param {WebGLProgram} program
             * @this Resource.WrapFunction
             */
            wrapFunctions["useProgram"] = function(program)
            {
                this._resource._registerBoundResource("__useProgram", program);
            }
            /**
             * @param {number} index
             * @this Resource.WrapFunction
             */
            wrapFunctions["vertexAttribPointer"] = function(index)
            {
                var gl = /** @type {WebGLRenderingContext} */ (this._originalObject);
                this._resource._registerBoundResource("__vertexAttribPointer_" + index, gl.getParameter(gl.ARRAY_BUFFER_BINDING));
            }

            WebGLRenderingContextResource._wrapFunctions = wrapFunctions;
        }
        return wrapFunctions;
    },

    __proto__: ContextResource.prototype
}

////////////////////////////////////////////////////////////////////////////////
// 2D Canvas
////////////////////////////////////////////////////////////////////////////////

/**
 * @constructor
 * @extends {ContextResource}
 * @param {!CanvasRenderingContext2D} context
 */
function CanvasRenderingContext2DResource(context)
{
    ContextResource.call(this, context, "CanvasRenderingContext2D");
}

/**
 * @const
 * @type {!Array.<string>}
 */
CanvasRenderingContext2DResource.AttributeProperties = [
    "strokeStyle",
    "fillStyle",
    "globalAlpha",
    "lineWidth",
    "lineCap",
    "lineJoin",
    "miterLimit",
    "shadowOffsetX",
    "shadowOffsetY",
    "shadowBlur",
    "shadowColor",
    "globalCompositeOperation",
    "font",
    "textAlign",
    "textBaseline",
    "lineDashOffset",
    "imageSmoothingEnabled",
    "webkitImageSmoothingEnabled",
    "webkitLineDash",
    "webkitLineDashOffset"
];

/**
 * @const
 * @type {!Array.<string>}
 */
CanvasRenderingContext2DResource.PathMethods = [
    "beginPath",
    "moveTo",
    "closePath",
    "lineTo",
    "quadraticCurveTo",
    "bezierCurveTo",
    "arcTo",
    "arc",
    "rect"
];

/**
 * @const
 * @type {!Array.<string>}
 */
CanvasRenderingContext2DResource.TransformationMatrixMethods = [
    "scale",
    "rotate",
    "translate",
    "transform",
    "setTransform"
];

/**
 * @const
 * @type {!Object.<string, boolean>}
 */
CanvasRenderingContext2DResource.DrawingMethods = TypeUtils.createPrefixedPropertyNamesSet([
    "clearRect",
    "drawImage",
    "drawImageFromRect",
    "drawCustomFocusRing",
    "drawSystemFocusRing",
    "fill",
    "fillRect",
    "fillText",
    "putImageData",
    "putImageDataHD",
    "stroke",
    "strokeRect",
    "strokeText"
]);

CanvasRenderingContext2DResource.prototype = {
    /**
     * @override (overrides @return type)
     * @return {CanvasRenderingContext2D}
     */
    wrappedObject: function()
    {
        return this._wrappedObject;
    },

    /**
     * @override
     * @return {string}
     */
    toDataURL: function()
    {
        return this.wrappedObject().canvas.toDataURL();
    },

    /**
     * @override
     * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
     */
    currentState: function()
    {
        var result = [];
        var state = this._internalCurrentState(null);
        for (var pname in state)
            result.push({ name: pname, value: state[pname] });
        result.push({ name: "context", value: this.contextResource() });
        return result;
    },

    /**
     * @param {?Cache.<ReplayableResource>} cache
     * @return {!Object.<string, *>}
     */
    _internalCurrentState: function(cache)
    {
        /**
         * @param {Resource|*} obj
         * @return {Resource|ReplayableResource|*}
         */
        function maybeToReplayable(obj)
        {
            return cache ? Resource.toReplayable(obj, cache) : (Resource.forObject(obj) || obj);
        }

        var ctx = this.wrappedObject();
        var state = Object.create(null);
        CanvasRenderingContext2DResource.AttributeProperties.forEach(function(attribute) {
            if (attribute in ctx)
                state[attribute] = maybeToReplayable(ctx[attribute]);
        });
        if (ctx.getLineDash)
            state.lineDash = ctx.getLineDash();
        return state;
    },

    /**
     * @param {Object.<string, *>} state
     * @param {!Cache.<Resource>} cache
     */
    _applyAttributesState: function(state, cache)
    {
        if (!state)
            return;
        var ctx = this.wrappedObject();
        for (var attribute in state) {
            if (attribute === "lineDash") {
                if (ctx.setLineDash)
                    ctx.setLineDash(/** @type {Array.<number>} */ (state[attribute]));
            } else
                ctx[attribute] = ReplayableResource.replay(state[attribute], cache);
        }
    },

    /**
     * @override
     * @param {!Object} data
     * @param {!Cache.<ReplayableResource>} cache
     */
    _populateReplayableData: function(data, cache)
    {
        var ctx = this.wrappedObject();
        // FIXME: Convert resources in the state (CanvasGradient, CanvasPattern) to Replayable.
        data.currentAttributes = this._internalCurrentState(null);
        data.originalCanvasCloned = TypeUtils.cloneIntoCanvas(ctx.canvas);
        if (ctx.getContextAttributes)
            data.originalContextAttributes = ctx.getContextAttributes();
    },

    /**
     * @override
     * @param {!Object} data
     * @param {!Cache.<Resource>} cache
     */
    _doReplayCalls: function(data, cache)
    {
        var canvas = TypeUtils.cloneIntoCanvas(data.originalCanvasCloned);
        var ctx = /** @type {!CanvasRenderingContext2D} */ (Resource.wrappedObject(canvas.getContext("2d", data.originalContextAttributes)));
        this.setWrappedObject(ctx);

        for (var i = 0, n = data.calls.length; i < n; ++i) {
            var replayableCall = /** @type {ReplayableCall} */ (data.calls[i]);
            if (replayableCall.functionName() === "save")
                this._applyAttributesState(replayableCall.attachment("canvas2dAttributesState"), cache);
            this._calls.push(replayableCall.replay(cache));
        }
        this._applyAttributesState(data.currentAttributes, cache);
    },

    /**
     * @param {!Call} call
     */
    pushCall_setTransform: function(call)
    {
        var saveCallIndex = this._lastIndexOfMatchingSaveCall();
        var index = this._lastIndexOfAnyCall(CanvasRenderingContext2DResource.PathMethods);
        index = Math.max(index, saveCallIndex);
        if (this._removeCallsFromLog(CanvasRenderingContext2DResource.TransformationMatrixMethods, index + 1))
            this._removeAllObsoleteCallsFromLog();
        this.pushCall(call);
    },

    /**
     * @param {!Call} call
     */
    pushCall_beginPath: function(call)
    {
        var index = this._lastIndexOfAnyCall(["clip"]);
        if (this._removeCallsFromLog(CanvasRenderingContext2DResource.PathMethods, index + 1))
            this._removeAllObsoleteCallsFromLog();
        this.pushCall(call);
    },

    /**
     * @param {!Call} call
     */
    pushCall_save: function(call)
    {
        // FIXME: Convert resources in the state (CanvasGradient, CanvasPattern) to Replayable.
        call.setAttachment("canvas2dAttributesState", this._internalCurrentState(null));
        this.pushCall(call);
    },

    /**
     * @param {!Call} call
     */
    pushCall_restore: function(call)
    {
        var lastIndexOfSave = this._lastIndexOfMatchingSaveCall();
        if (lastIndexOfSave === -1)
            return;
        this._calls[lastIndexOfSave].setAttachment("canvas2dAttributesState", null); // No longer needed, free memory.

        var modified = false;
        if (this._removeCallsFromLog(["clip"], lastIndexOfSave + 1))
            modified = true;

        var lastIndexOfAnyPathMethod = this._lastIndexOfAnyCall(CanvasRenderingContext2DResource.PathMethods);
        var index = Math.max(lastIndexOfSave, lastIndexOfAnyPathMethod);
        if (this._removeCallsFromLog(CanvasRenderingContext2DResource.TransformationMatrixMethods, index + 1))
            modified = true;

        if (modified)
            this._removeAllObsoleteCallsFromLog();

        var lastCall = this._calls[this._calls.length - 1];
        if (lastCall && lastCall.functionName() === "save")
            this._calls.pop();
        else
            this.pushCall(call);
    },

    /**
     * @param {number=} fromIndex
     * @return {number}
     */
    _lastIndexOfMatchingSaveCall: function(fromIndex)
    {
        if (typeof fromIndex !== "number")
            fromIndex = this._calls.length - 1;
        else
            fromIndex = Math.min(fromIndex, this._calls.length - 1);
        var stackDepth = 1;
        for (var i = fromIndex; i >= 0; --i) {
            var functionName = this._calls[i].functionName();
            if (functionName === "restore")
                ++stackDepth;
            else if (functionName === "save") {
                --stackDepth;
                if (!stackDepth)
                    return i;
            }
        }
        return -1;
    },

    /**
     * @param {!Array.<string>} functionNames
     * @param {number=} fromIndex
     * @return {number}
     */
    _lastIndexOfAnyCall: function(functionNames, fromIndex)
    {
        if (typeof fromIndex !== "number")
            fromIndex = this._calls.length - 1;
        else
            fromIndex = Math.min(fromIndex, this._calls.length - 1);
        for (var i = fromIndex; i >= 0; --i) {
            if (functionNames.indexOf(this._calls[i].functionName()) !== -1)
                return i;
        }
        return -1;
    },

    _removeAllObsoleteCallsFromLog: function()
    {
        // Remove all PATH methods between clip() and beginPath() calls.
        var lastIndexOfBeginPath = this._lastIndexOfAnyCall(["beginPath"]);
        while (lastIndexOfBeginPath !== -1) {
            var index = this._lastIndexOfAnyCall(["clip"], lastIndexOfBeginPath - 1);
            this._removeCallsFromLog(CanvasRenderingContext2DResource.PathMethods, index + 1, lastIndexOfBeginPath);
            lastIndexOfBeginPath = this._lastIndexOfAnyCall(["beginPath"], index - 1);
        }

        // Remove all TRASFORMATION MATRIX methods before restore() or setTransform() but after any PATH or corresponding save() method.
        var lastRestore = this._lastIndexOfAnyCall(["restore", "setTransform"]);
        while (lastRestore !== -1) {
            var saveCallIndex = this._lastIndexOfMatchingSaveCall(lastRestore - 1);
            var index = this._lastIndexOfAnyCall(CanvasRenderingContext2DResource.PathMethods, lastRestore - 1);
            index = Math.max(index, saveCallIndex);
            this._removeCallsFromLog(CanvasRenderingContext2DResource.TransformationMatrixMethods, index + 1, lastRestore);
            lastRestore = this._lastIndexOfAnyCall(["restore", "setTransform"], index - 1);
        }

        // Remove all save-restore consecutive pairs.
        var restoreCalls = 0;
        for (var i = this._calls.length - 1; i >= 0; --i) {
            var functionName = this._calls[i].functionName();
            if (functionName === "restore") {
                ++restoreCalls;
                continue;
            }
            if (functionName === "save" && restoreCalls > 0) {
                var saveCallIndex = i;
                for (var j = i - 1; j >= 0 && i - j < restoreCalls; --j) {
                    if (this._calls[j].functionName() === "save")
                        saveCallIndex = j;
                    else
                        break;
                }
                this._calls.splice(saveCallIndex, (i - saveCallIndex + 1) * 2);
                i = saveCallIndex;
            }
            restoreCalls = 0;
        }
    },

    /**
     * @param {!Array.<string>} functionNames
     * @param {number} fromIndex
     * @param {number=} toIndex
     * @return {boolean}
     */
    _removeCallsFromLog: function(functionNames, fromIndex, toIndex)
    {
        var oldLength = this._calls.length;
        if (typeof toIndex !== "number")
            toIndex = oldLength;
        else
            toIndex = Math.min(toIndex, oldLength);
        var newIndex = Math.min(fromIndex, oldLength);
        for (var i = newIndex; i < toIndex; ++i) {
            var call = this._calls[i];
            if (functionNames.indexOf(call.functionName()) === -1)
                this._calls[newIndex++] = call;
        }
        if (newIndex >= toIndex)
            return false;
        this._calls.splice(newIndex, toIndex - newIndex);
        return true;
    },

    /**
     * @override
     * @return {!Object.<string, Function>}
     */
    _customWrapFunctions: function()
    {
        var wrapFunctions = CanvasRenderingContext2DResource._wrapFunctions;
        if (!wrapFunctions) {
            wrapFunctions = Object.create(null);

            wrapFunctions["createLinearGradient"] = Resource.WrapFunction.resourceFactoryMethod(LogEverythingResource, "CanvasGradient");
            wrapFunctions["createRadialGradient"] = Resource.WrapFunction.resourceFactoryMethod(LogEverythingResource, "CanvasGradient");
            wrapFunctions["createPattern"] = Resource.WrapFunction.resourceFactoryMethod(LogEverythingResource, "CanvasPattern");

            /**
             * @param {string} methodName
             * @param {function(this:Resource, !Call)=} func
             */
            function stateModifyingWrapFunction(methodName, func)
            {
                if (func) {
                    /** @this Resource.WrapFunction */
                    wrapFunctions[methodName] = function()
                    {
                        func.call(this._resource, this.call());
                    }
                } else {
                    /** @this Resource.WrapFunction */
                    wrapFunctions[methodName] = function()
                    {
                        this._resource.pushCall(this.call());
                    }
                }
            }

            for (var i = 0, methodName; methodName = CanvasRenderingContext2DResource.TransformationMatrixMethods[i]; ++i)
                stateModifyingWrapFunction(methodName, methodName === "setTransform" ? this.pushCall_setTransform : undefined);
            for (var i = 0, methodName; methodName = CanvasRenderingContext2DResource.PathMethods[i]; ++i)
                stateModifyingWrapFunction(methodName, methodName === "beginPath" ? this.pushCall_beginPath : undefined);

            stateModifyingWrapFunction("save", this.pushCall_save);
            stateModifyingWrapFunction("restore", this.pushCall_restore);
            stateModifyingWrapFunction("clip");

            CanvasRenderingContext2DResource._wrapFunctions = wrapFunctions;
        }
        return wrapFunctions;
    },

    __proto__: ContextResource.prototype
}

/**
 * @constructor
 * @param {!Object.<string, boolean>=} drawingMethodNames
 */
function CallFormatter(drawingMethodNames)
{
    this._drawingMethodNames = drawingMethodNames || Object.create(null);
}

CallFormatter.prototype = {
    /**
     * @param {!ReplayableCall} replayableCall
     * @param {string=} objectGroup
     * @return {!Object}
     */
    formatCall: function(replayableCall, objectGroup)
    {
        var result = {};
        var functionName = replayableCall.functionName();
        if (functionName) {
            result.functionName = functionName;
            result.arguments = [];
            var args = replayableCall.args();
            for (var i = 0, n = args.length; i < n; ++i)
                result.arguments.push(this.formatValue(args[i], objectGroup));
            if (replayableCall.result() !== undefined)
                result.result = this.formatValue(replayableCall.result(), objectGroup);
            if (this._drawingMethodNames[functionName])
                result.isDrawingCall = true;
        } else {
            result.property = replayableCall.propertyName();
            result.value = this.formatValue(replayableCall.propertyValue(), objectGroup);
        }
        return result;
    },

    /**
     * @param {*} value
     * @param {string=} objectGroup
     * @return {!CanvasAgent.CallArgument}
     */
    formatValue: function(value, objectGroup)
    {
        if (value instanceof Resource || value instanceof ReplayableResource) {
            return {
                description: value.description(),
                resourceId: CallFormatter.makeStringResourceId(value.id())
            };
        }

        var remoteObject = injectedScript.wrapObject(value, objectGroup || "", true, false);
        var description = remoteObject.description || ("" + value);

        var result = {
            description: description,
            type: /** @type {CanvasAgent.CallArgumentType} */ (remoteObject.type)
        };
        if (remoteObject.subtype)
            result.subtype = /** @type {CanvasAgent.CallArgumentSubtype} */ (remoteObject.subtype);
        if (remoteObject.objectId) {
            if (objectGroup)
                result.remoteObject = remoteObject;
            else
                injectedScript.releaseObject(remoteObject.objectId);
        }
        return result;
    },

    /**
     * @param {string} name
     * @return {?string}
     */
    enumValueForName: function(name)
    {
        return null;
    },

    /**
     * @param {number} value
     * @param {Array.<string>=} options
     * @return {?string}
     */
    enumNameForValue: function(value, options)
    {
        return null;
    },

    /**
     * @param {!Array.<TypeUtils.InternalResourceStateDescriptor>} descriptors
     * @param {string=} objectGroup
     * @return {!Array.<!CanvasAgent.ResourceStateDescriptor>}
     */
    formatResourceStateDescriptors: function(descriptors, objectGroup)
    {
        var result = [];
        for (var i = 0, n = descriptors.length; i < n; ++i) {
            var d = descriptors[i];
            var item;
            if (d.values)
                item = { name: d.name, values: this.formatResourceStateDescriptors(d.values, objectGroup) };
            else {
                item = { name: d.name, value: this.formatValue(d.value, objectGroup) };
                if (d.valueIsEnum && typeof d.value === "number") {
                    var enumName = this.enumNameForValue(d.value);
                    if (enumName)
                        item.value.enumName = enumName;
                }
            }
            var enumValue = this.enumValueForName(d.name);
            if (enumValue)
                item.enumValueForName = enumValue;
            if (d.isArray)
                item.isArray = true;
            result.push(item);
        }
        return result;
    }
}

/**
 * @const
 * @type {!Object.<string, !CallFormatter>}
 */
CallFormatter._formatters = {};

/**
 * @param {string} resourceName
 * @param {!CallFormatter} callFormatter
 */
CallFormatter.register = function(resourceName, callFormatter)
{
    CallFormatter._formatters[resourceName] = callFormatter;
}

/**
 * @param {!Resource|!ReplayableResource} resource
 * @return {!CallFormatter}
 */
CallFormatter.forResource = function(resource)
{
    var formatter = CallFormatter._formatters[resource.name()];
    if (!formatter) {
        var contextResource = resource.contextResource();
        formatter = (contextResource && CallFormatter._formatters[contextResource.name()]) || new CallFormatter();
    }
    return formatter;
}

/**
 * @param {number} resourceId
 * @return {CanvasAgent.ResourceId}
 */
CallFormatter.makeStringResourceId = function(resourceId)
{
    return "{\"injectedScriptId\":" + injectedScriptId + ",\"resourceId\":" + resourceId + "}";
}

/**
 * @constructor
 * @extends {CallFormatter}
 * @param {!Object.<string, boolean>} drawingMethodNames
 */
function WebGLCallFormatter(drawingMethodNames)
{
    CallFormatter.call(this, drawingMethodNames);
}

/**
 * NOTE: The code below is generated from the IDL file by the script:
 * /devtools/scripts/check_injected_webgl_calls_info.py
 *
 * @type {!Array.<{aname: string, enum: (!Array.<number>|undefined), bitfield: (!Array.<number>|undefined), returnType: string, hints: (!Array.<string>|undefined)}>}
 */
WebGLCallFormatter.EnumsInfo = [
    {"aname": "activeTexture", "enum": [0]},
    {"aname": "bindBuffer", "enum": [0]},
    {"aname": "bindFramebuffer", "enum": [0]},
    {"aname": "bindRenderbuffer", "enum": [0]},
    {"aname": "bindTexture", "enum": [0]},
    {"aname": "blendEquation", "enum": [0]},
    {"aname": "blendEquationSeparate", "enum": [0, 1]},
    {"aname": "blendFunc", "enum": [0, 1], "hints": ["ZERO", "ONE"]},
    {"aname": "blendFuncSeparate", "enum": [0, 1, 2, 3], "hints": ["ZERO", "ONE"]},
    {"aname": "bufferData", "enum": [0, 2]},
    {"aname": "bufferSubData", "enum": [0]},
    {"aname": "checkFramebufferStatus", "enum": [0], "returnType": "enum"},
    {"aname": "clear", "bitfield": [0]},
    {"aname": "compressedTexImage2D", "enum": [0, 2]},
    {"aname": "compressedTexSubImage2D", "enum": [0, 6]},
    {"aname": "copyTexImage2D", "enum": [0, 2]},
    {"aname": "copyTexSubImage2D", "enum": [0]},
    {"aname": "createShader", "enum": [0]},
    {"aname": "cullFace", "enum": [0]},
    {"aname": "depthFunc", "enum": [0]},
    {"aname": "disable", "enum": [0]},
    {"aname": "drawArrays", "enum": [0], "hints": ["POINTS", "LINES"]},
    {"aname": "drawElements", "enum": [0, 2], "hints": ["POINTS", "LINES"]},
    {"aname": "enable", "enum": [0]},
    {"aname": "framebufferRenderbuffer", "enum": [0, 1, 2]},
    {"aname": "framebufferTexture2D", "enum": [0, 1, 2]},
    {"aname": "frontFace", "enum": [0]},
    {"aname": "generateMipmap", "enum": [0]},
    {"aname": "getBufferParameter", "enum": [0, 1]},
    {"aname": "getError", "hints": ["NO_ERROR"], "returnType": "enum"},
    {"aname": "getFramebufferAttachmentParameter", "enum": [0, 1, 2]},
    {"aname": "getParameter", "enum": [0]},
    {"aname": "getProgramParameter", "enum": [1]},
    {"aname": "getRenderbufferParameter", "enum": [0, 1]},
    {"aname": "getShaderParameter", "enum": [1]},
    {"aname": "getShaderPrecisionFormat", "enum": [0, 1]},
    {"aname": "getTexParameter", "enum": [0, 1], "returnType": "enum"},
    {"aname": "getVertexAttrib", "enum": [1]},
    {"aname": "getVertexAttribOffset", "enum": [1]},
    {"aname": "hint", "enum": [0, 1]},
    {"aname": "isEnabled", "enum": [0]},
    {"aname": "pixelStorei", "enum": [0]},
    {"aname": "readPixels", "enum": [4, 5]},
    {"aname": "renderbufferStorage", "enum": [0, 1]},
    {"aname": "stencilFunc", "enum": [0]},
    {"aname": "stencilFuncSeparate", "enum": [0, 1]},
    {"aname": "stencilMaskSeparate", "enum": [0]},
    {"aname": "stencilOp", "enum": [0, 1, 2], "hints": ["ZERO", "ONE"]},
    {"aname": "stencilOpSeparate", "enum": [0, 1, 2, 3], "hints": ["ZERO", "ONE"]},
    {"aname": "texParameterf", "enum": [0, 1, 2]},
    {"aname": "texParameteri", "enum": [0, 1, 2]},
    {"aname": "texImage2D", "enum": [0, 2, 6, 7]},
    {"aname": "texImage2D", "enum": [0, 2, 3, 4]},
    {"aname": "texSubImage2D", "enum": [0, 6, 7]},
    {"aname": "texSubImage2D", "enum": [0, 4, 5]},
    {"aname": "vertexAttribPointer", "enum": [2]}
];

WebGLCallFormatter.prototype = {
    /**
     * @override
     * @param {!ReplayableCall} replayableCall
     * @param {string=} objectGroup
     * @return {!Object}
     */
    formatCall: function(replayableCall, objectGroup)
    {
        var result = CallFormatter.prototype.formatCall.call(this, replayableCall, objectGroup);
        if (!result.functionName)
            return result;
        var enumsInfo = this._findEnumsInfo(replayableCall);
        if (!enumsInfo)
            return result;
        var enumArgsIndexes = enumsInfo["enum"] || [];
        for (var i = 0, n = enumArgsIndexes.length; i < n; ++i) {
            var index = enumArgsIndexes[i];
            var callArgument = result.arguments[index];
            this._formatEnumValue(callArgument, enumsInfo["hints"]);
        }
        var bitfieldArgsIndexes = enumsInfo["bitfield"] || [];
        for (var i = 0, n = bitfieldArgsIndexes.length; i < n; ++i) {
            var index = bitfieldArgsIndexes[i];
            var callArgument = result.arguments[index];
            this._formatEnumBitmaskValue(callArgument, enumsInfo["hints"]);
        }
        if (enumsInfo.returnType === "enum")
            this._formatEnumValue(result.result, enumsInfo["hints"]);
        else if (enumsInfo.returnType === "bitfield")
            this._formatEnumBitmaskValue(result.result, enumsInfo["hints"]);
        return result;
    },

    /**
     * @override
     * @param {string} name
     * @return {?string}
     */
    enumValueForName: function(name)
    {
        this._initialize();
        if (name in this._enumNameToValue)
            return "" + this._enumNameToValue[name];
        return null;
    },

    /**
     * @override
     * @param {number} value
     * @param {Array.<string>=} options
     * @return {?string}
     */
    enumNameForValue: function(value, options)
    {
        this._initialize();
        options = options || [];
        for (var i = 0, n = options.length; i < n; ++i) {
            if (this._enumNameToValue[options[i]] === value)
                return options[i];
        }
        var names = this._enumValueToNames[value];
        if (!names || names.length !== 1)
            return null;
        return names[0];
    },

    /**
     * @param {!ReplayableCall} replayableCall
     * @return {Object}
     */
    _findEnumsInfo: function(replayableCall)
    {
        function findMaxArgumentIndex(enumsInfo)
        {
            var result = -1;
            var enumArgsIndexes = enumsInfo["enum"] || [];
            for (var i = 0, n = enumArgsIndexes.length; i < n; ++i)
                result = Math.max(result, enumArgsIndexes[i]);
            var bitfieldArgsIndexes = enumsInfo["bitfield"] || [];
            for (var i = 0, n = bitfieldArgsIndexes.length; i < n; ++i)
                result = Math.max(result, bitfieldArgsIndexes[i]);
            return result;
        }

        var result = null;
        for (var i = 0, enumsInfo; enumsInfo = WebGLCallFormatter.EnumsInfo[i]; ++i) {
            if (enumsInfo["aname"] !== replayableCall.functionName())
                continue;
            var argsCount = replayableCall.args().length;
            var maxArgumentIndex = findMaxArgumentIndex(enumsInfo);
            if (maxArgumentIndex >= argsCount)
                continue;
            // To resolve ambiguity (see texImage2D, texSubImage2D) choose description with max argument indexes.
            if (!result || findMaxArgumentIndex(result) < maxArgumentIndex)
                result = enumsInfo;
        }
        return result;
    },

    /**
     * @param {?CanvasAgent.CallArgument|undefined} callArgument
     * @param {Array.<string>=} options
     */
    _formatEnumValue: function(callArgument, options)
    {
        if (!callArgument || isNaN(callArgument.description))
            return;
        this._initialize();
        var value = +callArgument.description;
        var enumName = this.enumNameForValue(value, options);
        if (enumName)
            callArgument.enumName = enumName;
    },

    /**
     * @param {?CanvasAgent.CallArgument|undefined} callArgument
     * @param {Array.<string>=} options
     */
    _formatEnumBitmaskValue: function(callArgument, options)
    {
        if (!callArgument || isNaN(callArgument.description))
            return;
        this._initialize();
        var value = +callArgument.description;
        options = options || [];
        /** @type {!Array.<string>} */
        var result = [];
        for (var i = 0, n = options.length; i < n; ++i) {
            var bitValue = this._enumNameToValue[options[i]] || 0;
            if (value & bitValue) {
                result.push(options[i]);
                value &= ~bitValue;
            }
        }
        while (value) {
            var nextValue = value & (value - 1);
            var bitValue = value ^ nextValue;
            var names = this._enumValueToNames[bitValue];
            if (!names || names.length !== 1) {
                console.warn("Ambiguous WebGL enum names for value " + bitValue + ": " + names);
                return;
            }
            result.push(names[0]);
            value = nextValue;
        }
        result.sort();
        callArgument.enumName = result.join(" | ");
    },

    _initialize: function()
    {
        if (this._enumNameToValue)
            return;

        /** @type {!Object.<string, number>} */
        this._enumNameToValue = Object.create(null);
        /** @type {!Object.<number, !Array.<string>>} */
        this._enumValueToNames = Object.create(null);

        /**
         * @param {Object} obj
         * @this WebGLCallFormatter
         */
        function iterateWebGLEnums(obj)
        {
            if (!obj)
                return;
            for (var property in obj) {
                if (TypeUtils.isEnumPropertyName(property, obj)) {
                    var value = /** @type {number} */ (obj[property]);
                    this._enumNameToValue[property] = value;
                    var names = this._enumValueToNames[value];
                    if (names) {
                        if (names.indexOf(property) === -1)
                            names.push(property);
                    } else
                        this._enumValueToNames[value] = [property];
                }
            }
        }

        /**
         * @param {!Array.<string>} values
         * @return {string}
         */
        function commonSubstring(values)
        {
            var length = values.length;
            for (var i = 0; i < length; ++i) {
                for (var j = 0; j < length; ++j) {
                    if (values[j].indexOf(values[i]) === -1)
                        break;
                }
                if (j === length)
                    return values[i];
            }
            return "";
        }

        var gl = this._createUninstrumentedWebGLRenderingContext();
        iterateWebGLEnums.call(this, gl);

        var extensions = gl.getSupportedExtensions() || [];
        for (var i = 0, n = extensions.length; i < n; ++i)
            iterateWebGLEnums.call(this, gl.getExtension(extensions[i]));

        // Sort to get rid of ambiguity.
        for (var value in this._enumValueToNames) {
            var names = this._enumValueToNames[value];
            if (names.length > 1) {
                // Choose one enum name if possible. For example:
                //   [BLEND_EQUATION, BLEND_EQUATION_RGB] => BLEND_EQUATION
                //   [COLOR_ATTACHMENT0, COLOR_ATTACHMENT0_WEBGL] => COLOR_ATTACHMENT0
                var common = commonSubstring(names);
                if (common)
                    this._enumValueToNames[value] = [common];
                else
                    this._enumValueToNames[value] = names.sort();
            }
        }
    },

    /**
     * @return {WebGLRenderingContext}
     */
    _createUninstrumentedWebGLRenderingContext: function()
    {
        var canvas = /** @type {HTMLCanvasElement} */ (inspectedWindow.document.createElement("canvas"));
        var contextIds = ["experimental-webgl", "webkit-3d", "3d"];
        for (var i = 0, contextId; contextId = contextIds[i]; ++i) {
            var context = canvas.getContext(contextId);
            if (context)
                return /** @type {WebGLRenderingContext} */ (Resource.wrappedObject(context));
        }
        return null;
    },

    __proto__: CallFormatter.prototype
}

CallFormatter.register("CanvasRenderingContext2D", new CallFormatter(CanvasRenderingContext2DResource.DrawingMethods));
CallFormatter.register("WebGLRenderingContext", new WebGLCallFormatter(WebGLRenderingContextResource.DrawingMethods));

/**
 * @constructor
 */
function TraceLog()
{
    /** @type {!Array.<ReplayableCall>} */
    this._replayableCalls = [];
    /** @type {!Cache.<ReplayableResource>} */
    this._replayablesCache = new Cache();
    /** @type {!Object.<number, boolean>} */
    this._frameEndCallIndexes = {};
}

TraceLog.prototype = {
    /**
     * @return {number}
     */
    size: function()
    {
        return this._replayableCalls.length;
    },

    /**
     * @return {!Array.<ReplayableCall>}
     */
    replayableCalls: function()
    {
        return this._replayableCalls;
    },

    /**
     * @param {number} id
     * @return {ReplayableResource|undefined}
     */
    replayableResource: function(id)
    {
        return this._replayablesCache.get(id);
    },

    /**
     * @param {!Resource} resource
     */
    captureResource: function(resource)
    {
        resource.toReplayable(this._replayablesCache);
    },

    /**
     * @param {!Call} call
     */
    addCall: function(call)
    {
        this._replayableCalls.push(call.toReplayable(this._replayablesCache));
    },

    addFrameEndMark: function()
    {
        var index = this._replayableCalls.length - 1;
        if (index >= 0)
            this._frameEndCallIndexes[index] = true;
    },

    /**
     * @param {number} index
     * @return {boolean}
     */
    isFrameEndCallAt: function(index)
    {
        return !!this._frameEndCallIndexes[index];
    }
}

/**
 * @constructor
 * @param {!TraceLog} traceLog
 */
function TraceLogPlayer(traceLog)
{
    /** @type {!TraceLog} */
    this._traceLog = traceLog;
    /** @type {number} */
    this._nextReplayStep = 0;
    /** @type {!Cache.<Resource>} */
    this._replayWorldCache = new Cache();
}

TraceLogPlayer.prototype = {
    /**
     * @return {!TraceLog}
     */
    traceLog: function()
    {
        return this._traceLog;
    },

    /**
     * @param {number} id
     * @return {Resource|undefined}
     */
    replayWorldResource: function(id)
    {
        return this._replayWorldCache.get(id);
    },

    /**
     * @return {number}
     */
    nextReplayStep: function()
    {
        return this._nextReplayStep;
    },

    reset: function()
    {
        this._nextReplayStep = 0;
        this._replayWorldCache.reset();
    },

    /**
     * @return {Call}
     */
    step: function()
    {
        return this.stepTo(this._nextReplayStep);
    },

    /**
     * @param {number} stepNum
     * @return {Call}
     */
    stepTo: function(stepNum)
    {
        stepNum = Math.min(stepNum, this._traceLog.size() - 1);
        console.assert(stepNum >= 0);
        if (this._nextReplayStep > stepNum)
            this.reset();
        // FIXME: Replay all the cached resources first to warm-up.
        var lastCall = null;
        var replayableCalls = this._traceLog.replayableCalls();
        while (this._nextReplayStep <= stepNum)
            lastCall = replayableCalls[this._nextReplayStep++].replay(this._replayWorldCache);
        return lastCall;
    },

    /**
     * @return {Call}
     */
    replay: function()
    {
        return this.stepTo(this._traceLog.size() - 1);
    }
}

/**
 * @constructor
 */
function ResourceTrackingManager()
{
    this._capturing = false;
    this._stopCapturingOnFrameEnd = false;
    this._lastTraceLog = null;
}

ResourceTrackingManager.prototype = {
    /**
     * @return {boolean}
     */
    capturing: function()
    {
        return this._capturing;
    },

    /**
     * @return {TraceLog}
     */
    lastTraceLog: function()
    {
        return this._lastTraceLog;
    },

    /**
     * @param {!Resource} resource
     */
    registerResource: function(resource)
    {
        resource.setManager(this);
    },

    startCapturing: function()
    {
        if (!this._capturing)
            this._lastTraceLog = new TraceLog();
        this._capturing = true;
        this._stopCapturingOnFrameEnd = false;
    },

    /**
     * @param {TraceLog=} traceLog
     */
    stopCapturing: function(traceLog)
    {
        if (traceLog && this._lastTraceLog !== traceLog)
            return;
        this._capturing = false;
        this._stopCapturingOnFrameEnd = false;
        if (this._lastTraceLog)
            this._lastTraceLog.addFrameEndMark();
    },

    /**
     * @param {!TraceLog} traceLog
     */
    dropTraceLog: function(traceLog)
    {
        this.stopCapturing(traceLog);
        if (this._lastTraceLog === traceLog)
            this._lastTraceLog = null;
    },

    captureFrame: function()
    {
        this._lastTraceLog = new TraceLog();
        this._capturing = true;
        this._stopCapturingOnFrameEnd = true;
    },

    /**
     * @param {!Resource} resource
     * @param {Array|Arguments} args
     */
    captureArguments: function(resource, args)
    {
        if (!this._capturing)
            return;
        this._lastTraceLog.captureResource(resource);
        for (var i = 0, n = args.length; i < n; ++i) {
            var res = Resource.forObject(args[i]);
            if (res)
                this._lastTraceLog.captureResource(res);
        }
    },

    /**
     * @param {!Call} call
     */
    captureCall: function(call)
    {
        if (!this._capturing)
            return;
        this._lastTraceLog.addCall(call);
    },

    markFrameEnd: function()
    {
        if (!this._lastTraceLog)
            return;
        this._lastTraceLog.addFrameEndMark();
        if (this._stopCapturingOnFrameEnd && this._lastTraceLog.size())
            this.stopCapturing(this._lastTraceLog);
    }
}

/**
 * @constructor
 */
var InjectedCanvasModule = function()
{
    /** @type {!ResourceTrackingManager} */
    this._manager = new ResourceTrackingManager();
    /** @type {number} */
    this._lastTraceLogId = 0;
    /** @type {!Object.<string, TraceLog>} */
    this._traceLogs = {};
    /** @type {!Object.<string, TraceLogPlayer>} */
    this._traceLogPlayers = {};
}

InjectedCanvasModule.prototype = {
    /**
     * @param {!WebGLRenderingContext} glContext
     * @return {Object}
     */
    wrapWebGLContext: function(glContext)
    {
        var resource = Resource.forObject(glContext) || new WebGLRenderingContextResource(glContext);
        this._manager.registerResource(resource);
        return resource.proxyObject();
    },

    /**
     * @param {!CanvasRenderingContext2D} context
     * @return {Object}
     */
    wrapCanvas2DContext: function(context)
    {
        var resource = Resource.forObject(context) || new CanvasRenderingContext2DResource(context);
        this._manager.registerResource(resource);
        return resource.proxyObject();
    },

    /**
     * @return {CanvasAgent.TraceLogId}
     */
    captureFrame: function()
    {
        return this._callStartCapturingFunction(this._manager.captureFrame);
    },

    /**
     * @return {CanvasAgent.TraceLogId}
     */
    startCapturing: function()
    {
        return this._callStartCapturingFunction(this._manager.startCapturing);
    },

    markFrameEnd: function()
    {
        this._manager.markFrameEnd();
    },

    /**
     * @param {function(this:ResourceTrackingManager)} func
     * @return {CanvasAgent.TraceLogId}
     */
    _callStartCapturingFunction: function(func)
    {
        var oldTraceLog = this._manager.lastTraceLog();
        func.call(this._manager);
        var traceLog = this._manager.lastTraceLog();
        if (traceLog === oldTraceLog) {
            for (var id in this._traceLogs) {
                if (this._traceLogs[id] === traceLog)
                    return id;
            }
        }
        var id = this._makeTraceLogId();
        this._traceLogs[id] = traceLog;
        return id;
    },

    /**
     * @param {CanvasAgent.TraceLogId} id
     */
    stopCapturing: function(id)
    {
        var traceLog = this._traceLogs[id];
        if (traceLog)
            this._manager.stopCapturing(traceLog);
    },

    /**
     * @param {CanvasAgent.TraceLogId} id
     */
    dropTraceLog: function(id)
    {
        var traceLog = this._traceLogs[id];
        if (traceLog)
            this._manager.dropTraceLog(traceLog);
        delete this._traceLogs[id];
        delete this._traceLogPlayers[id];
        injectedScript.releaseObjectGroup(id);
    },

    /**
     * @param {CanvasAgent.TraceLogId} id
     * @param {number=} startOffset
     * @param {number=} maxLength
     * @return {!CanvasAgent.TraceLog|string}
     */
    traceLog: function(id, startOffset, maxLength)
    {
        var traceLog = this._traceLogs[id];
        if (!traceLog)
            return "Error: Trace log with the given ID not found.";

        // Ensure last call ends a frame.
        traceLog.addFrameEndMark();

        var replayableCalls = traceLog.replayableCalls();
        if (typeof startOffset !== "number")
            startOffset = 0;
        if (typeof maxLength !== "number")
            maxLength = replayableCalls.length;

        var fromIndex = Math.max(0, startOffset);
        var toIndex = Math.min(replayableCalls.length - 1, fromIndex + maxLength - 1);

        var alive = this._manager.capturing() && this._manager.lastTraceLog() === traceLog;
        var result = {
            id: id,
            /** @type {Array.<CanvasAgent.Call>} */
            calls: [],
            /** @type {Array.<CanvasAgent.CallArgument>} */
            contexts: [],
            alive: alive,
            startOffset: fromIndex,
            totalAvailableCalls: replayableCalls.length
        };
        /** @type {!Object.<string, boolean>} */
        var contextIds = {};
        for (var i = fromIndex; i <= toIndex; ++i) {
            var call = replayableCalls[i];
            var resource = call.replayableResource();
            var contextResource = resource.contextResource();
            var stackTrace = call.stackTrace();
            var callFrame = stackTrace ? stackTrace.callFrame(0) || {} : {};
            var item = CallFormatter.forResource(resource).formatCall(call);
            item.contextId = CallFormatter.makeStringResourceId(contextResource.id());
            item.sourceURL = callFrame.sourceURL;
            item.lineNumber = callFrame.lineNumber;
            item.columnNumber = callFrame.columnNumber;
            item.isFrameEndCall = traceLog.isFrameEndCallAt(i);
            result.calls.push(item);
            if (!contextIds[item.contextId]) {
                contextIds[item.contextId] = true;
                result.contexts.push(CallFormatter.forResource(resource).formatValue(contextResource));
            }
        }
        return result;
    },

    /**
     * @param {CanvasAgent.TraceLogId} traceLogId
     * @param {number} stepNo
     * @return {{resourceState: !CanvasAgent.ResourceState, replayTime: number}|string}
     */
    replayTraceLog: function(traceLogId, stepNo)
    {
        var traceLog = this._traceLogs[traceLogId];
        if (!traceLog)
            return "Error: Trace log with the given ID not found.";
        this._traceLogPlayers[traceLogId] = this._traceLogPlayers[traceLogId] || new TraceLogPlayer(traceLog);

        injectedScript.releaseObjectGroup(traceLogId);

        var beforeTime = TypeUtils.now();
        var lastCall = this._traceLogPlayers[traceLogId].stepTo(stepNo);
        var replayTime = Math.max(0, TypeUtils.now() - beforeTime);

        var resource = lastCall.resource();
        var dataURL = resource.toDataURL();
        if (!dataURL) {
            resource = resource.contextResource();
            dataURL = resource.toDataURL();
        }
        return {
            resourceState: this._makeResourceState(resource.id(), traceLogId, resource, dataURL),
            replayTime: replayTime
        };
    },

    /**
     * @param {CanvasAgent.TraceLogId} traceLogId
     * @param {CanvasAgent.ResourceId} stringResourceId
     * @return {!CanvasAgent.ResourceState|string}
     */
    resourceState: function(traceLogId, stringResourceId)
    {
        var traceLog = this._traceLogs[traceLogId];
        if (!traceLog)
            return "Error: Trace log with the given ID not found.";

        var parsedStringId1 = this._parseStringId(traceLogId);
        var parsedStringId2 = this._parseStringId(stringResourceId);
        if (parsedStringId1.injectedScriptId !== parsedStringId2.injectedScriptId)
            return "Error: Both IDs must point to the same injected script.";

        var resourceId = parsedStringId2.resourceId;
        if (!resourceId)
            return "Error: Wrong resource ID: " + stringResourceId;

        var traceLogPlayer = this._traceLogPlayers[traceLogId];
        var resource = traceLogPlayer && traceLogPlayer.replayWorldResource(resourceId);
        return this._makeResourceState(resourceId, traceLogId, resource);
    },

    /**
     * @param {CanvasAgent.TraceLogId} traceLogId
     * @param {number} callIndex
     * @param {number} argumentIndex
     * @param {string} objectGroup
     * @return {{result:(!RuntimeAgent.RemoteObject|undefined), resourceState:(!CanvasAgent.ResourceState|undefined)}|string}
     */
    evaluateTraceLogCallArgument: function(traceLogId, callIndex, argumentIndex, objectGroup)
    {
        var traceLog = this._traceLogs[traceLogId];
        if (!traceLog)
            return "Error: Trace log with the given ID not found.";

        var replayableCall = traceLog.replayableCalls()[callIndex];
        if (!replayableCall)
            return "Error: No call found at index " + callIndex;

        var value;
        if (replayableCall.isPropertySetter())
            value = replayableCall.propertyValue();
        else if (argumentIndex === -1)
            value = replayableCall.result();
        else {
            var args = replayableCall.args();
            if (argumentIndex < 0 || argumentIndex >= args.length)
                return "Error: No argument found at index " + argumentIndex + " for call at index " + callIndex;
            value = args[argumentIndex];
        }

        if (value instanceof ReplayableResource) {
            var traceLogPlayer = this._traceLogPlayers[traceLogId];
            var resource = traceLogPlayer && traceLogPlayer.replayWorldResource(value.id());
            var resourceState = this._makeResourceState(value.id(), traceLogId, resource);
            return { resourceState: resourceState };
        }

        var remoteObject = injectedScript.wrapObject(value, objectGroup, true, false);
        return { result: remoteObject };
    },

    /**
     * @return {CanvasAgent.TraceLogId}
     */
    _makeTraceLogId: function()
    {
        return "{\"injectedScriptId\":" + injectedScriptId + ",\"traceLogId\":" + (++this._lastTraceLogId) + "}";
    },

    /**
     * @param {number} resourceId
     * @param {CanvasAgent.TraceLogId} traceLogId
     * @param {Resource|undefined} resource
     * @param {string=} overrideImageURL
     * @return {!CanvasAgent.ResourceState}
     */
    _makeResourceState: function(resourceId, traceLogId, resource, overrideImageURL)
    {
        var result = {
            id: CallFormatter.makeStringResourceId(resourceId),
            traceLogId: traceLogId
        };
        if (resource) {
            result.imageURL = overrideImageURL || resource.toDataURL();
            result.descriptors = CallFormatter.forResource(resource).formatResourceStateDescriptors(resource.currentState(), traceLogId);
        }
        return result;
    },

    /**
     * @param {string} stringId
     * @return {{injectedScriptId: number, traceLogId: ?number, resourceId: ?number}}
     */
    _parseStringId: function(stringId)
    {
        return InjectedScriptHost.evaluate("(" + stringId + ")");
    }
}

var injectedCanvasModule = new InjectedCanvasModule();
return injectedCanvasModule;

})
