/// <summary>
        /// Called when the browser component is about to loose focus. For
        /// instance, if focus was on the last HTML element and the user pressed
        /// the TAB key. |next| will be true if the browser is giving focus to
        /// the next component and false if the browser is giving focus to the
        /// previous component.
        /// </summary>
        private void on_take_focus(cef_focus_handler_t* self, cef_browser_t* browser, int next)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);

            this.OnTakeFocus(m_browser, next != 0);
        }
        /// <summary>
        /// Called when the browser is done loading a frame. The |frame| value
        /// will never be empty -- call the IsMain() method to check if this
        /// frame is the main frame. Multiple frames may be loading at the same
        /// time. Sub-frames may start or continue loading after the main frame
        /// load has ended. This method will always be called for all frames
        /// irrespective of whether the request completes successfully.
        /// </summary>
        private void on_load_end(cef_load_handler_t* self, cef_browser_t* browser, cef_frame_t* frame, int httpStatusCode)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_frame = CefFrame.From(frame);
            this.OnLoadEnd(m_browser, m_frame, httpStatusCode);
        }
        /// <summary>
        /// Called when the browser's zoom level has been set to |zoomLevel| for
        /// the given |url|. Return true (1) to indicate that the new setting has
        /// been handled. Return false (0) to use the browser's default zoom
        /// handling behavior.
        /// </summary>
        private int on_set_zoom_level(cef_zoom_handler_t* self, cef_browser_t* browser, /*const*/ cef_string_t* url, double zoomLevel)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_url = cef_string_t.ToString(url);

            return OnSetZoomLevel(m_browser, m_url, zoomLevel) ? 1 : 0;
        }
        /// <summary>
        /// Called when the browser component is requesting focus. |source| indicates
        /// where the focus request is originating from. Return false to allow the
        /// focus to be set or true to cancel setting the focus.
        /// </summary>
        private int on_set_focus(cef_focus_handler_t* self, cef_browser_t* browser, cef_handler_focus_source_t source)
        {
            ThrowIfObjectDisposed();

            var mBrowser = CefBrowser.From(browser);
            var handled = this.OnSetFocus(mBrowser, (CefHandlerFocusSource)source);

            return handled ? 1 : 0;
        }
        /// <summary>
        /// Called when a geolocation access request is canceled.
        /// |requesting_url| is the URL that originally requested permission and
        /// |request_id| is the unique ID for the permission request.
        /// </summary>
        private void on_cancel_geolocation_permission(cef_geolocation_handler_t* self, cef_browser_t* browser, /*const*/ cef_string_t* requesting_url, int request_id)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_requestingUrl = cef_string_t.ToString(requesting_url);

            OnCancelGeolocationPermission(m_browser, m_requestingUrl, request_id);
        }
        /// <summary>
        /// Called immediately before the V8 context for a frame is released. No
        /// references to the context should be kept after this function is
        /// called.
        /// </summary>
        private void on_context_released(cef_v8context_handler_t* self, cef_browser_t* browser, cef_frame_t* frame, cef_v8context_t* context)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_frame = CefFrame.From(frame);
            var m_context = CefV8Context.From(context);

            this.OnContextReleased(m_browser, m_frame, m_context);
        }
        /// <summary>
        /// Called when a page requests permission to access geolocation information.
        /// |requesting_url| is the URL requesting permission and |request_id| is the
        /// unique ID for the permission request. Call
        /// cef_geolocation_callback_t::Continue to allow or deny the permission
        /// request.
        /// </summary>
        private void on_request_geolocation_permission(cef_geolocation_handler_t* self, cef_browser_t* browser, /*const*/ cef_string_t* requesting_url, int request_id, cef_geolocation_callback_t* callback)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_requestingUrl = cef_string_t.ToString(requesting_url);
            var m_callback = CefGeolocationCallback.From(callback);

            OnRequestGeolocationPermission(m_browser, m_requestingUrl, request_id, m_callback);
        }
        /// <summary>
        /// Called when a frame's address has changed.
        /// </summary>
        private void on_address_change(cef_display_handler_t* self, cef_browser_t* browser, cef_frame_t* frame, /*const*/ cef_string_t* url)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_frame = CefFrame.From(frame);
            var m_url = cef_string_t.ToString(url);

            this.OnAddressChange(m_browser, m_frame, m_url);
        }
        /// <summary>
        /// Called to report find results returned by CefBrowser::Find().
        /// |identifer| is the identifier passed to CefBrowser::Find(), |count|
        /// is the number of matches currently identified, |selectionRect| is the
        /// location of where the match was found (in window coordinates),
        /// |activeMatchOrdinal| is the current position in the search results,
        /// and |finalUpdate| is true if this is the last find notification.
        /// </summary>
        private void on_find_result(cef_find_handler_t* self, cef_browser_t* browser, int identifier, int count, /*const*/ cef_rect_t* selectionRect, int activeMatchOrdinal, int finalUpdate)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_selectionRect = CefRect.From(selectionRect);
            var m_finalUpdate = finalUpdate != 0;

            this.OnFindResult(m_browser, identifier, count, m_selectionRect, activeMatchOrdinal, m_finalUpdate);
        }
        /// <summary>
        /// Called when a window has recieved a request to close. Return false to
        /// proceed with the window close or true to cancel the window close. If
        /// this is a modal window and a custom modal loop implementation was
        /// provided in RunModal() this callback should be used to restore the
        /// opener window to a usable state.
        /// </summary>
        private int do_close(cef_life_span_handler_t* self, cef_browser_t* browser)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);

            var handled = this.DoClose(m_browser);

            return handled ? 1 : 0;
        }
        /// <summary>
        /// Called when an option is selected from the default context menu.
        /// Return false to execute the default action or true to cancel the
        /// action.
        /// </summary>
        private int on_menu_action(cef_menu_handler_t* self, cef_browser_t* browser, cef_menu_id_t menuId)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_menuId = (CefHandlerMenuId)menuId;

            var handled = this.OnMenuAction(m_browser, m_menuId);

            return handled ? 1 : 0;
        }
        /// <summary>
        /// Called when the browser window initiates a drag event. |dragData|
        /// contains the drag event data and |mask| represents the type of drag
        /// operation. Return false for default drag handling behavior or true to
        /// cancel the drag event.
        /// </summary>
        private int on_drag_start(cef_drag_handler_t* self, cef_browser_t* browser, cef_drag_data_t* dragData, cef_drag_operations_mask_t mask)
        {
            ThrowIfObjectDisposed();

            var mBrowser = CefBrowser.From(browser);
            var mDragData = CefDragData.From(dragData);

            var handled = this.OnDragStart(mBrowser, mDragData, (CefDragOperations)mask);

            return handled ? 1 : 0;
        }
        /// <summary>
        /// Called on the UI thread before a script extension is loaded.
        /// Return false to let the extension load normally.
        /// </summary>
        private int on_before_script_extension_load(cef_permission_handler_t* self, cef_browser_t* browser, cef_frame_t* frame, /*const*/ cef_string_t* extensionName)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_frame = CefFrame.From(frame);
            var m_extensionName = cef_string_t.ToString(extensionName);

            var handled = this.OnBeforeScriptExtensionLoad(m_browser, m_frame, m_extensionName);

            return handled ? 1 : 0;
        }
        /// <summary>
        /// Called  to run a JavaScript alert message. Return false to display
        /// the default alert or true if you displayed a custom alert.
        /// </summary>
        private int on_jsalert(cef_jsdialog_handler_t* self, cef_browser_t* browser, cef_frame_t* frame, /*const*/ cef_string_t* message)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_frame = CefFrame.From(frame);
            var m_message = cef_string_t.ToString(message);

            var handled = this.OnJSAlert(m_browser, m_frame, m_message);

            return handled ? 1 : 0;
        }
        /// <summary>
        /// Called for global uncaught exceptions. Execution of this callback is
        /// disabled by default. To enable set
        /// CefSettings.uncaught_exception_stack_size &gt; 0.
        /// </summary>
        private void on_uncaught_exception(cef_v8context_handler_t* self, cef_browser_t* browser, cef_frame_t* frame, cef_v8context_t* context, cef_v8exception_t* exception, cef_v8stack_trace_t* stackTrace)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_frame = CefFrame.From(frame);
            var m_context = CefV8Context.From(context);
            var m_exception = CefV8Exception.From(exception);
            var m_stackTrace = CefV8StackTrace.From(stackTrace);

            this.OnUncaughtException(m_browser, m_frame, m_context, m_exception, m_stackTrace);
        }
        /// <summary>
        /// Return a new scheme handler instance to handle the request. |browser| will
        /// be the browser window that initiated the request. If the request was
        /// initiated using the CefWebURLRequest API |browser| will be NULL.
        /// </summary>
        private cef_scheme_handler_t* create(cef_scheme_handler_factory_t* self, cef_browser_t* browser, /*const*/ cef_string_t* scheme_name, cef_request_t* request)
        {
            ThrowIfObjectDisposed();

            var mBrowser = CefBrowser.FromOrDefault(browser);
            var m_schemeName = cef_string_t.ToString(scheme_name);
            var m_request = CefRequest.From(request);

            var handler = this.Create(mBrowser, m_schemeName, m_request);

            return handler.GetNativePointerAndAddRef();
        }
        /// <summary>
        /// Called before a context menu is displayed. Return false to display
        /// the default context menu or true to cancel the display.
        /// </summary>
        private int on_before_menu(cef_menu_handler_t* self, cef_browser_t* browser, /*const*/ cef_menu_info_t* menuInfo)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_menuInfo = CefMenuInfo.From(menuInfo);

            var handled = this.OnBeforeMenu(m_browser, m_menuInfo);

            //m_menuInfo.Dispose();

            return handled ? 1 : 0;
        }
        /// <summary>
        /// Called when a new node in the the browser gets focus. The |node|
        /// value may be empty if no specific node has gained focus. The node
        /// object passed to this method represents a snapshot of the DOM at the
        /// time this method is executed. DOM objects are only valid for the
        /// scope of this method. Do not keep references to or attempt to access
        /// any DOM objects outside the scope of this method.
        /// </summary>
        private void on_focused_node_changed(cef_focus_handler_t* self, cef_browser_t* browser, cef_frame_t* frame, cef_domnode_t* node)
        {
            ThrowIfObjectDisposed();

            var mBrowser = CefBrowser.From(browser);
            var mFrame = CefFrame.From(frame);
            var mNode = CefDomNode.FromOrDefault(node);

            // TODO: DOM nodes context
            this.OnFocusedNodeChanged(mBrowser, mFrame, mNode);

            if (mNode != null) mNode.Dispose();
        }
        /// <summary>
        /// Called when the browser component receives a keyboard event. This method
        /// is called both before the event is passed to the renderer and after
        /// JavaScript in the page has had a chance to handle the event. |type| is the
        /// type of keyboard event, |code| is the windows scan-code for the event,
        /// |modifiers| is a set of bit- flags describing any pressed modifier keys and
        /// |isSystemKey| is true if Windows considers this a 'system key' message (see
        /// http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx). If
        /// |isAfterJavaScript| is true then JavaScript in the page has had a chance
        /// to handle the event and has chosen not to. Only RAWKEYDOWN, KEYDOWN and
        /// CHAR events will be sent with |isAfterJavaScript| set to true. Return
        /// true if the keyboard event was handled or false to allow continued handling
        /// of the event by the renderer.
        /// </summary>
        private int on_key_event(cef_keyboard_handler_t* self, cef_browser_t* browser, cef_handler_keyevent_type_t type, int code, int modifiers, int isSystemKey, int isAfterJavaScript)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_type = (CefHandlerKeyEventType)type;
            var m_isSystemKey = isSystemKey != 0;
            var mIsAfterJavaScript = isAfterJavaScript != 0;

            var handled = this.OnKeyEvent(m_browser, m_type, code, (CefHandlerKeyEventModifiers)modifiers, m_isSystemKey, mIsAfterJavaScript);

            return handled ? 1 : 0;
        }
        /// <summary>
        /// Called when the browser wants to retrieve the zoom level for the
        /// given |url|. Return true (1) if |zoomLevel| has been set to the
        /// custom zoom level. Return false (0) for the browser's default zoom
        /// handling behavior.
        /// </summary>
        private int on_get_zoom_level(cef_zoom_handler_t* self, cef_browser_t* browser, /*const*/ cef_string_t* url, double* zoomLevel)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_url = cef_string_t.ToString(url);

            double m_zoomLevel = 0;
            if (OnGetZoomLevel(m_browser, m_url, ref m_zoomLevel))
            {
                *zoomLevel = m_zoomLevel;
                return 1;
            }
            else
                return 0;
        }
        /// <summary>
        /// Called to optionally override the default text for a context menu
        /// item. |label| contains the default text and may be modified to
        /// substitute alternate text.
        /// </summary>
        private void get_menu_label(cef_menu_handler_t* self, cef_browser_t* browser, cef_menu_id_t menuId, cef_string_t* label)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_menuId = (CefHandlerMenuId)menuId;
            var m_label = cef_string_t.ToString(label);

            var o_label = m_label;
            this.GetMenuLabel(m_browser, m_menuId, ref m_label);

            if ((object)m_label != (object)o_label)
            {
                cef_string_t.Copy(m_label, label);
            }
        }
        /// <summary>
        /// Called when the browser fails to load a resource. |errorCode| is the
        /// error code number and |failedUrl| is the URL that failed to load. To
        /// provide custom error text assign the text to |errorText| and return
        /// true. Otherwise, return false for the default error text. See
        /// net\base\net_error_list.h for complete descriptions of the error
        /// codes.
        /// </summary>
        private int on_load_error(cef_load_handler_t* self, cef_browser_t* browser, cef_frame_t* frame, cef_handler_errorcode_t errorCode, /*const*/ cef_string_t* failedUrl, cef_string_t* errorText)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_frame = CefFrame.From(frame);
            var m_failedUrl = cef_string_t.ToString(failedUrl);
            var m_errorText = cef_string_t.ToString(errorText);
            var c_errorText = m_errorText;
            var result = this.OnLoadError(m_browser, m_frame, (CefHandlerErrorCode)errorCode, m_failedUrl, ref m_errorText) ? 1 : 0;
            if ((object)c_errorText != (object)m_errorText)
            {
                cef_string_t.Copy(m_errorText, errorText);
            }
            return result;
        }
        /// <summary>
        /// Called to run a JavaScript confirm request. Return false to display
        /// the default alert or true if you displayed a custom alert. If you
        /// handled the alert set |retval| to true if the user accepted the
        /// confirmation.
        /// </summary>
        private int on_jsconfirm(cef_jsdialog_handler_t* self, cef_browser_t* browser, cef_frame_t* frame, /*const*/ cef_string_t* message, int* retval)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_frame = CefFrame.From(frame);
            var m_message = cef_string_t.ToString(message);
            bool m_retval;

            var handled = this.OnJSConfirm(m_browser, m_frame, m_message, out m_retval);

            if (handled)
            {
                *retval = m_retval ? 1 : 0;
            }

            return handled ? 1 : 0;
        }
        /// <summary>
        /// Called to retrieve the translation from view coordinates to actual
        /// screen coordinates. Return true if the screen coordinates were
        /// provided.
        /// </summary>
        private int get_screen_point(cef_render_handler_t* self, cef_browser_t* browser, int viewX, int viewY, int* screenX, int* screenY)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            int m_screenX;
            int m_screenY;

            var handled = this.GetScreenPoint(m_browser, viewX, viewY, out m_screenX, out m_screenY);

            if (handled)
            {
                *screenX = m_screenX;
                *screenY = m_screenY;
            }

            return handled ? 1 : 0;
        }
        /// <summary>
        /// Called to format print headers and footers. |printInfo| contains
        /// platform- specific information about the printer context. |url| is
        /// the URL if the currently printing page, |title| is the title of the
        /// currently printing page, |currentPage| is the current page number and
        /// |maxPages| is the total number of pages. Six default header locations
        /// are provided by the implementation: top left, top center, top right,
        /// bottom left, bottom center and bottom right. To use one of these
        /// default locations just assign a string to the appropriate variable.
        /// To draw the header and footer yourself return true. Otherwise,
        /// populate the approprate variables and return false.
        /// </summary>
        private int get_print_header_footer(cef_print_handler_t* self, cef_browser_t* browser, cef_frame_t* frame, /*const*/ cef_print_info_t* printInfo, /*const*/ cef_string_t* url, /*const*/ cef_string_t* title, int currentPage, int maxPages, cef_string_t* topLeft, cef_string_t* topCenter, cef_string_t* topRight, cef_string_t* bottomLeft, cef_string_t* bottomCenter, cef_string_t* bottomRight)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_frame = CefFrame.From(frame);
            var m_printInfo = CefPrintInfo.From(printInfo);
            var m_url = cef_string_t.ToString(url);
            var m_title = cef_string_t.ToString(title);

            var m_topLeft = cef_string_t.ToString(topLeft);
            var m_topCenter = cef_string_t.ToString(topCenter);
            var m_topRight = cef_string_t.ToString(topRight);
            var m_bottomLeft = cef_string_t.ToString(bottomLeft);
            var m_bottomCenter = cef_string_t.ToString(bottomCenter);
            var m_bottomRight = cef_string_t.ToString(bottomRight);

            var o_topLeft = m_topLeft;
            var o_topCenter = m_topCenter;
            var o_topRight = m_topRight;
            var o_bottomLeft = m_bottomLeft;
            var o_bottomCenter = m_bottomCenter;
            var o_bottomRight = m_bottomRight;

            var handled = this.GetPrintHeaderFooter(m_browser, m_frame,
                m_printInfo, m_url, m_title, currentPage, maxPages,
                ref m_topLeft, ref m_topCenter, ref m_topRight,
                ref m_bottomLeft, ref m_bottomCenter, ref m_bottomRight);

            m_printInfo.Dispose();

            if (!handled)
            {
                if ((object)m_topLeft != (object)o_topLeft) cef_string_t.Copy(m_topLeft, topLeft);
                if ((object)m_topCenter != (object)o_topCenter) cef_string_t.Copy(m_topCenter, topCenter);
                if ((object)m_topRight != (object)o_topRight) cef_string_t.Copy(m_topRight, topRight);
                if ((object)m_bottomLeft != (object)o_bottomLeft) cef_string_t.Copy(m_bottomLeft, bottomLeft);
                if ((object)m_bottomCenter != (object)o_bottomCenter) cef_string_t.Copy(m_bottomCenter, bottomCenter);
                if ((object)m_bottomRight != (object)o_bottomRight) cef_string_t.Copy(m_bottomRight, bottomRight);
            }

            return handled ? 1 : 0;
        }
        /// <summary>
        /// Called when the navigation state has changed.
        /// </summary>
        private void on_nav_state_change(cef_display_handler_t* self, cef_browser_t* browser, int canGoBack, int canGoForward)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);

            this.OnNavStateChange(m_browser, canGoBack != 0, canGoForward != 0);
        }
        /// <summary>
        /// Called to display a console message.
        /// Return true to stop the message from being output to the console.
        /// </summary>
        private int on_console_message(cef_display_handler_t* self, cef_browser_t* browser, /*const*/ cef_string_t* message, /*const*/ cef_string_t* source, int line)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_message = cef_string_t.ToString(message);
            var m_source = cef_string_t.ToString(source);

            var handled = this.OnConsoleMessage(m_browser, m_message, m_source, line);

            return handled ? 1 : 0;
        }
        /// <summary>
        /// Called when the browser is about to display a tooltip. |text|
        /// contains the text that will be displayed in the tooltip. To handle
        /// the display of the tooltip yourself return true. Otherwise, you can
        /// optionally modify |text| and then return false to allow the browser
        /// to display the tooltip.
        /// </summary>
        private int on_tooltip(cef_display_handler_t* self, cef_browser_t* browser, cef_string_t* text)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_text = cef_string_t.ToString(text);

            var o_text = m_text;
            var handled = this.OnTooltip(m_browser, ref m_text);

            if (!handled && (object)m_text != (object)o_text)
            {
                cef_string_t.Copy(m_text, text);
            }

            return handled ? 1 : 0;
        }
        /// <summary>
        /// Called when the page title changes.
        /// </summary>
        private void on_title_change(cef_display_handler_t* self, cef_browser_t* browser, /*const*/ cef_string_t* title)
        {
            ThrowIfObjectDisposed();

            var m_browser = CefBrowser.From(browser);
            var m_title = cef_string_t.ToString(title);

            this.OnTitleChange(m_browser, m_title);
        }
        /// <summary>
        /// Called when the browser receives a status message.
        /// |text| contains the text that will be displayed in the status message and |type| indicates the status message type.
        /// </summary>
        private void on_status_message(cef_display_handler_t* self, cef_browser_t* browser, /*const*/ cef_string_t* value, cef_handler_statustype_t type)
        {
            ThrowIfObjectDisposed();

            // TODO: we can do not expose this event if same message arrived -> no needed creating proxy, but if we do not create proxy we must call releaseref
            // also this optimization can be done if we store state per-browser, not per-handler
            // or we can do it per-handler

            var m_browser = CefBrowser.From(browser);
            var m_value = cef_string_t.ToString(value);
            var m_type = (CefHandlerStatusType)type;

            this.OnStatusMessage(m_browser, m_value, m_type);
        }