private void RemoveAndCancelCall(BrowserCallInfo info)
        {
            _pendingCallbacks.Remove(info);

            if (info.RequestMessage.MessageType == PluginMessageType.FunctionCallback)
            {
                CancelUnhandledQuery(info.Browser, info.RequestMessage);
            }

            info.Dispose();
        }
        /// <summary>
        /// Send a response to a function call.
        /// Can be called on any thread as the CEF API involved (<see cref="CefBrowser.SendProcessMessage"/>) can be called on any thread when in the browser process.
        /// </summary>
        /// <param name="info">
        /// The callback that was created when the function was invoked.
        /// </param>
        /// <param name="result">
        /// The result of the function (result, errorCode, error).
        /// </param>
        public void SendFunctionResponse(BrowserCallInfo info, ResultData result)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            if (result == null)
            {
                throw new ArgumentNullException("result");
            }

            if (!info.IsRetained)
            {
                _pendingCallbacks.Remove(info);
            }

            SendFunctionResponse(info.Browser, info.RequestMessage, result);

            if (!info.IsRetained)
            {
                info.Dispose();
            }
        }