/// <summary>
        /// Called when there is no more data to be processed. It is expected
        /// that whatever data was retained in the last ProcessData() call, it
        /// should be returned now by setting |remainder| if appropriate.
        /// </summary>
        private void drain(cef_content_filter_t* self, cef_stream_reader_t** remainder)
        {
            ThrowIfObjectDisposed();

            CefStreamReader m_remainder;

            this.Drain(out m_remainder);

            if (m_remainder != null)
            {
                *remainder = m_remainder.GetNativePointerAndAddRef();
            }
        }
        /// <summary>
        /// Set |substitute_data| to the replacement for the data in |data| if
        /// data should be modified.
        /// </summary>
        private void process_data(cef_content_filter_t* self, /*const*/ void* data, int data_size, cef_stream_reader_t** substitute_data)
        {
            ThrowIfObjectDisposed();

            var m_stream = new UnmanagedMemoryStream((byte*)data, data_size, data_size, FileAccess.Read);
            CefStreamReader m_substitute_data;

            this.ProcessData(m_stream, out m_substitute_data);

            if (m_substitute_data != null)
            {
                *substitute_data = m_substitute_data.GetNativePointerAndAddRef();
            }

            m_stream.Dispose();
        }
        /// <summary>
        /// Called on the IO thread before a resource is loaded.  To allow the
        /// resource to load normally return false. To redirect the resource to a
        /// new url populate the |redirectUrl| value and return false.  To
        /// specify data for the resource return a CefStream object in
        /// |resourceStream|, use the |response| object to set mime type, HTTP
        /// status code and optional header values, and return false. To cancel
        /// loading of the resource return true. Any modifications to |request|
        /// will be observed.  If the URL in |request| is changed and
        /// |redirectUrl| is also set, the URL in |request| will be used.
        /// </summary>
        private int on_before_resource_load(cef_request_handler_t* self, cef_browser_t* browser, cef_request_t* request, cef_string_t* redirectUrl, cef_stream_reader_t** resourceStream, cef_response_t* response, int loadFlags)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_request = CefRequest.From(request);
            string m_redirectUrl;
            CefStreamReader m_resourceStream;
            var m_response = CefResponse.From(response);

            var handled = this.OnBeforeResourceLoad(m_browser, m_request, out m_redirectUrl, out m_resourceStream, m_response, loadFlags);

            if (!handled)
            {
                if (!string.IsNullOrEmpty(m_redirectUrl))
                {
                    cef_string_t.Copy(m_redirectUrl, redirectUrl);
                }

                if (m_resourceStream != null)
                {
                    *resourceStream = m_resourceStream.GetNativePointerAndAddRef();
                }
            }

            return handled ? 1 : 0;
        }