PJ_DEF(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,
					 pjsip_module *mod,
					 void *mod_data )
{
    unsigned index;

    PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL);
    PJ_ASSERT_RETURN(mod->id >= 0 && mod->id < PJSIP_MAX_MODULE,
		     PJ_EINVAL);
    PJ_ASSERT_RETURN(dlg->usage_cnt < PJSIP_MAX_MODULE, PJ_EBUG);

    PJ_LOG(5,(dlg->obj_name,
	      "Module %.*s added as dialog usage, data=%p",
	      (int)mod->name.slen, mod->name.ptr, mod_data));

    pjsip_dlg_inc_lock(dlg);

    /* Usages are sorted on priority, lowest number first.
     * Find position to put the new module, also makes sure that
     * this module has not been registered before.
     */
    for (index=0; index<dlg->usage_cnt; ++index) {
	if (dlg->usage[index] == mod) {
	    /* Module may be registered more than once in the same dialog.
	     * For example, when call transfer fails, application may retry
	     * call transfer on the same dialog.
	     * So return PJ_SUCCESS here.
	     */
	    PJ_LOG(4,(dlg->obj_name,
		      "Module %.*s already registered as dialog usage, "
		      "updating the data %p",
		      (int)mod->name.slen, mod->name.ptr, mod_data));
	    dlg->mod_data[mod->id] = mod_data;

	    pjsip_dlg_dec_lock(dlg);
	    return PJ_SUCCESS;

	    //pj_assert(!"This module is already registered");
	    //pjsip_dlg_dec_lock(dlg);
	    //return PJSIP_ETYPEEXISTS;
	}

	if (dlg->usage[index]->priority > mod->priority)
	    break;
    }

    /* index holds position to put the module.
     * Insert module at this index.
     */
    pj_array_insert(dlg->usage, sizeof(dlg->usage[0]), dlg->usage_cnt,
		    index, &mod);

    /* Set module data. */
    dlg->mod_data[mod->id] = mod_data;

    /* Increment count. */
    ++dlg->usage_cnt;

    pjsip_dlg_dec_lock(dlg);

    return PJ_SUCCESS;
}
PJ_DEF(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,
					 pjsip_module *mod,
					 void *mod_data )
{
    unsigned index;

    PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL);
    PJ_ASSERT_RETURN(mod->id >= 0 && mod->id < PJSIP_MAX_MODULE,
		     PJ_EINVAL);
    PJ_ASSERT_RETURN(dlg->usage_cnt < PJSIP_MAX_MODULE, PJ_EBUG);

    PJ_LOG(5,(dlg->obj_name,
	      "Module %.*s added as dialog usage, data=%p",
	      (int)mod->name.slen, mod->name.ptr, mod_data));

    pjsip_dlg_inc_lock(dlg);

     
    for (index=0; index<dlg->usage_cnt; ++index) {
	if (dlg->usage[index] == mod) {
	     
	    PJ_LOG(4,(dlg->obj_name,
		      "Module %.*s already registered as dialog usage, "
		      "updating the data %p",
		      (int)mod->name.slen, mod->name.ptr, mod_data));
	    dlg->mod_data[mod->id] = mod_data;

	    pjsip_dlg_dec_lock(dlg);
	    return PJ_SUCCESS;

	     
	     
	     
	}

	if (dlg->usage[index]->priority > mod->priority)
	    break;
    }

     
    pj_array_insert(dlg->usage, sizeof(dlg->usage[0]), dlg->usage_cnt,
		    index, &mod);

     
    dlg->mod_data[mod->id] = mod_data;

     
    ++dlg->usage_cnt;

    pjsip_dlg_dec_lock(dlg);

    return PJ_SUCCESS;
}