/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from CombinedDomains.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#include "config.h"
#include "InspectorBackendDispatchers.h"

#include <inspector/InspectorFrontendRouter.h>
#include <inspector/InspectorValues.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/text/CString.h>

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
#include "InspectorAlternateBackendDispatchers.h"
#endif

namespace Inspector {

ApplicationCacheBackendDispatcherHandler::~ApplicationCacheBackendDispatcherHandler() { }
CSSBackendDispatcherHandler::~CSSBackendDispatcherHandler() { }
ConsoleBackendDispatcherHandler::~ConsoleBackendDispatcherHandler() { }
DOMBackendDispatcherHandler::~DOMBackendDispatcherHandler() { }
DOMDebuggerBackendDispatcherHandler::~DOMDebuggerBackendDispatcherHandler() { }
DOMStorageBackendDispatcherHandler::~DOMStorageBackendDispatcherHandler() { }
DatabaseBackendDispatcherHandler::~DatabaseBackendDispatcherHandler() { }
DebuggerBackendDispatcherHandler::~DebuggerBackendDispatcherHandler() { }
HeapBackendDispatcherHandler::~HeapBackendDispatcherHandler() { }
InspectorBackendDispatcherHandler::~InspectorBackendDispatcherHandler() { }
LayerTreeBackendDispatcherHandler::~LayerTreeBackendDispatcherHandler() { }
NetworkBackendDispatcherHandler::~NetworkBackendDispatcherHandler() { }
PageBackendDispatcherHandler::~PageBackendDispatcherHandler() { }
RuntimeBackendDispatcherHandler::~RuntimeBackendDispatcherHandler() { }
ScriptProfilerBackendDispatcherHandler::~ScriptProfilerBackendDispatcherHandler() { }
TimelineBackendDispatcherHandler::~TimelineBackendDispatcherHandler() { }

Ref<ApplicationCacheBackendDispatcher> ApplicationCacheBackendDispatcher::create(BackendDispatcher& backendDispatcher, ApplicationCacheBackendDispatcherHandler* agent)
{
    return adoptRef(*new ApplicationCacheBackendDispatcher(backendDispatcher, agent));
}

ApplicationCacheBackendDispatcher::ApplicationCacheBackendDispatcher(BackendDispatcher& backendDispatcher, ApplicationCacheBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("ApplicationCache"), this);
}

void ApplicationCacheBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<ApplicationCacheBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    if (method == "getFramesWithManifests")
        getFramesWithManifests(requestId, WTFMove(parameters));
    else if (method == "enable")
        enable(requestId, WTFMove(parameters));
    else if (method == "getManifestForFrame")
        getManifestForFrame(requestId, WTFMove(parameters));
    else if (method == "getApplicationCacheForFrame")
        getApplicationCacheForFrame(requestId, WTFMove(parameters));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "ApplicationCache", '.', method, "' was not found"));
}

void ApplicationCacheBackendDispatcher::getFramesWithManifests(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getFramesWithManifests(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::ApplicationCache::FrameWithManifest>> out_frameIds;
    m_agent->getFramesWithManifests(error, out_frameIds);

    if (!error.length())
        result->setArray(ASCIILiteral("frameIds"), out_frameIds);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void ApplicationCacheBackendDispatcher::enable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void ApplicationCacheBackendDispatcher::getManifestForFrame(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_frameId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("frameId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "ApplicationCache.getManifestForFrame"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getManifestForFrame(requestId, in_frameId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    String out_manifestURL;
    m_agent->getManifestForFrame(error, in_frameId, &out_manifestURL);

    if (!error.length())
        result->setString(ASCIILiteral("manifestURL"), out_manifestURL);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void ApplicationCacheBackendDispatcher::getApplicationCacheForFrame(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_frameId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("frameId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "ApplicationCache.getApplicationCacheForFrame"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getApplicationCacheForFrame(requestId, in_frameId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::ApplicationCache::ApplicationCache> out_applicationCache;
    m_agent->getApplicationCacheForFrame(error, in_frameId, out_applicationCache);

    if (!error.length())
        result->setObject(ASCIILiteral("applicationCache"), out_applicationCache);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

Ref<CSSBackendDispatcher> CSSBackendDispatcher::create(BackendDispatcher& backendDispatcher, CSSBackendDispatcherHandler* agent)
{
    return adoptRef(*new CSSBackendDispatcher(backendDispatcher, agent));
}

CSSBackendDispatcher::CSSBackendDispatcher(BackendDispatcher& backendDispatcher, CSSBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("CSS"), this);
}

void CSSBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<CSSBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    typedef void (CSSBackendDispatcher::*CallHandler)(long requestId, RefPtr<InspectorObject>&& message);
    typedef HashMap<String, CallHandler> DispatchMap;
    static NeverDestroyed<DispatchMap> dispatchMap;
    if (dispatchMap.get().isEmpty()) {
        static const struct MethodTable {
            const char* name;
            CallHandler handler;
        } commands[] = {
            { "enable", &CSSBackendDispatcher::enable },
            { "disable", &CSSBackendDispatcher::disable },
            { "getMatchedStylesForNode", &CSSBackendDispatcher::getMatchedStylesForNode },
            { "getInlineStylesForNode", &CSSBackendDispatcher::getInlineStylesForNode },
            { "getComputedStyleForNode", &CSSBackendDispatcher::getComputedStyleForNode },
            { "getAllStyleSheets", &CSSBackendDispatcher::getAllStyleSheets },
            { "getStyleSheet", &CSSBackendDispatcher::getStyleSheet },
            { "getStyleSheetText", &CSSBackendDispatcher::getStyleSheetText },
            { "setStyleSheetText", &CSSBackendDispatcher::setStyleSheetText },
            { "setStyleText", &CSSBackendDispatcher::setStyleText },
            { "setRuleSelector", &CSSBackendDispatcher::setRuleSelector },
            { "createStyleSheet", &CSSBackendDispatcher::createStyleSheet },
            { "addRule", &CSSBackendDispatcher::addRule },
            { "getSupportedCSSProperties", &CSSBackendDispatcher::getSupportedCSSProperties },
            { "getSupportedSystemFontFamilyNames", &CSSBackendDispatcher::getSupportedSystemFontFamilyNames },
            { "forcePseudoState", &CSSBackendDispatcher::forcePseudoState },
            { "getNamedFlowCollection", &CSSBackendDispatcher::getNamedFlowCollection },
        };
        size_t length = WTF_ARRAY_LENGTH(commands);
        for (size_t i = 0; i < length; ++i)
            dispatchMap.get().add(commands[i].name, commands[i].handler);
    }

    auto findResult = dispatchMap.get().find(method);
    if (findResult == dispatchMap.get().end()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "CSS", '.', method, "' was not found"));
        return;
    }

    ((*this).*findResult->value)(requestId, WTFMove(parameters));
}

void CSSBackendDispatcher::enable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::disable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->disable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->disable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::getMatchedStylesForNode(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    bool opt_in_includePseudo_valueFound = false;
    bool opt_in_includePseudo = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("includePseudo"), &opt_in_includePseudo_valueFound);
    bool opt_in_includeInherited_valueFound = false;
    bool opt_in_includeInherited = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("includeInherited"), &opt_in_includeInherited_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "CSS.getMatchedStylesForNode"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getMatchedStylesForNode(requestId, in_nodeId, opt_in_includePseudo_valueFound ? &opt_in_includePseudo : nullptr, opt_in_includeInherited_valueFound ? &opt_in_includeInherited : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::RuleMatch>> out_matchedCSSRules;
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::PseudoIdMatches>> out_pseudoElements;
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::InheritedStyleEntry>> out_inherited;
    m_agent->getMatchedStylesForNode(error, in_nodeId, opt_in_includePseudo_valueFound ? &opt_in_includePseudo : nullptr, opt_in_includeInherited_valueFound ? &opt_in_includeInherited : nullptr, out_matchedCSSRules, out_pseudoElements, out_inherited);

    if (!error.length()) {
        if (out_matchedCSSRules)
            result->setArray(ASCIILiteral("matchedCSSRules"), out_matchedCSSRules);
        if (out_pseudoElements)
            result->setArray(ASCIILiteral("pseudoElements"), out_pseudoElements);
        if (out_inherited)
            result->setArray(ASCIILiteral("inherited"), out_inherited);
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::getInlineStylesForNode(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "CSS.getInlineStylesForNode"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getInlineStylesForNode(requestId, in_nodeId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::CSS::CSSStyle> out_inlineStyle;
    RefPtr<Inspector::Protocol::CSS::CSSStyle> out_attributesStyle;
    m_agent->getInlineStylesForNode(error, in_nodeId, out_inlineStyle, out_attributesStyle);

    if (!error.length()) {
        if (out_inlineStyle)
            result->setObject(ASCIILiteral("inlineStyle"), out_inlineStyle);
        if (out_attributesStyle)
            result->setObject(ASCIILiteral("attributesStyle"), out_attributesStyle);
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::getComputedStyleForNode(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "CSS.getComputedStyleForNode"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getComputedStyleForNode(requestId, in_nodeId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSComputedStyleProperty>> out_computedStyle;
    m_agent->getComputedStyleForNode(error, in_nodeId, out_computedStyle);

    if (!error.length())
        result->setArray(ASCIILiteral("computedStyle"), out_computedStyle);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::getAllStyleSheets(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getAllStyleSheets(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSStyleSheetHeader>> out_headers;
    m_agent->getAllStyleSheets(error, out_headers);

    if (!error.length())
        result->setArray(ASCIILiteral("headers"), out_headers);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::getStyleSheet(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_styleSheetId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("styleSheetId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "CSS.getStyleSheet"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getStyleSheet(requestId, in_styleSheetId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::CSS::CSSStyleSheetBody> out_styleSheet;
    m_agent->getStyleSheet(error, in_styleSheetId, out_styleSheet);

    if (!error.length())
        result->setObject(ASCIILiteral("styleSheet"), out_styleSheet);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::getStyleSheetText(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_styleSheetId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("styleSheetId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "CSS.getStyleSheetText"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getStyleSheetText(requestId, in_styleSheetId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    String out_text;
    m_agent->getStyleSheetText(error, in_styleSheetId, &out_text);

    if (!error.length())
        result->setString(ASCIILiteral("text"), out_text);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::setStyleSheetText(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_styleSheetId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("styleSheetId"), nullptr);
    String in_text = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("text"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "CSS.setStyleSheetText"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setStyleSheetText(requestId, in_styleSheetId, in_text);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setStyleSheetText(error, in_styleSheetId, in_text);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::setStyleText(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorObject> in_styleId = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("styleId"), nullptr);
    String in_text = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("text"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "CSS.setStyleText"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setStyleText(requestId, *in_styleId, in_text);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::CSS::CSSStyle> out_style;
    m_agent->setStyleText(error, *in_styleId, in_text, out_style);

    if (!error.length())
        result->setObject(ASCIILiteral("style"), out_style);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::setRuleSelector(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorObject> in_ruleId = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("ruleId"), nullptr);
    String in_selector = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("selector"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "CSS.setRuleSelector"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setRuleSelector(requestId, *in_ruleId, in_selector);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::CSS::CSSRule> out_rule;
    m_agent->setRuleSelector(error, *in_ruleId, in_selector, out_rule);

    if (!error.length())
        result->setObject(ASCIILiteral("rule"), out_rule);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::createStyleSheet(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_frameId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("frameId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "CSS.createStyleSheet"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->createStyleSheet(requestId, in_frameId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Inspector::Protocol::CSS::StyleSheetId out_styleSheetId;
    m_agent->createStyleSheet(error, in_frameId, &out_styleSheetId);

    if (!error.length())
        result->setString(ASCIILiteral("styleSheetId"), out_styleSheetId);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::addRule(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_styleSheetId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("styleSheetId"), nullptr);
    String in_selector = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("selector"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "CSS.addRule"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->addRule(requestId, in_styleSheetId, in_selector);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::CSS::CSSRule> out_rule;
    m_agent->addRule(error, in_styleSheetId, in_selector, out_rule);

    if (!error.length())
        result->setObject(ASCIILiteral("rule"), out_rule);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::getSupportedCSSProperties(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getSupportedCSSProperties(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSPropertyInfo>> out_cssProperties;
    m_agent->getSupportedCSSProperties(error, out_cssProperties);

    if (!error.length())
        result->setArray(ASCIILiteral("cssProperties"), out_cssProperties);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::getSupportedSystemFontFamilyNames(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getSupportedSystemFontFamilyNames(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<String>> out_fontFamilyNames;
    m_agent->getSupportedSystemFontFamilyNames(error, out_fontFamilyNames);

    if (!error.length())
        result->setArray(ASCIILiteral("fontFamilyNames"), out_fontFamilyNames);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::forcePseudoState(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    RefPtr<Inspector::InspectorArray> in_forcedPseudoClasses = m_backendDispatcher->getArray(parameters.get(), ASCIILiteral("forcedPseudoClasses"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "CSS.forcePseudoState"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->forcePseudoState(requestId, in_nodeId, *in_forcedPseudoClasses);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->forcePseudoState(error, in_nodeId, *in_forcedPseudoClasses);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void CSSBackendDispatcher::getNamedFlowCollection(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_documentNodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("documentNodeId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "CSS.getNamedFlowCollection"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getNamedFlowCollection(requestId, in_documentNodeId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::NamedFlow>> out_namedFlows;
    m_agent->getNamedFlowCollection(error, in_documentNodeId, out_namedFlows);

    if (!error.length())
        result->setArray(ASCIILiteral("namedFlows"), out_namedFlows);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

Ref<ConsoleBackendDispatcher> ConsoleBackendDispatcher::create(BackendDispatcher& backendDispatcher, ConsoleBackendDispatcherHandler* agent)
{
    return adoptRef(*new ConsoleBackendDispatcher(backendDispatcher, agent));
}

ConsoleBackendDispatcher::ConsoleBackendDispatcher(BackendDispatcher& backendDispatcher, ConsoleBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Console"), this);
}

void ConsoleBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<ConsoleBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    if (method == "enable")
        enable(requestId, WTFMove(parameters));
    else if (method == "disable")
        disable(requestId, WTFMove(parameters));
    else if (method == "clearMessages")
        clearMessages(requestId, WTFMove(parameters));
    else if (method == "setMonitoringXHREnabled")
        setMonitoringXHREnabled(requestId, WTFMove(parameters));
    else if (method == "addInspectedNode")
        addInspectedNode(requestId, WTFMove(parameters));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Console", '.', method, "' was not found"));
}

void ConsoleBackendDispatcher::enable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void ConsoleBackendDispatcher::disable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->disable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->disable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void ConsoleBackendDispatcher::clearMessages(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->clearMessages(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->clearMessages(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void ConsoleBackendDispatcher::setMonitoringXHREnabled(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool in_enabled = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("enabled"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Console.setMonitoringXHREnabled"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setMonitoringXHREnabled(requestId, in_enabled);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setMonitoringXHREnabled(error, in_enabled);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void ConsoleBackendDispatcher::addInspectedNode(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Console.addInspectedNode"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->addInspectedNode(requestId, in_nodeId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->addInspectedNode(error, in_nodeId);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

Ref<DOMBackendDispatcher> DOMBackendDispatcher::create(BackendDispatcher& backendDispatcher, DOMBackendDispatcherHandler* agent)
{
    return adoptRef(*new DOMBackendDispatcher(backendDispatcher, agent));
}

DOMBackendDispatcher::DOMBackendDispatcher(BackendDispatcher& backendDispatcher, DOMBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("DOM"), this);
}

void DOMBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<DOMBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    typedef void (DOMBackendDispatcher::*CallHandler)(long requestId, RefPtr<InspectorObject>&& message);
    typedef HashMap<String, CallHandler> DispatchMap;
    static NeverDestroyed<DispatchMap> dispatchMap;
    if (dispatchMap.get().isEmpty()) {
        static const struct MethodTable {
            const char* name;
            CallHandler handler;
        } commands[] = {
            { "getDocument", &DOMBackendDispatcher::getDocument },
            { "requestChildNodes", &DOMBackendDispatcher::requestChildNodes },
            { "querySelector", &DOMBackendDispatcher::querySelector },
            { "querySelectorAll", &DOMBackendDispatcher::querySelectorAll },
            { "setNodeName", &DOMBackendDispatcher::setNodeName },
            { "setNodeValue", &DOMBackendDispatcher::setNodeValue },
            { "removeNode", &DOMBackendDispatcher::removeNode },
            { "setAttributeValue", &DOMBackendDispatcher::setAttributeValue },
            { "setAttributesAsText", &DOMBackendDispatcher::setAttributesAsText },
            { "removeAttribute", &DOMBackendDispatcher::removeAttribute },
            { "getEventListenersForNode", &DOMBackendDispatcher::getEventListenersForNode },
            { "getAccessibilityPropertiesForNode", &DOMBackendDispatcher::getAccessibilityPropertiesForNode },
            { "getOuterHTML", &DOMBackendDispatcher::getOuterHTML },
            { "setOuterHTML", &DOMBackendDispatcher::setOuterHTML },
            { "performSearch", &DOMBackendDispatcher::performSearch },
            { "getSearchResults", &DOMBackendDispatcher::getSearchResults },
            { "discardSearchResults", &DOMBackendDispatcher::discardSearchResults },
            { "requestNode", &DOMBackendDispatcher::requestNode },
            { "setInspectModeEnabled", &DOMBackendDispatcher::setInspectModeEnabled },
            { "highlightRect", &DOMBackendDispatcher::highlightRect },
            { "highlightQuad", &DOMBackendDispatcher::highlightQuad },
            { "highlightSelector", &DOMBackendDispatcher::highlightSelector },
            { "highlightNode", &DOMBackendDispatcher::highlightNode },
            { "hideHighlight", &DOMBackendDispatcher::hideHighlight },
            { "highlightFrame", &DOMBackendDispatcher::highlightFrame },
            { "pushNodeByPathToFrontend", &DOMBackendDispatcher::pushNodeByPathToFrontend },
            { "pushNodeByBackendIdToFrontend", &DOMBackendDispatcher::pushNodeByBackendIdToFrontend },
            { "releaseBackendNodeIds", &DOMBackendDispatcher::releaseBackendNodeIds },
            { "resolveNode", &DOMBackendDispatcher::resolveNode },
            { "getAttributes", &DOMBackendDispatcher::getAttributes },
            { "moveTo", &DOMBackendDispatcher::moveTo },
            { "undo", &DOMBackendDispatcher::undo },
            { "redo", &DOMBackendDispatcher::redo },
            { "markUndoableState", &DOMBackendDispatcher::markUndoableState },
            { "focus", &DOMBackendDispatcher::focus },
        };
        size_t length = WTF_ARRAY_LENGTH(commands);
        for (size_t i = 0; i < length; ++i)
            dispatchMap.get().add(commands[i].name, commands[i].handler);
    }

    auto findResult = dispatchMap.get().find(method);
    if (findResult == dispatchMap.get().end()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "DOM", '.', method, "' was not found"));
        return;
    }

    ((*this).*findResult->value)(requestId, WTFMove(parameters));
}

void DOMBackendDispatcher::getDocument(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getDocument(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::DOM::Node> out_root;
    m_agent->getDocument(error, out_root);

    if (!error.length())
        result->setObject(ASCIILiteral("root"), out_root);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::requestChildNodes(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    bool opt_in_depth_valueFound = false;
    int opt_in_depth = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("depth"), &opt_in_depth_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.requestChildNodes"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->requestChildNodes(requestId, in_nodeId, opt_in_depth_valueFound ? &opt_in_depth : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->requestChildNodes(error, in_nodeId, opt_in_depth_valueFound ? &opt_in_depth : nullptr);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::querySelector(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    String in_selector = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("selector"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.querySelector"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->querySelector(requestId, in_nodeId, in_selector);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Inspector::Protocol::DOM::NodeId out_nodeId;
    m_agent->querySelector(error, in_nodeId, in_selector, &out_nodeId);

    if (!error.length())
        result->setInteger(ASCIILiteral("nodeId"), out_nodeId);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::querySelectorAll(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    String in_selector = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("selector"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.querySelectorAll"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->querySelectorAll(requestId, in_nodeId, in_selector);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::DOM::NodeId>> out_nodeIds;
    m_agent->querySelectorAll(error, in_nodeId, in_selector, out_nodeIds);

    if (!error.length())
        result->setArray(ASCIILiteral("nodeIds"), out_nodeIds);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::setNodeName(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    String in_name = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("name"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.setNodeName"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setNodeName(requestId, in_nodeId, in_name);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Inspector::Protocol::DOM::NodeId out_nodeId;
    m_agent->setNodeName(error, in_nodeId, in_name, &out_nodeId);

    if (!error.length())
        result->setInteger(ASCIILiteral("nodeId"), out_nodeId);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::setNodeValue(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    String in_value = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("value"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.setNodeValue"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setNodeValue(requestId, in_nodeId, in_value);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setNodeValue(error, in_nodeId, in_value);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::removeNode(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.removeNode"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->removeNode(requestId, in_nodeId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->removeNode(error, in_nodeId);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::setAttributeValue(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    String in_name = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("name"), nullptr);
    String in_value = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("value"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.setAttributeValue"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setAttributeValue(requestId, in_nodeId, in_name, in_value);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setAttributeValue(error, in_nodeId, in_name, in_value);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::setAttributesAsText(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    String in_text = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("text"), nullptr);
    bool opt_in_name_valueFound = false;
    String opt_in_name = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("name"), &opt_in_name_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.setAttributesAsText"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setAttributesAsText(requestId, in_nodeId, in_text, opt_in_name_valueFound ? &opt_in_name : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setAttributesAsText(error, in_nodeId, in_text, opt_in_name_valueFound ? &opt_in_name : nullptr);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::removeAttribute(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    String in_name = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("name"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.removeAttribute"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->removeAttribute(requestId, in_nodeId, in_name);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->removeAttribute(error, in_nodeId, in_name);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::getEventListenersForNode(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    bool opt_in_objectGroup_valueFound = false;
    String opt_in_objectGroup = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectGroup"), &opt_in_objectGroup_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.getEventListenersForNode"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getEventListenersForNode(requestId, in_nodeId, opt_in_objectGroup_valueFound ? &opt_in_objectGroup : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::DOM::EventListener>> out_listeners;
    m_agent->getEventListenersForNode(error, in_nodeId, opt_in_objectGroup_valueFound ? &opt_in_objectGroup : nullptr, out_listeners);

    if (!error.length())
        result->setArray(ASCIILiteral("listeners"), out_listeners);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::getAccessibilityPropertiesForNode(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.getAccessibilityPropertiesForNode"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getAccessibilityPropertiesForNode(requestId, in_nodeId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::DOM::AccessibilityProperties> out_properties;
    m_agent->getAccessibilityPropertiesForNode(error, in_nodeId, out_properties);

    if (!error.length())
        result->setObject(ASCIILiteral("properties"), out_properties);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::getOuterHTML(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.getOuterHTML"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getOuterHTML(requestId, in_nodeId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    String out_outerHTML;
    m_agent->getOuterHTML(error, in_nodeId, &out_outerHTML);

    if (!error.length())
        result->setString(ASCIILiteral("outerHTML"), out_outerHTML);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::setOuterHTML(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    String in_outerHTML = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("outerHTML"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.setOuterHTML"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setOuterHTML(requestId, in_nodeId, in_outerHTML);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setOuterHTML(error, in_nodeId, in_outerHTML);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::performSearch(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_query = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("query"), nullptr);
    bool opt_in_nodeIds_valueFound = false;
    RefPtr<Inspector::InspectorArray> opt_in_nodeIds = m_backendDispatcher->getArray(parameters.get(), ASCIILiteral("nodeIds"), &opt_in_nodeIds_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.performSearch"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->performSearch(requestId, in_query, opt_in_nodeIds_valueFound ? opt_in_nodeIds.get() : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    String out_searchId;
    int out_resultCount;
    m_agent->performSearch(error, in_query, opt_in_nodeIds_valueFound ? opt_in_nodeIds.get() : nullptr, &out_searchId, &out_resultCount);

    if (!error.length()) {
        result->setString(ASCIILiteral("searchId"), out_searchId);
        result->setInteger(ASCIILiteral("resultCount"), out_resultCount);
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::getSearchResults(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_searchId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("searchId"), nullptr);
    int in_fromIndex = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("fromIndex"), nullptr);
    int in_toIndex = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("toIndex"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.getSearchResults"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getSearchResults(requestId, in_searchId, in_fromIndex, in_toIndex);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::DOM::NodeId>> out_nodeIds;
    m_agent->getSearchResults(error, in_searchId, in_fromIndex, in_toIndex, out_nodeIds);

    if (!error.length())
        result->setArray(ASCIILiteral("nodeIds"), out_nodeIds);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::discardSearchResults(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_searchId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("searchId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.discardSearchResults"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->discardSearchResults(requestId, in_searchId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->discardSearchResults(error, in_searchId);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::requestNode(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_objectId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.requestNode"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->requestNode(requestId, in_objectId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Inspector::Protocol::DOM::NodeId out_nodeId;
    m_agent->requestNode(error, in_objectId, &out_nodeId);

    if (!error.length())
        result->setInteger(ASCIILiteral("nodeId"), out_nodeId);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::setInspectModeEnabled(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool in_enabled = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("enabled"), nullptr);
    bool opt_in_highlightConfig_valueFound = false;
    RefPtr<Inspector::InspectorObject> opt_in_highlightConfig = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("highlightConfig"), &opt_in_highlightConfig_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.setInspectModeEnabled"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setInspectModeEnabled(requestId, in_enabled, opt_in_highlightConfig_valueFound ? opt_in_highlightConfig.get() : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setInspectModeEnabled(error, in_enabled, opt_in_highlightConfig_valueFound ? opt_in_highlightConfig.get() : nullptr);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::highlightRect(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_x = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("x"), nullptr);
    int in_y = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("y"), nullptr);
    int in_width = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("width"), nullptr);
    int in_height = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("height"), nullptr);
    bool opt_in_color_valueFound = false;
    RefPtr<Inspector::InspectorObject> opt_in_color = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("color"), &opt_in_color_valueFound);
    bool opt_in_outlineColor_valueFound = false;
    RefPtr<Inspector::InspectorObject> opt_in_outlineColor = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("outlineColor"), &opt_in_outlineColor_valueFound);
    bool opt_in_usePageCoordinates_valueFound = false;
    bool opt_in_usePageCoordinates = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("usePageCoordinates"), &opt_in_usePageCoordinates_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.highlightRect"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->highlightRect(requestId, in_x, in_y, in_width, in_height, opt_in_color_valueFound ? opt_in_color.get() : nullptr, opt_in_outlineColor_valueFound ? opt_in_outlineColor.get() : nullptr, opt_in_usePageCoordinates_valueFound ? &opt_in_usePageCoordinates : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->highlightRect(error, in_x, in_y, in_width, in_height, opt_in_color_valueFound ? opt_in_color.get() : nullptr, opt_in_outlineColor_valueFound ? opt_in_outlineColor.get() : nullptr, opt_in_usePageCoordinates_valueFound ? &opt_in_usePageCoordinates : nullptr);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::highlightQuad(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorArray> in_quad = m_backendDispatcher->getArray(parameters.get(), ASCIILiteral("quad"), nullptr);
    bool opt_in_color_valueFound = false;
    RefPtr<Inspector::InspectorObject> opt_in_color = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("color"), &opt_in_color_valueFound);
    bool opt_in_outlineColor_valueFound = false;
    RefPtr<Inspector::InspectorObject> opt_in_outlineColor = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("outlineColor"), &opt_in_outlineColor_valueFound);
    bool opt_in_usePageCoordinates_valueFound = false;
    bool opt_in_usePageCoordinates = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("usePageCoordinates"), &opt_in_usePageCoordinates_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.highlightQuad"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->highlightQuad(requestId, *in_quad, opt_in_color_valueFound ? opt_in_color.get() : nullptr, opt_in_outlineColor_valueFound ? opt_in_outlineColor.get() : nullptr, opt_in_usePageCoordinates_valueFound ? &opt_in_usePageCoordinates : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->highlightQuad(error, *in_quad, opt_in_color_valueFound ? opt_in_color.get() : nullptr, opt_in_outlineColor_valueFound ? opt_in_outlineColor.get() : nullptr, opt_in_usePageCoordinates_valueFound ? &opt_in_usePageCoordinates : nullptr);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::highlightSelector(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorObject> in_highlightConfig = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("highlightConfig"), nullptr);
    String in_selectorString = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("selectorString"), nullptr);
    bool opt_in_frameId_valueFound = false;
    String opt_in_frameId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("frameId"), &opt_in_frameId_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.highlightSelector"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->highlightSelector(requestId, *in_highlightConfig, in_selectorString, opt_in_frameId_valueFound ? &opt_in_frameId : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->highlightSelector(error, *in_highlightConfig, in_selectorString, opt_in_frameId_valueFound ? &opt_in_frameId : nullptr);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::highlightNode(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorObject> in_highlightConfig = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("highlightConfig"), nullptr);
    bool opt_in_nodeId_valueFound = false;
    int opt_in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), &opt_in_nodeId_valueFound);
    bool opt_in_objectId_valueFound = false;
    String opt_in_objectId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectId"), &opt_in_objectId_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.highlightNode"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->highlightNode(requestId, *in_highlightConfig, opt_in_nodeId_valueFound ? &opt_in_nodeId : nullptr, opt_in_objectId_valueFound ? &opt_in_objectId : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->highlightNode(error, *in_highlightConfig, opt_in_nodeId_valueFound ? &opt_in_nodeId : nullptr, opt_in_objectId_valueFound ? &opt_in_objectId : nullptr);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::hideHighlight(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->hideHighlight(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->hideHighlight(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::highlightFrame(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_frameId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("frameId"), nullptr);
    bool opt_in_contentColor_valueFound = false;
    RefPtr<Inspector::InspectorObject> opt_in_contentColor = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("contentColor"), &opt_in_contentColor_valueFound);
    bool opt_in_contentOutlineColor_valueFound = false;
    RefPtr<Inspector::InspectorObject> opt_in_contentOutlineColor = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("contentOutlineColor"), &opt_in_contentOutlineColor_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.highlightFrame"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->highlightFrame(requestId, in_frameId, opt_in_contentColor_valueFound ? opt_in_contentColor.get() : nullptr, opt_in_contentOutlineColor_valueFound ? opt_in_contentOutlineColor.get() : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->highlightFrame(error, in_frameId, opt_in_contentColor_valueFound ? opt_in_contentColor.get() : nullptr, opt_in_contentOutlineColor_valueFound ? opt_in_contentOutlineColor.get() : nullptr);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::pushNodeByPathToFrontend(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_path = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("path"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.pushNodeByPathToFrontend"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->pushNodeByPathToFrontend(requestId, in_path);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Inspector::Protocol::DOM::NodeId out_nodeId;
    m_agent->pushNodeByPathToFrontend(error, in_path, &out_nodeId);

    if (!error.length())
        result->setInteger(ASCIILiteral("nodeId"), out_nodeId);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::pushNodeByBackendIdToFrontend(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_backendNodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("backendNodeId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.pushNodeByBackendIdToFrontend"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->pushNodeByBackendIdToFrontend(requestId, in_backendNodeId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Inspector::Protocol::DOM::NodeId out_nodeId;
    m_agent->pushNodeByBackendIdToFrontend(error, in_backendNodeId, &out_nodeId);

    if (!error.length())
        result->setInteger(ASCIILiteral("nodeId"), out_nodeId);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::releaseBackendNodeIds(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_nodeGroup = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("nodeGroup"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.releaseBackendNodeIds"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->releaseBackendNodeIds(requestId, in_nodeGroup);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->releaseBackendNodeIds(error, in_nodeGroup);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::resolveNode(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    bool opt_in_objectGroup_valueFound = false;
    String opt_in_objectGroup = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectGroup"), &opt_in_objectGroup_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.resolveNode"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->resolveNode(requestId, in_nodeId, opt_in_objectGroup_valueFound ? &opt_in_objectGroup : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Runtime::RemoteObject> out_object;
    m_agent->resolveNode(error, in_nodeId, opt_in_objectGroup_valueFound ? &opt_in_objectGroup : nullptr, out_object);

    if (!error.length())
        result->setObject(ASCIILiteral("object"), out_object);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::getAttributes(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.getAttributes"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getAttributes(requestId, in_nodeId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<String>> out_attributes;
    m_agent->getAttributes(error, in_nodeId, out_attributes);

    if (!error.length())
        result->setArray(ASCIILiteral("attributes"), out_attributes);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::moveTo(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    int in_targetNodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("targetNodeId"), nullptr);
    bool opt_in_insertBeforeNodeId_valueFound = false;
    int opt_in_insertBeforeNodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("insertBeforeNodeId"), &opt_in_insertBeforeNodeId_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.moveTo"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->moveTo(requestId, in_nodeId, in_targetNodeId, opt_in_insertBeforeNodeId_valueFound ? &opt_in_insertBeforeNodeId : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Inspector::Protocol::DOM::NodeId out_nodeId;
    m_agent->moveTo(error, in_nodeId, in_targetNodeId, opt_in_insertBeforeNodeId_valueFound ? &opt_in_insertBeforeNodeId : nullptr, &out_nodeId);

    if (!error.length())
        result->setInteger(ASCIILiteral("nodeId"), out_nodeId);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::undo(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->undo(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->undo(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::redo(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->redo(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->redo(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::markUndoableState(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->markUndoableState(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->markUndoableState(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMBackendDispatcher::focus(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOM.focus"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->focus(requestId, in_nodeId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->focus(error, in_nodeId);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

Ref<DOMDebuggerBackendDispatcher> DOMDebuggerBackendDispatcher::create(BackendDispatcher& backendDispatcher, DOMDebuggerBackendDispatcherHandler* agent)
{
    return adoptRef(*new DOMDebuggerBackendDispatcher(backendDispatcher, agent));
}

DOMDebuggerBackendDispatcher::DOMDebuggerBackendDispatcher(BackendDispatcher& backendDispatcher, DOMDebuggerBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("DOMDebugger"), this);
}

void DOMDebuggerBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<DOMDebuggerBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    typedef void (DOMDebuggerBackendDispatcher::*CallHandler)(long requestId, RefPtr<InspectorObject>&& message);
    typedef HashMap<String, CallHandler> DispatchMap;
    static NeverDestroyed<DispatchMap> dispatchMap;
    if (dispatchMap.get().isEmpty()) {
        static const struct MethodTable {
            const char* name;
            CallHandler handler;
        } commands[] = {
            { "setDOMBreakpoint", &DOMDebuggerBackendDispatcher::setDOMBreakpoint },
            { "removeDOMBreakpoint", &DOMDebuggerBackendDispatcher::removeDOMBreakpoint },
            { "setEventListenerBreakpoint", &DOMDebuggerBackendDispatcher::setEventListenerBreakpoint },
            { "removeEventListenerBreakpoint", &DOMDebuggerBackendDispatcher::removeEventListenerBreakpoint },
            { "setInstrumentationBreakpoint", &DOMDebuggerBackendDispatcher::setInstrumentationBreakpoint },
            { "removeInstrumentationBreakpoint", &DOMDebuggerBackendDispatcher::removeInstrumentationBreakpoint },
            { "setXHRBreakpoint", &DOMDebuggerBackendDispatcher::setXHRBreakpoint },
            { "removeXHRBreakpoint", &DOMDebuggerBackendDispatcher::removeXHRBreakpoint },
        };
        size_t length = WTF_ARRAY_LENGTH(commands);
        for (size_t i = 0; i < length; ++i)
            dispatchMap.get().add(commands[i].name, commands[i].handler);
    }

    auto findResult = dispatchMap.get().find(method);
    if (findResult == dispatchMap.get().end()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "DOMDebugger", '.', method, "' was not found"));
        return;
    }

    ((*this).*findResult->value)(requestId, WTFMove(parameters));
}

void DOMDebuggerBackendDispatcher::setDOMBreakpoint(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    String in_type = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("type"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOMDebugger.setDOMBreakpoint"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setDOMBreakpoint(requestId, in_nodeId, in_type);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setDOMBreakpoint(error, in_nodeId, in_type);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMDebuggerBackendDispatcher::removeDOMBreakpoint(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    String in_type = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("type"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOMDebugger.removeDOMBreakpoint"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->removeDOMBreakpoint(requestId, in_nodeId, in_type);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->removeDOMBreakpoint(error, in_nodeId, in_type);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMDebuggerBackendDispatcher::setEventListenerBreakpoint(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_eventName = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("eventName"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOMDebugger.setEventListenerBreakpoint"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setEventListenerBreakpoint(requestId, in_eventName);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setEventListenerBreakpoint(error, in_eventName);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMDebuggerBackendDispatcher::removeEventListenerBreakpoint(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_eventName = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("eventName"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOMDebugger.removeEventListenerBreakpoint"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->removeEventListenerBreakpoint(requestId, in_eventName);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->removeEventListenerBreakpoint(error, in_eventName);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMDebuggerBackendDispatcher::setInstrumentationBreakpoint(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_eventName = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("eventName"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOMDebugger.setInstrumentationBreakpoint"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setInstrumentationBreakpoint(requestId, in_eventName);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setInstrumentationBreakpoint(error, in_eventName);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMDebuggerBackendDispatcher::removeInstrumentationBreakpoint(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_eventName = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("eventName"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOMDebugger.removeInstrumentationBreakpoint"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->removeInstrumentationBreakpoint(requestId, in_eventName);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->removeInstrumentationBreakpoint(error, in_eventName);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMDebuggerBackendDispatcher::setXHRBreakpoint(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_url = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("url"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOMDebugger.setXHRBreakpoint"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setXHRBreakpoint(requestId, in_url);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setXHRBreakpoint(error, in_url);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMDebuggerBackendDispatcher::removeXHRBreakpoint(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_url = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("url"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOMDebugger.removeXHRBreakpoint"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->removeXHRBreakpoint(requestId, in_url);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->removeXHRBreakpoint(error, in_url);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

Ref<DOMStorageBackendDispatcher> DOMStorageBackendDispatcher::create(BackendDispatcher& backendDispatcher, DOMStorageBackendDispatcherHandler* agent)
{
    return adoptRef(*new DOMStorageBackendDispatcher(backendDispatcher, agent));
}

DOMStorageBackendDispatcher::DOMStorageBackendDispatcher(BackendDispatcher& backendDispatcher, DOMStorageBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("DOMStorage"), this);
}

void DOMStorageBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<DOMStorageBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    if (method == "enable")
        enable(requestId, WTFMove(parameters));
    else if (method == "disable")
        disable(requestId, WTFMove(parameters));
    else if (method == "getDOMStorageItems")
        getDOMStorageItems(requestId, WTFMove(parameters));
    else if (method == "setDOMStorageItem")
        setDOMStorageItem(requestId, WTFMove(parameters));
    else if (method == "removeDOMStorageItem")
        removeDOMStorageItem(requestId, WTFMove(parameters));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "DOMStorage", '.', method, "' was not found"));
}

void DOMStorageBackendDispatcher::enable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMStorageBackendDispatcher::disable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->disable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->disable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMStorageBackendDispatcher::getDOMStorageItems(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorObject> in_storageId = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("storageId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOMStorage.getDOMStorageItems"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getDOMStorageItems(requestId, *in_storageId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::DOMStorage::Item>> out_entries;
    m_agent->getDOMStorageItems(error, *in_storageId, out_entries);

    if (!error.length())
        result->setArray(ASCIILiteral("entries"), out_entries);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMStorageBackendDispatcher::setDOMStorageItem(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorObject> in_storageId = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("storageId"), nullptr);
    String in_key = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("key"), nullptr);
    String in_value = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("value"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOMStorage.setDOMStorageItem"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setDOMStorageItem(requestId, *in_storageId, in_key, in_value);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setDOMStorageItem(error, *in_storageId, in_key, in_value);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DOMStorageBackendDispatcher::removeDOMStorageItem(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorObject> in_storageId = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("storageId"), nullptr);
    String in_key = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("key"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "DOMStorage.removeDOMStorageItem"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->removeDOMStorageItem(requestId, *in_storageId, in_key);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->removeDOMStorageItem(error, *in_storageId, in_key);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

Ref<DatabaseBackendDispatcher> DatabaseBackendDispatcher::create(BackendDispatcher& backendDispatcher, DatabaseBackendDispatcherHandler* agent)
{
    return adoptRef(*new DatabaseBackendDispatcher(backendDispatcher, agent));
}

DatabaseBackendDispatcher::DatabaseBackendDispatcher(BackendDispatcher& backendDispatcher, DatabaseBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Database"), this);
}

void DatabaseBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<DatabaseBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    if (method == "enable")
        enable(requestId, WTFMove(parameters));
    else if (method == "disable")
        disable(requestId, WTFMove(parameters));
    else if (method == "getDatabaseTableNames")
        getDatabaseTableNames(requestId, WTFMove(parameters));
    else if (method == "executeSQL")
        executeSQL(requestId, WTFMove(parameters));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Database", '.', method, "' was not found"));
}

void DatabaseBackendDispatcher::enable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DatabaseBackendDispatcher::disable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->disable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->disable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DatabaseBackendDispatcher::getDatabaseTableNames(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_databaseId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("databaseId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Database.getDatabaseTableNames"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getDatabaseTableNames(requestId, in_databaseId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<String>> out_tableNames;
    m_agent->getDatabaseTableNames(error, in_databaseId, out_tableNames);

    if (!error.length())
        result->setArray(ASCIILiteral("tableNames"), out_tableNames);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

DatabaseBackendDispatcherHandler::ExecuteSQLCallback::ExecuteSQLCallback(Ref<BackendDispatcher>&& backendDispatcher, int id) : BackendDispatcher::CallbackBase(WTFMove(backendDispatcher), id) { }

void DatabaseBackendDispatcherHandler::ExecuteSQLCallback::sendSuccess(RefPtr<Inspector::Protocol::Array<String>>&& columnNames, RefPtr<Inspector::Protocol::Array<Inspector::InspectorValue>>&& values, RefPtr<Inspector::Protocol::Database::Error>&& sqlError)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    if (columnNames)
        jsonMessage->setArray(ASCIILiteral("columnNames"), columnNames);
    if (values)
        jsonMessage->setArray(ASCIILiteral("values"), values);
    if (sqlError)
        jsonMessage->setObject(ASCIILiteral("sqlError"), sqlError);
    CallbackBase::sendSuccess(WTFMove(jsonMessage));
}

void DatabaseBackendDispatcher::executeSQL(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_databaseId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("databaseId"), nullptr);
    String in_query = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("query"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Database.executeSQL"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->executeSQL(requestId, in_databaseId, in_query);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Ref<DatabaseBackendDispatcherHandler::ExecuteSQLCallback> callback = adoptRef(*new DatabaseBackendDispatcherHandler::ExecuteSQLCallback(m_backendDispatcher.copyRef(), requestId));
    m_agent->executeSQL(error, in_databaseId, in_query, callback.copyRef());

    if (error.length()) {
        callback->disable();
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, error);
        return;
    }
}

Ref<DebuggerBackendDispatcher> DebuggerBackendDispatcher::create(BackendDispatcher& backendDispatcher, DebuggerBackendDispatcherHandler* agent)
{
    return adoptRef(*new DebuggerBackendDispatcher(backendDispatcher, agent));
}

DebuggerBackendDispatcher::DebuggerBackendDispatcher(BackendDispatcher& backendDispatcher, DebuggerBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Debugger"), this);
}

void DebuggerBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<DebuggerBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    typedef void (DebuggerBackendDispatcher::*CallHandler)(long requestId, RefPtr<InspectorObject>&& message);
    typedef HashMap<String, CallHandler> DispatchMap;
    static NeverDestroyed<DispatchMap> dispatchMap;
    if (dispatchMap.get().isEmpty()) {
        static const struct MethodTable {
            const char* name;
            CallHandler handler;
        } commands[] = {
            { "enable", &DebuggerBackendDispatcher::enable },
            { "disable", &DebuggerBackendDispatcher::disable },
            { "setBreakpointsActive", &DebuggerBackendDispatcher::setBreakpointsActive },
            { "setBreakpointByUrl", &DebuggerBackendDispatcher::setBreakpointByUrl },
            { "setBreakpoint", &DebuggerBackendDispatcher::setBreakpoint },
            { "removeBreakpoint", &DebuggerBackendDispatcher::removeBreakpoint },
            { "continueToLocation", &DebuggerBackendDispatcher::continueToLocation },
            { "stepOver", &DebuggerBackendDispatcher::stepOver },
            { "stepInto", &DebuggerBackendDispatcher::stepInto },
            { "stepOut", &DebuggerBackendDispatcher::stepOut },
            { "pause", &DebuggerBackendDispatcher::pause },
            { "resume", &DebuggerBackendDispatcher::resume },
            { "searchInContent", &DebuggerBackendDispatcher::searchInContent },
            { "getScriptSource", &DebuggerBackendDispatcher::getScriptSource },
            { "getFunctionDetails", &DebuggerBackendDispatcher::getFunctionDetails },
            { "setPauseOnExceptions", &DebuggerBackendDispatcher::setPauseOnExceptions },
            { "evaluateOnCallFrame", &DebuggerBackendDispatcher::evaluateOnCallFrame },
            { "setOverlayMessage", &DebuggerBackendDispatcher::setOverlayMessage },
        };
        size_t length = WTF_ARRAY_LENGTH(commands);
        for (size_t i = 0; i < length; ++i)
            dispatchMap.get().add(commands[i].name, commands[i].handler);
    }

    auto findResult = dispatchMap.get().find(method);
    if (findResult == dispatchMap.get().end()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Debugger", '.', method, "' was not found"));
        return;
    }

    ((*this).*findResult->value)(requestId, WTFMove(parameters));
}

void DebuggerBackendDispatcher::enable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::disable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->disable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->disable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::setBreakpointsActive(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool in_active = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("active"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Debugger.setBreakpointsActive"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setBreakpointsActive(requestId, in_active);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setBreakpointsActive(error, in_active);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::setBreakpointByUrl(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_lineNumber = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("lineNumber"), nullptr);
    bool opt_in_url_valueFound = false;
    String opt_in_url = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("url"), &opt_in_url_valueFound);
    bool opt_in_urlRegex_valueFound = false;
    String opt_in_urlRegex = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("urlRegex"), &opt_in_urlRegex_valueFound);
    bool opt_in_columnNumber_valueFound = false;
    int opt_in_columnNumber = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("columnNumber"), &opt_in_columnNumber_valueFound);
    bool opt_in_options_valueFound = false;
    RefPtr<Inspector::InspectorObject> opt_in_options = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("options"), &opt_in_options_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Debugger.setBreakpointByUrl"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setBreakpointByUrl(requestId, in_lineNumber, opt_in_url_valueFound ? &opt_in_url : nullptr, opt_in_urlRegex_valueFound ? &opt_in_urlRegex : nullptr, opt_in_columnNumber_valueFound ? &opt_in_columnNumber : nullptr, opt_in_options_valueFound ? opt_in_options.get() : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Inspector::Protocol::Debugger::BreakpointId out_breakpointId;
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Debugger::Location>> out_locations;
    m_agent->setBreakpointByUrl(error, in_lineNumber, opt_in_url_valueFound ? &opt_in_url : nullptr, opt_in_urlRegex_valueFound ? &opt_in_urlRegex : nullptr, opt_in_columnNumber_valueFound ? &opt_in_columnNumber : nullptr, opt_in_options_valueFound ? opt_in_options.get() : nullptr, &out_breakpointId, out_locations);

    if (!error.length()) {
        result->setString(ASCIILiteral("breakpointId"), out_breakpointId);
        result->setArray(ASCIILiteral("locations"), out_locations);
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::setBreakpoint(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorObject> in_location = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("location"), nullptr);
    bool opt_in_options_valueFound = false;
    RefPtr<Inspector::InspectorObject> opt_in_options = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("options"), &opt_in_options_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Debugger.setBreakpoint"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setBreakpoint(requestId, *in_location, opt_in_options_valueFound ? opt_in_options.get() : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Inspector::Protocol::Debugger::BreakpointId out_breakpointId;
    RefPtr<Inspector::Protocol::Debugger::Location> out_actualLocation;
    m_agent->setBreakpoint(error, *in_location, opt_in_options_valueFound ? opt_in_options.get() : nullptr, &out_breakpointId, out_actualLocation);

    if (!error.length()) {
        result->setString(ASCIILiteral("breakpointId"), out_breakpointId);
        result->setObject(ASCIILiteral("actualLocation"), out_actualLocation);
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::removeBreakpoint(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_breakpointId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("breakpointId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Debugger.removeBreakpoint"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->removeBreakpoint(requestId, in_breakpointId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->removeBreakpoint(error, in_breakpointId);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::continueToLocation(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorObject> in_location = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("location"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Debugger.continueToLocation"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->continueToLocation(requestId, *in_location);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->continueToLocation(error, *in_location);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::stepOver(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->stepOver(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->stepOver(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::stepInto(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->stepInto(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->stepInto(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::stepOut(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->stepOut(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->stepOut(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::pause(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->pause(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->pause(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::resume(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->resume(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->resume(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::searchInContent(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_scriptId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("scriptId"), nullptr);
    String in_query = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("query"), nullptr);
    bool opt_in_caseSensitive_valueFound = false;
    bool opt_in_caseSensitive = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("caseSensitive"), &opt_in_caseSensitive_valueFound);
    bool opt_in_isRegex_valueFound = false;
    bool opt_in_isRegex = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("isRegex"), &opt_in_isRegex_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Debugger.searchInContent"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->searchInContent(requestId, in_scriptId, in_query, opt_in_caseSensitive_valueFound ? &opt_in_caseSensitive : nullptr, opt_in_isRegex_valueFound ? &opt_in_isRegex : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::GenericTypes::SearchMatch>> out_result;
    m_agent->searchInContent(error, in_scriptId, in_query, opt_in_caseSensitive_valueFound ? &opt_in_caseSensitive : nullptr, opt_in_isRegex_valueFound ? &opt_in_isRegex : nullptr, out_result);

    if (!error.length())
        result->setArray(ASCIILiteral("result"), out_result);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::getScriptSource(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_scriptId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("scriptId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Debugger.getScriptSource"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getScriptSource(requestId, in_scriptId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    String out_scriptSource;
    m_agent->getScriptSource(error, in_scriptId, &out_scriptSource);

    if (!error.length())
        result->setString(ASCIILiteral("scriptSource"), out_scriptSource);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::getFunctionDetails(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_functionId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("functionId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Debugger.getFunctionDetails"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getFunctionDetails(requestId, in_functionId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Debugger::FunctionDetails> out_details;
    m_agent->getFunctionDetails(error, in_functionId, out_details);

    if (!error.length())
        result->setObject(ASCIILiteral("details"), out_details);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::setPauseOnExceptions(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_state = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("state"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Debugger.setPauseOnExceptions"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setPauseOnExceptions(requestId, in_state);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setPauseOnExceptions(error, in_state);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::evaluateOnCallFrame(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_callFrameId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("callFrameId"), nullptr);
    String in_expression = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("expression"), nullptr);
    bool opt_in_objectGroup_valueFound = false;
    String opt_in_objectGroup = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectGroup"), &opt_in_objectGroup_valueFound);
    bool opt_in_includeCommandLineAPI_valueFound = false;
    bool opt_in_includeCommandLineAPI = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("includeCommandLineAPI"), &opt_in_includeCommandLineAPI_valueFound);
    bool opt_in_doNotPauseOnExceptionsAndMuteConsole_valueFound = false;
    bool opt_in_doNotPauseOnExceptionsAndMuteConsole = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("doNotPauseOnExceptionsAndMuteConsole"), &opt_in_doNotPauseOnExceptionsAndMuteConsole_valueFound);
    bool opt_in_returnByValue_valueFound = false;
    bool opt_in_returnByValue = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("returnByValue"), &opt_in_returnByValue_valueFound);
    bool opt_in_generatePreview_valueFound = false;
    bool opt_in_generatePreview = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("generatePreview"), &opt_in_generatePreview_valueFound);
    bool opt_in_saveResult_valueFound = false;
    bool opt_in_saveResult = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("saveResult"), &opt_in_saveResult_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Debugger.evaluateOnCallFrame"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->evaluateOnCallFrame(requestId, in_callFrameId, in_expression, opt_in_objectGroup_valueFound ? &opt_in_objectGroup : nullptr, opt_in_includeCommandLineAPI_valueFound ? &opt_in_includeCommandLineAPI : nullptr, opt_in_doNotPauseOnExceptionsAndMuteConsole_valueFound ? &opt_in_doNotPauseOnExceptionsAndMuteConsole : nullptr, opt_in_returnByValue_valueFound ? &opt_in_returnByValue : nullptr, opt_in_generatePreview_valueFound ? &opt_in_generatePreview : nullptr, opt_in_saveResult_valueFound ? &opt_in_saveResult : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Runtime::RemoteObject> out_result;
    Inspector::Protocol::OptOutput<bool> out_wasThrown;
    Inspector::Protocol::OptOutput<int> out_savedResultIndex;
    m_agent->evaluateOnCallFrame(error, in_callFrameId, in_expression, opt_in_objectGroup_valueFound ? &opt_in_objectGroup : nullptr, opt_in_includeCommandLineAPI_valueFound ? &opt_in_includeCommandLineAPI : nullptr, opt_in_doNotPauseOnExceptionsAndMuteConsole_valueFound ? &opt_in_doNotPauseOnExceptionsAndMuteConsole : nullptr, opt_in_returnByValue_valueFound ? &opt_in_returnByValue : nullptr, opt_in_generatePreview_valueFound ? &opt_in_generatePreview : nullptr, opt_in_saveResult_valueFound ? &opt_in_saveResult : nullptr, out_result, &out_wasThrown, &out_savedResultIndex);

    if (!error.length()) {
        result->setObject(ASCIILiteral("result"), out_result);
        if (out_wasThrown.isAssigned())
            result->setBoolean(ASCIILiteral("wasThrown"), out_wasThrown.getValue());
        if (out_savedResultIndex.isAssigned())
            result->setInteger(ASCIILiteral("savedResultIndex"), out_savedResultIndex.getValue());
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void DebuggerBackendDispatcher::setOverlayMessage(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool opt_in_message_valueFound = false;
    String opt_in_message = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("message"), &opt_in_message_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Debugger.setOverlayMessage"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setOverlayMessage(requestId, opt_in_message_valueFound ? &opt_in_message : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setOverlayMessage(error, opt_in_message_valueFound ? &opt_in_message : nullptr);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

Ref<HeapBackendDispatcher> HeapBackendDispatcher::create(BackendDispatcher& backendDispatcher, HeapBackendDispatcherHandler* agent)
{
    return adoptRef(*new HeapBackendDispatcher(backendDispatcher, agent));
}

HeapBackendDispatcher::HeapBackendDispatcher(BackendDispatcher& backendDispatcher, HeapBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Heap"), this);
}

void HeapBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<HeapBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    typedef void (HeapBackendDispatcher::*CallHandler)(long requestId, RefPtr<InspectorObject>&& message);
    typedef HashMap<String, CallHandler> DispatchMap;
    static NeverDestroyed<DispatchMap> dispatchMap;
    if (dispatchMap.get().isEmpty()) {
        static const struct MethodTable {
            const char* name;
            CallHandler handler;
        } commands[] = {
            { "enable", &HeapBackendDispatcher::enable },
            { "disable", &HeapBackendDispatcher::disable },
            { "gc", &HeapBackendDispatcher::gc },
            { "snapshot", &HeapBackendDispatcher::snapshot },
            { "startTracking", &HeapBackendDispatcher::startTracking },
            { "stopTracking", &HeapBackendDispatcher::stopTracking },
            { "getPreview", &HeapBackendDispatcher::getPreview },
            { "getRemoteObject", &HeapBackendDispatcher::getRemoteObject },
        };
        size_t length = WTF_ARRAY_LENGTH(commands);
        for (size_t i = 0; i < length; ++i)
            dispatchMap.get().add(commands[i].name, commands[i].handler);
    }

    auto findResult = dispatchMap.get().find(method);
    if (findResult == dispatchMap.get().end()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Heap", '.', method, "' was not found"));
        return;
    }

    ((*this).*findResult->value)(requestId, WTFMove(parameters));
}

void HeapBackendDispatcher::enable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void HeapBackendDispatcher::disable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->disable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->disable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void HeapBackendDispatcher::gc(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->gc(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->gc(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void HeapBackendDispatcher::snapshot(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->snapshot(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    double out_timestamp;
    Inspector::Protocol::Heap::HeapSnapshotData out_snapshotData;
    m_agent->snapshot(error, &out_timestamp, &out_snapshotData);

    if (!error.length()) {
        result->setDouble(ASCIILiteral("timestamp"), out_timestamp);
        result->setString(ASCIILiteral("snapshotData"), out_snapshotData);
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void HeapBackendDispatcher::startTracking(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->startTracking(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->startTracking(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void HeapBackendDispatcher::stopTracking(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->stopTracking(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->stopTracking(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void HeapBackendDispatcher::getPreview(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_heapObjectId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("heapObjectId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Heap.getPreview"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getPreview(requestId, in_heapObjectId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Inspector::Protocol::OptOutput<String> out_string;
    RefPtr<Inspector::Protocol::Debugger::FunctionDetails> out_functionDetails;
    RefPtr<Inspector::Protocol::Runtime::ObjectPreview> out_preview;
    m_agent->getPreview(error, in_heapObjectId, &out_string, out_functionDetails, out_preview);

    if (!error.length()) {
        if (out_string.isAssigned())
            result->setString(ASCIILiteral("string"), out_string.getValue());
        if (out_functionDetails)
            result->setObject(ASCIILiteral("functionDetails"), out_functionDetails);
        if (out_preview)
            result->setObject(ASCIILiteral("preview"), out_preview);
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void HeapBackendDispatcher::getRemoteObject(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_heapObjectId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("heapObjectId"), nullptr);
    bool opt_in_objectGroup_valueFound = false;
    String opt_in_objectGroup = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectGroup"), &opt_in_objectGroup_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Heap.getRemoteObject"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getRemoteObject(requestId, in_heapObjectId, opt_in_objectGroup_valueFound ? &opt_in_objectGroup : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Runtime::RemoteObject> out_result;
    m_agent->getRemoteObject(error, in_heapObjectId, opt_in_objectGroup_valueFound ? &opt_in_objectGroup : nullptr, out_result);

    if (!error.length())
        result->setObject(ASCIILiteral("result"), out_result);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

Ref<InspectorBackendDispatcher> InspectorBackendDispatcher::create(BackendDispatcher& backendDispatcher, InspectorBackendDispatcherHandler* agent)
{
    return adoptRef(*new InspectorBackendDispatcher(backendDispatcher, agent));
}

InspectorBackendDispatcher::InspectorBackendDispatcher(BackendDispatcher& backendDispatcher, InspectorBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Inspector"), this);
}

void InspectorBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<InspectorBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    if (method == "enable")
        enable(requestId, WTFMove(parameters));
    else if (method == "disable")
        disable(requestId, WTFMove(parameters));
    else if (method == "initialized")
        initialized(requestId, WTFMove(parameters));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Inspector", '.', method, "' was not found"));
}

void InspectorBackendDispatcher::enable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void InspectorBackendDispatcher::disable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->disable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->disable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void InspectorBackendDispatcher::initialized(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->initialized(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->initialized(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

Ref<LayerTreeBackendDispatcher> LayerTreeBackendDispatcher::create(BackendDispatcher& backendDispatcher, LayerTreeBackendDispatcherHandler* agent)
{
    return adoptRef(*new LayerTreeBackendDispatcher(backendDispatcher, agent));
}

LayerTreeBackendDispatcher::LayerTreeBackendDispatcher(BackendDispatcher& backendDispatcher, LayerTreeBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("LayerTree"), this);
}

void LayerTreeBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<LayerTreeBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    if (method == "enable")
        enable(requestId, WTFMove(parameters));
    else if (method == "disable")
        disable(requestId, WTFMove(parameters));
    else if (method == "layersForNode")
        layersForNode(requestId, WTFMove(parameters));
    else if (method == "reasonsForCompositingLayer")
        reasonsForCompositingLayer(requestId, WTFMove(parameters));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "LayerTree", '.', method, "' was not found"));
}

void LayerTreeBackendDispatcher::enable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void LayerTreeBackendDispatcher::disable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->disable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->disable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void LayerTreeBackendDispatcher::layersForNode(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "LayerTree.layersForNode"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->layersForNode(requestId, in_nodeId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::LayerTree::Layer>> out_layers;
    m_agent->layersForNode(error, in_nodeId, out_layers);

    if (!error.length())
        result->setArray(ASCIILiteral("layers"), out_layers);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void LayerTreeBackendDispatcher::reasonsForCompositingLayer(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_layerId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("layerId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "LayerTree.reasonsForCompositingLayer"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->reasonsForCompositingLayer(requestId, in_layerId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::LayerTree::CompositingReasons> out_compositingReasons;
    m_agent->reasonsForCompositingLayer(error, in_layerId, out_compositingReasons);

    if (!error.length())
        result->setObject(ASCIILiteral("compositingReasons"), out_compositingReasons);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

Ref<NetworkBackendDispatcher> NetworkBackendDispatcher::create(BackendDispatcher& backendDispatcher, NetworkBackendDispatcherHandler* agent)
{
    return adoptRef(*new NetworkBackendDispatcher(backendDispatcher, agent));
}

NetworkBackendDispatcher::NetworkBackendDispatcher(BackendDispatcher& backendDispatcher, NetworkBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Network"), this);
}

void NetworkBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<NetworkBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    typedef void (NetworkBackendDispatcher::*CallHandler)(long requestId, RefPtr<InspectorObject>&& message);
    typedef HashMap<String, CallHandler> DispatchMap;
    static NeverDestroyed<DispatchMap> dispatchMap;
    if (dispatchMap.get().isEmpty()) {
        static const struct MethodTable {
            const char* name;
            CallHandler handler;
        } commands[] = {
            { "enable", &NetworkBackendDispatcher::enable },
            { "disable", &NetworkBackendDispatcher::disable },
            { "setExtraHTTPHeaders", &NetworkBackendDispatcher::setExtraHTTPHeaders },
            { "getResponseBody", &NetworkBackendDispatcher::getResponseBody },
            { "setCacheDisabled", &NetworkBackendDispatcher::setCacheDisabled },
            { "loadResource", &NetworkBackendDispatcher::loadResource },
        };
        size_t length = WTF_ARRAY_LENGTH(commands);
        for (size_t i = 0; i < length; ++i)
            dispatchMap.get().add(commands[i].name, commands[i].handler);
    }

    auto findResult = dispatchMap.get().find(method);
    if (findResult == dispatchMap.get().end()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Network", '.', method, "' was not found"));
        return;
    }

    ((*this).*findResult->value)(requestId, WTFMove(parameters));
}

void NetworkBackendDispatcher::enable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void NetworkBackendDispatcher::disable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->disable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->disable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void NetworkBackendDispatcher::setExtraHTTPHeaders(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorObject> in_headers = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("headers"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Network.setExtraHTTPHeaders"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setExtraHTTPHeaders(requestId, *in_headers);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setExtraHTTPHeaders(error, *in_headers);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void NetworkBackendDispatcher::getResponseBody(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_requestId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("requestId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Network.getResponseBody"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getResponseBody(requestId, in_requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    String out_body;
    bool out_base64Encoded;
    m_agent->getResponseBody(error, in_requestId, &out_body, &out_base64Encoded);

    if (!error.length()) {
        result->setString(ASCIILiteral("body"), out_body);
        result->setBoolean(ASCIILiteral("base64Encoded"), out_base64Encoded);
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void NetworkBackendDispatcher::setCacheDisabled(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool in_cacheDisabled = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("cacheDisabled"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Network.setCacheDisabled"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setCacheDisabled(requestId, in_cacheDisabled);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setCacheDisabled(error, in_cacheDisabled);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

NetworkBackendDispatcherHandler::LoadResourceCallback::LoadResourceCallback(Ref<BackendDispatcher>&& backendDispatcher, int id) : BackendDispatcher::CallbackBase(WTFMove(backendDispatcher), id) { }

void NetworkBackendDispatcherHandler::LoadResourceCallback::sendSuccess(const String& content, const String& mimeType, double status)
{
    Ref<InspectorObject> jsonMessage = InspectorObject::create();
    jsonMessage->setString(ASCIILiteral("content"), content);
    jsonMessage->setString(ASCIILiteral("mimeType"), mimeType);
    jsonMessage->setDouble(ASCIILiteral("status"), status);
    CallbackBase::sendSuccess(WTFMove(jsonMessage));
}

void NetworkBackendDispatcher::loadResource(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_frameId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("frameId"), nullptr);
    String in_url = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("url"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Network.loadResource"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->loadResource(requestId, in_frameId, in_url);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Ref<NetworkBackendDispatcherHandler::LoadResourceCallback> callback = adoptRef(*new NetworkBackendDispatcherHandler::LoadResourceCallback(m_backendDispatcher.copyRef(), requestId));
    m_agent->loadResource(error, in_frameId, in_url, callback.copyRef());

    if (error.length()) {
        callback->disable();
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, error);
        return;
    }
}

Ref<PageBackendDispatcher> PageBackendDispatcher::create(BackendDispatcher& backendDispatcher, PageBackendDispatcherHandler* agent)
{
    return adoptRef(*new PageBackendDispatcher(backendDispatcher, agent));
}

PageBackendDispatcher::PageBackendDispatcher(BackendDispatcher& backendDispatcher, PageBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Page"), this);
}

void PageBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<PageBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    typedef void (PageBackendDispatcher::*CallHandler)(long requestId, RefPtr<InspectorObject>&& message);
    typedef HashMap<String, CallHandler> DispatchMap;
    static NeverDestroyed<DispatchMap> dispatchMap;
    if (dispatchMap.get().isEmpty()) {
        static const struct MethodTable {
            const char* name;
            CallHandler handler;
        } commands[] = {
            { "enable", &PageBackendDispatcher::enable },
            { "disable", &PageBackendDispatcher::disable },
            { "addScriptToEvaluateOnLoad", &PageBackendDispatcher::addScriptToEvaluateOnLoad },
            { "removeScriptToEvaluateOnLoad", &PageBackendDispatcher::removeScriptToEvaluateOnLoad },
            { "reload", &PageBackendDispatcher::reload },
            { "navigate", &PageBackendDispatcher::navigate },
            { "getCookies", &PageBackendDispatcher::getCookies },
            { "deleteCookie", &PageBackendDispatcher::deleteCookie },
            { "getResourceTree", &PageBackendDispatcher::getResourceTree },
            { "getResourceContent", &PageBackendDispatcher::getResourceContent },
            { "searchInResource", &PageBackendDispatcher::searchInResource },
            { "searchInResources", &PageBackendDispatcher::searchInResources },
            { "setDocumentContent", &PageBackendDispatcher::setDocumentContent },
            { "setShowPaintRects", &PageBackendDispatcher::setShowPaintRects },
            { "getScriptExecutionStatus", &PageBackendDispatcher::getScriptExecutionStatus },
            { "setScriptExecutionDisabled", &PageBackendDispatcher::setScriptExecutionDisabled },
            { "setTouchEmulationEnabled", &PageBackendDispatcher::setTouchEmulationEnabled },
            { "setEmulatedMedia", &PageBackendDispatcher::setEmulatedMedia },
            { "getCompositingBordersVisible", &PageBackendDispatcher::getCompositingBordersVisible },
            { "setCompositingBordersVisible", &PageBackendDispatcher::setCompositingBordersVisible },
            { "snapshotNode", &PageBackendDispatcher::snapshotNode },
            { "snapshotRect", &PageBackendDispatcher::snapshotRect },
            { "handleJavaScriptDialog", &PageBackendDispatcher::handleJavaScriptDialog },
            { "archive", &PageBackendDispatcher::archive },
        };
        size_t length = WTF_ARRAY_LENGTH(commands);
        for (size_t i = 0; i < length; ++i)
            dispatchMap.get().add(commands[i].name, commands[i].handler);
    }

    auto findResult = dispatchMap.get().find(method);
    if (findResult == dispatchMap.get().end()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Page", '.', method, "' was not found"));
        return;
    }

    ((*this).*findResult->value)(requestId, WTFMove(parameters));
}

void PageBackendDispatcher::enable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::disable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->disable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->disable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::addScriptToEvaluateOnLoad(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_scriptSource = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("scriptSource"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.addScriptToEvaluateOnLoad"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->addScriptToEvaluateOnLoad(requestId, in_scriptSource);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Inspector::Protocol::Page::ScriptIdentifier out_identifier;
    m_agent->addScriptToEvaluateOnLoad(error, in_scriptSource, &out_identifier);

    if (!error.length())
        result->setString(ASCIILiteral("identifier"), out_identifier);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::removeScriptToEvaluateOnLoad(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_identifier = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("identifier"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.removeScriptToEvaluateOnLoad"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->removeScriptToEvaluateOnLoad(requestId, in_identifier);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->removeScriptToEvaluateOnLoad(error, in_identifier);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::reload(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool opt_in_ignoreCache_valueFound = false;
    bool opt_in_ignoreCache = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("ignoreCache"), &opt_in_ignoreCache_valueFound);
    bool opt_in_scriptToEvaluateOnLoad_valueFound = false;
    String opt_in_scriptToEvaluateOnLoad = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("scriptToEvaluateOnLoad"), &opt_in_scriptToEvaluateOnLoad_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.reload"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->reload(requestId, opt_in_ignoreCache_valueFound ? &opt_in_ignoreCache : nullptr, opt_in_scriptToEvaluateOnLoad_valueFound ? &opt_in_scriptToEvaluateOnLoad : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->reload(error, opt_in_ignoreCache_valueFound ? &opt_in_ignoreCache : nullptr, opt_in_scriptToEvaluateOnLoad_valueFound ? &opt_in_scriptToEvaluateOnLoad : nullptr);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::navigate(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_url = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("url"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.navigate"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->navigate(requestId, in_url);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->navigate(error, in_url);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::getCookies(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getCookies(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Page::Cookie>> out_cookies;
    m_agent->getCookies(error, out_cookies);

    if (!error.length())
        result->setArray(ASCIILiteral("cookies"), out_cookies);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::deleteCookie(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_cookieName = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("cookieName"), nullptr);
    String in_url = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("url"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.deleteCookie"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->deleteCookie(requestId, in_cookieName, in_url);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->deleteCookie(error, in_cookieName, in_url);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::getResourceTree(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getResourceTree(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Page::FrameResourceTree> out_frameTree;
    m_agent->getResourceTree(error, out_frameTree);

    if (!error.length())
        result->setObject(ASCIILiteral("frameTree"), out_frameTree);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::getResourceContent(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_frameId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("frameId"), nullptr);
    String in_url = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("url"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.getResourceContent"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getResourceContent(requestId, in_frameId, in_url);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    String out_content;
    bool out_base64Encoded;
    m_agent->getResourceContent(error, in_frameId, in_url, &out_content, &out_base64Encoded);

    if (!error.length()) {
        result->setString(ASCIILiteral("content"), out_content);
        result->setBoolean(ASCIILiteral("base64Encoded"), out_base64Encoded);
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::searchInResource(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_frameId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("frameId"), nullptr);
    String in_url = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("url"), nullptr);
    String in_query = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("query"), nullptr);
    bool opt_in_caseSensitive_valueFound = false;
    bool opt_in_caseSensitive = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("caseSensitive"), &opt_in_caseSensitive_valueFound);
    bool opt_in_isRegex_valueFound = false;
    bool opt_in_isRegex = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("isRegex"), &opt_in_isRegex_valueFound);
    bool opt_in_requestId_valueFound = false;
    String opt_in_requestId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("requestId"), &opt_in_requestId_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.searchInResource"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->searchInResource(requestId, in_frameId, in_url, in_query, opt_in_caseSensitive_valueFound ? &opt_in_caseSensitive : nullptr, opt_in_isRegex_valueFound ? &opt_in_isRegex : nullptr, opt_in_requestId_valueFound ? &opt_in_requestId : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::GenericTypes::SearchMatch>> out_result;
    m_agent->searchInResource(error, in_frameId, in_url, in_query, opt_in_caseSensitive_valueFound ? &opt_in_caseSensitive : nullptr, opt_in_isRegex_valueFound ? &opt_in_isRegex : nullptr, opt_in_requestId_valueFound ? &opt_in_requestId : nullptr, out_result);

    if (!error.length())
        result->setArray(ASCIILiteral("result"), out_result);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::searchInResources(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_text = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("text"), nullptr);
    bool opt_in_caseSensitive_valueFound = false;
    bool opt_in_caseSensitive = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("caseSensitive"), &opt_in_caseSensitive_valueFound);
    bool opt_in_isRegex_valueFound = false;
    bool opt_in_isRegex = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("isRegex"), &opt_in_isRegex_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.searchInResources"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->searchInResources(requestId, in_text, opt_in_caseSensitive_valueFound ? &opt_in_caseSensitive : nullptr, opt_in_isRegex_valueFound ? &opt_in_isRegex : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Page::SearchResult>> out_result;
    m_agent->searchInResources(error, in_text, opt_in_caseSensitive_valueFound ? &opt_in_caseSensitive : nullptr, opt_in_isRegex_valueFound ? &opt_in_isRegex : nullptr, out_result);

    if (!error.length())
        result->setArray(ASCIILiteral("result"), out_result);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::setDocumentContent(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_frameId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("frameId"), nullptr);
    String in_html = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("html"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.setDocumentContent"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setDocumentContent(requestId, in_frameId, in_html);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setDocumentContent(error, in_frameId, in_html);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::setShowPaintRects(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool in_result = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("result"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.setShowPaintRects"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setShowPaintRects(requestId, in_result);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setShowPaintRects(error, in_result);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::getScriptExecutionStatus(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getScriptExecutionStatus(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    PageBackendDispatcherHandler::Result out_result;
    m_agent->getScriptExecutionStatus(error, &out_result);

    if (!error.length())
        result->setString(ASCIILiteral("result"), Inspector::Protocol::InspectorHelpers::getEnumConstantValue(out_result));

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::setScriptExecutionDisabled(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool in_value = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("value"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.setScriptExecutionDisabled"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setScriptExecutionDisabled(requestId, in_value);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setScriptExecutionDisabled(error, in_value);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::setTouchEmulationEnabled(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool in_enabled = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("enabled"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.setTouchEmulationEnabled"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setTouchEmulationEnabled(requestId, in_enabled);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setTouchEmulationEnabled(error, in_enabled);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::setEmulatedMedia(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_media = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("media"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.setEmulatedMedia"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setEmulatedMedia(requestId, in_media);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setEmulatedMedia(error, in_media);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::getCompositingBordersVisible(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getCompositingBordersVisible(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    bool out_result;
    m_agent->getCompositingBordersVisible(error, &out_result);

    if (!error.length())
        result->setBoolean(ASCIILiteral("result"), out_result);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::setCompositingBordersVisible(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool in_visible = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("visible"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.setCompositingBordersVisible"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setCompositingBordersVisible(requestId, in_visible);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setCompositingBordersVisible(error, in_visible);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::snapshotNode(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_nodeId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("nodeId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.snapshotNode"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->snapshotNode(requestId, in_nodeId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    String out_dataURL;
    m_agent->snapshotNode(error, in_nodeId, &out_dataURL);

    if (!error.length())
        result->setString(ASCIILiteral("dataURL"), out_dataURL);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::snapshotRect(long requestId, RefPtr<InspectorObject>&& parameters)
{
    int in_x = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("x"), nullptr);
    int in_y = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("y"), nullptr);
    int in_width = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("width"), nullptr);
    int in_height = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("height"), nullptr);
    String in_coordinateSystem = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("coordinateSystem"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.snapshotRect"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->snapshotRect(requestId, in_x, in_y, in_width, in_height, in_coordinateSystem);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    String out_dataURL;
    m_agent->snapshotRect(error, in_x, in_y, in_width, in_height, in_coordinateSystem, &out_dataURL);

    if (!error.length())
        result->setString(ASCIILiteral("dataURL"), out_dataURL);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::handleJavaScriptDialog(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool in_accept = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("accept"), nullptr);
    bool opt_in_promptText_valueFound = false;
    String opt_in_promptText = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("promptText"), &opt_in_promptText_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Page.handleJavaScriptDialog"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->handleJavaScriptDialog(requestId, in_accept, opt_in_promptText_valueFound ? &opt_in_promptText : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->handleJavaScriptDialog(error, in_accept, opt_in_promptText_valueFound ? &opt_in_promptText : nullptr);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void PageBackendDispatcher::archive(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->archive(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    String out_data;
    m_agent->archive(error, &out_data);

    if (!error.length())
        result->setString(ASCIILiteral("data"), out_data);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

Ref<RuntimeBackendDispatcher> RuntimeBackendDispatcher::create(BackendDispatcher& backendDispatcher, RuntimeBackendDispatcherHandler* agent)
{
    return adoptRef(*new RuntimeBackendDispatcher(backendDispatcher, agent));
}

RuntimeBackendDispatcher::RuntimeBackendDispatcher(BackendDispatcher& backendDispatcher, RuntimeBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Runtime"), this);
}

void RuntimeBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<RuntimeBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    typedef void (RuntimeBackendDispatcher::*CallHandler)(long requestId, RefPtr<InspectorObject>&& message);
    typedef HashMap<String, CallHandler> DispatchMap;
    static NeverDestroyed<DispatchMap> dispatchMap;
    if (dispatchMap.get().isEmpty()) {
        static const struct MethodTable {
            const char* name;
            CallHandler handler;
        } commands[] = {
            { "parse", &RuntimeBackendDispatcher::parse },
            { "evaluate", &RuntimeBackendDispatcher::evaluate },
            { "callFunctionOn", &RuntimeBackendDispatcher::callFunctionOn },
            { "getProperties", &RuntimeBackendDispatcher::getProperties },
            { "getDisplayableProperties", &RuntimeBackendDispatcher::getDisplayableProperties },
            { "getCollectionEntries", &RuntimeBackendDispatcher::getCollectionEntries },
            { "saveResult", &RuntimeBackendDispatcher::saveResult },
            { "releaseObject", &RuntimeBackendDispatcher::releaseObject },
            { "releaseObjectGroup", &RuntimeBackendDispatcher::releaseObjectGroup },
            { "enable", &RuntimeBackendDispatcher::enable },
            { "disable", &RuntimeBackendDispatcher::disable },
            { "getRuntimeTypesForVariablesAtOffsets", &RuntimeBackendDispatcher::getRuntimeTypesForVariablesAtOffsets },
            { "enableTypeProfiler", &RuntimeBackendDispatcher::enableTypeProfiler },
            { "disableTypeProfiler", &RuntimeBackendDispatcher::disableTypeProfiler },
            { "enableControlFlowProfiler", &RuntimeBackendDispatcher::enableControlFlowProfiler },
            { "disableControlFlowProfiler", &RuntimeBackendDispatcher::disableControlFlowProfiler },
            { "getBasicBlocks", &RuntimeBackendDispatcher::getBasicBlocks },
        };
        size_t length = WTF_ARRAY_LENGTH(commands);
        for (size_t i = 0; i < length; ++i)
            dispatchMap.get().add(commands[i].name, commands[i].handler);
    }

    auto findResult = dispatchMap.get().find(method);
    if (findResult == dispatchMap.get().end()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Runtime", '.', method, "' was not found"));
        return;
    }

    ((*this).*findResult->value)(requestId, WTFMove(parameters));
}

void RuntimeBackendDispatcher::parse(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_source = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("source"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Runtime.parse"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->parse(requestId, in_source);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Inspector::Protocol::Runtime::SyntaxErrorType out_result;
    Inspector::Protocol::OptOutput<String> out_message;
    RefPtr<Inspector::Protocol::Runtime::ErrorRange> out_range;
    m_agent->parse(error, in_source, &out_result, &out_message, out_range);

    if (!error.length()) {
        result->setString(ASCIILiteral("result"), Inspector::Protocol::InspectorHelpers::getEnumConstantValue(out_result));
        if (out_message.isAssigned())
            result->setString(ASCIILiteral("message"), out_message.getValue());
        if (out_range)
            result->setObject(ASCIILiteral("range"), out_range);
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::evaluate(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_expression = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("expression"), nullptr);
    bool opt_in_objectGroup_valueFound = false;
    String opt_in_objectGroup = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectGroup"), &opt_in_objectGroup_valueFound);
    bool opt_in_includeCommandLineAPI_valueFound = false;
    bool opt_in_includeCommandLineAPI = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("includeCommandLineAPI"), &opt_in_includeCommandLineAPI_valueFound);
    bool opt_in_doNotPauseOnExceptionsAndMuteConsole_valueFound = false;
    bool opt_in_doNotPauseOnExceptionsAndMuteConsole = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("doNotPauseOnExceptionsAndMuteConsole"), &opt_in_doNotPauseOnExceptionsAndMuteConsole_valueFound);
    bool opt_in_contextId_valueFound = false;
    int opt_in_contextId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("contextId"), &opt_in_contextId_valueFound);
    bool opt_in_returnByValue_valueFound = false;
    bool opt_in_returnByValue = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("returnByValue"), &opt_in_returnByValue_valueFound);
    bool opt_in_generatePreview_valueFound = false;
    bool opt_in_generatePreview = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("generatePreview"), &opt_in_generatePreview_valueFound);
    bool opt_in_saveResult_valueFound = false;
    bool opt_in_saveResult = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("saveResult"), &opt_in_saveResult_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Runtime.evaluate"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->evaluate(requestId, in_expression, opt_in_objectGroup_valueFound ? &opt_in_objectGroup : nullptr, opt_in_includeCommandLineAPI_valueFound ? &opt_in_includeCommandLineAPI : nullptr, opt_in_doNotPauseOnExceptionsAndMuteConsole_valueFound ? &opt_in_doNotPauseOnExceptionsAndMuteConsole : nullptr, opt_in_contextId_valueFound ? &opt_in_contextId : nullptr, opt_in_returnByValue_valueFound ? &opt_in_returnByValue : nullptr, opt_in_generatePreview_valueFound ? &opt_in_generatePreview : nullptr, opt_in_saveResult_valueFound ? &opt_in_saveResult : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Runtime::RemoteObject> out_result;
    Inspector::Protocol::OptOutput<bool> out_wasThrown;
    Inspector::Protocol::OptOutput<int> out_savedResultIndex;
    m_agent->evaluate(error, in_expression, opt_in_objectGroup_valueFound ? &opt_in_objectGroup : nullptr, opt_in_includeCommandLineAPI_valueFound ? &opt_in_includeCommandLineAPI : nullptr, opt_in_doNotPauseOnExceptionsAndMuteConsole_valueFound ? &opt_in_doNotPauseOnExceptionsAndMuteConsole : nullptr, opt_in_contextId_valueFound ? &opt_in_contextId : nullptr, opt_in_returnByValue_valueFound ? &opt_in_returnByValue : nullptr, opt_in_generatePreview_valueFound ? &opt_in_generatePreview : nullptr, opt_in_saveResult_valueFound ? &opt_in_saveResult : nullptr, out_result, &out_wasThrown, &out_savedResultIndex);

    if (!error.length()) {
        result->setObject(ASCIILiteral("result"), out_result);
        if (out_wasThrown.isAssigned())
            result->setBoolean(ASCIILiteral("wasThrown"), out_wasThrown.getValue());
        if (out_savedResultIndex.isAssigned())
            result->setInteger(ASCIILiteral("savedResultIndex"), out_savedResultIndex.getValue());
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::callFunctionOn(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_objectId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectId"), nullptr);
    String in_functionDeclaration = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("functionDeclaration"), nullptr);
    bool opt_in_arguments_valueFound = false;
    RefPtr<Inspector::InspectorArray> opt_in_arguments = m_backendDispatcher->getArray(parameters.get(), ASCIILiteral("arguments"), &opt_in_arguments_valueFound);
    bool opt_in_doNotPauseOnExceptionsAndMuteConsole_valueFound = false;
    bool opt_in_doNotPauseOnExceptionsAndMuteConsole = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("doNotPauseOnExceptionsAndMuteConsole"), &opt_in_doNotPauseOnExceptionsAndMuteConsole_valueFound);
    bool opt_in_returnByValue_valueFound = false;
    bool opt_in_returnByValue = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("returnByValue"), &opt_in_returnByValue_valueFound);
    bool opt_in_generatePreview_valueFound = false;
    bool opt_in_generatePreview = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("generatePreview"), &opt_in_generatePreview_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Runtime.callFunctionOn"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->callFunctionOn(requestId, in_objectId, in_functionDeclaration, opt_in_arguments_valueFound ? opt_in_arguments.get() : nullptr, opt_in_doNotPauseOnExceptionsAndMuteConsole_valueFound ? &opt_in_doNotPauseOnExceptionsAndMuteConsole : nullptr, opt_in_returnByValue_valueFound ? &opt_in_returnByValue : nullptr, opt_in_generatePreview_valueFound ? &opt_in_generatePreview : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Runtime::RemoteObject> out_result;
    Inspector::Protocol::OptOutput<bool> out_wasThrown;
    m_agent->callFunctionOn(error, in_objectId, in_functionDeclaration, opt_in_arguments_valueFound ? opt_in_arguments.get() : nullptr, opt_in_doNotPauseOnExceptionsAndMuteConsole_valueFound ? &opt_in_doNotPauseOnExceptionsAndMuteConsole : nullptr, opt_in_returnByValue_valueFound ? &opt_in_returnByValue : nullptr, opt_in_generatePreview_valueFound ? &opt_in_generatePreview : nullptr, out_result, &out_wasThrown);

    if (!error.length()) {
        result->setObject(ASCIILiteral("result"), out_result);
        if (out_wasThrown.isAssigned())
            result->setBoolean(ASCIILiteral("wasThrown"), out_wasThrown.getValue());
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::getProperties(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_objectId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectId"), nullptr);
    bool opt_in_ownProperties_valueFound = false;
    bool opt_in_ownProperties = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("ownProperties"), &opt_in_ownProperties_valueFound);
    bool opt_in_generatePreview_valueFound = false;
    bool opt_in_generatePreview = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("generatePreview"), &opt_in_generatePreview_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Runtime.getProperties"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getProperties(requestId, in_objectId, opt_in_ownProperties_valueFound ? &opt_in_ownProperties : nullptr, opt_in_generatePreview_valueFound ? &opt_in_generatePreview : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::PropertyDescriptor>> out_result;
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>> out_internalProperties;
    m_agent->getProperties(error, in_objectId, opt_in_ownProperties_valueFound ? &opt_in_ownProperties : nullptr, opt_in_generatePreview_valueFound ? &opt_in_generatePreview : nullptr, out_result, out_internalProperties);

    if (!error.length()) {
        result->setArray(ASCIILiteral("result"), out_result);
        if (out_internalProperties)
            result->setArray(ASCIILiteral("internalProperties"), out_internalProperties);
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::getDisplayableProperties(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_objectId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectId"), nullptr);
    bool opt_in_generatePreview_valueFound = false;
    bool opt_in_generatePreview = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("generatePreview"), &opt_in_generatePreview_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Runtime.getDisplayableProperties"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getDisplayableProperties(requestId, in_objectId, opt_in_generatePreview_valueFound ? &opt_in_generatePreview : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::PropertyDescriptor>> out_properties;
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>> out_internalProperties;
    m_agent->getDisplayableProperties(error, in_objectId, opt_in_generatePreview_valueFound ? &opt_in_generatePreview : nullptr, out_properties, out_internalProperties);

    if (!error.length()) {
        result->setArray(ASCIILiteral("properties"), out_properties);
        if (out_internalProperties)
            result->setArray(ASCIILiteral("internalProperties"), out_internalProperties);
    }
    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::getCollectionEntries(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_objectId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectId"), nullptr);
    bool opt_in_objectGroup_valueFound = false;
    String opt_in_objectGroup = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectGroup"), &opt_in_objectGroup_valueFound);
    bool opt_in_startIndex_valueFound = false;
    int opt_in_startIndex = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("startIndex"), &opt_in_startIndex_valueFound);
    bool opt_in_numberToFetch_valueFound = false;
    int opt_in_numberToFetch = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("numberToFetch"), &opt_in_numberToFetch_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Runtime.getCollectionEntries"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getCollectionEntries(requestId, in_objectId, opt_in_objectGroup_valueFound ? &opt_in_objectGroup : nullptr, opt_in_startIndex_valueFound ? &opt_in_startIndex : nullptr, opt_in_numberToFetch_valueFound ? &opt_in_numberToFetch : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::CollectionEntry>> out_entries;
    m_agent->getCollectionEntries(error, in_objectId, opt_in_objectGroup_valueFound ? &opt_in_objectGroup : nullptr, opt_in_startIndex_valueFound ? &opt_in_startIndex : nullptr, opt_in_numberToFetch_valueFound ? &opt_in_numberToFetch : nullptr, out_entries);

    if (!error.length())
        result->setArray(ASCIILiteral("entries"), out_entries);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::saveResult(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorObject> in_value = m_backendDispatcher->getObject(parameters.get(), ASCIILiteral("value"), nullptr);
    bool opt_in_contextId_valueFound = false;
    int opt_in_contextId = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("contextId"), &opt_in_contextId_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Runtime.saveResult"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->saveResult(requestId, *in_value, opt_in_contextId_valueFound ? &opt_in_contextId : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    Inspector::Protocol::OptOutput<int> out_savedResultIndex;
    m_agent->saveResult(error, *in_value, opt_in_contextId_valueFound ? &opt_in_contextId : nullptr, &out_savedResultIndex);

    if (!error.length())
        if (out_savedResultIndex.isAssigned())
            result->setInteger(ASCIILiteral("savedResultIndex"), out_savedResultIndex.getValue());

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::releaseObject(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_objectId = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectId"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Runtime.releaseObject"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->releaseObject(requestId, in_objectId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->releaseObject(error, in_objectId);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::releaseObjectGroup(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_objectGroup = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("objectGroup"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Runtime.releaseObjectGroup"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->releaseObjectGroup(requestId, in_objectGroup);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->releaseObjectGroup(error, in_objectGroup);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::enable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::disable(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->disable(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->disable(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::getRuntimeTypesForVariablesAtOffsets(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorArray> in_locations = m_backendDispatcher->getArray(parameters.get(), ASCIILiteral("locations"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Runtime.getRuntimeTypesForVariablesAtOffsets"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getRuntimeTypesForVariablesAtOffsets(requestId, *in_locations);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::TypeDescription>> out_types;
    m_agent->getRuntimeTypesForVariablesAtOffsets(error, *in_locations, out_types);

    if (!error.length())
        result->setArray(ASCIILiteral("types"), out_types);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::enableTypeProfiler(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enableTypeProfiler(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enableTypeProfiler(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::disableTypeProfiler(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->disableTypeProfiler(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->disableTypeProfiler(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::enableControlFlowProfiler(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->enableControlFlowProfiler(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->enableControlFlowProfiler(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::disableControlFlowProfiler(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->disableControlFlowProfiler(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->disableControlFlowProfiler(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void RuntimeBackendDispatcher::getBasicBlocks(long requestId, RefPtr<InspectorObject>&& parameters)
{
    String in_sourceID = m_backendDispatcher->getString(parameters.get(), ASCIILiteral("sourceID"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Runtime.getBasicBlocks"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->getBasicBlocks(requestId, in_sourceID);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::BasicBlock>> out_basicBlocks;
    m_agent->getBasicBlocks(error, in_sourceID, out_basicBlocks);

    if (!error.length())
        result->setArray(ASCIILiteral("basicBlocks"), out_basicBlocks);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

Ref<ScriptProfilerBackendDispatcher> ScriptProfilerBackendDispatcher::create(BackendDispatcher& backendDispatcher, ScriptProfilerBackendDispatcherHandler* agent)
{
    return adoptRef(*new ScriptProfilerBackendDispatcher(backendDispatcher, agent));
}

ScriptProfilerBackendDispatcher::ScriptProfilerBackendDispatcher(BackendDispatcher& backendDispatcher, ScriptProfilerBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("ScriptProfiler"), this);
}

void ScriptProfilerBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<ScriptProfilerBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    if (method == "startTracking")
        startTracking(requestId, WTFMove(parameters));
    else if (method == "stopTracking")
        stopTracking(requestId, WTFMove(parameters));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "ScriptProfiler", '.', method, "' was not found"));
}

void ScriptProfilerBackendDispatcher::startTracking(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool opt_in_includeSamples_valueFound = false;
    bool opt_in_includeSamples = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("includeSamples"), &opt_in_includeSamples_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "ScriptProfiler.startTracking"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->startTracking(requestId, opt_in_includeSamples_valueFound ? &opt_in_includeSamples : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->startTracking(error, opt_in_includeSamples_valueFound ? &opt_in_includeSamples : nullptr);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void ScriptProfilerBackendDispatcher::stopTracking(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->stopTracking(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->stopTracking(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

Ref<TimelineBackendDispatcher> TimelineBackendDispatcher::create(BackendDispatcher& backendDispatcher, TimelineBackendDispatcherHandler* agent)
{
    return adoptRef(*new TimelineBackendDispatcher(backendDispatcher, agent));
}

TimelineBackendDispatcher::TimelineBackendDispatcher(BackendDispatcher& backendDispatcher, TimelineBackendDispatcherHandler* agent)
    : SupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Timeline"), this);
}

void TimelineBackendDispatcher::dispatch(long requestId, const String& method, Ref<InspectorObject>&& message)
{
    Ref<TimelineBackendDispatcher> protect(*this);

    RefPtr<InspectorObject> parameters;
    message->getObject(ASCIILiteral("params"), parameters);

    if (method == "start")
        start(requestId, WTFMove(parameters));
    else if (method == "stop")
        stop(requestId, WTFMove(parameters));
    else if (method == "setAutoCaptureEnabled")
        setAutoCaptureEnabled(requestId, WTFMove(parameters));
    else if (method == "setInstruments")
        setInstruments(requestId, WTFMove(parameters));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::MethodNotFound, makeString('\'', "Timeline", '.', method, "' was not found"));
}

void TimelineBackendDispatcher::start(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool opt_in_maxCallStackDepth_valueFound = false;
    int opt_in_maxCallStackDepth = m_backendDispatcher->getInteger(parameters.get(), ASCIILiteral("maxCallStackDepth"), &opt_in_maxCallStackDepth_valueFound);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Timeline.start"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->start(requestId, opt_in_maxCallStackDepth_valueFound ? &opt_in_maxCallStackDepth : nullptr);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->start(error, opt_in_maxCallStackDepth_valueFound ? &opt_in_maxCallStackDepth : nullptr);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void TimelineBackendDispatcher::stop(long requestId, RefPtr<InspectorObject>&&)
{
#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->stop(requestId);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->stop(error);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void TimelineBackendDispatcher::setAutoCaptureEnabled(long requestId, RefPtr<InspectorObject>&& parameters)
{
    bool in_enabled = m_backendDispatcher->getBoolean(parameters.get(), ASCIILiteral("enabled"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Timeline.setAutoCaptureEnabled"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setAutoCaptureEnabled(requestId, in_enabled);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setAutoCaptureEnabled(error, in_enabled);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

void TimelineBackendDispatcher::setInstruments(long requestId, RefPtr<InspectorObject>&& parameters)
{
    RefPtr<Inspector::InspectorArray> in_instruments = m_backendDispatcher->getArray(parameters.get(), ASCIILiteral("instruments"), nullptr);
    if (m_backendDispatcher->hasProtocolErrors()) {
        m_backendDispatcher->reportProtocolError(BackendDispatcher::InvalidParams, String::format("Some arguments of method '%s' can't be processed", "Timeline.setInstruments"));
        return;
    }

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
    if (m_alternateDispatcher) {
        m_alternateDispatcher->setInstruments(requestId, *in_instruments);
        return;
    }
#endif

    ErrorString error;
    Ref<InspectorObject> result = InspectorObject::create();
    m_agent->setInstruments(error, *in_instruments);

    if (!error.length())
        m_backendDispatcher->sendResponse(requestId, WTFMove(result));
    else
        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));
}

} // namespace Inspector
