function deprecationWarning(message, oncePerCaller, callerStackPos) {
        // If oncePerCaller isn't set, then only show the message once no matter who calls it.
        if (!message || (!oncePerCaller && displayedWarnings[message])) {
            return;
        }

        // Don't show the warning again if we've already gotten it from the current caller.
        // The true caller location is the fourth line in the stack trace:
        // * 0 is the word "Error"
        // * 1 is this function
        // * 2 is the caller of this function (the one throwing the deprecation warning)
        // * 3 is the actual caller of the deprecated function.
        var stack = new Error().stack,
            callerLocation = stack.split("\n")[callerStackPos || 3];
        if (oncePerCaller && displayedWarnings[message] && displayedWarnings[message][callerLocation]) {
            return;
        }

        console.warn(message + "\n" + _trimStack(stack));
        if (!displayedWarnings[message]) {
            displayedWarnings[message] = {};
        }
        displayedWarnings[message][callerLocation] = true;
    }
Show deprecation warning with the call stack if it
has never been displayed before.
@param {!string} message The deprecation message to be displayed.
@param {boolean=} oncePerCaller If true, displays the message once for each unique call location.
    If false (the default), only displays the message once no matter where it's called from.
    Note that setting this to true can cause a slight performance hit (because it has to generate
    a stack trace), so don't set this for functions that you expect to be called from performance-
    sensitive code (e.g. tight loops).
@param {number=} callerStackPos Only used if oncePerCaller=true. Overrides the `Error().stack` depth
    where the client-code caller can be found. Only needed if extra shim layers are involved.