/*
 * Copyright (C) 2013, 2015 Apple 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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

WI.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WI.NavigationSidebarPanel
{
    constructor()
    {
        super("debugger", WI.UIString("Debugger"), true);

        WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
        WI.Frame.addEventListener(WI.Frame.Event.ResourceWasAdded, this._resourceAdded, this);
        WI.Target.addEventListener(WI.Target.Event.ResourceAdded, this._resourceAdded, this);

        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointAdded, this._breakpointAdded, this);
        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.DOMBreakpointAdded, this._breakpointAdded, this);
        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.EventBreakpointAdded, this._breakpointAdded, this);
        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.URLBreakpointAdded, this._breakpointAdded, this);

        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointRemoved, this._breakpointRemoved, this);
        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.DOMBreakpointRemoved, this._breakpointRemoved, this);
        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.EventBreakpointRemoved, this._breakpointRemoved, this);
        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.URLBreakpointRemoved, this._breakpointRemoved, this);

        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointsEnabledDidChange, this._breakpointsEnabledDidChange, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptAdded, this._scriptAdded, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptRemoved, this._scriptRemoved, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptsCleared, this._scriptsCleared, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, this._debuggerDidPause, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Resumed, this._debuggerDidResume, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.CallFramesDidChange, this._debuggerCallFramesDidChange, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ActiveCallFrameDidChange, this._debuggerActiveCallFrameDidChange, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.WaitingToPause, this._debuggerWaitingToPause, this);

        WI.DOMBreakpoint.addEventListener(WI.DOMBreakpoint.Event.DOMNodeChanged, this._handleDOMBreakpointDOMNodeChanged, this);

        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);

        WI.auditManager.addEventListener(WI.AuditManager.Event.TestScheduled, this._handleAuditManagerTestScheduled, this);
        WI.auditManager.addEventListener(WI.AuditManager.Event.TestCompleted, this._handleAuditManagerTestCompleted, this);

        WI.targetManager.addEventListener(WI.TargetManager.Event.TargetAdded, this._targetAdded, this);
        WI.targetManager.addEventListener(WI.TargetManager.Event.TargetRemoved, this._targetRemoved, this);

        this._timelineRecordingWarningElement = document.createElement("div");
        this._timelineRecordingWarningElement.classList.add("warning-banner");
        this._timelineRecordingWarningElement.append(WI.UIString("Debugger disabled during Timeline recording"), document.createElement("br"));
        let timelineStopRecordingLink = this._timelineRecordingWarningElement.appendChild(document.createElement("a"));
        timelineStopRecordingLink.textContent = WI.UIString("Stop recording");
        timelineStopRecordingLink.addEventListener("click", () => { WI.timelineManager.stopCapturing(); });

        this._auditTestWarningElement = document.createElement("div");
        this._auditTestWarningElement.classList.add("warning-banner");
        this._auditTestWarningElement.append(WI.UIString("Debugger disabled during Audit"), document.createElement("br"));
        let auditStopRecordingLink = this._auditTestWarningElement.appendChild(document.createElement("a"));
        auditStopRecordingLink.textContent = WI.UIString("Stop Audit");
        auditStopRecordingLink.addEventListener("click", () => { WI.auditManager.stop(); });

        this._breakpointsDisabledWarningElement = document.createElement("div");
        this._breakpointsDisabledWarningElement.classList.add("warning-banner");
        this._breakpointsDisabledWarningElement.append(WI.UIString("Breakpoints disabled"), document.createElement("br"));
        let enableBreakpointsLink = this._breakpointsDisabledWarningElement.appendChild(document.createElement("a"));
        enableBreakpointsLink.textContent = WI.UIString("Enable breakpoints");
        enableBreakpointsLink.addEventListener("click", () => { WI.debuggerToggleBreakpoints(); });

        this._navigationBar = new WI.NavigationBar;
        this.addSubview(this._navigationBar);

        var breakpointsImage = {src: "Images/Breakpoints.svg", width: 15, height: 15};
        var pauseImage = {src: "Images/Pause.svg", width: 15, height: 15};
        var resumeImage = {src: "Images/Resume.svg", width: 15, height: 15};
        var stepOverImage = {src: "Images/StepOver.svg", width: 15, height: 15};
        var stepIntoImage = {src: "Images/StepInto.svg", width: 15, height: 15};
        var stepOutImage = {src: "Images/StepOut.svg", width: 15, height: 15};

        var toolTip = WI.UIString("Enable all breakpoints (%s)").format(WI.toggleBreakpointsKeyboardShortcut.displayName);
        var altToolTip = WI.UIString("Disable all breakpoints (%s)").format(WI.toggleBreakpointsKeyboardShortcut.displayName);

        this._debuggerBreakpointsButtonItem = new WI.ActivateButtonNavigationItem("debugger-breakpoints", toolTip, altToolTip, breakpointsImage.src, breakpointsImage.width, breakpointsImage.height);
        this._debuggerBreakpointsButtonItem.activated = WI.debuggerManager.breakpointsEnabled;
        this._debuggerBreakpointsButtonItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.debuggerToggleBreakpoints, this);
        this._navigationBar.addNavigationItem(this._debuggerBreakpointsButtonItem);

        toolTip = WI.UIString("Pause script execution (%s or %s)").format(WI.pauseOrResumeKeyboardShortcut.displayName, WI.pauseOrResumeAlternateKeyboardShortcut.displayName);
        altToolTip = WI.UIString("Continue script execution (%s or %s)").format(WI.pauseOrResumeKeyboardShortcut.displayName, WI.pauseOrResumeAlternateKeyboardShortcut.displayName);

        this._debuggerPauseResumeButtonItem = new WI.ToggleButtonNavigationItem("debugger-pause-resume", toolTip, altToolTip, pauseImage.src, resumeImage.src, pauseImage.width, pauseImage.height);
        this._debuggerPauseResumeButtonItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.debuggerPauseResumeToggle, this);
        this._navigationBar.addNavigationItem(this._debuggerPauseResumeButtonItem);

        this._debuggerStepOverButtonItem = new WI.ButtonNavigationItem("debugger-step-over", WI.UIString("Step over (%s or %s)").format(WI.stepOverKeyboardShortcut.displayName, WI.stepOverAlternateKeyboardShortcut.displayName), stepOverImage.src, stepOverImage.width, stepOverImage.height);
        this._debuggerStepOverButtonItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.debuggerStepOver, this);
        this._debuggerStepOverButtonItem.enabled = false;
        this._navigationBar.addNavigationItem(this._debuggerStepOverButtonItem);

        this._debuggerStepIntoButtonItem = new WI.ButtonNavigationItem("debugger-step-into", WI.UIString("Step into (%s or %s)").format(WI.stepIntoKeyboardShortcut.displayName, WI.stepIntoAlternateKeyboardShortcut.displayName), stepIntoImage.src, stepIntoImage.width, stepIntoImage.height);
        this._debuggerStepIntoButtonItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.debuggerStepInto, this);
        this._debuggerStepIntoButtonItem.enabled = false;
        this._navigationBar.addNavigationItem(this._debuggerStepIntoButtonItem);

        this._debuggerStepOutButtonItem = new WI.ButtonNavigationItem("debugger-step-out", WI.UIString("Step out (%s or %s)").format(WI.stepOutKeyboardShortcut.displayName, WI.stepOutAlternateKeyboardShortcut.displayName), stepOutImage.src, stepOutImage.width, stepOutImage.height);
        this._debuggerStepOutButtonItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.debuggerStepOut, this);
        this._debuggerStepOutButtonItem.enabled = false;
        this._navigationBar.addNavigationItem(this._debuggerStepOutButtonItem);

        function showResourcesWithIssuesOnlyFilterFunction(treeElement)
        {
            // Issues are only shown in the scripts tree outline.
            if (treeElement.treeOutline !== this._scriptsContentTreeOutline)
                return true;

            // Keep issues.
            if (treeElement instanceof WI.IssueTreeElement)
                return true;

            // Keep resources with issues.
            if (treeElement.hasChildren) {
                for (let child of treeElement.children) {
                    if (child instanceof WI.IssueTreeElement)
                        return true;
                }
            }
            return false;
        }

        this.filterBar.addFilterBarButton("debugger-show-resources-with-issues-only", showResourcesWithIssuesOnlyFilterFunction.bind(this), false, WI.UIString("Only show resources with issues"), WI.UIString("Show all resources"), "Images/Errors.svg", 15, 15);

        this._breakpointsContentTreeOutline = this.contentTreeOutline;

        let breakpointsRow = new WI.DetailsSectionRow;
        breakpointsRow.element.appendChild(this._breakpointsContentTreeOutline.element);

        let breakpointNavigationBarWrapper = document.createElement("div");

        let breakpointNavigationBar = new WI.NavigationBar;
        breakpointNavigationBarWrapper.appendChild(breakpointNavigationBar.element);

        this._createBreakpointButton = new WI.ButtonNavigationItem("create-breakpoint", WI.UIString("Create Breakpoint"), "Images/Plus13.svg", 13, 13);
        WI.addMouseDownContextMenuHandlers(this._createBreakpointButton.element, this._populateCreateBreakpointContextMenu.bind(this));
        breakpointNavigationBar.addNavigationItem(this._createBreakpointButton);

        let breakpointsGroup = new WI.DetailsSectionGroup([breakpointsRow]);
        this._breakpointsSection = new WI.DetailsSection("breakpoints", WI.UIString("Breakpoints"), [breakpointsGroup], breakpointNavigationBarWrapper);
        this.contentView.element.appendChild(this._breakpointsSection.element);

        this._breakpointsContentTreeOutline.addEventListener(WI.TreeOutline.Event.ElementAdded, this._handleBreakpointElementAddedOrRemoved, this);
        this._breakpointsContentTreeOutline.addEventListener(WI.TreeOutline.Event.ElementRemoved, this._handleBreakpointElementAddedOrRemoved, this);
        this._breakpointsContentTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
        this._breakpointsContentTreeOutline.ondelete = this._breakpointTreeOutlineDeleteTreeElement.bind(this);
        this._breakpointsContentTreeOutline.populateContextMenu = function(contextMenu, event, treeElement) {
            this._breakpointTreeOutlineContextMenuTreeElement(contextMenu, event, treeElement);

            WI.TreeOutline.prototype.populateContextMenu(contextMenu, event, treeElement);
        }.bind(this);

        this._scriptsContentTreeOutline = this.createContentTreeOutline();
        this._scriptsContentTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
        this._scriptsContentTreeOutline.includeSourceMapResourceChildren = true;

        let scriptsRow = new WI.DetailsSectionRow;
        scriptsRow.element.appendChild(this._scriptsContentTreeOutline.element);

        let scriptsGroup = new WI.DetailsSectionGroup([scriptsRow]);
        this._scriptsSection = new WI.DetailsSection("scripts", WI.UIString("Sources"), [scriptsGroup]);
        this.contentView.element.appendChild(this._scriptsSection.element);

        this._callStackTreeOutline = this.createContentTreeOutline({suppressFiltering: true});
        this._callStackTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);

        this._callStackRow = new WI.DetailsSectionRow;
        this._callStackRow.element.appendChild(this._callStackTreeOutline.element);

        this._callStackGroup = new WI.DetailsSectionGroup([this._callStackRow]);
        this._callStackSection = new WI.DetailsSection("call-stack", WI.UIString("Call Stack"), [this._callStackGroup]);

        this._mainTargetTreeElement = null;
        this._activeCallFrameTreeElement = null;

        this._pauseReasonTreeOutline = null;

        this._pauseReasonLinkContainerElement = document.createElement("span");
        this._pauseReasonTextRow = new WI.DetailsSectionTextRow;
        this._pauseReasonGroup = new WI.DetailsSectionGroup([this._pauseReasonTextRow]);
        this._pauseReasonSection = new WI.DetailsSection("paused-reason", WI.UIString("Pause Reason"), [this._pauseReasonGroup], this._pauseReasonLinkContainerElement);

        WI.Breakpoint.addEventListener(WI.Breakpoint.Event.DisplayLocationDidChange, this._handleDebuggerObjectDisplayLocationDidChange, this);
        WI.IssueMessage.addEventListener(WI.IssueMessage.Event.DisplayLocationDidChange, this._handleDebuggerObjectDisplayLocationDidChange, this);
        WI.consoleManager.addEventListener(WI.ConsoleManager.Event.IssueAdded, this._handleIssueAdded, this);
        WI.consoleManager.addEventListener(WI.ConsoleManager.Event.Cleared, this._handleIssuesCleared, this);

        WI.debuggerManager.addBreakpoint(WI.debuggerManager.allExceptionsBreakpoint);
        WI.debuggerManager.addBreakpoint(WI.debuggerManager.uncaughtExceptionsBreakpoint);

        // COMPATIBILITY (iOS 10): DebuggerAgent.setPauseOnAssertions did not exist yet.
        if (InspectorBackend.domains.Debugger.setPauseOnAssertions && WI.settings.showAssertionFailuresBreakpoint.value)
            WI.debuggerManager.addBreakpoint(WI.debuggerManager.assertionFailuresBreakpoint);

        // COMPATIBILITY (iOS 13): DebuggerAgent.setPauseOnMicrotasks did not exist yet.
        if (InspectorBackend.domains.Debugger.setPauseOnMicrotasks && WI.settings.showAllMicrotasksBreakpoint.value)
            WI.debuggerManager.addBreakpoint(WI.debuggerManager.allMicrotasksBreakpoint);

        for (let target of WI.targets)
            this._addTarget(target);
        this._updateCallStackTreeOutline();

        if (WI.networkManager.mainFrame)
            this._addResourcesRecursivelyForFrame(WI.networkManager.mainFrame);

        for (let script of WI.debuggerManager.knownNonResourceScripts)
            this._addScript(script);

        if (WI.domDebuggerManager.supported) {
            if (WI.settings.showAllAnimationFramesBreakpoint.value)
                WI.domDebuggerManager.addEventBreakpoint(WI.domDebuggerManager.allAnimationFramesBreakpoint);

            if (WI.settings.showAllTimeoutsBreakpoint.value)
                WI.domDebuggerManager.addEventBreakpoint(WI.domDebuggerManager.allTimeoutsBreakpoint);

            if (WI.settings.showAllIntervalsBreakpoint.value)
                WI.domDebuggerManager.addEventBreakpoint(WI.domDebuggerManager.allIntervalsBreakpoint);

            if (WI.settings.showAllListenersBreakpoint.value)
                WI.domDebuggerManager.addEventBreakpoint(WI.domDebuggerManager.allListenersBreakpoint);

            for (let eventBreakpoint of WI.domDebuggerManager.listenerBreakpoints)
                this._addBreakpoint(eventBreakpoint);

            for (let eventListenerBreakpoint of WI.domManager.eventListenerBreakpoints)
                this._addBreakpoint(eventListenerBreakpoint);

            for (let domBreakpoint of WI.domDebuggerManager.domBreakpoints)
                this._addBreakpoint(domBreakpoint);

            if (WI.settings.showAllRequestsBreakpoint.value)
                WI.domDebuggerManager.addURLBreakpoint(WI.domDebuggerManager.allRequestsBreakpoint);

            for (let urlBreakpoints of WI.domDebuggerManager.urlBreakpoints)
                this._addBreakpoint(urlBreakpoints);
        }

        if (WI.debuggerManager.paused)
            this._debuggerDidPause(null);

        if (WI.debuggerManager.breakpointsDisabledTemporarily) {
            this._handleTimelineCapturingStateChanged();

            if (WI.auditManager.runningState === WI.AuditManager.RunningState.Active || WI.auditManager.runningState === WI.AuditManager.RunningState.Stopping)
                this._handleAuditManagerTestScheduled();
        }

        this._updateBreakpointsDisabledBanner();
    }

    // Public

    get minimumWidth()
    {
        return this._navigationBar.minimumWidth;
    }

    closed()
    {
        super.closed();

        WI.Frame.removeEventListener(null, null, this);
        WI.Target.removeEventListener(null, null, this);
        WI.debuggerManager.removeEventListener(null, null, this);
        WI.domDebuggerManager.removeEventListener(null, null, this);
        WI.DOMBreakpoint.removeEventListener(null, null, this);
        WI.timelineManager.removeEventListener(null, null, this);
        WI.targetManager.removeEventListener(null, null, this);
        WI.Breakpoint.removeEventListener(null, null, this);
        WI.IssueMessage.removeEventListener(null, null, this);
    }

    showDefaultContentView()
    {
        if (WI.networkManager.mainFrame) {
            let mainTreeElement = this._scriptsContentTreeOutline.findTreeElement(WI.networkManager.mainFrame.mainResource);
            if (mainTreeElement && this.showDefaultContentViewForTreeElement(mainTreeElement))
                return;
        }

        let currentTreeElement = this._scriptsContentTreeOutline.children[0];
        while (currentTreeElement && !currentTreeElement.root) {
            if (currentTreeElement instanceof WI.ResourceTreeElement || currentTreeElement instanceof WI.ScriptTreeElement) {
                if (this.showDefaultContentViewForTreeElement(currentTreeElement))
                    return;
            }

            currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, true);
        }
    }

    treeElementForRepresentedObject(representedObject)
    {
        if (representedObject instanceof WI.LocalResource)
            return null;

        // The main resource is used as the representedObject instead of Frame in our tree.
        if (representedObject instanceof WI.Frame)
            representedObject = representedObject.mainResource;

        let treeElement = this._breakpointsContentTreeOutline.findTreeElement(representedObject);
        if (!treeElement)
            treeElement = this._scriptsContentTreeOutline.findTreeElement(representedObject);

        if (treeElement)
            return treeElement;

        // Only special case Script objects.
        if (!(representedObject instanceof WI.Script)) {
            console.error("Didn't find a TreeElement for representedObject", representedObject);
            return null;
        }

        // If the Script has a URL we should have found it earlier.
        if (representedObject.url) {
            console.error("Didn't find a ScriptTreeElement for a Script with a URL.");
            return null;
        }

        // Since the Script does not have a URL we consider it an 'anonymous' script. These scripts happen from calls to
        // window.eval() or browser features like Auto Fill and Reader. They are not normally added to the sidebar, but since
        // we have a ScriptContentView asking for the tree element we will make a ScriptTreeElement on demand and add it.

        return this._addScript(representedObject);
    }

    createContentTreeOutline(options = {})
    {
        let treeOutline = super.createContentTreeOutline(options);

        treeOutline.addEventListener(WI.TreeOutline.Event.ElementRevealed, (event) => {
            let treeElement = event.data.element;
            let detailsSections = [this._pauseReasonSection, this._callStackSection, this._breakpointsSection, this._scriptsSection];
            let detailsSection = detailsSections.find((detailsSection) => detailsSection.element.contains(treeElement.listItemElement));
            if (!detailsSection)
                return;

            // Revealing a TreeElement at the scroll container's topmost edge with
            // scrollIntoViewIfNeeded may result in the element being covered by the
            // DetailsSection header, which uses sticky positioning. Detect this case,
            // and adjust the sidebar content's scroll position to compensate.
            let offset = detailsSection.headerElement.totalOffsetBottom - treeElement.listItemElement.totalOffsetTop;
            if (offset > 0)
                this.scrollElement.scrollBy(0, -offset);
        });

        return treeOutline;
    }

    // Protected

    saveStateToCookie(cookie)
    {
        console.assert(cookie);

        var selectedTreeElement = this._breakpointsContentTreeOutline.selectedTreeElement;
        if (!selectedTreeElement) {
            super.saveStateToCookie(cookie);
            return;
        }

        switch (selectedTreeElement.representedObject) {
        case WI.debuggerManager.allExceptionsBreakpoint:
            cookie[DebuggerSidebarPanel.SelectedAllExceptionsCookieKey] = true;
            return;

        case WI.debuggerManager.uncaughtExceptionsBreakpoint:
            cookie[DebuggerSidebarPanel.SelectedUncaughtExceptionsCookieKey] = true;
            return;

        case WI.debuggerManager.assertionFailuresBreakpoint:
            cookie[DebuggerSidebarPanel.SelectedAssertionFailuresCookieKey] = true;
            return;

        case WI.debuggerManager.allMicrotasksBreakpoint:
            cookie[DebuggerSidebarPanel.SelectedAllMicrotasksCookieKey] = true;
            return;

        case WI.domDebuggerManager.allAnimationFramesBreakpoint:
            cookie[DebuggerSidebarPanel.SelectedAllAnimationFramesBreakpoint] = true;
            return;

        case WI.domDebuggerManager.allIntervalsBreakpoint:
            cookie[DebuggerSidebarPanel.SelectedAllIntervalsBreakpoint] = true;
            return;

        case WI.domDebuggerManager.allListenersBreakpoint:
            cookie[DebuggerSidebarPanel.SelectedAllListenersBreakpoint] = true;
            return;

        case WI.domDebuggerManager.allTimeoutsBreakpoint:
            cookie[DebuggerSidebarPanel.SelectedAllTimeoutsBreakpoint] = true;
            return;

        case WI.domDebuggerManager.allRequestsBreakpoint:
            cookie[DebuggerSidebarPanel.SelectedAllRequestsCookieKey] = true;
            return;
        }

        super.saveStateToCookie(cookie);
    }

    restoreStateFromCookie(cookie, relaxedMatchDelay)
    {
        console.assert(cookie);

        function revealAndSelect(treeOutline, breakpoint) {
            let treeElement = treeOutline.findTreeElement(breakpoint);
            if (!treeElement)
                return;

            treeElement.revealAndSelect();
        }

        // Eagerly resolve the special breakpoints; otherwise, use the default behavior.
        if (cookie[DebuggerSidebarPanel.SelectedAllExceptionsCookieKey])
            revealAndSelect(this._breakpointsContentTreeOutline, WI.debuggerManager.allExceptionsBreakpoint);
        else if (cookie[DebuggerSidebarPanel.SelectedUncaughtExceptionsCookieKey])
            revealAndSelect(this._breakpointsContentTreeOutline, WI.debuggerManager.uncaughtExceptionsBreakpoint);
        else if (cookie[DebuggerSidebarPanel.SelectedAssertionFailuresCookieKey])
            revealAndSelect(this._breakpointsContentTreeOutline, WI.debuggerManager.assertionFailuresBreakpoint);
        else if (cookie[DebuggerSidebarPanel.SelectedAllMicrotasksCookieKey])
            revealAndSelect(this._breakpointsContentTreeOutline, WI.debuggerManager.allMicrotasksBreakpoint);
        else if (cookie[DebuggerSidebarPanel.SelectedAllAnimationFramesBreakpoint])
            revealAndSelect(this._breakpointsContentTreeOutline, WI.domDebuggerManager.allAnimationFramesBreakpoint);
        else if (cookie[DebuggerSidebarPanel.SelectedAllIntervalsBreakpoint])
            revealAndSelect(this._breakpointsContentTreeOutline, WI.domDebuggerManager.allIntervalsBreakpoint);
        else if (cookie[DebuggerSidebarPanel.SelectedAllListenersBreakpoint])
            revealAndSelect(this._breakpointsContentTreeOutline, WI.domDebuggerManager.allListenersBreakpoint);
        else if (cookie[DebuggerSidebarPanel.SelectedAllRequestsCookieKey])
            revealAndSelect(this._breakpointsContentTreeOutline, WI.domDebuggerManager.allRequestsBreakpoint);
        else if (cookie[DebuggerSidebarPanel.SelectedAllTimeoutsBreakpoint])
            revealAndSelect(this._breakpointsContentTreeOutline, WI.domDebuggerManager.allTimeoutsBreakpoint);
        else
            super.restoreStateFromCookie(cookie, relaxedMatchDelay);
    }

    // Popover delegate

    willDismissPopover(popover)
    {
        let breakpoint = popover.breakpoint;
        if (!breakpoint)
            return;

        if (breakpoint instanceof WI.EventBreakpoint)
            WI.domDebuggerManager.addEventBreakpoint(breakpoint);
        else if (breakpoint instanceof WI.URLBreakpoint)
            WI.domDebuggerManager.addURLBreakpoint(breakpoint);
    }

    // Private

    _debuggerWaitingToPause(event)
    {
        this._debuggerPauseResumeButtonItem.enabled = false;
    }

    _debuggerDidPause(event)
    {
        this.contentView.element.insertBefore(this._callStackSection.element, this.contentView.element.firstChild);

        if (this._updatePauseReason())
            this.contentView.element.insertBefore(this._pauseReasonSection.element, this.contentView.element.firstChild);

        this._debuggerPauseResumeButtonItem.enabled = true;
        this._debuggerPauseResumeButtonItem.toggled = true;
        this._debuggerStepOverButtonItem.enabled = true;
        this._debuggerStepIntoButtonItem.enabled = true;
        this._debuggerStepOutButtonItem.enabled = true;

        this.element.classList.add(WI.DebuggerSidebarPanel.DebuggerPausedStyleClassName);
    }

    _debuggerDidResume(event)
    {
        this._callStackSection.element.remove();

        this._pauseReasonSection.element.remove();

        this._debuggerPauseResumeButtonItem.enabled = true;
        this._debuggerPauseResumeButtonItem.toggled = false;
        this._debuggerStepOverButtonItem.enabled = false;
        this._debuggerStepIntoButtonItem.enabled = false;
        this._debuggerStepOutButtonItem.enabled = false;

        this.element.classList.remove(WI.DebuggerSidebarPanel.DebuggerPausedStyleClassName);
    }

    _breakpointsEnabledDidChange(event)
    {
        this._debuggerBreakpointsButtonItem.activated = WI.debuggerManager.breakpointsEnabled;

        this._updateBreakpointsDisabledBanner();
    }

    _addBreakpoint(breakpoint)
    {
        let constructor = WI.BreakpointTreeElement;
        let options = {};
        let parentTreeElement = this._breakpointsContentTreeOutline;

        let getDOMNodeTreeElement = (domNode) => {
            console.assert(domNode, "Missing DOMNode for identifier", breakpoint.domNodeIdentifier);
            if (!domNode)
                return null;

            let domNodeTreeElement = this._breakpointsContentTreeOutline.findTreeElement(domNode);
            if (!domNodeTreeElement) {
                domNodeTreeElement = new WI.DOMNodeTreeElement(domNode);
                this._addTreeElement(domNodeTreeElement, parentTreeElement);
            }
            return domNodeTreeElement;
        };

        if (breakpoint === WI.debuggerManager.allExceptionsBreakpoint) {
            options.className = WI.DebuggerSidebarPanel.ExceptionIconStyleClassName;
            options.title = WI.repeatedUIString.allExceptions();
        } else if (breakpoint === WI.debuggerManager.uncaughtExceptionsBreakpoint) {
            options.className = WI.DebuggerSidebarPanel.ExceptionIconStyleClassName;
            options.title = WI.repeatedUIString.uncaughtExceptions();
        } else if (breakpoint === WI.debuggerManager.assertionFailuresBreakpoint) {
            options.className = WI.DebuggerSidebarPanel.AssertionIconStyleClassName;
            options.title = WI.repeatedUIString.assertionFailures();
        } else if (breakpoint === WI.debuggerManager.allMicrotasksBreakpoint) {
            options.className = "breakpoint-microtask-icon";
            options.title = WI.UIString("All Microtasks");
        } else if (breakpoint instanceof WI.DOMBreakpoint) {
            if (!breakpoint.domNodeIdentifier)
                return null;

            constructor = WI.DOMBreakpointTreeElement;

            let domNode = WI.domManager.nodeForId(breakpoint.domNodeIdentifier);
            parentTreeElement = getDOMNodeTreeElement(domNode);
        } else if (breakpoint instanceof WI.EventBreakpoint) {
            constructor = WI.EventBreakpointTreeElement;

            if (breakpoint === WI.domDebuggerManager.allAnimationFramesBreakpoint)
                options.title = WI.UIString("All Animation Frames");
            else if (breakpoint === WI.domDebuggerManager.allIntervalsBreakpoint)
                options.title = WI.UIString("All Intervals");
            else if (breakpoint === WI.domDebuggerManager.allListenersBreakpoint)
                options.title = WI.UIString("All Events");
            else if (breakpoint === WI.domDebuggerManager.allTimeoutsBreakpoint)
                options.title = WI.UIString("All Timeouts");
            else if (breakpoint.eventListener) {
                let eventTargetTreeElement = null;
                if (breakpoint.eventListener.onWindow) {
                    if (!DebuggerSidebarPanel.__windowEventTargetRepresentedObject)
                        DebuggerSidebarPanel.__windowEventTargetRepresentedObject = {__window: true};

                    eventTargetTreeElement = this._breakpointsContentTreeOutline.findTreeElement(DebuggerSidebarPanel.__windowEventTargetRepresentedObject);
                    if (!eventTargetTreeElement) {
                        const subtitle = null;
                        eventTargetTreeElement = new WI.GeneralTreeElement(["event-target-window"], WI.unlocalizedString("window"), subtitle, DebuggerSidebarPanel.__windowEventTargetRepresentedObject);
                        this._addTreeElement(eventTargetTreeElement, parentTreeElement);
                    }
                } else if (breakpoint.eventListener.node)
                    eventTargetTreeElement = getDOMNodeTreeElement(breakpoint.eventListener.node);
                if (eventTargetTreeElement)
                    parentTreeElement = eventTargetTreeElement;
            }
        } else if (breakpoint instanceof WI.URLBreakpoint) {
            constructor = WI.URLBreakpointTreeElement;

            if (breakpoint === WI.domDebuggerManager.allRequestsBreakpoint)
                options.title = WI.repeatedUIString.allRequests();
        } else {
            let sourceCode = breakpoint.sourceCodeLocation && breakpoint.sourceCodeLocation.displaySourceCode;
            if (!sourceCode)
                return null;

            if (this._breakpointsContentTreeOutline.findTreeElement(breakpoint))
                return null;

            parentTreeElement = this._addTreeElementForSourceCodeToTreeOutline(sourceCode, this._breakpointsContentTreeOutline);

            // Mark disabled breakpoints as resolved if there is source code loaded with that URL.
            // This gives the illusion the breakpoint was resolved, but since we don't send disabled
            // breakpoints to the backend we don't know for sure. If the user enables the breakpoint
            // it will be resolved properly.
            if (breakpoint.disabled)
                breakpoint.resolved = true;
        }

        let breakpointTreeElement = new constructor(breakpoint, options);
        this._addTreeElement(breakpointTreeElement, parentTreeElement);
        if (parentTreeElement.children.length === 1)
            parentTreeElement.expand();
        return breakpointTreeElement;
    }

    _removeBreakpoint(breakpoint)
    {
        if (this._pauseReasonTreeOutline) {
            let pauseReasonBreakpointTreeElement = this._pauseReasonTreeOutline.getCachedTreeElement(breakpoint);
            if (pauseReasonBreakpointTreeElement)
                pauseReasonBreakpointTreeElement.status = null;
        }

        let breakpointTreeElement = this._breakpointsContentTreeOutline.getCachedTreeElement(breakpoint);
        if (!breakpointTreeElement)
            return;

        this._removeDebuggerTreeElement(breakpointTreeElement);
    }

    _addBreakpointsForSourceCode(sourceCode)
    {
        for (let breakpoint of WI.debuggerManager.breakpointsForSourceCode(sourceCode))
            this._addBreakpoint(breakpoint, sourceCode);
    }

    _addIssuesForSourceCode(sourceCode)
    {
        var issues = WI.consoleManager.issuesForSourceCode(sourceCode);
        for (var issue of issues)
            this._addIssue(issue, sourceCode);
    }

    _addTreeElementForSourceCodeToTreeOutline(sourceCode, treeOutline)
    {
        let treeElement = treeOutline.getCachedTreeElement(sourceCode);
        if (!treeElement) {
            if (sourceCode instanceof WI.SourceMapResource)
                treeElement = new WI.SourceMapResourceTreeElement(sourceCode);
            else if (sourceCode instanceof WI.Resource)
                treeElement = new WI.ResourceTreeElement(sourceCode);
            else if (sourceCode instanceof WI.Script)
                treeElement = new WI.ScriptTreeElement(sourceCode);
        }

        if (!treeElement) {
            console.error("Unknown sourceCode instance", sourceCode);
            return null;
        }

        if (!treeElement.parent) {
            treeElement.hasChildren = false;
            treeElement.expand();

            this._addTreeElement(treeElement, treeOutline);
        }

        return treeElement;
    }

    _addResourcesRecursivelyForFrame(frame)
    {
        this._addResource(frame.mainResource);

        for (let resource of frame.resourceCollection)
            this._addResource(resource);

        for (let childFrame of frame.childFrameCollection)
            this._addResourcesRecursivelyForFrame(childFrame);
    }

    _resourceAdded(event)
    {
        this._addResource(event.data.resource);
    }

    _addResource(resource)
    {
        if (![WI.Resource.Type.Document, WI.Resource.Type.Script].includes(resource.type))
            return;

        let treeElement = this._addTreeElementForSourceCodeToTreeOutline(resource, this._scriptsContentTreeOutline);
        this._addBreakpointsForSourceCode(resource);
        this._addIssuesForSourceCode(resource);

        if (this.parentSidebar && !this.contentBrowser.currentContentView)
            this.showDefaultContentViewForTreeElement(treeElement);
    }

    _mainResourceDidChange(event)
    {
        if (event.target.isMainFrame()) {
            // Aggressively prune resources now so the old resources are removed before
            // the new main resource is added below. This avoids a visual flash when the
            // prune normally happens on a later event loop cycle.
            this.pruneStaleResourceTreeElements();
            this.contentBrowser.contentViewContainer.closeAllContentViews();

            for (let domBreakpoint of WI.domDebuggerManager.domBreakpoints)
                this._removeBreakpoint(domBreakpoint);
        }

        if (!event.data.oldMainResource) {
            var resource = event.target.mainResource;
            this._addTreeElementForSourceCodeToTreeOutline(resource, this._scriptsContentTreeOutline);
            this._addBreakpointsForSourceCode(resource);
            this._addIssuesForSourceCode(resource);
        }
    }

    _handleTimelineCapturingStateChanged(event)
    {
        this._updateTemporarilyDisabledBreakpointsButtons();

        switch (WI.timelineManager.capturingState) {
        case WI.TimelineManager.CapturingState.Starting:
            this.contentView.element.insertBefore(this._timelineRecordingWarningElement, this.contentView.element.firstChild);
            break;

        case WI.TimelineManager.CapturingState.Inactive:
            this._timelineRecordingWarningElement.remove();
            break;
        }

        this._updateBreakpointsDisabledBanner();
    }

    _handleAuditManagerTestScheduled(event)
    {
        this._updateTemporarilyDisabledBreakpointsButtons();

        this.contentView.element.insertBefore(this._auditTestWarningElement, this.contentView.element.firstChild);
        this._updateBreakpointsDisabledBanner();
    }

    _handleAuditManagerTestCompleted(event)
    {
        this._updateTemporarilyDisabledBreakpointsButtons();

        this._auditTestWarningElement.remove();
        this._updateBreakpointsDisabledBanner();
    }

    _updateTemporarilyDisabledBreakpointsButtons()
    {
        let breakpointsDisabledTemporarily = WI.debuggerManager.breakpointsDisabledTemporarily;
        this._debuggerBreakpointsButtonItem.enabled = !breakpointsDisabledTemporarily;
        this._debuggerPauseResumeButtonItem.enabled = !breakpointsDisabledTemporarily;
    }

    _updateBreakpointsDisabledBanner()
    {
        let breakpointsEnabled = WI.debuggerManager.breakpointsEnabled;
        let timelineWarningShowing = !!this._timelineRecordingWarningElement.parentElement;
        let auditWarningShowing = !!this._auditTestWarningElement.parentElement;

        if (!breakpointsEnabled && !timelineWarningShowing && !auditWarningShowing)
            this.contentView.element.insertBefore(this._breakpointsDisabledWarningElement, this.contentView.element.firstChild);
        else
            this._breakpointsDisabledWarningElement.remove();
    }

    _scriptAdded(event)
    {
        this._addScript(event.data.script);
    }

    _addScript(script)
    {
        // COMPATIBILITY(iOS 9): Backends could send the frontend built-in code, filter out JSC internals.
        if (!script.url && !script.sourceURL)
            return null;

        // In general, do not show dynamically added script elements.
        if (script.dynamicallyAddedScriptElement && !script.sourceURL)
            return null;

        // Don't add breakpoints if the script is represented by a Resource. They were
        // already added by _resourceAdded.
        if (script.resource)
            return null;

        let treeElement = this._addTreeElementForSourceCodeToTreeOutline(script, this._scriptsContentTreeOutline);
        this._addBreakpointsForSourceCode(script);
        this._addIssuesForSourceCode(script);

        if (this.parentSidebar && !this.contentBrowser.currentContentView)
            this.showDefaultContentViewForTreeElement(treeElement);

        return treeElement;
    }

    _scriptRemoved(event)
    {
        function removeScript(script, treeOutline)
        {
            let scriptTreeElement = treeOutline.getCachedTreeElement(script);
            if (scriptTreeElement)
                scriptTreeElement.parent.removeChild(scriptTreeElement);
        }

        let script = event.data.script;
        removeScript(script, this._breakpointsContentTreeOutline);
        removeScript(script, this._scriptsContentTreeOutline);
    }

    _scriptsCleared(event)
    {
        for (var i = this._breakpointsContentTreeOutline.children.length - 1; i >= 0; --i) {
            var treeElement = this._breakpointsContentTreeOutline.children[i];
            if (!(treeElement instanceof WI.ScriptTreeElement))
                continue;

            this._breakpointsContentTreeOutline.removeChildAtIndex(i, true, true);
        }

        this._scriptsContentTreeOutline.removeChildren();

        this._addResourcesRecursivelyForFrame(WI.networkManager.mainFrame);
    }

    _breakpointAdded(event)
    {
        var breakpoint = event.data.breakpoint;
        this._addBreakpoint(breakpoint);
    }

    _breakpointRemoved(event)
    {
        var breakpoint = event.data.breakpoint;
        this._removeBreakpoint(breakpoint);
    }

    _findThreadTreeElementForTarget(target)
    {
        for (let child of this._callStackTreeOutline.children) {
            if (child.target === target)
                return child;
        }

        return null;
    }

    _targetAdded(event)
    {
        this._addTarget(event.data.target);
    }

    _addTarget(target)
    {
        let treeElement = new WI.ThreadTreeElement(target);
        this._callStackTreeOutline.appendChild(treeElement);

        // FIXME: When WI.mainTarget changes?
        if (target === WI.mainTarget)
            this._mainTargetTreeElement = treeElement;

        this._updateCallStackTreeOutline();
    }

    _targetRemoved(event)
    {
        let target = event.data.target;
        let treeElement = this._findThreadTreeElementForTarget(target);
        this._callStackTreeOutline.removeChild(treeElement);

        this._updateCallStackTreeOutline();
    }

    _updateCallStackTreeOutline()
    {
        let singleThreadShowing = WI.targets.length <= 1;
        this._callStackTreeOutline.element.classList.toggle("single-thread", singleThreadShowing);
        if (this._mainTargetTreeElement)
            this._mainTargetTreeElement.selectable = !singleThreadShowing;
    }

    _handleDebuggerObjectDisplayLocationDidChange(event)
    {
        var debuggerObject = event.target;

        if (event.data.oldDisplaySourceCode === debuggerObject.sourceCodeLocation.displaySourceCode)
            return;

        // A known debugger object (breakpoint, issueMessage, etc.) moved between resources. Remove
        // the old tree element and create a new tree element with the updated file.

        let wasSelected = false;
        let oldDebuggerTreeElement = this._breakpointsContentTreeOutline.getCachedTreeElement(debuggerObject);
        if (oldDebuggerTreeElement)
            wasSelected = oldDebuggerTreeElement.selected;

        let newDebuggerTreeElement = null;
        if (debuggerObject instanceof WI.Breakpoint)
            newDebuggerTreeElement = this._addBreakpoint(debuggerObject);
        else if (debuggerObject instanceof WI.IssueMessage)
            newDebuggerTreeElement = this._addIssue(debuggerObject);
        if (!newDebuggerTreeElement)
            return;

        if (oldDebuggerTreeElement)
            this._removeDebuggerTreeElement(oldDebuggerTreeElement);

        if (wasSelected)
            newDebuggerTreeElement.revealAndSelect(true, false, true);
    }

    _removeDebuggerTreeElement(debuggerTreeElement)
    {
        // If this is a BreakpointTreeElement being deleted because of a cause
        // outside of the TreeOutline then deselect if it is selected to avoid
        // TreeOutline selection changes causing unexpected ContentView changes.
        if (!debuggerTreeElement.__deletedViaDeleteKeyboardShortcut)
            debuggerTreeElement.deselect();

        let parentTreeElement = debuggerTreeElement.parent;
        parentTreeElement.removeChild(debuggerTreeElement);

        if (parentTreeElement.children.length || parentTreeElement === this._breakpointsContentTreeOutline)
            return;

        parentTreeElement.treeOutline.removeChild(parentTreeElement);
    }

    _debuggerCallFramesDidChange(event)
    {
        let target = event.data.target;
        let treeElement = this._findThreadTreeElementForTarget(target);
        treeElement.refresh();

        let activeCallFrameTreeElement = this._callStackTreeOutline.findTreeElement(WI.debuggerManager.activeCallFrame);
        if (activeCallFrameTreeElement)
            activeCallFrameTreeElement.reveal();
    }

    _debuggerActiveCallFrameDidChange()
    {
        if (this._activeCallFrameTreeElement) {
            this._activeCallFrameTreeElement.isActiveCallFrame = false;
            this._activeCallFrameTreeElement = null;
        }

        if (!WI.debuggerManager.activeCallFrame)
            return;

        this._activeCallFrameTreeElement = this._callStackTreeOutline.findTreeElement(WI.debuggerManager.activeCallFrame);
        if (this._activeCallFrameTreeElement)
            this._activeCallFrameTreeElement.isActiveCallFrame = true;
    }

    _breakpointsBeneathTreeElement(treeElement)
    {
        console.assert(treeElement instanceof WI.ResourceTreeElement || treeElement instanceof WI.ScriptTreeElement);
        if (!(treeElement instanceof WI.ResourceTreeElement) && !(treeElement instanceof WI.ScriptTreeElement))
            return [];

        var breakpoints = [];
        var breakpointTreeElements = treeElement.children;
        for (var i = 0; i < breakpointTreeElements.length; ++i) {
            console.assert(breakpointTreeElements[i] instanceof WI.BreakpointTreeElement);
            console.assert(breakpointTreeElements[i].breakpoint);
            var breakpoint = breakpointTreeElements[i].breakpoint;
            if (breakpoint)
                breakpoints.push(breakpoint);
        }

        return breakpoints;
    }

    _removeAllBreakpoints(breakpoints)
    {
        for (var i = 0; i < breakpoints.length; ++i) {
            var breakpoint = breakpoints[i];
            if (WI.debuggerManager.isBreakpointRemovable(breakpoint))
                WI.debuggerManager.removeBreakpoint(breakpoint);
        }
    }

    _toggleAllBreakpoints(breakpoints, disabled)
    {
        for (var i = 0; i < breakpoints.length; ++i)
            breakpoints[i].disabled = disabled;
    }

    _breakpointTreeOutlineDeleteTreeElement(selectedTreeElement)
    {
        console.assert(selectedTreeElement.selected);

        if (!WI.debuggerManager.isBreakpointRemovable(selectedTreeElement.representedObject)) {
            let treeElementToSelect = selectedTreeElement.nextSelectableSibling;
            if (treeElementToSelect) {
                const omitFocus = true;
                const selectedByUser = true;
                treeElementToSelect.select(omitFocus, selectedByUser);
            }
        } else if (selectedTreeElement instanceof WI.ResourceTreeElement || selectedTreeElement instanceof WI.ScriptTreeElement) {
            let breakpoints = this._breakpointsBeneathTreeElement(selectedTreeElement);
            this._removeAllBreakpoints(breakpoints);
        } else if (selectedTreeElement.representedObject === DebuggerSidebarPanel.__windowEventTargetRepresentedObject) {
            let eventBreakpointsOnWindow = WI.domManager.eventListenerBreakpoints.filter((eventBreakpoint) => eventBreakpoint.eventListener.onWindow);
            for (let eventBreakpoint of eventBreakpointsOnWindow)
                WI.domManager.removeBreakpointForEventListener(eventBreakpoint.eventListener);
        }

        return true;
    }

    _breakpointTreeOutlineContextMenuTreeElement(contextMenu, event, treeElement)
    {
        // This check is necessary since the context menu is created by the TreeOutline, meaning
        // that any child could be the target of the context menu event.
        if (!(treeElement instanceof WI.ResourceTreeElement) && !(treeElement instanceof WI.ScriptTreeElement))
            return;

        let breakpoints = this._breakpointsBeneathTreeElement(treeElement);
        let shouldDisable = breakpoints.some((breakpoint) => !breakpoint.disabled);

        let removeAllResourceBreakpoints = () => {
            this._removeAllBreakpoints(breakpoints);
        };

        let toggleAllResourceBreakpoints = () => {
            this._toggleAllBreakpoints(breakpoints, shouldDisable);
        };

        if (shouldDisable)
            contextMenu.appendItem(WI.UIString("Disable Breakpoints"), toggleAllResourceBreakpoints);
        else
            contextMenu.appendItem(WI.UIString("Enable Breakpoints"), toggleAllResourceBreakpoints);
        contextMenu.appendItem(WI.UIString("Delete Breakpoints"), removeAllResourceBreakpoints);
    }

    _treeSelectionDidChange(event)
    {
        if (!this.selected)
            return;

        let treeElement = event.target.selectedTreeElement;
        if (!treeElement)
            return;

        if (treeElement instanceof WI.DOMNodeTreeElement
            || treeElement instanceof WI.DOMBreakpointTreeElement
            || treeElement instanceof WI.EventBreakpointTreeElement
            || treeElement instanceof WI.URLBreakpointTreeElement)
            return;

        if (treeElement.representedObject === DebuggerSidebarPanel.__windowEventTargetRepresentedObject)
            return;

        const options = {
            ignoreNetworkTab: true,
            ignoreSearchTab: true,
        };

        if (treeElement instanceof WI.ResourceTreeElement || treeElement instanceof WI.ScriptTreeElement) {
            WI.showSourceCode(treeElement.representedObject, options);
            return;
        }

        if (treeElement instanceof WI.CallFrameTreeElement) {
            let callFrame = treeElement.callFrame;
            if (callFrame.id)
                WI.debuggerManager.activeCallFrame = callFrame;

            if (callFrame.sourceCodeLocation)
                WI.showSourceCodeLocation(callFrame.sourceCodeLocation, options);

            return;
        }

        if (treeElement instanceof WI.IssueTreeElement) {
            WI.showSourceCodeLocation(treeElement.issueMessage.sourceCodeLocation, options);
            return;
        }

        if (!(treeElement instanceof WI.BreakpointTreeElement))
            return;

        let breakpoint = treeElement.breakpoint;
        if (treeElement.treeOutline === this._pauseReasonTreeOutline) {
            WI.showSourceCodeLocation(breakpoint.sourceCodeLocation, options);
            return;
        }

        if (!treeElement.parent.representedObject)
            return;

        console.assert(treeElement.parent.representedObject instanceof WI.SourceCode);
        if (!(treeElement.parent.representedObject instanceof WI.SourceCode))
            return;

        WI.showSourceCodeLocation(breakpoint.sourceCodeLocation, options);
    }

    _addTreeElement(treeElement, parentTreeElement)
    {
        if (!parentTreeElement)
            parentTreeElement = this._breakpointsContentTreeOutline;

        let comparator = (a, b) => {
            const rankFunctions = [
                (treeElement) => treeElement.representedObject === WI.debuggerManager.allExceptionsBreakpoint,
                (treeElement) => treeElement.representedObject === WI.debuggerManager.uncaughtExceptionsBreakpoint,
                (treeElement) => treeElement.representedObject === WI.debuggerManager.assertionFailuresBreakpoint,
                (treeElement) => treeElement instanceof WI.BreakpointTreeElement || treeElement instanceof WI.ResourceTreeElement || treeElement instanceof WI.ScriptTreeElement,
                (treeElement) => treeElement.representedObject === WI.debuggerManager.allMicrotasksBreakpoint,
                (treeElement) => treeElement.representedObject === WI.domDebuggerManager.allAnimationFramesBreakpoint,
                (treeElement) => treeElement.representedObject === WI.domDebuggerManager.allTimeoutsBreakpoint,
                (treeElement) => treeElement.representedObject === WI.domDebuggerManager.allIntervalsBreakpoint,
                (treeElement) => treeElement.representedObject === WI.domDebuggerManager.allListenersBreakpoint,
                (treeElement) => treeElement instanceof WI.EventBreakpointTreeElement,
                (treeElement) => treeElement instanceof WI.DOMNodeTreeElement,
                (treeElement) => treeElement.representedObject === DebuggerSidebarPanel.__windowEventTargetRepresentedObject,
                (treeElement) => treeElement instanceof WI.DOMBreakpointTreeElement,
                (treeElement) => treeElement.representedObject === WI.domDebuggerManager.allRequestsBreakpoint,
                (treeElement) => treeElement instanceof WI.URLBreakpointTreeElement,
            ];

            let aRank = rankFunctions.findIndex((rankFunction) => rankFunction(a));
            let bRank = rankFunctions.findIndex((rankFunction) => rankFunction(b));
            if (aRank >= 0 && bRank >= 0) {
                if (aRank < bRank)
                    return -1;
                if (bRank < aRank)
                    return 1;
            }

            if (a instanceof WI.BreakpointTreeElement && b instanceof WI.BreakpointTreeElement)
                return this._compareBreakpointTreeElements(a, b);

            return a.mainTitle.extendedLocaleCompare(b.mainTitle) || a.subtitle.extendedLocaleCompare(b.subtitle);
        };

        parentTreeElement.insertChild(treeElement, insertionIndexForObjectInListSortedByFunction(treeElement, parentTreeElement.children, comparator));
    }

    _compareBreakpointTreeElements(a, b)
    {
        if (!a.representedObject || !b.representedObject)
            return 0;

        let aLocation = a.representedObject.sourceCodeLocation;
        let bLocation = b.representedObject.sourceCodeLocation;
        if (!aLocation || !bLocation)
            return 0;

        var comparisonResult = aLocation.displayLineNumber - bLocation.displayLineNumber;
        if (comparisonResult !== 0)
            return comparisonResult;

        return aLocation.displayColumnNumber - bLocation.displayColumnNumber;
    }

    _updatePauseReason()
    {
        this._pauseReasonTreeOutline = null;

        this._updatePauseReasonGotoArrow();
        let target = WI.debuggerManager.activeCallFrame.target;
        let targetData = WI.debuggerManager.dataForTarget(target);
        return this._updatePauseReasonSection(target, targetData.pauseReason, targetData.pauseData);
    }

    _updatePauseReasonSection(target, pauseReason, pauseData)
    {
        switch (pauseReason) {
        case WI.DebuggerManager.PauseReason.AnimationFrame:
            this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

            var eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(WI.domDebuggerManager.allAnimationFramesBreakpoint, {
                className: WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName,
                title: WI.UIString("requestAnimationFrame Fired"),
            });
            this._pauseReasonTreeOutline.appendChild(eventBreakpointTreeElement);

            var eventBreakpointRow = new WI.DetailsSectionRow;
            eventBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

            this._pauseReasonGroup.rows = [eventBreakpointRow];
            return true;

        case WI.DebuggerManager.PauseReason.Assertion:
            // FIXME: We should include the assertion condition string.
            console.assert(pauseData, "Expected data with an assertion, but found none.");
            if (pauseData && pauseData.message) {
                this._pauseReasonTextRow.text = WI.UIString("Assertion with message: %s").format(pauseData.message);
                return true;
            }

            this._pauseReasonTextRow.text = WI.UIString("Assertion Failed");
            this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
            return true;

        case WI.DebuggerManager.PauseReason.BlackboxedScript: {
            console.assert(pauseData);
            if (pauseData)
                this._updatePauseReasonSection(target, WI.DebuggerManager.pauseReasonFromPayload(pauseData.originalReason), pauseData.originalData);

            // Don't use `_pauseReasonTextRow` as it may have already been set.
            let blackboxReasonTextRow = new WI.DetailsSectionTextRow(WI.UIString("Deferred pause from blackboxed script"));
            blackboxReasonTextRow.__blackboxReason = true;

            let existingRows = this._pauseReasonGroup.rows.filter((row) => !row.__blackboxReason);
            this._pauseReasonGroup.rows = [blackboxReasonTextRow, ...existingRows];
            return true;
        }

        case WI.DebuggerManager.PauseReason.Breakpoint:
            console.assert(pauseData, "Expected breakpoint identifier, but found none.");
            if (pauseData && pauseData.breakpointId) {
                this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});
                this._pauseReasonTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);

                let breakpoint = WI.debuggerManager.breakpointForIdentifier(pauseData.breakpointId);
                let breakpointTreeElement = new WI.BreakpointTreeElement(breakpoint, {
                    className: WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName,
                    title: WI.UIString("Triggered Breakpoint"),
                });
                let breakpointDetailsSection = new WI.DetailsSectionRow;
                this._pauseReasonTreeOutline.appendChild(breakpointTreeElement);
                breakpointDetailsSection.element.appendChild(this._pauseReasonTreeOutline.element);

                this._pauseReasonGroup.rows = [breakpointDetailsSection];
                return true;
            }
            break;

        case WI.DebuggerManager.PauseReason.CSPViolation:
            console.assert(pauseData, "Expected data with a CSP Violation, but found none.");
            if (pauseData) {
                // COMPATIBILITY (iOS 8): 'directive' was 'directiveText'.
                this._pauseReasonTextRow.text = WI.UIString("Content Security Policy violation of directive: %s").format(pauseData.directive || pauseData.directiveText);
                this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
                return true;
            }
            break;

        case WI.DebuggerManager.PauseReason.DebuggerStatement:
            this._pauseReasonTextRow.text = WI.UIString("Debugger Statement");
            this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
            return true;

        case WI.DebuggerManager.PauseReason.DOM:
            console.assert(WI.domDebuggerManager.supported);
            console.assert(pauseData, "Expected DOM breakpoint data, but found none.");
            if (pauseData && pauseData.nodeId) {
                let domNode = WI.domManager.nodeForId(pauseData.nodeId);
                let domBreakpoints = WI.domDebuggerManager.domBreakpointsForNode(domNode);
                let domBreakpoint;
                for (let breakpoint of domBreakpoints) {
                    if (breakpoint.type === pauseData.type) {
                        domBreakpoint = breakpoint;
                        break;
                    }
                }

                if (!domBreakpoint)
                    return;

                this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

                let type = WI.DOMBreakpointTreeElement.displayNameForType(domBreakpoint.type);
                let domBreakpointTreeElement = new WI.DOMBreakpointTreeElement(domBreakpoint, {
                    className: WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName,
                    title: type,
                });
                let domBreakpointRow = new WI.DetailsSectionRow;
                this._pauseReasonTreeOutline.appendChild(domBreakpointTreeElement);
                domBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

                let ownerElementRow = new WI.DetailsSectionSimpleRow(WI.UIString("Element"), WI.linkifyNodeReference(domNode));
                this._pauseReasonGroup.rows = [domBreakpointRow, ownerElementRow];

                if (domBreakpoint.type !== WI.DOMBreakpoint.Type.SubtreeModified)
                    return true;

                console.assert(pauseData.targetNode);

                let remoteObject = WI.RemoteObject.fromPayload(pauseData.targetNode, target);
                remoteObject.pushNodeToFrontend((nodeId) => {
                    if (!nodeId)
                        return;

                    let node = WI.domManager.nodeForId(nodeId);
                    console.assert(node, "Missing node for id.", nodeId);
                    if (!node)
                        return;

                    let fragment = document.createDocumentFragment();
                    let description = pauseData.insertion ? WI.UIString("Child added to ") : WI.UIString("Removed descendant ");
                    fragment.append(description, WI.linkifyNodeReference(node));

                    let targetDescriptionRow = new WI.DetailsSectionSimpleRow(WI.UIString("Details"), fragment);
                    targetDescriptionRow.element.classList.add("target-description");

                    this._pauseReasonGroup.rows = this._pauseReasonGroup.rows.concat(targetDescriptionRow);
                });

                return true;
            }
            break;

        case WI.DebuggerManager.PauseReason.Listener:
        case WI.DebuggerManager.PauseReason.EventListener:
            console.assert(pauseData, "Expected data with an event listener, but found none.");
            if (!pauseData)
                return false;

            var eventBreakpoint = null;
            if (pauseData.eventListenerId)
                eventBreakpoint = WI.domManager.breakpointForEventListenerId(pauseData.eventListenerId);
            if (!eventBreakpoint)
                eventBreakpoint = WI.domDebuggerManager.listenerBreakpointForEventName(pauseData.eventName);

            console.assert(eventBreakpoint, "Expected Event Listener breakpoint for event name.", pauseData.eventName);
            if (!eventBreakpoint)
                return false;

            this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

            var eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(eventBreakpoint, {
                className: WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName,
                title: WI.UIString("\u201C%s\u201D Event Fired").format(pauseData.eventName),
            });
            this._pauseReasonTreeOutline.appendChild(eventBreakpointTreeElement);

            var eventBreakpointRow = new WI.DetailsSectionRow;
            eventBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

            var rows = [eventBreakpointRow];

            var eventListener = eventBreakpoint.eventListener;
            if (eventListener) {
                console.assert(eventListener.eventListenerId === pauseData.eventListenerId);

                let value = null;
                if (eventListener.onWindow)
                    value = WI.unlocalizedString("window");
                else if (eventListener.node)
                    value = WI.linkifyNodeReference(eventListener.node);
                if (value)
                    rows.push(new WI.DetailsSectionSimpleRow(WI.UIString("Target"), value));
            }

            this._pauseReasonGroup.rows = rows;
            return true;

        case WI.DebuggerManager.PauseReason.Exception:
            console.assert(pauseData, "Expected data with an exception, but found none.");
            if (pauseData) {
                // FIXME: We should improve the appearance of thrown objects. This works well for exception strings.
                var data = WI.RemoteObject.fromPayload(pauseData, target);
                this._pauseReasonTextRow.text = WI.UIString("Exception with thrown value: %s").format(data.description);
                this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
                return true;
            }
            break;

        case WI.DebuggerManager.PauseReason.Interval:
            this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

            var eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(WI.domDebuggerManager.allIntervalsBreakpoint, {
                className: WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName,
                title: WI.UIString("setInterval Fired"),
            });
            this._pauseReasonTreeOutline.appendChild(eventBreakpointTreeElement);

            var eventBreakpointRow = new WI.DetailsSectionRow;
            eventBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

            this._pauseReasonGroup.rows = [eventBreakpointRow];
            return true;

        case WI.DebuggerManager.PauseReason.Microtask:
            this._pauseReasonTextRow.text = WI.UIString("Microtask Fired");
            this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
            return true;

        case WI.DebuggerManager.PauseReason.PauseOnNextStatement:
            this._pauseReasonTextRow.text = WI.UIString("Immediate Pause Requested");
            this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
            return true;

        case WI.DebuggerManager.PauseReason.Timer:
            console.assert(pauseData, "Expected data with a timer, but found none.");
            if (!pauseData)
                return false;

            var eventBreakpoint = null;
            switch (pauseData.eventName) {
            case "setTimeout":
                eventBreakpoint = WI.domDebuggerManager.allTimeoutsBreakpoint;
                break;

            case "setInterval":
                eventBreakpoint = WI.domDebuggerManager.allIntervalsBreakpoint;
                break;
            }
            console.assert(eventBreakpoint, "Expected Timer breakpoint for event name.", pauseData.eventName);
            if (!eventBreakpoint)
                return false;

            this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

            var eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(eventBreakpoint, {
                className: WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName,
                title: WI.UIString("%s Fired").format(pauseData.eventName),
            });
            this._pauseReasonTreeOutline.appendChild(eventBreakpointTreeElement);

            var eventBreakpointRow = new WI.DetailsSectionRow;
            eventBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

            this._pauseReasonGroup.rows = [eventBreakpointRow];
            return true;

        case WI.DebuggerManager.PauseReason.Timeout:
            this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

            var eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(WI.domDebuggerManager.allTimeoutsBreakpoint, {
                className: WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName,
                title: WI.UIString("setTimeout Fired"),
            });
            this._pauseReasonTreeOutline.appendChild(eventBreakpointTreeElement);

            var eventBreakpointRow = new WI.DetailsSectionRow;
            eventBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

            this._pauseReasonGroup.rows = [eventBreakpointRow];
            return true;

        case WI.DebuggerManager.PauseReason.Fetch:
        case WI.DebuggerManager.PauseReason.XHR:
            console.assert(WI.domDebuggerManager.supported);
            console.assert(pauseData, "Expected URL breakpoint data, but found none.");
            if (pauseData) {
                if (pauseData.breakpointURL) {
                    let urlBreakpoint = WI.domDebuggerManager.urlBreakpointForURL(pauseData.breakpointURL);
                    console.assert(urlBreakpoint, "Expected URL breakpoint for URL.", pauseData.breakpointURL);

                    this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

                    let urlBreakpointTreeElement = new WI.URLBreakpointTreeElement(urlBreakpoint, {
                        className: WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName,
                        title: WI.DOMDebuggerManager.supportsURLBreakpoints() ? WI.UIString("Triggered URL Breakpoint") : WI.UIString("Triggered XHR Breakpoint"),
                    });
                    let urlBreakpointRow = new WI.DetailsSectionRow;
                    this._pauseReasonTreeOutline.appendChild(urlBreakpointTreeElement);
                    urlBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

                    this._pauseReasonTextRow.text = pauseData.url;
                    this._pauseReasonGroup.rows = [urlBreakpointRow, this._pauseReasonTextRow];
                } else {
                    console.assert(pauseData.breakpointURL === "", "Should be the All Requests breakpoint which has an empty URL");
                    this._pauseReasonTextRow.text = WI.UIString("Requesting: %s").format(pauseData.url);
                    this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
                }
                this._pauseReasonTextRow.element.title = pauseData.url;
                return true;
            }
            break;

        case WI.DebuggerManager.PauseReason.Other:
            console.error("Paused for unknown reason. We should always have a reason.");
            break;
        }

        return false;
    }

    _updatePauseReasonGotoArrow()
    {
        this._pauseReasonLinkContainerElement.removeChildren();

        var activeCallFrame = WI.debuggerManager.activeCallFrame;
        if (!activeCallFrame)
            return;

        var sourceCodeLocation = activeCallFrame.sourceCodeLocation;
        if (!sourceCodeLocation)
            return;

        const options = {
            useGoToArrowButton: true,
            ignoreNetworkTab: true,
            ignoreSearchTab: true,
        };
        let linkElement = WI.createSourceCodeLocationLink(sourceCodeLocation, options);
        this._pauseReasonLinkContainerElement.appendChild(linkElement);
    }

    _addIssue(issueMessage, sourceCode)
    {
        let issueTreeElement = this._scriptsContentTreeOutline.findTreeElement(issueMessage);
        if (issueTreeElement)
            return issueTreeElement;

        console.assert(sourceCode || (issueMessage.sourceCodeLocation && issueMessage.sourceCodeLocation.sourceCode));
        let parentTreeElement = this._addTreeElementForSourceCodeToTreeOutline(sourceCode || issueMessage.sourceCodeLocation.sourceCode, this._scriptsContentTreeOutline);
        if (!parentTreeElement)
            return null;

        issueTreeElement = new WI.IssueTreeElement(issueMessage);

        parentTreeElement.insertChild(issueTreeElement, insertionIndexForObjectInListSortedByFunction(issueTreeElement, parentTreeElement.children, this._compareBreakpointTreeElements));
        if (parentTreeElement.children.length === 1)
            parentTreeElement.expand();

        return issueTreeElement;
    }

    _handleDOMBreakpointDOMNodeChanged(event)
    {
        let breakpoint = event.target;
        if (breakpoint.domNodeIdentifier)
            this._addBreakpoint(breakpoint);
        else
            this._removeBreakpoint(breakpoint);
    }

    _handleIssueAdded(event)
    {
        var issue = event.data.issue;

        // We only want to show issues originating from JavaScript source code.
        if (!issue.sourceCodeLocation || !issue.sourceCodeLocation.sourceCode || (issue.source !== "javascript" && issue.source !== "console-api"))
            return;

        this._addIssue(issue);
    }

    _handleIssuesCleared(event)
    {
        let currentTreeElement = this._scriptsContentTreeOutline.children[0];
        let issueTreeElements = [];

        while (currentTreeElement && !currentTreeElement.root) {
            if (currentTreeElement instanceof WI.IssueTreeElement)
                issueTreeElements.push(currentTreeElement);
            currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, true);
        }

        issueTreeElements.forEach((treeElement) => treeElement.parent.removeChild(treeElement));
    }

    _handleBreakpointElementAddedOrRemoved(event)
    {
        let treeElement = event.data.element;

        let setting = null;
        switch (treeElement.representedObject) {
        case WI.debuggerManager.assertionFailuresBreakpoint:
            setting = WI.settings.showAssertionFailuresBreakpoint;
            break;

        case WI.debuggerManager.allMicrotasksBreakpoint:
            setting = WI.settings.showAllMicrotasksBreakpoint;
            break;

        case WI.domDebuggerManager.allAnimationFramesBreakpoint:
            setting = WI.settings.showAllAnimationFramesBreakpoint;
            break;

        case WI.domDebuggerManager.allIntervalsBreakpoint:
            setting = WI.settings.showAllIntervalsBreakpoint;
            break;

        case WI.domDebuggerManager.allListenersBreakpoint:
            setting = WI.settings.showAllListenersBreakpoint;
            break;

        case WI.domDebuggerManager.allRequestsBreakpoint:
            setting = WI.settings.showAllRequestsBreakpoint;
            break;

        case WI.domDebuggerManager.allTimeoutsBreakpoint:
            setting = WI.settings.showAllTimeoutsBreakpoint;
            break;
        }
        if (setting)
            setting.value = !!treeElement.parent;

        if (event.type === WI.TreeOutline.Event.ElementRemoved) {
            let selectedTreeElement = this._breakpointsContentTreeOutline.selectedTreeElement;
            if (selectedTreeElement) {
                if (selectedTreeElement.representedObject === WI.debuggerManager.assertionFailuresBreakpoint || !WI.debuggerManager.isBreakpointRemovable(selectedTreeElement.representedObject)) {
                    const skipUnrevealed = true;
                    const dontPopulate = true;
                    let treeElementToSelect = selectedTreeElement.traverseNextTreeElement(skipUnrevealed, dontPopulate);
                    if (treeElementToSelect) {
                        const omitFocus = true;
                        const selectedByUser = true;
                        treeElementToSelect.select(omitFocus, selectedByUser);
                    }
                }
            }
        }
    }

    _populateCreateBreakpointContextMenu(contextMenu)
    {
        // COMPATIBILITY (iOS 10): DebuggerAgent.setPauseOnAssertions did not exist yet.
        if (InspectorBackend.domains.Debugger.setPauseOnAssertions) {
            let assertionFailuresBreakpointShown = WI.settings.showAssertionFailuresBreakpoint.value;

            contextMenu.appendCheckboxItem(WI.repeatedUIString.assertionFailures(), () => {
                if (assertionFailuresBreakpointShown)
                    WI.debuggerManager.removeBreakpoint(WI.debuggerManager.assertionFailuresBreakpoint);
                else {
                    WI.debuggerManager.assertionFailuresBreakpoint.disabled = false;
                    WI.debuggerManager.addBreakpoint(WI.debuggerManager.assertionFailuresBreakpoint);
                }
            }, assertionFailuresBreakpointShown);
        }

        contextMenu.appendSeparator();

        // COMPATIBILITY (iOS 13): DebuggerAgent.setPauseOnMicrotasks did not exist yet.
        if (InspectorBackend.domains.Debugger.setPauseOnMicrotasks) {
            let allMicrotasksBreakpointShown = WI.settings.showAllMicrotasksBreakpoint.value;

            contextMenu.appendCheckboxItem(WI.UIString("All Microtasks"), () => {
                if (allMicrotasksBreakpointShown)
                    WI.debuggerManager.removeBreakpoint(WI.debuggerManager.allMicrotasksBreakpoint);
                else {
                    WI.debuggerManager.allMicrotasksBreakpoint.disabled = false;
                    WI.debuggerManager.addBreakpoint(WI.debuggerManager.allMicrotasksBreakpoint);
                }
            }, allMicrotasksBreakpointShown);
        }

        if (WI.DOMDebuggerManager.supportsEventBreakpoints() || WI.DOMDebuggerManager.supportsEventListenerBreakpoints()) {
            function addToggleForSpecialEventBreakpoint(breakpoint, label, checked) {
                contextMenu.appendCheckboxItem(label, () => {
                    if (checked)
                        WI.domDebuggerManager.removeEventBreakpoint(breakpoint);
                    else {
                        breakpoint.disabled = false;
                        WI.domDebuggerManager.addEventBreakpoint(breakpoint);
                    }
                }, checked);
            }

            addToggleForSpecialEventBreakpoint(WI.domDebuggerManager.allAnimationFramesBreakpoint, WI.UIString("All Animation Frames"), WI.settings.showAllAnimationFramesBreakpoint.value);
            addToggleForSpecialEventBreakpoint(WI.domDebuggerManager.allTimeoutsBreakpoint, WI.UIString("All Timeouts"), WI.settings.showAllTimeoutsBreakpoint.value);
            addToggleForSpecialEventBreakpoint(WI.domDebuggerManager.allIntervalsBreakpoint, WI.UIString("All Intervals"), WI.settings.showAllIntervalsBreakpoint.value);

            contextMenu.appendSeparator();

            if (WI.DOMDebuggerManager.supportsAllListenersBreakpoint())
                addToggleForSpecialEventBreakpoint(WI.domDebuggerManager.allListenersBreakpoint, WI.UIString("All Events"), WI.settings.showAllListenersBreakpoint.value);

            contextMenu.appendItem(WI.UIString("Event Breakpoint\u2026"), () => {
                let popover = new WI.EventBreakpointPopover(this);
                popover.show(this._createBreakpointButton.element, [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
            });
        }

        if (WI.DOMDebuggerManager.supportsURLBreakpoints() || WI.DOMDebuggerManager.supportsXHRBreakpoints()) {
            contextMenu.appendSeparator();

            let allRequestsBreakpointShown = WI.settings.showAllRequestsBreakpoint.value;
            contextMenu.appendCheckboxItem(WI.repeatedUIString.allRequests(), () => {
                if (allRequestsBreakpointShown)
                    WI.domDebuggerManager.removeURLBreakpoint(WI.domDebuggerManager.allRequestsBreakpoint);
                else {
                    WI.domDebuggerManager.allRequestsBreakpoint.disabled = false;
                    WI.domDebuggerManager.addURLBreakpoint(WI.domDebuggerManager.allRequestsBreakpoint);
                }
            }, allRequestsBreakpointShown);

            contextMenu.appendItem(WI.DOMDebuggerManager.supportsURLBreakpoints() ? WI.UIString("URL Breakpoint\u2026") : WI.UIString("XHR Breakpoint\u2026"), () => {
                let popover = new WI.URLBreakpointPopover(this);
                popover.show(this._createBreakpointButton.element, [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
            });
        }
    }
};

WI.DebuggerSidebarPanel.DebuggerPausedStyleClassName = "paused";
WI.DebuggerSidebarPanel.ExceptionIconStyleClassName = "breakpoint-exception-icon";
WI.DebuggerSidebarPanel.AssertionIconStyleClassName = "breakpoint-assertion-icon";
WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName = "breakpoint-paused-icon";

WI.DebuggerSidebarPanel.SelectedAllExceptionsCookieKey = "debugger-sidebar-panel-all-exceptions-breakpoint";
WI.DebuggerSidebarPanel.SelectedUncaughtExceptionsCookieKey = "debugger-sidebar-panel-uncaught-exceptions-breakpoint";
WI.DebuggerSidebarPanel.SelectedAssertionFailuresCookieKey = "debugger-sidebar-panel-assertion-failures-breakpoint";
WI.DebuggerSidebarPanel.SelectedAllMicrotasksCookieKey = "debugger-sidebar-panel-all-microtasks-breakpoint";
WI.DebuggerSidebarPanel.SelectedAllAnimationFramesBreakpoint = "debugger-sidebar-panel-all-animation-frames-breakpoint";
WI.DebuggerSidebarPanel.SelectedAllIntervalsBreakpoint = "debugger-sidebar-panel-all-intervals-breakpoint";
WI.DebuggerSidebarPanel.SelectedAllListenersBreakpoint = "debugger-sidebar-panel-all-listeners-breakpoint";
WI.DebuggerSidebarPanel.SelectedAllTimeoutsBreakpoint = "debugger-sidebar-panel-all-timeouts-breakpoint";
WI.DebuggerSidebarPanel.SelectedAllRequestsCookieKey = "debugger-sidebar-panel-all-requests-breakpoint";
