PJ_DEF(pj_status_t) pjsip_endpt_create_request_from_hdr( pjsip_endpoint *endpt,
				     const pjsip_method *method,
				     const pjsip_uri *param_target,
				     const pjsip_from_hdr *param_from,
				     const pjsip_to_hdr *param_to,
				     const pjsip_contact_hdr *param_contact,
				     const pjsip_cid_hdr *param_call_id,
				     int param_cseq,
				     const pj_str_t *param_text,
				     pjsip_tx_data **p_tdata)
{
    pjsip_uri *target;
    pjsip_tx_data *tdata;
    pjsip_from_hdr *from;
    pjsip_to_hdr *to;
    pjsip_contact_hdr *contact;
    pjsip_cid_hdr *call_id;
    pjsip_cseq_hdr *cseq = NULL; /* The NULL because warning in VC6 */
    pj_status_t status;
    PJ_USE_EXCEPTION;

    /* Check arguments. */
    PJ_ASSERT_RETURN(endpt && method && param_target && param_from &&
		     param_to && p_tdata, PJ_EINVAL);

    /* Create new transmit data. */
    status = pjsip_endpt_create_tdata(endpt, &tdata);
    if (status != PJ_SUCCESS)
	return status;

    /* Set initial reference counter to 1. */
    pjsip_tx_data_add_ref(tdata);

    PJ_TRY {
	/* Duplicate target URI and headers. */
	target = (pjsip_uri*) pjsip_uri_clone(tdata->pool, param_target);
	from = (pjsip_from_hdr*) pjsip_hdr_clone(tdata->pool, param_from);
	pjsip_fromto_hdr_set_from(from);
	to = (pjsip_to_hdr*) pjsip_hdr_clone(tdata->pool, param_to);
	pjsip_fromto_hdr_set_to(to);
	if (param_contact) {
	    contact = (pjsip_contact_hdr*) 
	    	      pjsip_hdr_clone(tdata->pool, param_contact);
	} else {
	    contact = NULL;
	}
	call_id = pjsip_cid_hdr_create(tdata->pool);
	if (param_call_id != NULL && param_call_id->id.slen)
	    pj_strdup(tdata->pool, &call_id->id, &param_call_id->id);
	else
	    pj_create_unique_string(tdata->pool, &call_id->id);

	cseq = pjsip_cseq_hdr_create(tdata->pool);
	if (param_cseq >= 0)
	    cseq->cseq = param_cseq;
	else
	    cseq->cseq = pj_rand() % 0xFFFF;
	pjsip_method_copy(tdata->pool, &cseq->method, method);

	/* Copy headers to the request. */
	init_request_throw(endpt, tdata, &cseq->method, target, from, to, 
                           contact, call_id, cseq, param_text);
    }
    PJ_CATCH_ANY {
	status = PJ_ENOMEM;
	goto on_error;
    }
    PJ_END;

    *p_tdata = tdata;
    return PJ_SUCCESS;

on_error:
    pjsip_tx_data_dec_ref(tdata);
    return status;
}
PJ_DEF(pj_status_t) pjsip_endpt_create_request_from_hdr( pjsip_endpoint *endpt,
				     const pjsip_method *method,
				     const pjsip_uri *param_target,
				     const pjsip_from_hdr *param_from,
				     const pjsip_to_hdr *param_to,
				     const pjsip_contact_hdr *param_contact,
				     const pjsip_cid_hdr *param_call_id,
				     int param_cseq,
				     const pj_str_t *param_text,
				     pjsip_tx_data **p_tdata)
{
    pjsip_uri *target;
    pjsip_tx_data *tdata;
    pjsip_from_hdr *from;
    pjsip_to_hdr *to;
    pjsip_contact_hdr *contact;
    pjsip_cid_hdr *call_id;
    pjsip_cseq_hdr *cseq = NULL;  
    pj_status_t status;
    PJ_USE_EXCEPTION;

     
    PJ_ASSERT_RETURN(endpt && method && param_target && param_from &&
		     param_to && p_tdata, PJ_EINVAL);

     
    status = pjsip_endpt_create_tdata(endpt, &tdata);
    if (status != PJ_SUCCESS)
	return status;

     
    pjsip_tx_data_add_ref(tdata);

    PJ_TRY {
	 
	target = (pjsip_uri*) pjsip_uri_clone(tdata->pool, param_target);
	from = (pjsip_from_hdr*) pjsip_hdr_clone(tdata->pool, param_from);
	pjsip_fromto_hdr_set_from(from);
	to = (pjsip_to_hdr*) pjsip_hdr_clone(tdata->pool, param_to);
	pjsip_fromto_hdr_set_to(to);
	if (param_contact) {
	    contact = (pjsip_contact_hdr*) 
	    	      pjsip_hdr_clone(tdata->pool, param_contact);
	} else {
	    contact = NULL;
	}
	call_id = pjsip_cid_hdr_create(tdata->pool);
	if (param_call_id != NULL && param_call_id->id.slen)
	    pj_strdup(tdata->pool, &call_id->id, &param_call_id->id);
	else
	    pj_create_unique_string(tdata->pool, &call_id->id);

	cseq = pjsip_cseq_hdr_create(tdata->pool);
	if (param_cseq >= 0)
	    cseq->cseq = param_cseq;
	else
	    cseq->cseq = pj_rand() % 0xFFFF;
	pjsip_method_copy(tdata->pool, &cseq->method, method);

	 
	init_request_throw(endpt, tdata, &cseq->method, target, from, to, 
                           contact, call_id, cseq, param_text);
    }
    PJ_CATCH_ANY {
	status = PJ_ENOMEM;
	goto on_error;
    }
    PJ_END;

    *p_tdata = tdata;
    return PJ_SUCCESS;

on_error:
    pjsip_tx_data_dec_ref(tdata);
    return status;
}