void DocumentLoader::getSubresources(Vector<PassRefPtr<ArchiveResource> >& subresources) const
{
    if (!isCommitted())
        return;

    Document* document = m_frame->document();

    const CachedResourceLoader::DocumentResourceMap& allResources = document->cachedResourceLoader()->allCachedResources();
    CachedResourceLoader::DocumentResourceMap::const_iterator end = allResources.end();
    for (CachedResourceLoader::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) {
        RefPtr<ArchiveResource> subresource = this->subresource(KURL(ParsedURLString, it->second->url()));
        if (subresource)
            subresources.append(subresource.release());
    }

    return;
}
PassRefPtr<ArchiveResource> DocumentLoader::subresource(const KURL& url) const
{
    if (!isCommitted())
        return 0;
    
    CachedResource* resource = m_frame->document()->docLoader()->cachedResource(url);
    if (!resource || !resource->isLoaded())
        return archiveResourceForURL(url);

    // FIXME: This has the side effect of making the resource non-purgeable.
    // It would be better if it didn't have this permanent effect.
    if (!resource->makePurgeable(false))
        return 0;

    RefPtr<SharedBuffer> data = resource->data();
    if (!data)
        return 0;

    return ArchiveResource::create(data.release(), url, resource->response());
}
uint64_t findDocVer(DbMap *docStore, DocId docId, DocId txnId, uint64_t ts) {
	DbAddr *addr = fetchIdSlot(docStore, docId);
	DbMap *db = docStore->parent;
	uint64_t txnTs;

	//	examine all prior versions

	while (addr->bits) {
		DbDoc *doc = getObj(docStore, *addr);

		// is version in same txn?

		if (doc->txnId.bits == txnId.bits)
			return addr->bits;

		// is version committed?

		if (doc->docTs)
		  if (doc->docTs < ts)
			return addr->bits;

		// is txn committed?

		if (txnId.bits) {
			Txn *txn = fetchIdSlot(db, txnId);

			if (isCommitted(txn->ts) && ts >= txn->ts)
				return addr->bits;

            while (isReader((txnTs = txn->ts)) && txnTs < ts)
                compareAndSwap(&txn->ts, txnTs, ts);
		}

		addr = doc->oldDoc;
	}

	return 0;
}
bool ExtensionAgentResponse::startResponse(int status, string reason, list<pair<string, string>> headers) {

	if (isCommitted()) {
		jk_log(logger, JK_LOG_ERROR, "Attempting to restart a committed response");
		return false;
	}

	if (status < 100 || status > 1000) {
        jk_log(logger, JK_LOG_ERROR,
               "invalid status %d",
               status);
		return false;
	}

	// Create a plain string with headers:
	// <HEADER_NAME_1>: <HEADER_VALUE_1>\r\n<HEADER_NAME_2>: <HEADER_VALUE_2>\r\n...<HEADER_NAME_N>: <HEADER_VALUE_N>\r\n\r\n
	string plainHeaders;
	list<pair<string, string>>::iterator h;
	for (h = headers.begin() ; h != headers.end() ; h ++) {
		pair<string, string> p = *h;
		
		plainHeaders.append(p.first);
		plainHeaders.append(": ");
		plainHeaders.append(p.second);
		plainHeaders.append("\r\n");
	}

	if (plainHeaders.empty()) {
		jk_log(logger, JK_LOG_WARNING, "No HTTP headers in response");
	} else {
		jk_log(logger, JK_LOG_TRACE, "HTTP headers \r\n%s", plainHeaders.c_str());
	}

	plainHeaders.append("\r\n");
	const char * cHeaders = plainHeaders.c_str();

	// Create status string
	char * cStatus;
	cStatus = (char *)malloc((6 + reason.length()));
	StringCbPrintf(cStatus, 6 + reason.length(), "%d %s", status, reason.c_str());
	DWORD szStatus = (DWORD)strlen(cStatus);
	jk_log(logger, JK_LOG_TRACE, "HTTP status %s", cStatus);

	// Check status reason string
	if (reason.empty())
		reason.assign(status_reason(status));

	jk_log(logger, JK_LOG_TRACE, "HTTP status reason %s", reason.c_str());

	// Now start a response:
	jk_log(logger, JK_LOG_DEBUG, "Marking response as committed");
	committed = true;
	
    /* Old style response - forces Connection: close if Tomcat response doesn't
       specify necessary details to allow keep alive */
    BOOL ok = lpEcb->ServerSupportFunction(lpEcb->ConnID,
                                         HSE_REQ_SEND_RESPONSE_HEADER,
										 cStatus,
										 &szStatus,
										 (LPDWORD)plainHeaders.c_str());

	if (cStatus)
		free(cStatus);

	if (!ok) {
		DWORD error = GetLastError();
        jk_log(logger, JK_LOG_ERROR,
               "HSE_REQ_SEND_RESPONSE_HEADER failed with error=%d (0x%08x)", error, error);
		return false;
	} else {
		jk_log(logger, JK_LOG_DEBUG,
               "HSE_REQ_SEND_RESPONSE_HEADER succes");
		return true;
	}
}