void StatisticsRequest::completedRequest(uint64_t requestID, const StatisticsData& data)
{
    ASSERT(m_outstandingRequests.contains(requestID));
    m_outstandingRequests.remove(requestID);

    if (!m_responseDictionary)
        m_responseDictionary = MutableDictionary::create();

    // FIXME (Multi-WebProcess) <rdar://problem/13200059>: This code overwrites any previous response data received.
    // When getting responses from multiple WebProcesses we need to combine items instead of clobbering them.

    addToDictionaryFromHashMap(m_responseDictionary.get(), data.statisticsNumbers);

    if (!data.javaScriptProtectedObjectTypeCounts.isEmpty())
        m_responseDictionary->set("JavaScriptProtectedObjectTypeCounts", createDictionaryFromHashMap(data.javaScriptProtectedObjectTypeCounts).get());
    if (!data.javaScriptObjectTypeCounts.isEmpty())
        m_responseDictionary->set("JavaScriptObjectTypeCounts", createDictionaryFromHashMap(data.javaScriptObjectTypeCounts).get());

    if (!data.webCoreCacheStatistics.isEmpty()) {
        Vector<RefPtr<API::Object>> cacheStatistics;
        cacheStatistics.reserveInitialCapacity(data.webCoreCacheStatistics.size());

        for (const auto& statistic : data.webCoreCacheStatistics)
            cacheStatistics.uncheckedAppend(createDictionaryFromHashMap(statistic));

        m_responseDictionary->set("WebCoreCacheStatistics", API::Array::create(WTF::move(cacheStatistics)).get());
    }

    if (m_outstandingRequests.isEmpty()) {
        m_callback->performCallbackWithReturnValue(m_responseDictionary.get());
        m_callback = 0;
    }
}
void StatisticsRequest::completedRequest(uint64_t requestID, const StatisticsData& data)
{
    ASSERT(m_outstandingRequests.contains(requestID));
    m_outstandingRequests.remove(requestID);

    if (!m_responseDictionary)
        m_responseDictionary = MutableDictionary::create();
    
    // FIXME (Multi-WebProcess) <rdar://problem/13200059>: This code overwrites any previous response data received.
    // When getting responses from multiple WebProcesses we need to combine items instead of clobbering them.

    addToDictionaryFromHashMap(m_responseDictionary.get(), data.statisticsNumbers);

    if (!data.javaScriptProtectedObjectTypeCounts.isEmpty())
        m_responseDictionary->set("JavaScriptProtectedObjectTypeCounts", createDictionaryFromHashMap(data.javaScriptProtectedObjectTypeCounts).get());
    if (!data.javaScriptObjectTypeCounts.isEmpty())
        m_responseDictionary->set("JavaScriptObjectTypeCounts", createDictionaryFromHashMap(data.javaScriptObjectTypeCounts).get());
    
    size_t cacheStatisticsCount = data.webCoreCacheStatistics.size();
    if (cacheStatisticsCount) {
        Vector<RefPtr<APIObject>> cacheStatisticsVector(cacheStatisticsCount);
        for (size_t i = 0; i < cacheStatisticsCount; ++i)
            cacheStatisticsVector[i] = createDictionaryFromHashMap(data.webCoreCacheStatistics[i]);
        m_responseDictionary->set("WebCoreCacheStatistics", ImmutableArray::adopt(cacheStatisticsVector).get());
    }

    if (m_outstandingRequests.isEmpty()) {
        m_callback->performCallbackWithReturnValue(m_responseDictionary.get());
        m_callback = 0;
    }
}
static PassRefPtr<MutableDictionary> createDictionaryFromHashMap(const HashMap<String, uint64_t>& map)
{
    RefPtr<MutableDictionary> result = MutableDictionary::create();
    addToDictionaryFromHashMap(result.get(), map);
    return result;
}