PJ_DEF(pj_status_t) pjsip_dlg_update_remote_cap(pjsip_dialog *dlg,
					        const pjsip_msg *msg,
						pj_bool_t strict)
{
    pjsip_hdr_e htypes[] =
	{ PJSIP_H_ACCEPT, PJSIP_H_ALLOW, PJSIP_H_SUPPORTED };
    unsigned i;

    PJ_ASSERT_RETURN(dlg && msg, PJ_EINVAL);

    pjsip_dlg_inc_lock(dlg);

    /* Retrieve all specified capability header types */
    for (i = 0; i < PJ_ARRAY_SIZE(htypes); ++i) {
	const pjsip_generic_array_hdr *hdr;
	pj_status_t status;

	/* Find this capability type in the message */
	hdr = (const pjsip_generic_array_hdr*)
	      pjsip_msg_find_hdr(msg, htypes[i], NULL);
	if (!hdr) {
	    /* Not found.
	     * If strict update is specified, remote this capability type
	     * from the capability list.
	     */
	    if (strict)
		pjsip_dlg_remove_remote_cap_hdr(dlg, htypes[i], NULL);
	} else {
	    /* Found, a capability type may be specified in multiple headers,
	     * so combine all the capability tags/values into a temporary
	     * header.
	     */
	    pjsip_generic_array_hdr tmp_hdr;

	    /* Init temporary header */
	    pjsip_generic_array_hdr_init(dlg->pool, &tmp_hdr, NULL);
	    pj_memcpy(&tmp_hdr, hdr, sizeof(pjsip_hdr));

	    while (hdr) {
		unsigned j;

		/* Append the header content to temporary header */
		for(j=0; j<hdr->count &&
			 tmp_hdr.count<PJSIP_GENERIC_ARRAY_MAX_COUNT; ++j)
		{
		    tmp_hdr.values[tmp_hdr.count++] = hdr->values[j];
		}

		/* Get the next header for this capability */
		hdr = (const pjsip_generic_array_hdr*)
		      pjsip_msg_find_hdr(msg, htypes[i], hdr->next);
	    }

	    /* Save this capability */
	    status = pjsip_dlg_set_remote_cap_hdr(dlg, &tmp_hdr);
	    if (status != PJ_SUCCESS) {
		pjsip_dlg_dec_lock(dlg);
		return status;
	    }
	}
    }

    pjsip_dlg_dec_lock(dlg);

    return PJ_SUCCESS;
}
PJ_DEF(pj_status_t) pjsip_dlg_update_remote_cap(pjsip_dialog *dlg,
					        const pjsip_msg *msg,
						pj_bool_t strict)
{
    pjsip_hdr_e htypes[] =
	{ PJSIP_H_ACCEPT, PJSIP_H_ALLOW, PJSIP_H_SUPPORTED };
    unsigned i;

    PJ_ASSERT_RETURN(dlg && msg, PJ_EINVAL);

    pjsip_dlg_inc_lock(dlg);

     
    for (i = 0; i < PJ_ARRAY_SIZE(htypes); ++i) {
	const pjsip_generic_array_hdr *hdr;
	pj_status_t status;

	 
	hdr = (const pjsip_generic_array_hdr*)
	      pjsip_msg_find_hdr(msg, htypes[i], NULL);
	if (!hdr) {
	     
	    if (strict)
		pjsip_dlg_remove_remote_cap_hdr(dlg, htypes[i], NULL);
	} else {
	     
	    pjsip_generic_array_hdr tmp_hdr;

	     
	    pjsip_generic_array_hdr_init(dlg->pool, &tmp_hdr, NULL);
	    pj_memcpy(&tmp_hdr, hdr, sizeof(pjsip_hdr));

	    while (hdr) {
		unsigned j;

		 
		for(j=0; j<hdr->count &&
			 tmp_hdr.count<PJSIP_GENERIC_ARRAY_MAX_COUNT; ++j)
		{
		    tmp_hdr.values[tmp_hdr.count++] = hdr->values[j];
		}

		 
		hdr = (const pjsip_generic_array_hdr*)
		      pjsip_msg_find_hdr(msg, htypes[i], hdr->next);
	    }

	     
	    status = pjsip_dlg_set_remote_cap_hdr(dlg, &tmp_hdr);
	    if (status != PJ_SUCCESS) {
		pjsip_dlg_dec_lock(dlg);
		return status;
	    }
	}
    }

    pjsip_dlg_dec_lock(dlg);

    return PJ_SUCCESS;
}