// This is only called from SimpleResponseHandler.deliver() but lives in this
// class because all asyncronous response must have a "response" pointer
// to go through. Only operation classes have a response pointer
void OperationResponseHandler::send(Boolean isComplete)
{
    // It is possible to instantiate this class directly (not a derived
    // class, which would also inherit from SimpleResponseHandler).
    // The caller would do this only if the operation does not have any
    // data to be returned.

    SimpleResponseHandler* simpleP =
        dynamic_cast<SimpleResponseHandler*>(this);
    if (simpleP == 0)
    {
        // if there is no data to be returned, then the message should NEVER be
        // incomplete (even on an error)
        PEGASUS_ASSERT(isComplete);
        return;
    }

    // some handlers do not send async because their callers cannot handle
    // partial responses. If this is the case, stop here.

    if (!isAsync())
    {
        // preserve traditional behavior
        if (isComplete)
        {
            if (_response != 0)
            {
                _response->operationContext.set(
                    ContentLanguageListContainer(simpleP->getLanguages()));
            }
            transfer();
        }

        return;
    }

    SimpleResponseHandler& simple = *simpleP;
    PEGASUS_ASSERT(_response);
    Uint32 objectCount = simple.size();

    // have not reached threshold yet
    if ((isComplete == false) && (objectCount < _responseObjectThreshold))
    {
        return;
    }

    CIMResponseMessage* response = _response;

    // for complete responses, just use the one handed down from caller
    // otherwise, create our own that the caller never sees but is
    // utilized for async responses underneath

    if (isComplete == false)
    {
        _response = _request->buildResponse();
    }

    _response->setComplete(isComplete);
    _responseObjectTotal += objectCount;

    // since we are reusing response for every chunk, keep track of original
    // count
    _response->setIndex(_responseMessageTotal++);

    // set the originally allocated response to one more than the current.
    // The reason for doing this is proactive in case of an exception. This
    // allows the last response to be set as it may not re-enter this code.

    if (isComplete == false)
    {
        response->setIndex(_responseMessageTotal);
    }

    validate();

    if (_response->cimException.getCode() != CIM_ERR_SUCCESS)
    {
        simple.clear();
    }

    PEG_TRACE((
        TRC_PROVIDERMANAGER,
        Tracer::LEVEL4,
        "%s::transfer",
        (const char*) getClass().getCString()));

    transfer();
    simple.clear();

    _response->operationContext.set(
        ContentLanguageListContainer(simple.getLanguages()));

    // call thru ProviderManager to get externally declared entry point

    if (isComplete == false)
    {
        _responseChunkCallback(_request, _response);
    }

    // put caller's allocated response back in place. Note that _response
    // is INVALID after sending because it has been deleted externally

    _response = response;
}
// This is only called from SimpleResponseHandler.deliver() but lives in this
// class because all asyncronous response must have a "response" pointer
// to go through. Only operation classes have a response pointer
void OperationResponseHandler::send(Boolean isComplete)
{
	// some handlers do not send async because their callers cannot handle
	// partial responses. If this is the case, stop here.

	if (isAsync() == false)
	{
		// preserve tradional behavior
		if (isComplete == true)
        {
            transfer();
        }

        return;
	}

	SimpleResponseHandler *simpleP = dynamic_cast<SimpleResponseHandler*>(this);

	// It is possible to instantiate this class directly (not derived)
	// The caller would do this only if the operation does not have any data to
	// be returned

	if (! simpleP)
	{
		// if there is no data to be returned, then the message should NEVER be
		// incomplete (even on an error)
		if (isComplete == false)
        {
            PEGASUS_ASSERT(false);
        }

        return;
	}

	SimpleResponseHandler &simple = *simpleP;
	PEGASUS_ASSERT(_response);
	Uint32 objectCount = simple.size();

	// have not reached threshold yet
	if ((isComplete == false) && (objectCount < _responseObjectThreshold))
    {
        return;
    }

	CIMResponseMessage *response = _response;

	// for complete responses, just use the one handed down from caller
	// otherwise, create our own that the caller never sees but is
	// utilized for async responses underneath

	if (isComplete == false)
    {
        _response = _request->buildResponse();
    }

	_response->setComplete(isComplete);
	_responseObjectTotal += objectCount;

	// since we are reusing response for every chunk,keep track of original count
	_response->setIndex(_responseMessageTotal++);

	// set the originally allocated response to one more than the current.
	// The reason for doing this is proactive in case of an exception. This
	// allows the last response to be set as it may not re-enter this code.

	if (isComplete == false)
    {
        response->setIndex(_responseMessageTotal);
    }

	validate();

	if (_response->cimException.getCode() != CIM_ERR_SUCCESS)
    {
        simple.clear();
    }

	String function = getClass() + "::" + "transfer";
	Logger::put(
        Logger::STANDARD_LOG,
        System::CIMSERVER,
        Logger::TRACE,
        function);

	transfer();
	simple.clear();

	// l10n
	_response->operationContext.set(ContentLanguageListContainer(simple.getLanguages()));

	// call thru ProviderManager to get externally declared entry point

	if (isComplete == false)
	{
		ProviderManagerService::handleCimResponse(*_request, *_response);
	}

	// put caller's allocated response back in place. Note that _response
	// is INVALID after sending because it has been deleted externally

	_response = response;
}