Index: pjproject/trunk/pjmedia/build/pjmedia.dsp
===================================================================
--- pjproject/trunk/pjmedia/build/pjmedia.dsp	(revision 491)
+++ pjproject/trunk/pjmedia/build/pjmedia.dsp	(revision 492)
@@ -304,4 +304,8 @@
 # Begin Source File
 
+SOURCE=..\include\pjmedia\splitcomb.h
+# End Source File
+# Begin Source File
+
 SOURCE=..\include\pjmedia\stream.h
 # End Source File
Index: pjproject/trunk/pjmedia/include/pjmedia/conference.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia/conference.h	(revision 491)
+++ pjproject/trunk/pjmedia/include/pjmedia/conference.h	(revision 492)
@@ -47,5 +47,7 @@
     pj_bool_t	       *listener;	    /**< Array of listeners.	    */
     unsigned		clock_rate;	    /**< Clock rate of the port.    */
+    unsigned		channel_count;	    /**< Number of channels.	    */
     unsigned		samples_per_frame;  /**< Samples per frame	    */
+    unsigned		bits_per_sample;    /**< Bits per sample.	    */
     int			tx_adj_level;	    /**< Tx level adjustment.	    */
     int			rx_adj_level;	    /**< Rx level adjustment.	    */
@@ -255,4 +257,20 @@
 
 /**
+ * Enumerate occupied ports in the bridge.
+ *
+ * @param conf		The conference bridge.
+ * @param ports		Array of port numbers to be filled in.
+ * @param count		On input, specifies the maximum number of ports
+ *			in the array. On return, it will be filled with
+ *			the actual number of ports.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_enum_ports( pjmedia_conf *conf,
+					      unsigned ports[],
+					      unsigned *count );
+
+
+/**
  * Get port info.
  *
Index: pjproject/trunk/pjmedia/src/pjmedia/conference.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/conference.c	(revision 491)
+++ pjproject/trunk/pjmedia/src/pjmedia/conference.c	(revision 492)
@@ -821,4 +821,27 @@
 }
 
+
+/*
+ * Enum ports.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_enum_ports( pjmedia_conf *conf,
+					     unsigned ports[],
+					     unsigned *p_count )
+{
+    unsigned i, count=0;
+
+    PJ_ASSERT_RETURN(conf && p_count && ports, PJ_EINVAL);
+
+    for (i=0; i<conf->max_ports && count<*p_count; ++i) {
+	if (!conf->ports[i])
+	    continue;
+
+	ports[count++] = i;
+    }
+
+    *p_count = count;
+    return PJ_SUCCESS;
+}
+
 /*
  * Get port info
@@ -844,5 +867,7 @@
     info->listener = conf_port->listeners;
     info->clock_rate = conf_port->clock_rate;
+    info->channel_count = conf->channel_count;
     info->samples_per_frame = conf_port->samples_per_frame;
+    info->bits_per_sample = conf->bits_per_sample;
     info->tx_adj_level = conf_port->tx_adj_level - NORMAL_LEVEL;
     info->rx_adj_level = conf_port->rx_adj_level - NORMAL_LEVEL;
Index: pjproject/trunk/pjsip-apps/src/activex-pjsua/activex-pjsua.idl
===================================================================
--- pjproject/trunk/pjsip-apps/src/activex-pjsua/activex-pjsua.idl	(revision 491)
+++ pjproject/trunk/pjsip-apps/src/activex-pjsua/activex-pjsua.idl	(revision 492)
@@ -30,5 +30,5 @@
 		[id(10), helpstring("method call_has_media")] HRESULT call_has_media([in] int call_index, [out,retval] Pj_Bool *pRet);
 		[id(11), helpstring("method call_get_info")] HRESULT call_get_info([in] int call_index, [out] Pjsua_Call_Info *pInfo, [out,retval] Pj_Status *pRet);
-		[id(12), helpstring("method call_make_call")] HRESULT call_make_call([in] int acc_index, [in,string] Pj_String dst_uri, [out] int *call_index, [out,retval] Pj_Status *pRet);
+		[id(12), helpstring("method call_make_call")] HRESULT call_make_call([in] int acc_id, [in,string] Pj_String dst_uri, [out] int *call_index, [out,retval] Pj_Status *pRet);
 		[id(13), helpstring("method call_answer")] HRESULT call_answer([in] int call_index, [in] int status_code, [out,retval] Pj_Status *pRet);
 		[id(14), helpstring("method call_hangup")] HRESULT call_hangup([in] int call_index, [out,retval] Pj_Status *pRet);
@@ -41,14 +41,14 @@
 		[id(21), helpstring("method call_hangup_all")] HRESULT call_hangup_all();
 		[id(22), helpstring("method acc_get_count")] HRESULT acc_get_count([out,retval] int *pCount);
-		[id(23), helpstring("method acc_get_info")] HRESULT acc_get_info([in] int acc_index, [out] Pjsua_Acc_Info *pInfo, [out,retval] Pj_Status *pRet);
+		[id(23), helpstring("method acc_get_info")] HRESULT acc_get_info([in] int acc_id, [out] Pjsua_Acc_Info *pInfo, [out,retval] Pj_Status *pRet);
 		[id(24), helpstring("method acc_add")] HRESULT acc_add([in] Pjsua_Acc_Config *pConfig, [out] int *pAcc_Index, [out,retval] Pj_Status *pRet);
-		[id(25), helpstring("method acc_set_online_status")] HRESULT acc_set_online_status([in] int acc_index, [in] int is_online, [out,retval] Pj_Status *pRet);
-		[id(26), helpstring("method acc_set_registration")] HRESULT acc_set_registration([in] int acc_index, [in] int reg_active, [out,retval] Pj_Status *pRet);
+		[id(25), helpstring("method acc_set_online_status")] HRESULT acc_set_online_status([in] int acc_id, [in] int is_online, [out,retval] Pj_Status *pRet);
+		[id(26), helpstring("method acc_set_registration")] HRESULT acc_set_registration([in] int acc_id, [in] int reg_active, [out,retval] Pj_Status *pRet);
 		[id(27), helpstring("method buddy_get_count")] HRESULT buddy_get_count([out,retval] int *pCount);
 		[id(28), helpstring("method buddy_get_info")] HRESULT buddy_get_info([in] int buddy_index, [out] Pjsua_Buddy_Info *pInfo, [out,retval] Pj_Status *pRet);
 		[id(29), helpstring("method buddy_add")] HRESULT buddy_add([in,string] Pj_String uri, [out] int *pBuddy_Index, [out,retval] Pj_Status *pRet);
 		[id(30), helpstring("method buddy_subscribe_pres")] HRESULT buddy_subscribe_pres([in] int buddy_index, [in] int subscribe, [out,retval] Pj_Status *pRet);
-		[id(31), helpstring("method im_send_text")] HRESULT im_send_text([in] int acc_index, [in,string] Pj_String dst_uri, [in,string] Pj_String text, [out,retval] Pj_Status *pRet);
-		[id(32), helpstring("method im_typing")] HRESULT im_typing([in] int acc_index, [in,string] Pj_URI dst_uri, [in] int is_typing, [out,retval] Pj_Status *pRet);
+		[id(31), helpstring("method im_send_text")] HRESULT im_send_text([in] int acc_id, [in,string] Pj_String dst_uri, [in,string] Pj_String text, [out,retval] Pj_Status *pRet);
+		[id(32), helpstring("method im_typing")] HRESULT im_typing([in] int acc_id, [in,string] Pj_URI dst_uri, [in] int is_typing, [out,retval] Pj_Status *pRet);
 		[id(33), helpstring("method conf_connect")] HRESULT conf_connect([in] int src_port, [in] int sink_port, [out,retval] Pj_Status *pRet);
 		[id(34), helpstring("method conf_disconnect")] HRESULT conf_disconnect([in] int src_port, [in] int sink_port, [out,retval] Pj_Status *pRet);
@@ -67,4 +67,13 @@
 		[id(47), helpstring("method call_get_textstat")] HRESULT call_get_textstat([in] int call_index, [out,retval] BSTR *textstat);
 		[id(48), helpstring("method app_handle_events")] HRESULT app_handle_events([in] int msec_timeout, [out,retval] int *pEvCount);
+		[id(49), helpstring("method app_parse_uri")] HRESULT app_parse_uri([in] BSTR uriString, [out] Pjsip_Sip_Uri *pSipUri, [out,retval] Pj_Status *pStatus);
+		[id(50), helpstring("method app_print_uri")] HRESULT app_print_uri([in] Pjsip_Sip_Uri *pSipURI, [in] Pjsip_Uri_Context context, [out,retval] BSTR *uriText);
+		[id(51), helpstring("method app_compare_uri_string")] HRESULT app_compare_uri_string([in] Pjsip_Uri_Context context, [in] BSTR uri1, [in] BSTR uri2, [out,retval] Pj_Status *pStatus);
+		[id(52), helpstring("method buddy_del")] HRESULT buddy_del([in] int buddy_index, [out,retval] Pj_Status *pRet);
+		[id(53), helpstring("method acc_del")] HRESULT acc_del([in] int acc_id, [out,retval] Pj_Status *pRet);
+		[id(54), helpstring("method acc_find_for_outgoing")] HRESULT acc_find_for_outgoing([in] BSTR url, [out,retval] int *acc_id);
+		[id(55), helpstring("method acc_enum_id")] HRESULT acc_enum_id([out,retval] SAFEARRAY(int) *accIdArray);
+		[id(56), helpstring("method conf_enum_ports")] HRESULT conf_enum_ports([out,retval] SAFEARRAY(int) *pPortsArray);
+		[id(57), helpstring("method conf_get_port_info")] HRESULT conf_get_port_info([in] int port_id, [out] Pjsua_Conf_Port_Info *pInfo, [out,retval] Pj_Status *pRet);
 	};
 
@@ -85,4 +94,5 @@
 	struct Pjsua_Buddy_Info;
 	struct Pjsua_Acc_Info;
+	struct Pjsua_Conf_Port_Info;
 
 	[
@@ -95,8 +105,9 @@
 	    methods:
 		[id(1), helpstring("method OnCallState")] void OnCallState([in] int call_index, [in] Pjsua_Call_Info *pInfo);
-		[id(2), helpstring("method OnRegState")] void OnRegState([in] int acc_index);
+		[id(2), helpstring("method OnRegState")] void OnRegState([in] int acc_id);
 		[id(3), helpstring("method OnBuddyState")] void OnBuddyState([in] int buddy_index);
 		[id(4), helpstring("method OnIncomingPager")] void OnIncomingPager([in] int call_index, [in] BSTR fromUri, [in] BSTR toURI, [in] BSTR pagerText);
 		[id(5), helpstring("method OnTypingIndication")] void OnTypingIndication([in] int call_index, [in] BSTR fromUri, [in] BSTR toURI, [in] int isTyping);
+		[id(6), helpstring("method OnIncomingCall")] void OnIncomingCall([in] int call_index);
 	};
 
Index: pjproject/trunk/pjsip-apps/src/activex-pjsua/activex-pjsuaCP.h
===================================================================
--- pjproject/trunk/pjsip-apps/src/activex-pjsua/activex-pjsuaCP.h	(revision 491)
+++ pjproject/trunk/pjsip-apps/src/activex-pjsua/activex-pjsuaCP.h	(revision 492)
@@ -3,4 +3,5 @@
 
 //#import "C:\project\pjproject\pjsip-apps\src\activex-pjsua\activex-pjsua.tlb" raw_interfaces_only, raw_native_types, no_namespace, named_guids	//"Import typelib"
+
 template <class T>
 class CProxy_IPjsuaEvents : public IConnectionPointImpl<T, &DIID__IPjsuaEvents, CComDynamicUnkArray>
@@ -148,4 +149,27 @@
 	
 	}
+	VOID Fire_OnIncomingCall(INT call_index)
+	{
+		T* pT = static_cast<T*>(this);
+		int nConnectionIndex;
+		CComVariant* pvars = new CComVariant[1];
+		int nConnections = m_vec.GetSize();
+		
+		for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
+		{
+			pT->Lock();
+			CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
+			pT->Unlock();
+			IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
+			if (pDispatch != NULL)
+			{
+				pvars[0] = call_index;
+				DISPPARAMS disp = { pvars, NULL, 1, 0 };
+				pDispatch->Invoke(0x6, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+			}
+		}
+		delete[] pvars;
+	
+	}
 };
 #endif
Index: pjproject/trunk/pjsip-apps/src/activex-pjsua/app.cpp
===================================================================
--- pjproject/trunk/pjsip-apps/src/activex-pjsua/app.cpp	(revision 491)
+++ pjproject/trunk/pjsip-apps/src/activex-pjsua/app.cpp	(revision 492)
@@ -14,4 +14,8 @@
 { 0x9ce3052a, 0x7a32, 0x4229, { 0xb3, 0x1c, 0x5e, 0x2, 0xe0, 0x66, 0x7a, 0x77 } };
 
+// {7F6CFF0F-C5B3-41e8-B278-61CD584C1F34}
+static const GUID IID_Pjsip_Sip_Uri = 
+{ 0x7f6cff0f, 0xc5b3, 0x41e8, { 0xb2, 0x78, 0x61, 0xcd, 0x58, 0x4c, 0x1f, 0x34 } };
+
 // {3B12B04F-6E48-46a7-B9E0-6C4BF1594A96}
 static const GUID IID_Pjsua_Acc_Config = 
@@ -33,4 +37,9 @@
 static const GUID IID_Pjsua_Acc_Info = 
 { 0x8d345956, 0x10b7, 0x4450, { 0x8a, 0x6, 0xa8, 0xd, 0x2f, 0x31, 0x9e, 0xfd } };
+
+// {0D05907A-3E1F-4c92-9FD0-26CB6E1CC56A}
+static const GUID IID_Pjsua_Conf_Port_Info = 
+{ 0xd05907a, 0x3e1f, 0x4c92, { 0x9f, 0xd0, 0x26, 0xcb, 0x6e, 0x1c, 0xc5, 0x6a } };
+
 
 #define SA_SIZE(lbound,ubound)	(ubound-lbound)
@@ -118,5 +127,5 @@
 	    *count = 0;
 	    for (i=0; i<sa->cbElements; ++i) {
-		BSTR str;
+		BSTR str = NULL;
 		long rg = lbound + i;
 		hr = SafeArrayGetElement(sa, &rg, &str);
@@ -175,4 +184,5 @@
 		Pjsip_Cred_Info cred_info;
 		long rg = lbound + i;
+		pj_memset(&cred_info, 0, sizeof(cred_info));
 		hr = SafeArrayGetElement(c1->cred_info, &rg, &cred_info);
 		if (FAILED(hr))
@@ -245,4 +255,5 @@
     c2->sip_port = c1->sip_port;
     c2->start_rtp_port = c1->rtp_port;
+    c2->msg_logging = c1->msg_logging;
     c2->max_calls = c1->max_calls;
     c2->conf_ports = c1->conf_ports;
@@ -281,4 +292,5 @@
 		Pjsua_Acc_Config acc_config;
 		long rg = lbound + i;
+		pj_memset(&acc_config, 0, sizeof(acc_config));
 		hr = SafeArrayGetElement(c1->acc_config, &rg, &acc_config);
 		if (FAILED(hr))
@@ -312,4 +324,5 @@
     c2->sip_port = c1->sip_port;
     c2->rtp_port = c1->start_rtp_port;
+    c2->msg_logging = c1->msg_logging;
     c2->max_calls = c1->max_calls;
     c2->conf_ports = c1->conf_ports;
@@ -387,6 +400,6 @@
     c2->connect_duration = c1->connect_duration.sec;
     c2->total_duration = c1->total_duration.sec;
-    c2->cause = c1->cause;
-    Cp(c2->cause_text, &c1->cause_text);
+    c2->last_status = c1->last_status;
+    Cp(c2->last_status_text, &c1->last_status_text);
     c2->has_media = c1->has_media;
     c2->conf_slot = c1->conf_slot;
@@ -398,5 +411,5 @@
 
     info2->index = info1->index;
-    Cp(info2->acc_id, &info1->acc_id);
+    Cp(info2->acc_uri, &info1->acc_id);
     info2->has_registration = info1->has_registration;
     info2->expires = info1->expires;
@@ -420,5 +433,4 @@
     Cp(info2->status_text, &info1->status_text);
     info2->monitor = info1->monitor;
-    info2->acc_index = info1->acc_index;
 }
 
@@ -464,5 +476,5 @@
     Pjsua_Call_Info *Call_Info = new Pjsua_Call_Info;
 
-    pjsua_get_call_info(call_index, &call_info);
+    pjsua_call_get_info(call_index, &call_info);
     callinfo2CallInfo(&call_info, Call_Info);
 
@@ -470,7 +482,13 @@
 }
 
-static void on_reg_state(int acc_index)
-{
-    CApp_Instance->Fire_OnRegState(acc_index);
+static void on_incoming_call(int acc_id, int call_index,
+			     pjsip_rx_data *rdata)
+{
+    CApp_Instance->Fire_OnIncomingCall(call_index);
+}
+
+static void on_reg_state(int acc_id)
+{
+    CApp_Instance->Fire_OnRegState(acc_id);
 }
 
@@ -513,4 +531,5 @@
     pj_memset(&cb, 0, sizeof(cb));
     cb.on_call_state = &on_call_state;
+    cb.on_incoming_call = &on_incoming_call;
     cb.on_reg_state = &on_reg_state;
     cb.on_buddy_state = &on_buddy_state;
@@ -540,5 +559,5 @@
 STDMETHODIMP CApp::call_get_max_count(int *retCount)
 {
-    *retCount = pjsua_get_max_calls();
+    *retCount = pjsua_call_get_max_count();
     return S_OK;
 }
@@ -546,5 +565,5 @@
 STDMETHODIMP CApp::call_get_count(int *retCount)
 {
-    *retCount = pjsua_get_call_count();
+    *retCount = pjsua_call_get_count();
     return S_OK;
 }
@@ -565,15 +584,15 @@
 {
     pjsua_call_info info;
-    *pRet = pjsua_get_call_info(call_index, &info);
+    *pRet = pjsua_call_get_info(call_index, &info);
     callinfo2CallInfo(&info, pInfo);
     return S_OK;
 }
 
-STDMETHODIMP CApp::call_make_call(int acc_index, Pj_String dst_uri, int *call_index, Pj_Status *pRet)
+STDMETHODIMP CApp::call_make_call(int acc_id, Pj_String dst_uri, int *call_index, Pj_Status *pRet)
 {
     Temp_Pool tp;
     pj_str_t tmp = Pj_str(tp.get_pool(), dst_uri);
 
-    *pRet = pjsua_make_call(acc_index, &tmp, call_index);
+    *pRet = pjsua_call_make_call(acc_id, &tmp, call_index);
     return S_OK;
 }
@@ -581,6 +600,5 @@
 STDMETHODIMP CApp::call_answer(int call_index, int status_code, Pj_Status *pRet)
 {
-    pjsua_call_answer(call_index, status_code);
-    *pRet = PJ_SUCCESS;
+    *pRet = pjsua_call_answer(call_index, status_code);
     return S_OK;
 }
@@ -602,6 +620,5 @@
 STDMETHODIMP CApp::call_release_hold(int call_index, Pj_Status *pRet)
 {
-    pjsua_call_reinvite(call_index);
-    *pRet = PJ_SUCCESS;
+    *pRet = pjsua_call_reinvite(call_index);
     return S_OK;
 }
@@ -611,6 +628,5 @@
     Temp_Pool tp;
     pj_str_t tmp = Pj_str(tp.get_pool(), dst_uri);
-    pjsua_call_xfer(call_index, &tmp);
-    *pRet = PJ_SUCCESS;
+    *pRet = pjsua_call_xfer(call_index, &tmp);
     return S_OK;
 }
@@ -628,6 +644,5 @@
     Temp_Pool tp;
     pj_str_t tmp = Pj_str(tp.get_pool(), text);
-    pjsua_call_send_im(call_index, &tmp);
-    *pRet = PJ_SUCCESS;
+    *pRet = pjsua_call_send_im(call_index, &tmp);
     return S_OK;
 }
@@ -635,6 +650,5 @@
 STDMETHODIMP CApp::call_typing(int call_index, int is_typing, Pj_Status *pRet)
 {
-    pjsua_call_typing(call_index, is_typing);
-    *pRet = PJ_SUCCESS;
+    *pRet = pjsua_call_send_typing_ind(call_index, is_typing);
     return S_OK;
 }
@@ -649,5 +663,5 @@
 {
     char buf[1024];
-    pjsua_dump_call(call_index, 1, buf, sizeof(buf), "");
+    pjsua_call_dump(call_index, 1, buf, sizeof(buf), "");
 
     OLECHAR wbuf[1024];
@@ -664,8 +678,8 @@
 }
 
-STDMETHODIMP CApp::acc_get_info(int acc_index, Pjsua_Acc_Info *pInfo, Pj_Status *pRet)
+STDMETHODIMP CApp::acc_get_info(int acc_id, Pjsua_Acc_Info *pInfo, Pj_Status *pRet)
 {
     pjsua_acc_info info;
-    *pRet = pjsua_acc_get_info(acc_index, &info);
+    *pRet = pjsua_acc_get_info(acc_id, &info);
     accinfo2AccInfo(&info, pInfo);
     return S_OK;
@@ -681,13 +695,13 @@
 }
 
-STDMETHODIMP CApp::acc_set_online_status(int acc_index, int is_online, Pj_Status *pRet)
-{
-    *pRet = pjsua_acc_set_online_status(acc_index, is_online);
-    return S_OK;
-}
-
-STDMETHODIMP CApp::acc_set_registration(int acc_index, int reg_active, Pj_Status *pRet)
-{
-    *pRet = pjsua_acc_set_registration(acc_index, reg_active);
+STDMETHODIMP CApp::acc_set_online_status(int acc_id, int is_online, Pj_Status *pRet)
+{
+    *pRet = pjsua_acc_set_online_status(acc_id, is_online);
+    return S_OK;
+}
+
+STDMETHODIMP CApp::acc_set_registration(int acc_id, int reg_active, Pj_Status *pRet)
+{
+    *pRet = pjsua_acc_set_registration(acc_id, reg_active);
     return S_OK;
 }
@@ -718,22 +732,21 @@
 {
     *pRet = pjsua_buddy_subscribe_pres(buddy_index, subscribe);
-    pjsua_pres_refresh();
-    return S_OK;
-}
-
-STDMETHODIMP CApp::im_send_text(int acc_index, Pj_String dst_uri, Pj_String text, Pj_Status *pRet)
+    return S_OK;
+}
+
+STDMETHODIMP CApp::im_send_text(int acc_id, Pj_String dst_uri, Pj_String text, Pj_Status *pRet)
 {
     Temp_Pool tp;
     pj_str_t tmp_uri = Pj_str(tp.get_pool(), dst_uri);
     pj_str_t tmp_text = Pj_str(tp.get_pool(), text);
-    *pRet = pjsua_im_send(acc_index, &tmp_uri, &tmp_text);
-    return S_OK;
-}
-
-STDMETHODIMP CApp::im_typing(int acc_index, Pj_URI dst_uri, int is_typing, Pj_Status *pRet)
+    *pRet = pjsua_im_send(acc_id, &tmp_uri, &tmp_text);
+    return S_OK;
+}
+
+STDMETHODIMP CApp::im_typing(int acc_id, Pj_URI dst_uri, int is_typing, Pj_Status *pRet)
 {
     Temp_Pool tp;
     pj_str_t tmp_uri = Pj_str(tp.get_pool(), dst_uri);
-    *pRet = pjsua_im_typing(acc_index, &tmp_uri, is_typing);
+    *pRet = pjsua_im_typing(acc_id, &tmp_uri, is_typing);
     return S_OK;
 }
@@ -803,5 +816,5 @@
     pj_str_t tmp = Pj_str(tp.get_pool(), filename);
     pjsua_default_config(&config);
-    *pRet = pjsua_load_settings(tmp.ptr, &config);
+    *pRet = pjsua_load_settings(tmp.ptr, &config, NULL);
     if (*pRet == PJ_SUCCESS)
 	*pRet = config2Config(&config, pConfig);
@@ -826,7 +839,9 @@
 STDMETHODIMP CApp::app_get_current_config(Pjsua_Config *pConfig)
 {
-    pjsua_config *config;
-    config = (pjsua_config*) pjsua_get_config();
-    return config2Config(config, pConfig);
+    Temp_Pool tp;
+    pjsua_config config;
+
+    pjsua_get_config(tp.get_pool(), &config);
+    return config2Config(&config, pConfig);
 }
 
@@ -857,2 +872,194 @@
     return S_OK;
 }
+
+STDMETHODIMP CApp::app_parse_uri(BSTR uriString, Pjsip_Sip_Uri *pSipUri, Pj_Status *pStatus)
+{
+    Temp_Pool tp;
+    pj_str_t tmp = Pj_str(tp.get_pool(), uriString);
+    pjsip_name_addr *addr;
+    char buf[1024];
+    pj_str_t s;
+
+    addr = (pjsip_name_addr*)
+	pjsip_parse_uri(tp.get_pool(), tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+    if (addr == NULL) {
+	*pStatus = PJSIP_EINVALIDURI;
+	return S_OK;
+    }
+
+    if (!PJSIP_URI_SCHEME_IS_SIP(addr) && !PJSIP_URI_SCHEME_IS_SIPS(addr)) {
+	*pStatus = PJSIP_EINVALIDSCHEME;
+	return S_OK;
+    }
+
+    pjsip_sip_uri *sip = (pjsip_sip_uri*)addr->uri;
+
+    Cp2(&pSipUri->display, &addr->display);
+    Cp2(&pSipUri->user, &sip->user);
+    Cp2(&pSipUri->passwd, &sip->passwd);
+    Cp2(&pSipUri->host, &sip->host);
+    pSipUri->port = sip->port;
+    Cp2(&pSipUri->param_user, &sip->user_param);
+    Cp2(&pSipUri->param_method, &sip->method_param);
+    Cp2(&pSipUri->param_transport, &sip->transport_param);
+    pSipUri->param_ttl = sip->ttl_param;
+    pSipUri->param_lr = sip->lr_param;
+    Cp2(&pSipUri->param_maddr, &sip->maddr_param);
+
+    s.ptr = buf;
+    s.slen = pjsip_param_print_on(&sip->other_param, buf, sizeof(buf), 
+				  &pjsip_PARAM_CHAR_SPEC, &pjsip_PARAM_CHAR_SPEC, ';');
+    Cp2(&pSipUri->param_other, &s);
+
+    s.slen = pjsip_param_print_on(&sip->header_param, buf, sizeof(buf), 
+				  &pjsip_HDR_CHAR_SPEC, &pjsip_HDR_CHAR_SPEC, '?');
+    Cp2(&pSipUri->param_header, &s);
+
+    *pStatus = PJ_SUCCESS;
+    return S_OK;
+}
+
+STDMETHODIMP CApp::app_print_uri(Pjsip_Sip_Uri *pSipURI, Pjsip_Uri_Context context, BSTR *uriText)
+{
+    Temp_Pool tp;
+    pjsip_name_addr *addr;
+    pj_str_t tmp;
+    char buf[1024];
+    pjsip_sip_uri *sip;
+
+    addr = pjsip_name_addr_create(tp.get_pool());
+    sip = pjsip_sip_uri_create(tp.get_pool(), PJ_FALSE);
+    addr->uri = (pjsip_uri*)sip;
+
+    addr->display = Pj_str(tp.get_pool(), pSipURI->display);
+    sip->user = Pj_str(tp.get_pool(), pSipURI->user);
+    sip->passwd = Pj_str(tp.get_pool(), pSipURI->passwd);
+    sip->host = Pj_str(tp.get_pool(), pSipURI->host);
+    sip->port = pSipURI->port;
+    sip->user_param = Pj_str(tp.get_pool(), pSipURI->param_user);
+    sip->method_param = Pj_str(tp.get_pool(), pSipURI->param_method);
+    sip->transport_param = Pj_str(tp.get_pool(), pSipURI->param_transport);
+    sip->ttl_param = pSipURI->param_ttl;
+    sip->lr_param = pSipURI->param_lr;
+    sip->maddr_param = Pj_str(tp.get_pool(), pSipURI->param_maddr);
+    
+    /* Unfortunately can't transport params yet (no parsing function) */
+
+    tmp.ptr = buf;
+    tmp.slen = pjsip_uri_print((pjsip_uri_context_e)context, addr, buf, sizeof(buf));
+
+    Cp2(uriText, &tmp);
+    return S_OK;
+}
+
+STDMETHODIMP CApp::app_compare_uri_string(Pjsip_Uri_Context context, BSTR uri1, BSTR uri2, Pj_Status *pStatus)
+{
+    Temp_Pool tp;
+
+    pj_str_t tmp_uri1 = Pj_str(tp.get_pool(), uri1);
+    pj_str_t tmp_uri2 = Pj_str(tp.get_pool(), uri2);
+
+    pjsip_uri *u1, *u2;
+
+    u1 = pjsip_parse_uri(tp.get_pool(), tmp_uri1.ptr, tmp_uri1.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+    if (u1 == NULL) {
+	*pStatus = PJSIP_EINVALIDURI;
+	return S_OK;
+    }
+
+    u2 = pjsip_parse_uri(tp.get_pool(), tmp_uri2.ptr, tmp_uri2.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+    if (u2 == NULL) {
+	*pStatus = PJSIP_EINVALIDURI;
+	return S_OK;
+    }
+    
+    *pStatus = pjsip_uri_cmp((pjsip_uri_context_e)context, u1, u2);
+    return S_OK;
+}
+
+STDMETHODIMP CApp::buddy_del(int buddy_index, Pj_Status *pRet)
+{
+    *pRet = pjsua_buddy_del(buddy_index);
+    return S_OK;
+}
+
+STDMETHODIMP CApp::acc_del(int acc_id, Pj_Status *pRet)
+{
+    *pRet = pjsua_acc_del(acc_id);
+    return S_OK;
+}
+
+STDMETHODIMP CApp::acc_find_for_outgoing(BSTR url, int *acc_id)
+{
+    Temp_Pool tp;
+
+    pj_str_t tmp_uri = Pj_str(tp.get_pool(), url);
+
+    *acc_id = pjsua_acc_find_for_outgoing(&tmp_uri);
+
+    return S_OK;
+}
+
+STDMETHODIMP CApp::acc_enum_id(SAFEARRAY **accIdArray)
+{
+    int id[32];
+    unsigned count = PJ_ARRAY_SIZE(id);
+    unsigned i;
+
+    pjsua_acc_enum_id(id, &count);
+
+    *accIdArray = SafeArrayCreateVector(VT_INT, 0, count);
+
+    for (i=0; i<count; ++i) {
+	long rg = i;
+	SafeArrayPutElement(*accIdArray, &rg, &id[i]);
+    }
+
+    return S_OK;
+}
+
+STDMETHODIMP CApp::conf_enum_ports(SAFEARRAY **pPortsArray)
+{
+    int id[128];
+    unsigned count = PJ_ARRAY_SIZE(id);
+    unsigned i;
+
+    pjsua_conf_enum_port_ids(id, &count);
+
+    *pPortsArray = SafeArrayCreateVector(VT_INT, 0, count);
+
+    for (i=0; i<count; ++i) {
+	long rg = i;
+	SafeArrayPutElement(*pPortsArray, &rg, &id[i]);
+    }
+
+    return S_OK;
+}
+
+STDMETHODIMP CApp::conf_get_port_info(int port_id, Pjsua_Conf_Port_Info *pInfo, Pj_Status *pRet)
+{
+    unsigned i;
+    pjsua_conf_port_info info;
+
+    *pRet = pjsua_conf_get_port_info(port_id, &info);
+    if (*pRet != PJ_SUCCESS)
+	return S_OK;
+
+    pInfo->slot_id = info.slot_id;
+    Cp2(&pInfo->name, &info.name);
+    pInfo->clock_rate = info.clock_rate;
+    pInfo->channel_count = info.channel_count;
+    pInfo->samples_per_frame = info.samples_per_frame;
+    pInfo->bits_per_sample = info.bits_per_sample;
+    
+
+    pInfo->listeners = SafeArrayCreateVector(VT_INT, 0, info.listener_cnt);
+
+    for (i=0; i<info.listener_cnt; ++i) {
+	long rg = i;
+	SafeArrayPutElement(pInfo->listeners, &rg, &info.listeners[i]);
+    }
+
+    return S_OK;
+}
+
Index: pjproject/trunk/pjsip-apps/src/activex-pjsua/app.h
===================================================================
--- pjproject/trunk/pjsip-apps/src/activex-pjsua/app.h	(revision 491)
+++ pjproject/trunk/pjsip-apps/src/activex-pjsua/app.h	(revision 492)
@@ -5,5 +5,5 @@
 
 #include "resource.h"       // main symbols
-#include "..\activex-pjsua\activex-pjsuaCP.h"
+#include "activex-pjsuaCP.h"
 
 
@@ -38,4 +38,13 @@
 // IApp
 public:
+	STDMETHOD(app_destroy)(/*[out,retval]*/ Pj_Status *retStatus);
+	STDMETHOD(app_start)(/*[out,retval]*/ Pj_Status *retStatus);
+	STDMETHOD(app_init)(/*[in]*/ Pjsua_Config *pConfig, /*[out,retval]*/ Pj_Status *pStatus);
+	STDMETHOD(app_test_config)(/*[in]*/ Pjsua_Config *pConfig, /*[out,retval,string]*/ BSTR *retmsg);
+	STDMETHOD(app_default_config)(/*[in,out]*/ Pjsua_Config *pConfig);
+	STDMETHOD(app_create)(/*[out,retval]*/ Pj_Status *ret);
+	STDMETHOD(app_compare_uri_string)(/*[in]*/ Pjsip_Uri_Context context, /*[in]*/ BSTR uri1, /*[in]*/ BSTR uri2, /*[out,retval]*/ Pj_Status *pStatus);
+	STDMETHOD(app_print_uri)(/*[in]*/ Pjsip_Sip_Uri *pSipURI, Pjsip_Uri_Context context, /*[out,retval]*/ BSTR *uriText);
+	STDMETHOD(app_parse_uri)(/*[in]*/ BSTR uriString, /*[out]*/ Pjsip_Sip_Uri *pSipUri, /*[out,retval]*/ Pj_Status *pStatus);
 	STDMETHOD(app_handle_events)(/*[in]*/ int msec_timeout, /*[out,retval]*/ int *pEvCount);
 	STDMETHOD(app_verify_sip_url)(/*[in,string]*/ Pj_String uri, /*[out,retval]*/ Pj_Status *pRet);
@@ -53,4 +62,6 @@
 	STDMETHOD(conf_disconnect)(/*[in]*/ int src_port, /*[in]*/ int sink_port, /*[out,retval]*/ Pj_Status *pRet);
 	STDMETHOD(conf_connect)(/*[in]*/ int src_port, /*[in]*/ int sink_port, /*[out,retval]*/ Pj_Status *pRet);
+	STDMETHOD(conf_enum_ports)(SAFEARRAY **pPortsArray);
+	STDMETHOD(conf_get_port_info)(int port_id, Pjsua_Conf_Port_Info *pInfo, Pj_Status *pRet);
 	STDMETHOD(im_typing)(/*[in]*/ int acc_index, /*[in,string]*/ Pj_URI dst_uri, /*[in]*/ int is_typing, /*[out,retval]*/ Pj_Status *pRet);
 	STDMETHOD(im_send_text)(/*[in]*/ int acc_index, /*[in,string]*/ Pj_String dst_uri, /*[in,string]*/ Pj_String text, /*[out,retval]*/ Pj_Status *pRet);
@@ -59,9 +70,13 @@
 	STDMETHOD(buddy_get_info)(/*[in]*/ int buddy_index, /*[out]*/ Pjsua_Buddy_Info *pInfo, /*[out,retval]*/ Pj_Status *pRet);
 	STDMETHOD(buddy_get_count)(/*[out,retval]*/ int *pCount);
+	STDMETHOD(buddy_del)(/*[in]*/ int buddy_index, /*[out,retval]*/ Pj_Status *pRet);
 	STDMETHOD(acc_set_registration)(/*[in]*/ int acc_index, /*[in]*/ int reg_active, /*[out,retval]*/ Pj_Status *pRet);
 	STDMETHOD(acc_set_online_status)(/*[in]*/ int acc_index, /*[in]*/ int is_online, /*[out,retval]*/ Pj_Status *pRet);
 	STDMETHOD(acc_add)(/*[in]*/ Pjsua_Acc_Config *pConfig, /*[out]*/ int *pAcc_Index, /*[out,retval]*/ Pj_Status *pRet);
+	STDMETHOD(acc_del)(/*[out,retval]*/ int acc_index, Pj_Status *pRet);
 	STDMETHOD(acc_get_info)(/*[in]*/ int acc_index, /*[out]*/ Pjsua_Acc_Info *pInfo, /*[out,retval]*/ Pj_Status *pRet);
 	STDMETHOD(acc_get_count)(/*[out,retval]*/ int *pCount);
+	STDMETHOD(acc_enum_id)(SAFEARRAY **accIdArray);
+	STDMETHOD(acc_find_for_outgoing)(/*[in]*/ BSTR url, /*[out,retval]*/ int *acc_index);
 	STDMETHOD(call_hangup_all)();
 	STDMETHOD(call_typing)(/*[in]*/ int call_index, /*[in]*/ int is_typing, /*[out,retval]*/ Pj_Status *pRet);
@@ -79,10 +94,4 @@
 	STDMETHOD(call_get_count)(/*[out,retval]*/ int *retCount);
 	STDMETHOD(call_get_max_count)(/*[out,retval]*/ int *retCount);
-	STDMETHOD(app_destroy)(/*[out,retval]*/ Pj_Status *retStatus);
-	STDMETHOD(app_start)(/*[out,retval]*/ Pj_Status *retStatus);
-	STDMETHOD(app_init)(/*[in]*/ Pjsua_Config *pConfig, /*[out,retval]*/ Pj_Status *pStatus);
-	STDMETHOD(app_test_config)(/*[in]*/ Pjsua_Config *pConfig, /*[out,retval,string]*/ BSTR *retmsg);
-	STDMETHOD(app_default_config)(/*[in,out]*/ Pjsua_Config *pConfig);
-	STDMETHOD(app_create)(/*[out,retval]*/ Pj_Status *ret);
 	STDMETHOD(call_get_textstat)(/* [in] */ int call_index,    /* [retval][out] */ BSTR *textstat);
 
Index: pjproject/trunk/pjsip-apps/src/activex-pjsua/pjsua-structs.idl
===================================================================
--- pjproject/trunk/pjsip-apps/src/activex-pjsua/pjsua-structs.idl	(revision 491)
+++ pjproject/trunk/pjsip-apps/src/activex-pjsua/pjsua-structs.idl	(revision 492)
@@ -21,4 +21,37 @@
     Pj_String	data;
 } Pjsip_Cred_Info;
+
+
+[
+    uuid(7F6CFF0F-C5B3-41e8-B278-61CD584C1F34),
+    version(1.0),
+    helpstring("PJSIP SIP URI"),
+]
+typedef struct Pjsip_Sip_Uri
+{
+    Pj_String   display;
+    Pj_String	user;
+    Pj_String	passwd;
+    Pj_String	host;
+    int		port;
+    Pj_String	param_user;
+    Pj_String	param_method;
+    Pj_String	param_transport;
+    int		param_ttl;
+    int		param_lr;
+    Pj_String	param_maddr;
+    Pj_String	param_other;
+    Pj_String	param_header;
+} Pjsip_Sip_Uri;
+
+
+typedef enum Pjsip_Uri_Context
+{
+    PJSIPX_URI_IN_REQ_URI,
+    PJSIPX_URI_IN_FROMTO_HDR,
+    PJSIPX_URI_IN_CONTACT_HDR,
+    PJSIPX_URI_IN_ROUTING_HDR,
+    PJSIPX_URI_IN_OTHER
+} Pjsip_Uri_Context;
 
 
@@ -45,31 +78,32 @@
 typedef struct Pjsua_Config
 {
-    unsigned int		udp_port;
-    Pj_String			sip_host;
-    unsigned int		sip_port;
-    unsigned int		rtp_port;
-    unsigned int		max_calls;
-    unsigned int		conf_ports;
-    unsigned int		thread_cnt;
-    Pj_String			stun_srv1;
-    unsigned int		stun_port1;
-    Pj_String			stun_srv2;
-    unsigned int		stun_port2;
-    unsigned int		snd_player_id;
-    unsigned int		snd_capture_id;
-    unsigned int		clock_rate;
-    Pj_Bool			null_audio;
-    unsigned int		quality;
-    unsigned int		complexity;
-    SAFEARRAY(Pj_String)	codec_arg;
-    unsigned int		auto_answer;
-    unsigned int		uas_refresh;
-    Pj_String			outbound_proxy;
+    int			    udp_port;
+    Pj_String		    sip_host;
+    int			    sip_port;
+    int			    rtp_port;
+    int			    msg_logging;
+    int			    max_calls;
+    int			    conf_ports;
+    int			    thread_cnt;
+    Pj_String		    stun_srv1;
+    int			    stun_port1;
+    Pj_String		    stun_srv2;
+    int			    stun_port2;
+    int			    snd_player_id;
+    int			    snd_capture_id;
+    int			    clock_rate;
+    Pj_Bool		    null_audio;
+    int			    quality;
+    int			    complexity;
+    SAFEARRAY(Pj_String)    codec_arg;
+    int			    auto_answer;
+    int			    uas_refresh;
+    Pj_String		    outbound_proxy;
     SAFEARRAY(Pjsua_Acc_Config) acc_config;
-    unsigned int		log_level;
-    unsigned int		app_log_level;
-    unsigned long		log_decor;
-    Pj_String			log_filename;
-    SAFEARRAY(Pj_String)	buddy_uri;
+    int			    log_level;
+    int			    app_log_level;
+    long		    log_decor;
+    Pj_String		    log_filename;
+    SAFEARRAY(Pj_String)    buddy_uri;
 } Pjsua_Config;
 
@@ -94,5 +128,5 @@
 typedef struct Pjsua_Call_Info
 {
-    unsigned int	index;
+    int			index;
     Pj_Bool		active;
     Pj_Bool		is_uac;
@@ -101,10 +135,10 @@
     Pjsua_Call_State	state;
     Pj_String		state_text;
-    unsigned int	connect_duration;
-    unsigned int	total_duration;
-    unsigned int	cause;
-    Pj_String		cause_text;
+    int			connect_duration;
+    int			total_duration;
+    int			last_status;
+    Pj_String		last_status_text;
     Pj_Bool		has_media;
-    unsigned int	conf_slot;
+    int			conf_slot;
 } Pjsua_Call_Info;
 
@@ -125,15 +159,14 @@
 typedef struct Pjsua_Buddy_Info
 {
-    unsigned int	index;
+    int	index;
     Pj_Bool		is_valid;
     Pj_String		name;
     Pj_String		display;
     Pj_String		host;
-    unsigned int  	port;
+    int  		port;
     Pj_URI		uri;
     Pjsua_Buddy_State	status;
     Pj_String		status_text;
     Pj_Bool		monitor;
-    int			acc_index;
 } Pjsua_Buddy_Info;
 
@@ -146,11 +179,29 @@
 typedef struct Pjsua_Acc_Info
 {
-    unsigned int	index;
-    Pj_URI		acc_id;
+    int			index;
+    Pj_URI		acc_uri;
     Pj_Bool		has_registration;
     int			expires;
-    unsigned int	status_code;
+    int			status_code;
     Pj_String		status_text;
     Pj_Bool		online_status;
 } Pjsua_Acc_Info;
 
+
+
+[
+    uuid(0D05907A-3E1F-4c92-9FD0-26CB6E1CC56A),
+    version(1.0),
+    helpstring("PJSUA Conference Port Information"),
+]
+typedef struct Pjsua_Conf_Port_Info
+{
+    int			slot_id;
+    Pj_String		name;
+    int			clock_rate;
+    int			channel_count;
+    int			samples_per_frame;
+    int			bits_per_sample;
+    SAFEARRAY(int)	listeners;
+} Pjsua_Conf_Port_Info;
+
Index: pjproject/trunk/pjsip-apps/src/pjsua/main.c
===================================================================
--- pjproject/trunk/pjsip-apps/src/pjsua/main.c	(revision 491)
+++ pjproject/trunk/pjsip-apps/src/pjsua/main.c	(revision 492)
@@ -29,4 +29,5 @@
 {
     pjsua_config cfg;
+    pj_str_t uri_to_call = { NULL, 0 };
 
     /* Init default settings. */
@@ -39,5 +40,5 @@
 
     /* Parse command line arguments: */
-    if (pjsua_parse_args(argc, argv, &cfg) != PJ_SUCCESS)
+    if (pjsua_parse_args(argc, argv, &cfg, &uri_to_call) != PJ_SUCCESS)
 	return 1;
 
@@ -46,10 +47,4 @@
     if (pjsua_init(&cfg, &console_callback) != PJ_SUCCESS)
 	return 1;
-
-    /* Register message logger to print incoming and outgoing
-     * messages.
-     */
-    pjsip_endpt_register_module(pjsua_get_pjsip_endpt(),
-				&pjsua_console_app_msg_logger);
 
 
@@ -66,5 +61,5 @@
 
     /* Start UI console main loop: */
-    pjsua_console_app_main();
+    pjsua_console_app_main(&uri_to_call);
 
 
Index: pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 491)
+++ pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 492)
@@ -69,4 +69,11 @@
 
 
+typedef int pjsua_acc_id;
+typedef int pjsua_buddy_id;
+typedef int pjsua_player_id;
+typedef int pjsua_recorder_id;
+typedef int pjsua_conf_port_id;
+
+
 /**
  * Account configuration.
@@ -136,4 +143,9 @@
     unsigned	start_rtp_port;
 
+    /**
+     * Enable incoming and outgoing message logging (default: 1).
+     */
+    pj_bool_t	msg_logging;
+
     /** Maximum calls to support (default: 4) */
     unsigned	max_calls;
@@ -223,7 +235,4 @@
     /** Outbound proxy (default: none) */
     pj_str_t	outbound_proxy;
-
-    /** URI to call.			*/
-    pj_str_t	uri_to_call;
 
     /** Number of SIP accounts */
@@ -273,4 +282,10 @@
 
     /**
+     * Notify application on incoming call.
+     */
+    void (*on_incoming_call)(pjsua_acc_id acc_id, int call_index,
+			     pjsip_rx_data *rdata);
+
+    /**
      * Notify application on call being transfered.
      * Application can decide to accept/reject transfer request
@@ -288,5 +303,5 @@
      * registration details.
      */
-    void (*on_reg_state)(int acc_index);
+    void (*on_reg_state)(pjsua_acc_id acc_id);
 
     /**
@@ -294,5 +309,5 @@
      * Application may then query the buddy into to get the details.
      */
-    void (*on_buddy_state)(int buddy_index);
+    void (*on_buddy_state)(pjsua_buddy_id buddy_id);
 
     /**
@@ -330,10 +345,10 @@
     pjsip_inv_state	state;
     pj_str_t		state_text;
+    pjsip_status_code	last_status;
+    pj_str_t		last_status_text;
     pj_time_val		connect_duration;
     pj_time_val		total_duration;
-    pjsip_status_code	cause;
-    pj_str_t		cause_text;
     pj_bool_t		has_media;
-    unsigned		conf_slot;
+    pjsua_conf_port_id	conf_slot;
 };
 
@@ -356,5 +371,5 @@
 struct pjsua_buddy_info
 {
-    unsigned		index;
+    pjsua_buddy_id	index;
     pj_bool_t		is_valid;
     pj_str_t		name;
@@ -366,5 +381,4 @@
     pj_str_t		status_text;
     pj_bool_t		monitor;
-    int			acc_index;
 };
 
@@ -377,5 +391,5 @@
 struct pjsua_acc_info
 {
-    unsigned		index;
+    pjsua_acc_id	index;
     pj_str_t		acc_id;
     pj_bool_t		has_registration;
@@ -390,7 +404,21 @@
 
 
-typedef int pjsua_player_id;
-typedef int pjsua_recorder_id;
-
+/**
+ * Conference port info.
+ */
+struct pjsua_conf_port_info
+{
+    pjsua_conf_port_id	slot_id;
+    pj_str_t		name;
+    unsigned		clock_rate;
+    unsigned		channel_count;
+    unsigned		samples_per_frame;
+    unsigned		bits_per_sample;
+    unsigned		listener_cnt;
+    pjsua_conf_port_id	listeners[256];
+};
+
+
+typedef struct pjsua_conf_port_info pjsua_conf_port_info;
 
 
@@ -479,10 +507,10 @@
  * Get maximum number of calls configured in pjsua.
  */
-PJ_DECL(unsigned) pjsua_get_max_calls(void);
+PJ_DECL(unsigned) pjsua_call_get_max_count(void);
 
 /**
  * Get current number of active calls.
  */
-PJ_DECL(unsigned) pjsua_get_call_count(void);
+PJ_DECL(unsigned) pjsua_call_get_count(void);
 
 /**
@@ -502,5 +530,5 @@
  * Get call info.
  */
-PJ_DECL(pj_status_t) pjsua_get_call_info(unsigned call_index,
+PJ_DECL(pj_status_t) pjsua_call_get_info(unsigned call_index,
 					 pjsua_call_info *info);
 
@@ -509,5 +537,5 @@
  * Duplicate call info.
  */
-PJ_DECL(void) pjsua_dup_call_info(pj_pool_t *pool,
+PJ_DECL(void) pjsua_call_info_dup(pj_pool_t *pool,
 				  pjsua_call_info *dst_info,
 				  const pjsua_call_info *src_info);
@@ -517,7 +545,7 @@
  * Make outgoing call.
  */
-PJ_DECL(pj_status_t) pjsua_make_call(unsigned acc_index,
-				     const pj_str_t *dst_uri,
-				     int *p_call_index);
+PJ_DECL(pj_status_t) pjsua_call_make_call(unsigned acc_id,
+					  const pj_str_t *dst_uri,
+					  int *p_call_index);
 
 
@@ -525,5 +553,5 @@
  * Answer call.
  */
-PJ_DECL(void) pjsua_call_answer(int call_index, int code);
+PJ_DECL(pj_status_t) pjsua_call_answer(int call_index, int code);
 
 /**
@@ -536,5 +564,5 @@
  * Put call on-hold.
  */
-PJ_DECL(void) pjsua_call_set_hold(int call_index);
+PJ_DECL(pj_status_t) pjsua_call_set_hold(int call_index);
 
 
@@ -542,5 +570,5 @@
  * Send re-INVITE (to release hold).
  */
-PJ_DECL(void) pjsua_call_reinvite(int call_index);
+PJ_DECL(pj_status_t) pjsua_call_reinvite(int call_index);
 
 
@@ -548,5 +576,5 @@
  * Transfer call.
  */
-PJ_DECL(void) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest);
+PJ_DECL(pj_status_t) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest);
 
 /**
@@ -560,5 +588,5 @@
  * Send instant messaging inside INVITE session.
  */
-PJ_DECL(void) pjsua_call_send_im(int call_index, const pj_str_t *text);
+PJ_DECL(pj_status_t) pjsua_call_send_im(int call_index, const pj_str_t *text);
 
 
@@ -566,5 +594,6 @@
  * Send IM typing indication inside INVITE session.
  */
-PJ_DECL(void) pjsua_call_typing(int call_index, pj_bool_t is_typing);
+PJ_DECL(pj_status_t) pjsua_call_send_typing_ind(int call_index, 
+						pj_bool_t is_typing);
 
 /**
@@ -577,5 +606,5 @@
  * Dump call and media statistics to string.
  */
-PJ_DECL(void) pjsua_dump_call(int call_index, int with_media, 
+PJ_DECL(void) pjsua_call_dump(int call_index, int with_media, 
 			      char *buffer, unsigned maxlen,
 			      const char *indent);
@@ -595,6 +624,31 @@
  * Get account info.
  */
-PJ_DECL(pj_status_t) pjsua_acc_get_info(unsigned acc_index,
+PJ_DECL(pj_status_t) pjsua_acc_get_info(pjsua_acc_id acc_id,
 					pjsua_acc_info *info);
+
+
+/**
+ * Enum accounts id.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_enum_id( pjsua_acc_id ids[],
+				        unsigned *count );
+
+
+/**
+ * Enum accounts info.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_enum_info( pjsua_acc_info info[],
+					  unsigned *count );
+
+
+/**
+ * Find account for outgoing request.
+ */
+PJ_DECL(pjsua_acc_id) pjsua_acc_find_for_outgoing(const pj_str_t *url);
+
+/**
+ * Find account for incoming request.
+ */
+PJ_DECL(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata);
 
 /**
@@ -605,12 +659,16 @@
  */
 PJ_DECL(pj_status_t) pjsua_acc_add(const pjsua_acc_config *cfg,
-				   int *acc_index);
+				   pjsua_acc_id *acc_id);
+
+/**
+ * Delete account.
+ */
+PJ_DECL(pj_status_t) pjsua_acc_del(pjsua_acc_id acc_id);
 
 
 /**
  * Set account's presence status.
- * Must call pjsua_pres_refresh() after this.
- */
-PJ_DECL(pj_status_t) pjsua_acc_set_online_status(unsigned acc_index,
+ */
+PJ_DECL(pj_status_t) pjsua_acc_set_online_status(pjsua_acc_id acc_id,
 						 pj_bool_t is_online);
 
@@ -620,5 +678,6 @@
  * this will start unregistration process.
  */
-PJ_DECL(pj_status_t) pjsua_acc_set_registration(unsigned acc_index, pj_bool_t renew);
+PJ_DECL(pj_status_t) pjsua_acc_set_registration(pjsua_acc_id acc_id, 
+						pj_bool_t renew);
 
 
@@ -638,5 +697,5 @@
  * Get buddy info.
  */
-PJ_DECL(pj_status_t) pjsua_buddy_get_info(unsigned buddy_index,
+PJ_DECL(pj_status_t) pjsua_buddy_get_info(pjsua_buddy_id buddy_index,
 					  pjsua_buddy_info *info);
 
@@ -645,19 +704,19 @@
  */
 PJ_DECL(pj_status_t) pjsua_buddy_add(const pj_str_t *uri,
-				     int *buddy_index);
+				     pjsua_buddy_id *buddy_index);
+
+
+/**
+ * Delete buddy.
+ */
+PJ_DECL(pj_status_t) pjsua_buddy_del(pjsua_buddy_id buddy_index);
 
 
 /**
  * Enable/disable buddy's presence monitoring.
- * Must call pjsua_pres_refresh() after this.
- */
-PJ_DECL(pj_status_t) pjsua_buddy_subscribe_pres(unsigned buddy_index,
+ */
+PJ_DECL(pj_status_t) pjsua_buddy_subscribe_pres(pjsua_buddy_id buddy_index,
 						pj_bool_t monitor);
 
-
-/**
- * Refresh both presence client and server subscriptions.
- */
-PJ_DECL(void) pjsua_pres_refresh(void);
 
 /**
@@ -681,5 +740,5 @@
  * Send IM outside dialog.
  */
-PJ_DECL(pj_status_t) pjsua_im_send(int acc_index, const pj_str_t *dst_uri, 
+PJ_DECL(pj_status_t) pjsua_im_send(int acc_id, const pj_str_t *dst_uri, 
 				   const pj_str_t *text);
 
@@ -688,5 +747,5 @@
  * Send typing indication outside dialog.
  */
-PJ_DECL(pj_status_t) pjsua_im_typing(int acc_index, const pj_str_t *dst_uri, 
+PJ_DECL(pj_status_t) pjsua_im_typing(int acc_id, const pj_str_t *dst_uri, 
 				     pj_bool_t is_typing);
 
@@ -706,6 +765,13 @@
  * Enum all conference ports.
  */
-PJ_DECL(pj_status_t) pjsua_conf_enum_ports(unsigned *count,
-					   pjmedia_conf_port_info info[]);
+PJ_DECL(pj_status_t) pjsua_conf_enum_port_ids(pjsua_conf_port_id id[],
+					      unsigned *count);
+
+
+/**
+ * Get information about the specified conference port
+ */
+PJ_DECL(pj_status_t) pjsua_conf_get_port_info( pjsua_conf_port_id id,
+					       pjsua_conf_port_info *info);
 
 
@@ -713,6 +779,6 @@
  * Connect conference port.
  */
-PJ_DECL(pj_status_t) pjsua_conf_connect(unsigned src_port,
-					unsigned dst_port);
+PJ_DECL(pj_status_t) pjsua_conf_connect(pjsua_conf_port_id src_port,
+					pjsua_conf_port_id dst_port);
 
 
@@ -720,6 +786,6 @@
  * Connect conference port connection.
  */
-PJ_DECL(pj_status_t) pjsua_conf_disconnect(unsigned src_port,
-					   unsigned dst_port);
+PJ_DECL(pj_status_t) pjsua_conf_disconnect(pjsua_conf_port_id src_port,
+					   pjsua_conf_port_id dst_port);
 
 
@@ -734,5 +800,5 @@
  * Get conference port associated with player.
  */
-PJ_DECL(int) pjsua_player_get_conf_port(pjsua_player_id id);
+PJ_DECL(pjsua_conf_port_id) pjsua_player_get_conf_port(pjsua_player_id id);
 
 
@@ -761,5 +827,5 @@
  * Get conference port associated with recorder.
  */
-PJ_DECL(int) pjsua_recorder_get_conf_port(pjsua_recorder_id id);
+PJ_DECL(pjsua_conf_port_id) pjsua_recorder_get_conf_port(pjsua_recorder_id id);
 
 
@@ -798,5 +864,6 @@
  */
 PJ_DECL(pj_status_t) pjsua_parse_args(int argc, char *argv[],
-				      pjsua_config *cfg);
+				      pjsua_config *cfg,
+				      pj_str_t *uri_to_call);
 
 /**
@@ -804,10 +871,12 @@
  */
 PJ_DECL(pj_status_t) pjsua_load_settings(const char *filename,
-					 pjsua_config *cfg);
+					 pjsua_config *cfg,
+					 pj_str_t *uri_to_call);
 
 /**
  * Get pjsua running config.
  */
-PJ_DECL(const pjsua_config*) pjsua_get_config(void);
+PJ_DECL(void) pjsua_get_config(pj_pool_t *pool,
+			       pjsua_config *config);
 
 
Index: pjproject/trunk/pjsip/include/pjsua-lib/pjsua_console_app.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsua-lib/pjsua_console_app.h	(revision 491)
+++ pjproject/trunk/pjsip/include/pjsua-lib/pjsua_console_app.h	(revision 492)
@@ -21,5 +21,5 @@
 
 
-void pjsua_console_app_main(void);
+void pjsua_console_app_main(const pj_str_t *uri_to_call);
 
 extern pjsip_module pjsua_console_app_msg_logger;
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 491)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 492)
@@ -128,5 +128,5 @@
  * Get maximum number of calls configured in pjsua.
  */
-PJ_DEF(unsigned) pjsua_get_max_calls(void)
+PJ_DEF(unsigned) pjsua_call_get_max_count(void)
 {
     return pjsua.config.max_calls;
@@ -137,5 +137,5 @@
  * Get current number of active calls.
  */
-PJ_DEF(unsigned) pjsua_get_call_count(void)
+PJ_DEF(unsigned) pjsua_call_get_count(void)
 {
     return pjsua.call_cnt;
@@ -167,5 +167,5 @@
  * Get call info.
  */
-PJ_DEF(pj_status_t) pjsua_get_call_info( unsigned call_index,
+PJ_DEF(pj_status_t) pjsua_call_get_info( unsigned call_index,
 					 pjsua_call_info *info)
 {
@@ -213,6 +213,6 @@
     }
 
-    info->cause = call->inv->cause;
-    info->cause_text = *pjsip_get_status_text(info->cause);
+    info->last_status = call->last_code;
+    info->last_status_text = *pjsip_get_status_text(info->last_status);
 
     info->has_media = (call->session != NULL);
@@ -226,5 +226,5 @@
  * Duplicate call info.
  */
-PJ_DEF(void) pjsua_dup_call_info( pj_pool_t *pool,
+PJ_DEF(void) pjsua_call_info_dup( pj_pool_t *pool,
 				  pjsua_call_info *dst_info,
 				  const pjsua_call_info *src_info)
@@ -246,7 +246,7 @@
  * Make outgoing call.
  */
-PJ_DEF(pj_status_t) pjsua_make_call(unsigned acc_index,
-				    const pj_str_t *dest_uri,
-				    int *p_call_index)
+PJ_DEF(pj_status_t) pjsua_call_make_call(unsigned acc_index,
+					 const pj_str_t *dest_uri,
+					 int *p_call_index)
 {
     pjsip_dialog *dlg = NULL;
@@ -385,16 +385,16 @@
  * Answer call.
  */
-PJ_DEF(void) pjsua_call_answer(int call_index, int code)
+PJ_DEF(pj_status_t) pjsua_call_answer(int call_index, int code)
 {
     pjsip_tx_data *tdata;
     pj_status_t status;
 
-    PJ_ASSERT_ON_FAIL(call_index >= 0 && 
+    PJ_ASSERT_RETURN( call_index >= 0 && 
 		      call_index < (int)pjsua.config.max_calls,
-		      return);
+		      PJ_EINVAL);
 
     if (pjsua.calls[call_index].inv == NULL) {
 	PJ_LOG(3,(THIS_FILE, "Call %d already disconnected"));
-	return;
+	return PJSIP_ESESSIONTERMINATED;
     }
 
@@ -409,4 +409,5 @@
 		     status);
 
+    return status;
 }
 
@@ -613,4 +614,9 @@
     }
 
+    /* Notify application */
+    if (pjsua.cb.on_incoming_call)
+	pjsua.cb.on_incoming_call(acc_index, call_index, rdata);
+
+
     /* This INVITE request has been handled. */
     return PJ_TRUE;
@@ -636,4 +642,5 @@
 	    if (call->res_time.sec == 0)
 		pj_gettimeofday(&call->res_time);
+	    call->last_code = e->body.tsx_state.tsx->status_code;
 	    break;
 	case PJSIP_INV_STATE_CONFIRMED:
@@ -642,9 +649,10 @@
 	case PJSIP_INV_STATE_DISCONNECTED:
 	    pj_gettimeofday(&call->dis_time);
+	    if (e->body.tsx_state.tsx->status_code > call->last_code) {
+		call->last_code = e->body.tsx_state.tsx->status_code;
+	    }
 	    break;
 	default:
-	    /* Nothing to do. Just to keep gcc from complaining about
-	     * unused enums.
-	     */ 
+	    call->last_code = e->body.tsx_state.tsx->status_code;
 	    break;
     }
@@ -683,5 +691,5 @@
 	    break;
 
-	default:
+	case PJSIP_INV_STATE_INCOMING:
 	    /* Nothing to do. Just to keep gcc from complaining about
 	     * unused enums.
@@ -854,5 +862,5 @@
     /* Now make the outgoing call. */
     tmp = pj_str(uri);
-    status = pjsua_make_call(existing_call->acc_index, &tmp, &new_call);
+    status = pjsua_call_make_call(existing_call->acc_index, &tmp, &new_call);
     if (status != PJ_SUCCESS) {
 
@@ -1355,5 +1363,5 @@
  * Put call on-Hold.
  */
-PJ_DEF(void) pjsua_call_set_hold(int call_index)
+PJ_DEF(pj_status_t) pjsua_call_set_hold(int call_index)
 {
     pjmedia_sdp_session *sdp;
@@ -1366,15 +1374,15 @@
     if (!call->inv) {
 	PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
-	return;
+	return PJSIP_ESESSIONTERMINATED;
     }
 
     if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
 	PJ_LOG(3,(THIS_FILE, "Can not hold call that is not confirmed"));
-	return;
+	return PJSIP_ESESSIONSTATE;
     }
 
     status = create_inactive_sdp(call, &sdp);
     if (status != PJ_SUCCESS)
-	return;
+	return status;
 
     /* Send re-INVITE with new offer */
@@ -1382,5 +1390,5 @@
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
-	return;
+	return status;
     }
 
@@ -1388,6 +1396,8 @@
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
-	return;
-    }
+	return status;
+    }
+
+    return PJ_SUCCESS;
 }
 
@@ -1396,5 +1406,5 @@
  * re-INVITE.
  */
-PJ_DEF(void) pjsua_call_reinvite(int call_index)
+PJ_DEF(pj_status_t) pjsua_call_reinvite(int call_index)
 {
     pjmedia_sdp_session *sdp;
@@ -1407,5 +1417,5 @@
     if (!call->inv) {
 	PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
-	return;
+	return PJSIP_ESESSIONTERMINATED;
     }
 
@@ -1413,5 +1423,5 @@
     if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
 	PJ_LOG(3,(THIS_FILE, "Can not re-INVITE call that is not confirmed"));
-	return;
+	return PJSIP_ESESSIONSTATE;
     }
 
@@ -1422,5 +1432,5 @@
 	pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint", 
 		     status);
-	return;
+	return status;
     }
 
@@ -1429,5 +1439,5 @@
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
-	return;
+	return status;
     }
 
@@ -1435,6 +1445,8 @@
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
-	return;
-    }
+	return status;
+    }
+
+    return PJ_SUCCESS;
 }
 
@@ -1443,5 +1455,5 @@
  * Transfer call.
  */
-PJ_DEF(void) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest)
+PJ_DEF(pj_status_t) pjsua_call_xfer(unsigned call_index, const pj_str_t *dest)
 {
     pjsip_evsub *sub;
@@ -1455,5 +1467,5 @@
     if (!call->inv) {
 	PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
-	return;
+	return PJSIP_ESESSIONTERMINATED;
     }
    
@@ -1465,5 +1477,5 @@
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Unable to create xfer", status);
-	return;
+	return status;
     }
 
@@ -1474,5 +1486,5 @@
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Unable to create REFER request", status);
-	return;
+	return status;
     }
 
@@ -1481,5 +1493,5 @@
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Unable to send REFER request", status);
-	return;
+	return status;
     }
 
@@ -1488,4 +1500,6 @@
      * may want to hold the INVITE, or terminate the invite, or whatever.
      */
+
+    return PJ_SUCCESS;
 }
 
@@ -1513,5 +1527,5 @@
  * Send instant messaging inside INVITE session.
  */
-PJ_DECL(void) pjsua_call_send_im(int call_index, const pj_str_t *str)
+PJ_DEF(pj_status_t) pjsua_call_send_im(int call_index, const pj_str_t *str)
 {
     pjsua_call *call;
@@ -1525,5 +1539,5 @@
     if (!call->inv) {
 	PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
-	return;
+	return PJSIP_ESESSIONTERMINATED;
     }
 
@@ -1561,4 +1575,5 @@
 on_return:
     pjsip_dlg_dec_lock(call->inv->dlg);
+    return status;
 }
 
@@ -1567,5 +1582,6 @@
  * Send IM typing indication inside INVITE session.
  */
-PJ_DECL(void) pjsua_call_typing(int call_index, pj_bool_t is_typing)
+PJ_DEF(pj_status_t) pjsua_call_send_typing_ind(int call_index, 
+					       pj_bool_t is_typing)
 {
     pjsua_call *call;
@@ -1577,5 +1593,5 @@
     if (!call->inv) {
 	PJ_LOG(3,(THIS_FILE,"Call has been disconnected"));
-	return;
+	return PJSIP_ESESSIONTERMINATED;
     }
 
@@ -1603,5 +1619,7 @@
 
 on_return:
-    pjsip_dlg_dec_lock(call->inv->dlg);}
+    pjsip_dlg_dec_lock(call->inv->dlg);
+    return status;
+}
 
 
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_console_app.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_console_app.c	(revision 491)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_console_app.c	(revision 492)
@@ -37,5 +37,5 @@
     int i, max;
 
-    max = pjsua_get_max_calls();
+    max = pjsua_call_get_max_count();
     for (i=current_call+1; i<max; ++i) {
 	if (pjsua_call_is_active(i)) {
@@ -64,5 +64,5 @@
     int i, max;
 
-    max = pjsua_get_max_calls();
+    max = pjsua_call_get_max_count();
     for (i=current_call-1; i>=0; --i) {
 	if (pjsua_call_is_active(i)) {
@@ -94,5 +94,5 @@
     PJ_UNUSED_ARG(e);
 
-    pjsua_get_call_info(call_index, &call_info);
+    pjsua_call_get_info(call_index, &call_info);
 
     if (call_info.state == PJSIP_INV_STATE_DISCONNECTED) {
@@ -100,6 +100,6 @@
 	PJ_LOG(3,(THIS_FILE, "Call %d is DISCONNECTED [reason=%d (%s)]", 
 		  call_index,
-		  call_info.cause,
-		  call_info.cause_text.ptr));
+		  call_info.last_status,
+		  call_info.last_status_text.ptr));
 
 	if ((int)call_index == current_call) {
@@ -386,29 +386,30 @@
 {
     unsigned i, count;
-    pjmedia_conf_port_info info[PJSUA_MAX_CALLS];
+    pjsua_conf_port_id id[PJSUA_MAX_CALLS];
 
     printf("Conference ports:\n");
 
-    count = PJ_ARRAY_SIZE(info);
-    pjsua_conf_enum_ports(&count, info);
+    count = PJ_ARRAY_SIZE(id);
+    pjsua_conf_enum_port_ids(id, &count);
+
     for (i=0; i<count; ++i) {
 	char txlist[PJSUA_MAX_CALLS*4+10];
-	int j;
-	pjmedia_conf_port_info *port_info = &info[i];	
-	
+	unsigned j;
+	pjsua_conf_port_info info;
+
+	pjsua_conf_get_port_info(id[i], &info);
+
 	txlist[0] = '\0';
-	for (j=0; j<(int)count; ++j) {
+	for (j=0; j<info.listener_cnt; ++j) {
 	    char s[10];
-	    if (port_info->listener[j]) {
-		pj_ansi_sprintf(s, "#%d ", j);
-		pj_ansi_strcat(txlist, s);
-	    }
+	    pj_ansi_sprintf(s, "#%d ", info.listeners[j]);
+	    pj_ansi_strcat(txlist, s);
 	}
 	printf("Port #%02d[%2dKHz/%dms] %20.*s  transmitting to: %s\n", 
-	       port_info->slot, 
-	       port_info->clock_rate/1000,
-	       port_info->samples_per_frame * 1000 / port_info->clock_rate,
-	       (int)port_info->name.slen, 
-	       port_info->name.ptr,
+	       info.slot_id, 
+	       info.clock_rate/1000,
+	       info.samples_per_frame * 1000 / info.clock_rate,
+	       (int)info.name.slen, 
+	       info.name.ptr,
 	       txlist);
 
@@ -418,5 +419,5 @@
 
 
-void pjsua_console_app_main(void)
+void pjsua_console_app_main(const pj_str_t *uri_to_call)
 {
     char menuin[10];
@@ -432,7 +433,6 @@
 
     /* If user specifies URI to call, then call the URI */
-    if (pjsua_get_config()->uri_to_call.slen) {
-	pjsua_make_call( current_acc, &pjsua_get_config()->uri_to_call, 
-			 NULL);
+    if (uri_to_call->slen) {
+	pjsua_call_make_call( current_acc, uri_to_call, NULL);
     }
 
@@ -450,5 +450,6 @@
 	case 'm':
 	    /* Make call! : */
-	    printf("(You currently have %d calls)\n", pjsua_get_call_count());
+	    printf("(You currently have %d calls)\n", 
+		     pjsua_call_get_count());
 	    
 	    uri = NULL;
@@ -470,10 +471,11 @@
 	    
 	    tmp = pj_str(uri);
-	    pjsua_make_call( current_acc, &tmp, NULL);
+	    pjsua_call_make_call( current_acc, &tmp, NULL);
 	    break;
 
 	case 'M':
 	    /* Make multiple calls! : */
-	    printf("(You currently have %d calls)\n", pjsua_get_call_count());
+	    printf("(You currently have %d calls)\n", 
+		   pjsua_call_get_count());
 	    
 	    if (!simple_input("Number of calls", menuin, sizeof(menuin)))
@@ -501,5 +503,5 @@
 	    
 		tmp = pj_str(uri);
-		status = pjsua_make_call(current_acc, &tmp, NULL);
+		status = pjsua_call_make_call(current_acc, &tmp, NULL);
 		if (status != PJ_SUCCESS)
 		    break;
@@ -541,5 +543,5 @@
 	    /* Send typing indication. */
 	    if (i != -1)
-		pjsua_call_typing(i, PJ_TRUE);
+		pjsua_call_send_typing_ind(i, PJ_TRUE);
 	    else {
 		pj_str_t tmp_uri = pj_str(uri);
@@ -554,5 +556,5 @@
 		 */
 		if (i != -1)
-		    pjsua_call_typing(i, PJ_FALSE);
+		    pjsua_call_send_typing_ind(i, PJ_FALSE);
 		else {
 		    pj_str_t tmp_uri = pj_str(uri);
@@ -577,5 +579,5 @@
 
 	    if (current_call != -1) {
-		pjsua_get_call_info(current_call, &call_info);
+		pjsua_call_get_info(current_call, &call_info);
 	    } else {
 		/* Make compiler happy */
@@ -651,5 +653,5 @@
 	    if (current_call != -1) {
 		
-		pjsua_get_call_info(current_call, &call_info);
+		pjsua_call_get_info(current_call, &call_info);
 		PJ_LOG(3,(THIS_FILE,"Current dialog: %.*s", 
 			  (int)call_info.remote_info.slen, 
@@ -782,6 +784,4 @@
 		}
 
-		pjsua_pres_refresh();
-
 	    } else if (result.uri_result) {
 		puts("Sorry, can only subscribe to buddy's presence, "
@@ -815,5 +815,4 @@
 		   acc_info.acc_id.ptr,
 		   (acc_info.online_status?"online":"offline"));
-	    pjsua_pres_refresh();
 	    break;
 
@@ -898,78 +897,4 @@
 
 /*****************************************************************************
- * This is a very simple PJSIP module, whose sole purpose is to display
- * incoming and outgoing messages to log. This module will have priority
- * higher than transport layer, which means:
- *
- *  - incoming messages will come to this module first before reaching
- *    transaction layer.
- *
- *  - outgoing messages will come to this module last, after the message
- *    has been 'printed' to contiguous buffer by transport layer and
- *    appropriate transport instance has been decided for this message.
- *
- */
-
-/* Notification on incoming messages */
-static pj_bool_t console_on_rx_msg(pjsip_rx_data *rdata)
-{
-    PJ_LOG(4,(THIS_FILE, "RX %d bytes %s from %s:%d:\n"
-			 "%s\n"
-			 "--end msg--",
-			 rdata->msg_info.len,
-			 pjsip_rx_data_get_info(rdata),
-			 rdata->pkt_info.src_name,
-			 rdata->pkt_info.src_port,
-			 rdata->msg_info.msg_buf));
-    
-    /* Always return false, otherwise messages will not get processed! */
-    return PJ_FALSE;
-}
-
-/* Notification on outgoing messages */
-static pj_status_t console_on_tx_msg(pjsip_tx_data *tdata)
-{
-    
-    /* Important note:
-     *	tp_info field is only valid after outgoing messages has passed
-     *	transport layer. So don't try to access tp_info when the module
-     *	has lower priority than transport layer.
-     */
-
-    PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s:%d:\n"
-			 "%s\n"
-			 "--end msg--",
-			 (tdata->buf.cur - tdata->buf.start),
-			 pjsip_tx_data_get_info(tdata),
-			 tdata->tp_info.dst_name,
-			 tdata->tp_info.dst_port,
-			 tdata->buf.start));
-
-    /* Always return success, otherwise message will not get sent! */
-    return PJ_SUCCESS;
-}
-
-/* The module instance. */
-pjsip_module pjsua_console_app_msg_logger = 
-{
-    NULL, NULL,				/* prev, next.		*/
-    { "mod-pjsua-log", 13 },		/* Name.		*/
-    -1,					/* Id			*/
-    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority	        */
-    NULL,				/* load()		*/
-    NULL,				/* start()		*/
-    NULL,				/* stop()		*/
-    NULL,				/* unload()		*/
-    &console_on_rx_msg,			/* on_rx_request()	*/
-    &console_on_rx_msg,			/* on_rx_response()	*/
-    &console_on_tx_msg,			/* on_tx_request.	*/
-    &console_on_tx_msg,			/* on_tx_response()	*/
-    NULL,				/* on_tsx_state()	*/
-
-};
-
-
-
-/*****************************************************************************
  * Error display:
  */
@@ -993,5 +918,6 @@
 {
     &console_on_call_state,
-    NULL,   /* default accept transfer */
+    NULL,   /* on_incoming_call		*/
+    NULL,   /* default accept transfer	*/
     &console_on_reg_state,
     &console_on_buddy_state,
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 491)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 492)
@@ -56,4 +56,5 @@
     cfg->udp_port = 5060;
     cfg->start_rtp_port = 4000;
+    cfg->msg_logging = PJ_TRUE;
     cfg->max_calls = 4;
     cfg->conf_ports = 0;
@@ -722,4 +723,6 @@
     unsigned j;
 
+    pj_memcpy(dst_acc, src_acc, sizeof(pjsua_acc_config));
+
     pj_strdup_with_null(pool, &dst_acc->id, &src_acc->id);
     pj_strdup_with_null(pool, &dst_acc->reg_uri, &src_acc->reg_uri);
@@ -743,5 +746,5 @@
  * Copy configuration.
  */
-static void copy_config(pj_pool_t *pool, pjsua_config *dst, 
+void pjsua_copy_config( pj_pool_t *pool, pjsua_config *dst, 
 			const pjsua_config *src)
 {
@@ -762,5 +765,5 @@
 
     pj_strdup_with_null(pool, &dst->outbound_proxy, &src->outbound_proxy);
-    pj_strdup_with_null(pool, &dst->uri_to_call, &src->uri_to_call);
+    //pj_strdup_with_null(pool, &dst->uri_to_call, &src->uri_to_call);
 
     for (i=0; i<src->acc_cnt; ++i) {
@@ -814,4 +817,8 @@
     }
 
+    /* Enable SIP message logging */
+    if (pjsua.config.msg_logging)
+	pjsip_endpt_register_module(pjsua.endpt, &pjsua_msg_logger);
+
     return PJ_SUCCESS;
 }
@@ -864,5 +871,5 @@
 
     /* Copy configuration */
-    copy_config(pjsua.pool, &pjsua.config, cfg);
+    pjsua_copy_config(pjsua.pool, &pjsua.config, cfg);
 
     /* Copy callback */
@@ -1027,5 +1034,5 @@
  * Find account for incoming request.
  */
-int pjsua_find_account_for_incoming(pjsip_rx_data *rdata)
+PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata)
 {
     pjsip_uri *uri;
@@ -1035,9 +1042,9 @@
     uri = rdata->msg_info.to->uri;
 
-    /* Just return last account if To URI is not SIP: */
+    /* Just return default account if To URI is not SIP: */
     if (!PJSIP_URI_SCHEME_IS_SIP(uri) && 
 	!PJSIP_URI_SCHEME_IS_SIPS(uri)) 
     {
-	return pjsua.config.acc_cnt;
+	return pjsua.default_acc;
     }
 
@@ -1069,6 +1076,6 @@
     }
 
-    /* Still no match, just return last account */
-    return pjsua.config.acc_cnt;
+    /* Still no match, use default account */
+    return pjsua.default_acc;
 }
 
@@ -1077,10 +1084,50 @@
  * Find account for outgoing request.
  */
-int pjsua_find_account_for_outgoing(const pj_str_t *url)
-{
-    PJ_UNUSED_ARG(url);
-
-    /* Just use account #0 */
-    return 0;
+PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_outgoing(const pj_str_t *str_url)
+{
+    pj_str_t tmp;
+    pjsip_uri *uri;
+    pjsip_sip_uri *sip_uri;
+    unsigned i;
+
+    pj_strdup_with_null(pjsua.pool, &tmp, str_url);
+
+    uri = pjsip_parse_uri(pjsua.pool, tmp.ptr, tmp.slen, 0);
+    if (!uri)
+	return pjsua.config.acc_cnt-1;
+
+    if (!PJSIP_URI_SCHEME_IS_SIP(uri) && 
+	!PJSIP_URI_SCHEME_IS_SIPS(uri)) 
+    {
+	/* Return the first account with proxy */
+	for (i=0; i<PJ_ARRAY_SIZE(pjsua.acc); ++i) {
+	    if (!pjsua.acc[i].valid)
+		continue;
+	    if (pjsua.config.acc_config[i].proxy.slen)
+		break;
+	}
+
+	if (i != PJ_ARRAY_SIZE(pjsua.acc))
+	    return i;
+
+	/* Not found, use default account */
+	return pjsua.default_acc;
+    }
+
+    sip_uri = pjsip_uri_get_uri(uri);
+
+    /* Find matching domain */
+    for (i=0; i<PJ_ARRAY_SIZE(pjsua.acc); ++i) {
+	if (!pjsua.acc[i].valid)
+	    continue;
+	if (pj_stricmp(&pjsua.acc[i].host_part, &sip_uri->host)==0)
+	    break;
+    }
+
+    if (i != PJ_ARRAY_SIZE(pjsua.acc))
+	return i;
+
+    /* Just use default account */
+    return pjsua.default_acc;
 }
 
@@ -1193,4 +1240,8 @@
     }
 
+    /* Mark account as valid */
+    pjsua.acc[acc_index].valid = PJ_TRUE;
+
+
     return PJ_SUCCESS;
 }
@@ -1200,14 +1251,25 @@
  */
 PJ_DEF(pj_status_t) pjsua_acc_add( const pjsua_acc_config *cfg,
-				   int *acc_index)
-{
+				   pjsua_acc_id *acc_index)
+{
+    unsigned index;
     pj_status_t status;
 
-    PJ_ASSERT_RETURN(pjsua.config.acc_cnt<PJ_ARRAY_SIZE(pjsua.config.acc_config),
+    PJ_ASSERT_RETURN(pjsua.config.acc_cnt < 
+			PJ_ARRAY_SIZE(pjsua.config.acc_config),
 		     PJ_ETOOMANY);
 
-    copy_acc_config(pjsua.pool, &pjsua.config.acc_config[pjsua.config.acc_cnt], cfg);
+    /* Find empty account index. */
+    for (index=0; index < PJ_ARRAY_SIZE(pjsua.acc); ++index) {
+	if (pjsua.acc[index].valid == PJ_FALSE)
+	    break;
+    }
+
+    /* Expect to find a slot */
+    PJ_ASSERT_RETURN(index < PJ_ARRAY_SIZE(pjsua.acc), PJ_EBUG);
+
+    copy_acc_config(pjsua.pool, &pjsua.config.acc_config[index], cfg);
     
-    status = init_acc(pjsua.config.acc_cnt);
+    status = init_acc(index);
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Error adding account", status);
@@ -1216,5 +1278,5 @@
 
     if (acc_index)
-	*acc_index = pjsua.config.acc_cnt;
+	*acc_index = index;
 
     pjsua.config.acc_cnt++;
@@ -1223,4 +1285,23 @@
 }
 
+
+/*
+ * Delete account.
+ */
+PJ_DEF(pj_status_t) pjsua_acc_del(pjsua_acc_id acc_index)
+{
+    PJ_ASSERT_RETURN(acc_index < (int)pjsua.config.acc_cnt, 
+		     PJ_EINVAL);
+    PJ_ASSERT_RETURN(pjsua.acc[acc_index].valid, PJ_EINVALIDOP);
+
+    /* Delete registration */
+    if (pjsua.acc[acc_index].regc != NULL) 
+	pjsua_acc_set_registration(acc_index, PJ_FALSE);
+
+    /* Invalidate */
+    pjsua.acc[acc_index].valid = PJ_FALSE;
+
+    return PJ_SUCCESS;
+}
 
 
@@ -1267,5 +1348,5 @@
 
 	tmp.ptr = buf;
-	tmp.slen = pj_ansi_sprintf(tmp.ptr, "<sip:%s:%d>", 
+	tmp.slen = pj_ansi_sprintf(tmp.ptr, "Local <sip:%s:%d>", 
 				   pjsua.config.sip_host.ptr,
 				   pjsua.config.sip_port);
@@ -1283,4 +1364,15 @@
     }
     
+
+    /* Add another account as the last one. 
+     * This account corresponds to local endpoint, and is user-less.
+     * This is also the default account.
+     */
+    if (pjsua.config.acc_cnt < PJ_ARRAY_SIZE(pjsua.config.acc_config)) {
+	pjsua.default_acc = pjsua.config.acc_cnt;
+	pjsua.acc[pjsua.default_acc].auto_gen = 1;
+	pjsua.config.acc_cnt++;
+    }
+
 
     /* Initialize accounts: */
@@ -1292,5 +1384,4 @@
 	}
     }
-
 
 
@@ -1334,4 +1425,7 @@
 
 
+    /* Refresh presence */
+    pjsua_pres_refresh();
+
 
     PJ_LOG(3,(THIS_FILE, "PJSUA version %s started", PJ_VERSION));
@@ -1369,13 +1463,46 @@
 
 /**
- * Enum all conference ports.
- */
-PJ_DEF(pj_status_t) pjsua_conf_enum_ports( unsigned *count,
-					   pjmedia_conf_port_info info[])
-{
-    return pjmedia_conf_get_ports_info(pjsua.mconf, count, info);
-}
-
-
+ * Enum all conference port ID.
+ */
+PJ_DEF(pj_status_t) pjsua_conf_enum_port_ids( pjsua_conf_port_id id[],
+					      unsigned *count)
+{
+    return pjmedia_conf_enum_ports( pjsua.mconf, (unsigned*)id, count);
+}
+
+
+
+/**
+ * Get information about the specified conference port
+ */
+PJ_DEF(pj_status_t) pjsua_conf_get_port_info( pjsua_conf_port_id id,
+					      pjsua_conf_port_info *info)
+{
+    pjmedia_conf_port_info cinfo;
+    unsigned i, count;
+    pj_status_t status;
+
+    status = pjmedia_conf_get_port_info( pjsua.mconf, id, &cinfo);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    pj_memset(info, 0, sizeof(*info));
+    info->slot_id = id;
+    info->name = cinfo.name;
+    info->clock_rate = cinfo.clock_rate;
+    info->channel_count = cinfo.channel_count;
+    info->samples_per_frame = cinfo.samples_per_frame;
+    info->bits_per_sample = cinfo.bits_per_sample;
+
+    /* Build array of listeners */
+    count = pjsua.config.conf_ports;
+    for (i=0; i<count; ++i) {
+	if (cinfo.listener[i]) {
+	    info->listeners[info->listener_cnt++] = i;
+	}
+    }
+
+    return PJ_SUCCESS;
+}
 
 
@@ -1383,6 +1510,6 @@
  * Connect conference port.
  */
-PJ_DEF(pj_status_t) pjsua_conf_connect( unsigned src_port,
-					unsigned dst_port)
+PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id src_port,
+					pjsua_conf_port_id dst_port)
 {
     return pjmedia_conf_connect_port(pjsua.mconf, src_port, dst_port, 0);
@@ -1393,6 +1520,6 @@
  * Connect conference port connection.
  */
-PJ_DEF(pj_status_t) pjsua_conf_disconnect( unsigned src_port,
-					   unsigned dst_port)
+PJ_DEF(pj_status_t) pjsua_conf_disconnect( pjsua_conf_port_id src_port,
+					   pjsua_conf_port_id dst_port)
 {
     return pjmedia_conf_disconnect_port(pjsua.mconf, src_port, dst_port);
@@ -1435,5 +1562,5 @@
     pjsua.player[pjsua.player_cnt].slot = slot;
 
-    if (*id)
+    if (id)
 	*id = pjsua.player_cnt;
 
@@ -1447,5 +1574,5 @@
  * Get conference port associated with player.
  */
-PJ_DEF(int) pjsua_player_get_conf_port(pjsua_player_id id)
+PJ_DEF(pjsua_conf_port_id) pjsua_player_get_conf_port(pjsua_player_id id)
 {
     PJ_ASSERT_RETURN(id>=0 && id < PJ_ARRAY_SIZE(pjsua.player), PJ_EINVAL);
@@ -1531,5 +1658,5 @@
  * Get conference port associated with recorder.
  */
-PJ_DEF(int) pjsua_recorder_get_conf_port(pjsua_recorder_id id)
+PJ_DEF(pjsua_conf_port_id) pjsua_recorder_get_conf_port(pjsua_recorder_id id)
 {
     PJ_ASSERT_RETURN(id>=0 && id < PJ_ARRAY_SIZE(pjsua.recorder), PJ_EINVAL);
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_im.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_im.c	(revision 491)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_im.c	(revision 492)
@@ -186,4 +186,5 @@
     pj_str_t from, to;
     pjsip_accept_hdr *accept_hdr;
+    pjsip_contact_hdr *contact_hdr;
     pjsip_msg *msg;
     pj_status_t status;
@@ -222,9 +223,21 @@
 				  NULL, NULL, NULL);
 
-    /* Build the From text. */
+    /* For the source URI, we use Contact header if present, since
+     * Contact header contains the port number information. If this is
+     * not available, then use From header.
+     */
     from.ptr = pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE);
-    from.slen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, 
-				rdata->msg_info.from->uri,
-				from.ptr, PJSIP_MAX_URL_SIZE);
+    contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg,
+				     PJSIP_H_CONTACT, NULL);
+    if (contact_hdr) {
+	from.slen = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,
+				    contact_hdr->uri, 
+				    from.ptr, PJSIP_MAX_URL_SIZE);
+    } else {
+	from.slen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, 
+				    rdata->msg_info.from->uri,
+				    from.ptr, PJSIP_MAX_URL_SIZE);
+    }
+
     if (from.slen < 1)
 	from = pj_str("<--URI is too long-->");
@@ -337,4 +350,5 @@
 				    pj_bool_t is_typing)
 {
+    const pj_str_t STR_CONTACT = { "Contact", 7 };
     pjsip_tx_data *tdata;
     pj_status_t status;
@@ -351,4 +365,16 @@
 
 
+    /* Add accept header. */
+    pjsip_msg_add_hdr( tdata->msg, 
+		       (pjsip_hdr*)pjsua_im_create_accept(tdata->pool));
+
+
+    /* Add contact. */
+    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)
+	pjsip_generic_string_hdr_create(tdata->pool, 
+					&STR_CONTACT,
+					&pjsua.config.acc_config[acc_index].contact));
+
+
     /* Create "application/im-iscomposing+xml" msg body. */
     tdata->msg->body = pjsip_iscomposing_create_body( tdata->pool, is_typing,
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_imp.h
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_imp.h	(revision 491)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_imp.h	(revision 492)
@@ -33,4 +33,5 @@
     unsigned		 index;	    /**< Index in pjsua array.		    */
     pjsip_inv_session	*inv;	    /**< The invite session.		    */
+    pjsip_status_code	 last_code; /**<Last status code seen.		    */
     pj_time_val		 start_time;/**< First INVITE sent/received.	    */
     pj_time_val		 res_time;  /**< First response sent/received.	    */
@@ -62,5 +63,4 @@
     pj_str_t		 host;	    /**< Buddy host.			*/
     unsigned		 port;	    /**< Buddy port.			*/
-    int			 acc_index; /**< Which account to use.		*/
     pj_bool_t		 monitor;   /**< Should we monitor?		*/
     pjsip_evsub		*sub;	    /**< Buddy presence subscription	*/
@@ -90,4 +90,6 @@
 struct pjsua_acc
 {
+    pj_bool_t	     valid;	    /**< Is this account valid?		*/
+    pj_bool_t	     auto_gen;	    /**< Is this account generated.	*/
     int		     index;	    /**< Index in accounts array.	*/
     pj_str_t	     user_part;	    /**< User part of local URI.	*/
@@ -160,4 +162,5 @@
 
     /* Account: */
+    int		     default_acc;   /**< Default account to use.	*/
     pjsua_acc	     acc[PJSUA_MAX_ACC];    /** Client regs array.	*/
 
@@ -176,5 +179,4 @@
     pjsua_call	     calls[PJSUA_MAX_CALLS];	/** Calls array.	*/
 
-
     /* SIMPLE and buddy status: */
     pjsua_buddy	     buddies[PJSUA_MAX_BUDDIES];
@@ -186,15 +188,6 @@
 
 
-
-/**
- * Find account for incoming request.
- */
-int pjsua_find_account_for_incoming(pjsip_rx_data *rdata);
-
-
-/**
- * Find account for outgoing request.
- */
-int pjsua_find_account_for_outgoing(const pj_str_t *url);
+void pjsua_copy_config( pj_pool_t *pool, pjsua_config *dst, 
+			const pjsua_config *src);
 
 
@@ -224,4 +217,9 @@
 pj_status_t pjsua_pres_init();
 
+
+/**
+ * Refresh both presence client and server subscriptions.
+ */
+void pjsua_pres_refresh(void);
 
 /**
@@ -256,4 +254,5 @@
 
 
+extern pjsip_module pjsua_msg_logger;
 
 #endif	/* __PJSUA_IMP_H__ */
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c	(revision 491)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c	(revision 492)
@@ -98,5 +98,5 @@
 
     /* Find which account for the incoming request. */
-    acc_index = pjsua_find_account_for_incoming(rdata);
+    acc_index = pjsua_acc_find_for_incoming(rdata);
     acc_config = &pjsua.config.acc_config[acc_index];
 
@@ -311,5 +311,6 @@
     pj_status_t status;
 
-    acc_index = pjsua.buddies[index].acc_index;
+    acc_index = pjsua_acc_find_for_outgoing(&pjsua.config.buddy_uri[index]);
+
     acc_config = &pjsua.config.acc_config[acc_index];
 
@@ -440,10 +441,11 @@
  * Get buddy info.
  */
-PJ_DEF(pj_status_t) pjsua_buddy_get_info(unsigned index,
+PJ_DEF(pj_status_t) pjsua_buddy_get_info(pjsua_buddy_id index,
 					 pjsua_buddy_info *info)
 {
     pjsua_buddy *buddy;
 
-    PJ_ASSERT_RETURN(index < pjsua.config.buddy_cnt, PJ_EINVAL);
+    PJ_ASSERT_RETURN(index < (int)PJ_ARRAY_SIZE(pjsua.config.buddy_uri), 
+		     PJ_EINVAL);
 
     pj_memset(info, 0, sizeof(pjsua_buddy_info));
@@ -472,5 +474,4 @@
     }
 
-    info->acc_index = buddy->acc_index;
     return PJ_SUCCESS;
 }
@@ -481,5 +482,5 @@
  */
 PJ_DEF(pj_status_t) pjsua_buddy_add( const pj_str_t *uri,
-				     int *buddy_index)
+				     pjsua_buddy_id *buddy_index)
 {
     pjsip_name_addr *url;
@@ -488,8 +489,18 @@
     pj_str_t tmp;
 
-    PJ_ASSERT_RETURN(pjsua.config.buddy_cnt <= PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
+    PJ_ASSERT_RETURN(pjsua.config.buddy_cnt <= 
+			PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
 		     PJ_ETOOMANY);
 
-    index = pjsua.config.buddy_cnt;
+    /* Find empty slot */
+    for (index=0; index<PJ_ARRAY_SIZE(pjsua.config.buddy_uri); ++index) {
+	if (pjsua.config.buddy_uri[index].slen == 0)
+	    break;
+    }
+
+    /* Expect to find an empty slot */
+    PJ_ASSERT_RETURN(index < PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
+		     PJ_ETOOMANY);
+
 
     /* Get name and display name for buddy */
@@ -512,8 +523,4 @@
 	pjsua.buddies[index].port = 5060;
 
-    /* Find account for outgoing preence subscription */
-    pjsua.buddies[index].acc_index = 
-	pjsua_find_account_for_outgoing(&pjsua.config.buddy_uri[index]);
-
     if (buddy_index)
 	*buddy_index = index;
@@ -526,22 +533,50 @@
 
 
-PJ_DEF(pj_status_t) pjsua_buddy_subscribe_pres( unsigned index,
+/**
+ * Delete buddy.
+ */
+PJ_DEF(pj_status_t) pjsua_buddy_del(pjsua_buddy_id index)
+{
+    PJ_ASSERT_RETURN(index < (int)PJ_ARRAY_SIZE(pjsua.config.buddy_uri), 
+		     PJ_EINVAL);
+
+    if (pjsua.config.buddy_uri[index].slen == 0)
+	return PJ_SUCCESS;
+
+    /* Unsubscribe presence */
+    pjsua_buddy_subscribe_pres(index, PJ_FALSE);
+
+    /* Remove buddy */
+    pjsua.config.buddy_uri[index].slen = 0;
+    pjsua.config.buddy_cnt--;
+
+    return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pjsua_buddy_subscribe_pres( pjsua_buddy_id index,
 						pj_bool_t monitor)
 {
     pjsua_buddy *buddy;
 
-    PJ_ASSERT_RETURN(index < pjsua.config.buddy_cnt, PJ_EINVAL);
+    PJ_ASSERT_RETURN(index < (int)PJ_ARRAY_SIZE(pjsua.config.buddy_uri),
+		     PJ_EINVAL);
 
     buddy = &pjsua.buddies[index];
     buddy->monitor = monitor;
+    pjsua_pres_refresh();
     return PJ_SUCCESS;
 }
 
 
-PJ_DEF(pj_status_t) pjsua_acc_set_online_status( unsigned acc_index,
+PJ_DEF(pj_status_t) pjsua_acc_set_online_status( pjsua_acc_id acc_index,
 						 pj_bool_t is_online)
 {
-    PJ_ASSERT_RETURN(acc_index < pjsua.config.acc_cnt, PJ_EINVAL);
+    PJ_ASSERT_RETURN(acc_index < (int)PJ_ARRAY_SIZE(pjsua.acc), 
+		     PJ_EINVAL);
+    PJ_ASSERT_RETURN(pjsua.acc[acc_index].valid, PJ_EINVALIDOP);
+
     pjsua.acc[acc_index].online_status = is_online;
+    pjsua_pres_refresh();
     return PJ_SUCCESS;
 }
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_reg.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_reg.c	(revision 491)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_reg.c	(revision 492)
@@ -96,5 +96,5 @@
  * Get account info.
  */
-PJ_DEF(pj_status_t) pjsua_acc_get_info( unsigned acc_index,
+PJ_DEF(pj_status_t) pjsua_acc_get_info( pjsua_acc_id acc_index,
 					pjsua_acc_info *info)
 {
@@ -102,8 +102,13 @@
     pjsua_acc_config *acc_cfg = &pjsua.config.acc_config[acc_index];
 
-    PJ_ASSERT_RETURN(acc_index < pjsua.config.acc_cnt, PJ_EINVAL);
-
+    PJ_ASSERT_RETURN(info != NULL, PJ_EINVAL);
+    
     pj_memset(info, 0, sizeof(pjsua_acc_info));
 
+    PJ_ASSERT_RETURN(acc_index < (int)pjsua.config.acc_cnt, 
+		     PJ_EINVAL);
+    PJ_ASSERT_RETURN(pjsua.acc[acc_index].valid, PJ_EINVALIDOP);
+
+    
     info->index = acc_index;
     info->acc_id = acc_cfg->id;
@@ -115,7 +120,10 @@
 	pj_strerror(acc->reg_last_err, info->buf, sizeof(info->buf));
 	info->status_text = pj_str(info->buf);
-    } else {
+    } else if (acc->reg_last_code) {
 	info->status = acc->reg_last_code;
 	info->status_text = *pjsip_get_status_text(acc->reg_last_code);
+    } else {
+	info->status = 0;
+	info->status_text = pj_str("In Progress");
     }
     
@@ -130,11 +138,54 @@
 
 
+PJ_DEF(pj_status_t) pjsua_acc_enum_info( pjsua_acc_info info[],
+					 unsigned *count )
+{
+    unsigned i, c;
+
+    for (i=0, c=0; c<*count && i<PJ_ARRAY_SIZE(pjsua.acc); ++i) {
+	if (!pjsua.acc[i].valid)
+	    continue;
+
+	pjsua_acc_get_info(i, &info[c]);
+	++c;
+    }
+
+    *count = c;
+    return PJ_SUCCESS;
+}
+
+
+/**
+ * Enum accounts id.
+ */
+PJ_DEF(pj_status_t) pjsua_acc_enum_id( pjsua_acc_id ids[],
+				       unsigned *count )
+{
+    unsigned i, c;
+
+    for (i=0, c=0; c<*count && i<PJ_ARRAY_SIZE(pjsua.acc); ++i) {
+	if (!pjsua.acc[i].valid)
+	    continue;
+	ids[c] = i;
+	++c;
+    }
+
+    *count = c;
+    return PJ_SUCCESS;
+}
+
+
 /*
  * Update registration. If renew is false, then unregistration will be performed.
  */
-PJ_DECL(pj_status_t) pjsua_acc_set_registration(unsigned acc_index, pj_bool_t renew)
+PJ_DECL(pj_status_t) pjsua_acc_set_registration(pjsua_acc_id acc_index, 
+						pj_bool_t renew)
 {
     pj_status_t status = 0;
     pjsip_tx_data *tdata = 0;
+
+    PJ_ASSERT_RETURN(acc_index < (int)pjsua.config.acc_cnt, 
+		     PJ_EINVAL);
+    PJ_ASSERT_RETURN(pjsua.acc[acc_index].valid, PJ_EINVALIDOP);
 
     if (renew) {
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_settings.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_settings.c	(revision 491)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_settings.c	(revision 492)
@@ -212,5 +212,6 @@
 /* Parse arguments. */
 PJ_DEF(pj_status_t) pjsua_parse_args(int argc, char *argv[],
-				     pjsua_config *cfg)
+				     pjsua_config *cfg,
+				     pj_str_t *uri_to_call)
 {
     int c;
@@ -596,4 +597,5 @@
 
     if (pj_optind != argc) {
+	pj_str_t uri_arg;
 
 	if (pjsua_verify_sip_url(argv[pj_optind]) != PJ_SUCCESS) {
@@ -601,15 +603,21 @@
 	    return -1;
 	}
-	cfg->uri_to_call = pj_str(argv[pj_optind]);
+	uri_arg = pj_str(argv[pj_optind]);
+	if (uri_to_call)
+	    *uri_to_call = uri_arg;
 	pj_optind++;
 
 	/* Add URI to call to buddy list if it's not already there */
 	for (i=0; i<cfg->buddy_cnt; ++i) {
-	    if (pj_stricmp(&cfg->buddy_uri[i], &cfg->uri_to_call)==0)
+	    if (pj_stricmp(&cfg->buddy_uri[i], &uri_arg)==0)
 		break;
 	}
 	if (i == cfg->buddy_cnt && cfg->buddy_cnt < PJSUA_MAX_BUDDIES) {
-	    cfg->buddy_uri[cfg->buddy_cnt++] = cfg->uri_to_call;
-	}
+	    cfg->buddy_uri[cfg->buddy_cnt++] = uri_arg;
+	}
+
+    } else {
+	if (uri_to_call)
+	    uri_to_call->slen = 0;
     }
 
@@ -870,5 +878,5 @@
 }
 
-PJ_DEF(void) pjsua_dump_call(int call_index, int with_media, 
+PJ_DEF(void) pjsua_call_dump(int call_index, int with_media, 
 			     char *buffer, unsigned maxlen,
 			     const char *indent)
@@ -976,5 +984,5 @@
 	for (i=0; i<pjsua.config.max_calls; ++i) {
 	    if (pjsua.calls[i].inv) {
-		pjsua_dump_call(i, detail, buf, sizeof(buf), "  ");
+		pjsua_call_dump(i, detail, buf, sizeof(buf), "  ");
 		PJ_LOG(3,(THIS_FILE, "%s", buf));
 	    }
@@ -994,5 +1002,6 @@
  */
 PJ_DECL(pj_status_t) pjsua_load_settings(const char *filename,
-					 pjsua_config *cfg)
+					 pjsua_config *cfg,
+					 pj_str_t *uri_to_call)
 {
     int argc = 3;
@@ -1000,5 +1009,5 @@
 
     argv[2] = (char*)filename;
-    return pjsua_parse_args(argc, argv, cfg);
+    return pjsua_parse_args(argc, argv, cfg, uri_to_call);
 }
 
@@ -1298,7 +1307,129 @@
  * Get pjsua running config.
  */
-PJ_DEF(const pjsua_config*) pjsua_get_config(void)
-{
-    return &pjsua.config;
-}
-
+PJ_DEF(void) pjsua_get_config(pj_pool_t *pool,
+			      pjsua_config *cfg)
+{
+    unsigned i;
+
+    pjsua_copy_config(pool, cfg, &pjsua.config);
+
+    /* Compact buddy uris. */
+    for (i=0; i<PJ_ARRAY_SIZE(pjsua.config.buddy_uri)-1; ++i) {
+	if (pjsua.config.buddy_uri[i].slen == 0) {
+	    unsigned j;
+
+	    for (j=i+1; j<PJ_ARRAY_SIZE(pjsua.config.buddy_uri); ++j) {
+		if (pjsua.config.buddy_uri[j].slen != 0)
+		    break;
+	    }
+	
+	    if (j == PJ_ARRAY_SIZE(pjsua.config.buddy_uri))
+		break;
+	    else
+		pjsua.config.buddy_uri[i] = pjsua.config.buddy_uri[j];
+	}
+    }
+
+    /* Compact accounts. */
+    for (i=0; i<PJ_ARRAY_SIZE(pjsua.config.acc_config)-1; ++i) {
+
+	if (pjsua.acc[i].valid == PJ_FALSE || pjsua.acc[i].auto_gen) {
+	    unsigned j;
+
+	    for (j=i+1; j<PJ_ARRAY_SIZE(pjsua.config.acc_config); ++j) {
+		if (pjsua.acc[j].valid && !pjsua.acc[j].auto_gen)
+		    break;
+	    }
+	
+	    if (j == PJ_ARRAY_SIZE(pjsua.config.acc_config)) {
+		break;
+	    } else {
+		pj_memcpy(&pjsua.config.acc_config[i] ,
+			  &pjsua.config.acc_config[j],
+			  sizeof(pjsua_acc_config));
+	    }
+	}
+
+    }
+
+    /* Remove auto generated account from config */
+    for (i=0; i<PJ_ARRAY_SIZE(pjsua.config.acc_config); ++i) {
+	if (pjsua.acc[i].auto_gen)
+	    --cfg->acc_cnt;
+    }
+}
+
+
+
+/*****************************************************************************
+ * This is a very simple PJSIP module, whose sole purpose is to display
+ * incoming and outgoing messages to log. This module will have priority
+ * higher than transport layer, which means:
+ *
+ *  - incoming messages will come to this module first before reaching
+ *    transaction layer.
+ *
+ *  - outgoing messages will come to this module last, after the message
+ *    has been 'printed' to contiguous buffer by transport layer and
+ *    appropriate transport instance has been decided for this message.
+ *
+ */
+
+/* Notification on incoming messages */
+static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
+{
+    PJ_LOG(4,(THIS_FILE, "RX %d bytes %s from %s:%d:\n"
+			 "%s\n"
+			 "--end msg--",
+			 rdata->msg_info.len,
+			 pjsip_rx_data_get_info(rdata),
+			 rdata->pkt_info.src_name,
+			 rdata->pkt_info.src_port,
+			 rdata->msg_info.msg_buf));
+    
+    /* Always return false, otherwise messages will not get processed! */
+    return PJ_FALSE;
+}
+
+/* Notification on outgoing messages */
+static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
+{
+    
+    /* Important note:
+     *	tp_info field is only valid after outgoing messages has passed
+     *	transport layer. So don't try to access tp_info when the module
+     *	has lower priority than transport layer.
+     */
+
+    PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s:%d:\n"
+			 "%s\n"
+			 "--end msg--",
+			 (tdata->buf.cur - tdata->buf.start),
+			 pjsip_tx_data_get_info(tdata),
+			 tdata->tp_info.dst_name,
+			 tdata->tp_info.dst_port,
+			 tdata->buf.start));
+
+    /* Always return success, otherwise message will not get sent! */
+    return PJ_SUCCESS;
+}
+
+/* The module instance. */
+pjsip_module pjsua_msg_logger = 
+{
+    NULL, NULL,				/* prev, next.		*/
+    { "mod-pjsua-log", 13 },		/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority	        */
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &logging_on_rx_msg,			/* on_rx_request()	*/
+    &logging_on_rx_msg,			/* on_rx_response()	*/
+    &logging_on_tx_msg,			/* on_tx_request.	*/
+    &logging_on_tx_msg,			/* on_tx_response()	*/
+    NULL,				/* on_tsx_state()	*/
+
+};
+
