Index: pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h	(revision 174)
+++ pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h	(revision 175)
@@ -167,12 +167,13 @@
 struct pjsip_inv_session
 {
-    pj_pool_t		*pool;
-    pjsip_inv_state	 state;
-    pjsip_dialog	*dlg;
-    pjsip_role_e	 role;
-    unsigned		 options;
-    pjmedia_sdp_neg	*neg;
-    pjsip_transaction	*invite_tsx;
-    void		*mod_data[PJSIP_MAX_MODULE];
+    char		 obj_name[PJ_MAX_OBJ_NAME]; /**< Log identification. */
+    pj_pool_t		*pool;			    /**< Dialog's pool.	    */
+    pjsip_inv_state	 state;			    /**< Invite sess state. */
+    pjsip_dialog	*dlg;			    /**< Underlying dialog. */
+    pjsip_role_e	 role;			    /**< Invite role.	    */
+    unsigned		 options;		    /**< Options in use.    */
+    pjmedia_sdp_neg	*neg;			    /**< Negotiator.	    */
+    pjsip_transaction	*invite_tsx;		    /**< 1st invite tsx.    */
+    void		*mod_data[PJSIP_MAX_MODULE];/**< Modules data.	    */
 };
 
Index: pjproject/trunk/pjsip/include/pjsip/sip_dialog.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_dialog.h	(revision 174)
+++ pjproject/trunk/pjsip/include/pjsip/sip_dialog.h	(revision 175)
@@ -184,5 +184,6 @@
  * (after created) the dialog has the session counter set to zero.
  */
-PJ_DECL(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg );
+PJ_DECL(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg,
+					    pjsip_module *mod);
 
 
@@ -193,5 +194,6 @@
  * if there is no pending transaction when this function is called.
  */
-PJ_DECL(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg );
+PJ_DECL(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg,
+					    pjsip_module *mod);
 
 /**
Index: pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c	(revision 174)
+++ pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c	(revision 175)
@@ -131,5 +131,5 @@
 
     if (inv->state == PJSIP_INV_STATE_DISCONNECTED)
-	pjsip_dlg_dec_session(inv->dlg);
+	pjsip_dlg_dec_session(inv->dlg, &mod_inv.mod);
 }
 
@@ -142,4 +142,7 @@
     pjsip_tx_data *tdata;
     pj_status_t status;
+
+    PJ_LOG(5,(inv->obj_name, "Received %s, sending ACK",
+	      pjsip_rx_data_get_info(rdata)));
 
     status = pjsip_dlg_create_request(inv->dlg, &pjsip_ack_method, 
@@ -371,4 +374,7 @@
     inv->options = options;
 
+    /* Object name will use the same dialog pointer. */
+    pj_snprintf(inv->obj_name, PJ_MAX_OBJ_NAME, "inv%p", dlg);
+
     /* Create negotiator if local_sdp is specified. */
     if (local_sdp) {
@@ -385,8 +391,12 @@
 
     /* Increment dialog session */
-    pjsip_dlg_inc_session(dlg);
+    pjsip_dlg_inc_session(dlg, &mod_inv.mod);
 
     /* Done */
     *p_inv = inv;
+
+    PJ_LOG(5,(inv->obj_name, "UAC invite session created for dialog %s",
+	      dlg->obj_name));
+
     return PJ_SUCCESS;
 }
@@ -760,4 +770,7 @@
     inv->options = options;
 
+    /* Object name will use the same dialog pointer. */
+    pj_snprintf(inv->obj_name, PJ_MAX_OBJ_NAME, "inv%p", dlg);
+
     /* Parse SDP in message body, if present. */
     if (msg->body) {
@@ -795,5 +808,5 @@
 
     /* Increment session in the dialog. */
-    pjsip_dlg_inc_session(dlg);
+    pjsip_dlg_inc_session(dlg, &mod_inv.mod);
 
     /* Save the invite transaction. */
@@ -808,4 +821,8 @@
     /* Done */
     *p_inv = inv;
+
+    PJ_LOG(5,(inv->obj_name, "UAS invite session created for dialog %s",
+	      dlg->obj_name));
+
     return PJ_SUCCESS;
 }
@@ -912,4 +929,6 @@
 
     status = pjmedia_sdp_neg_negotiate(inv->pool, inv->neg, 0);
+
+    PJ_LOG(5,(inv->obj_name, "SDP negotiation done, status=%d", status));
 
     if (mod_inv.cb.on_media_update)
@@ -982,4 +1001,7 @@
 	/* This is an offer. */
 
+	PJ_LOG(5,(inv->obj_name, "Got SDP offer in %s", 
+		  pjsip_rx_data_get_info(rdata)));
+
 	if (inv->neg == NULL) {
 	    status=pjmedia_sdp_neg_create_w_remote_offer(inv->pool, NULL, 
@@ -1009,4 +1031,7 @@
 	 * Process and negotiate remote answer.
 	 */
+
+	PJ_LOG(5,(inv->obj_name, "Got SDP answer in %s", 
+		  pjsip_rx_data_get_info(rdata)));
 
 	status = pjmedia_sdp_neg_set_remote_answer(inv->pool, inv->neg, sdp);
@@ -1260,4 +1285,7 @@
     /* Verify arguments. */
     PJ_ASSERT_RETURN(inv && tdata, PJ_EINVAL);
+
+    PJ_LOG(5,(inv->obj_name, "Sending %s", 
+	      pjsip_tx_data_get_info(tdata)));
 
     if (tdata->msg->type == PJSIP_REQUEST_MSG) {
@@ -1582,4 +1610,21 @@
 	    break;
 	}
+
+    } else if (inv->role == PJSIP_ROLE_UAC &&
+	       tsx->role == PJSIP_ROLE_UAC &&
+	       tsx->method.id == PJSIP_CANCEL_METHOD)
+    {
+	/*
+	 * Handle case when outgoing CANCEL is answered with 481 (Call/
+	 * Transaction Does Not Exist), 408, or when it's timed out. In these
+	 * cases, disconnect session (i.e. dialog usage only).
+	 */
+	if (tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST ||
+	    tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT ||
+	    tsx->status_code == PJSIP_SC_TSX_TIMEOUT ||
+	    PJSIP_SC_TSX_TRANSPORT_ERROR)
+	{
+	    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
+	}
     }
 }
@@ -1738,4 +1783,20 @@
 	inv_respond_incoming_cancel(inv, tsx, e->body.tsx_state.src.rdata);
 
+    } else if (inv->role == PJSIP_ROLE_UAC &&
+	       tsx->role == PJSIP_ROLE_UAC &&
+	       tsx->method.id == PJSIP_CANCEL_METHOD)
+    {
+	/*
+	 * Handle case when outgoing CANCEL is answered with 481 (Call/
+	 * Transaction Does Not Exist), 408, or when it's timed out. In these
+	 * cases, disconnect session (i.e. dialog usage only).
+	 */
+	if (tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST ||
+	    tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT ||
+	    tsx->status_code == PJSIP_SC_TSX_TIMEOUT ||
+	    PJSIP_SC_TSX_TRANSPORT_ERROR)
+	{
+	    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
+	}
     }
 }
Index: pjproject/trunk/pjsip/src/pjsip/sip_dialog.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_dialog.c	(revision 174)
+++ pjproject/trunk/pjsip/src/pjsip/sip_dialog.c	(revision 175)
@@ -201,4 +201,7 @@
     *p_dlg = dlg;
 
+
+    PJ_LOG(5,(dlg->obj_name, "UAC dialog created"));
+
     return PJ_SUCCESS;
 
@@ -381,4 +384,5 @@
     /* Done. */
     *p_dlg = dlg;
+    PJ_LOG(5,(dlg->obj_name, "UAS dialog created"));
     return PJ_SUCCESS;
 
@@ -496,4 +500,5 @@
     *new_dlg = dlg;
 
+    PJ_LOG(5,(dlg->obj_name, "Forked dialog created"));
     return PJ_SUCCESS;
 
@@ -577,7 +582,8 @@
  * Increment session counter.
  */
-PJ_DEF(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg )
-{
-    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
+PJ_DEF(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg,
+					   pjsip_module *mod )
+{
+    PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL);
 
     pj_mutex_lock(dlg->mutex);
@@ -585,4 +591,7 @@
     pj_mutex_unlock(dlg->mutex);
 
+    PJ_LOG(5,(dlg->obj_name, "Session count inc to %d by %.*s",
+	      dlg->sess_count, (int)mod->name.slen, mod->name.ptr));
+
     return PJ_SUCCESS;
 }
@@ -591,9 +600,13 @@
  * Decrement session counter.
  */
-PJ_DEF(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg )
+PJ_DEF(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg,
+					   pjsip_module *mod)
 {
     pj_status_t status;
 
     PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
+
+    PJ_LOG(5,(dlg->obj_name, "Session count dec to %d by %.*s",
+	      dlg->sess_count-1, (int)mod->name.slen, mod->name.ptr));
 
     pj_mutex_lock(dlg->mutex);
@@ -626,4 +639,7 @@
 		     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",
+	      (int)mod->name.slen, mod->name.ptr));
 
     pj_mutex_lock(dlg->mutex);
@@ -795,4 +811,7 @@
 		     PJSIP_ENOTREQUESTMSG);
 
+    PJ_LOG(5,(dlg->obj_name, "Sending %s",
+	      pjsip_tx_data_get_info(tdata)));
+
     /* Update CSeq */
     pj_mutex_lock(dlg->mutex);
@@ -1024,4 +1043,7 @@
     PJ_ASSERT_RETURN(tsx->mod_data[dlg->ua->id] == dlg, PJ_EINVALIDOP);
 
+    PJ_LOG(5,(dlg->obj_name, "Sending %s",
+	      pjsip_tx_data_get_info(tdata)));
+
     /* Check that transaction method and cseq match the response. 
      * This operation is sloooww (search CSeq header twice), that's why
@@ -1078,4 +1100,7 @@
     pjsip_transaction *tsx = NULL;
     unsigned i;
+
+    PJ_LOG(5,(dlg->obj_name, "Received %s",
+	      pjsip_rx_data_get_info(rdata)));
 
     /* Lock the dialog. */
@@ -1144,4 +1169,7 @@
     int res_code;
 
+    PJ_LOG(5,(dlg->obj_name, "Received %s",
+	      pjsip_rx_data_get_info(rdata)));
+
     /* Lock the dialog. */
     pj_mutex_lock(dlg->mutex);
@@ -1250,4 +1278,7 @@
     unsigned i;
 
+    PJ_LOG(5,(dlg->obj_name, "Transaction %s state changed to %s",
+	      tsx->obj_name, pjsip_tsx_state_str(tsx->state)));
+
     /* Lock the dialog. */
     pj_mutex_lock(dlg->mutex);
Index: pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_transaction.c	(revision 174)
+++ pjproject/trunk/pjsip/src/pjsip/sip_transaction.c	(revision 175)
@@ -882,5 +882,5 @@
     if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
 	tsx->transport_flag |= TSX_HAS_PENDING_DESTROY;
-	PJ_LOG(5,(tsx->obj_name, "Will destroy later because transport is "
+	PJ_LOG(4,(tsx->obj_name, "Will destroy later because transport is "
 				 "in progress"));
 	return;
@@ -915,5 +915,5 @@
     PJ_UNUSED_ARG(theap);
 
-    PJ_LOG(6,(tsx->obj_name, "%s timer event", 
+    PJ_LOG(5,(tsx->obj_name, "%s timer event", 
 	     (entry->id==TSX_TIMER_RETRANSMISSION ? "Retransmit":"Timeout")));
 
@@ -1286,4 +1286,6 @@
 {
     struct tsx_lock_data lck;
+
+    PJ_LOG(5,(tsx->obj_name, "Request to terminate transaction"));
 
     PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL);
Index: pjproject/trunk/pjsip/src/pjsip/sip_ua_layer.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_ua_layer.c	(revision 174)
+++ pjproject/trunk/pjsip/src/pjsip/sip_ua_layer.c	(revision 175)
@@ -497,7 +497,13 @@
 	pj_mutex_unlock(mod_ua.mutex);
 
-	/* Respond with 481 . */
-	pjsip_endpt_respond_stateless( mod_ua.endpt, rdata, 481, NULL, NULL,
-				       NULL );
+	if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
+	    PJ_LOG(5,(THIS_FILE, 
+		      "Unable to find dialogset for %s, answering with 481",
+		      pjsip_rx_data_get_info(rdata)));
+
+	    /* Respond with 481 . */
+	    pjsip_endpt_respond_stateless( mod_ua.endpt, rdata, 481, NULL, 
+					   NULL, NULL );
+	}
 	return PJ_TRUE;
     }
@@ -518,6 +524,12 @@
     /* Dialog MUST be found! */
     if (dlg == (pjsip_dialog*)&dlg_set->dlg_list) {
+
 	/* Not found. Mulfunction UAC? */
 	pj_mutex_unlock(mod_ua.mutex);
+
+	PJ_LOG(5,(THIS_FILE, 
+	          "Unable to find dialog for %s, answering with 481",
+		  pjsip_rx_data_get_info(rdata)));
+
 	pjsip_endpt_respond_stateless(mod_ua.endpt, rdata,
 				      PJSIP_SC_CALL_TSX_DOES_NOT_EXIST, 
@@ -662,4 +674,10 @@
 	    ((st_code/100==1 && st_code!=100) || st_code/100==2)) 
 	{
+
+	    PJ_LOG(5,(THIS_FILE, 
+		      "Received forked %s for existing dialog %s",
+		      pjsip_rx_data_get_info(rdata), 
+		      dlg_set->dlg_list.next->obj_name));
+
 	    /* Report to application about forked condition.
 	     * Application can either create a dialog or ignore the response.
Index: pjproject/trunk/pjsip/src/pjsip/sip_util.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_util.c	(revision 174)
+++ pjproject/trunk/pjsip/src/pjsip/sip_util.c	(revision 175)
@@ -357,4 +357,8 @@
     req_msg = rdata->msg_info.msg;
     pj_assert(req_msg->type == PJSIP_REQUEST_MSG);
+
+    /* Request MUST NOT be ACK request! */
+    PJ_ASSERT_RETURN(req_msg->line.req.method.id != PJSIP_ACK_METHOD,
+		     PJ_EINVALIDOP);
 
     /* Create a new transmit buffer. */
Index: pjproject/trunk/pjsip/src/pjsua/pjsua_core.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua/pjsua_core.c	(revision 174)
+++ pjproject/trunk/pjsip/src/pjsua/pjsua_core.c	(revision 175)
@@ -487,5 +487,4 @@
     status = init_sockets();
     if (status != PJ_SUCCESS) {
-	pj_caching_pool_destroy(&pjsua.cp);
 	pjsua_perror("init_sockets() has returned error", status);
 	return status;
@@ -621,5 +620,4 @@
 		pj_thread_destroy(pjsua.threads[i]);
 	    }
-	    pj_caching_pool_destroy(&pjsua.cp);
 	    return status;
 	}
@@ -666,5 +664,7 @@
     pjsua.quit_flag = 1;
 
-    /* Destroy sound framework: */
+    /* Destroy sound framework: 
+     * (this should be done in pjmedia_shutdown())
+     */
     pj_snd_deinit();
 
@@ -673,6 +673,9 @@
     for (i=0; i<pjsua.thread_cnt; ++i) {
 	
-	pj_thread_join(pjsua.threads[i]);
-	pj_thread_destroy(pjsua.threads[i]);
+	if (pjsua.threads[i]) {
+	    pj_thread_join(pjsua.threads[i]);
+	    pj_thread_destroy(pjsua.threads[i]);
+	    pjsua.threads[i] = NULL;
+	}
     }
 
