Index: /pjproject/trunk/pjsip/include/pjsip-ua/sip_regc.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip-ua/sip_regc.h	(revision 2854)
+++ /pjproject/trunk/pjsip/include/pjsip-ua/sip_regc.h	(revision 2855)
@@ -167,5 +167,13 @@
  *		    be a SIP/SIPS URL.
  * @param ccnt	    Number of contacts in the array.
- * @param contact   Array of contacts.
+ * @param contact   Array of contacts, each contact item must be formatted
+ *		    as described in RFC 3261 Section 20.10:
+ *		    When the header field value contains a display 
+ *		    name, the URI including all URI parameters is 
+ *		    enclosed in "<" and ">".  If no "<" and ">" are 
+ *		    present, all parameters after the URI are header
+ *		    parameters, not URI parameters.  The display name 
+ *		    can be tokens, or a quoted string, if a larger 
+ *		    character set is desired.
  * @param expires   Default expiration interval (in seconds) to be applied for
  *		    contact URL that doesn't have expiration settings. If the
@@ -304,6 +312,6 @@
 /**
  * Update Contact details in the client registration structure. For each
- * contact URI, if the uri is not found in existing contact, it will be
- * added to the Contact list. If the URI matches existing contact, nothing
+ * contact, if the contact is not found in existing contact, it will be
+ * added to the Contact list. If it matches existing contact, nothing
  * will be added. This function will also mark existing contacts which
  * are not specified in the new contact list as to be removed, by adding
@@ -318,5 +326,13 @@
  * @param regc	    The client registration structure.
  * @param ccnt	    Number of contacts.
- * @param contact   Array of contact URIs.
+ * @param contact   Array of contacts, each contact item must be formatted
+ *		    as described in RFC 3261 Section 20.10:
+ *		    When the header field value contains a display 
+ *		    name, the URI including all URI parameters is 
+ *		    enclosed in "<" and ">".  If no "<" and ">" are 
+ *		    present, all parameters after the URI are header
+ *		    parameters, not URI parameters.  The display name 
+ *		    can be tokens, or a quoted string, if a larger 
+ *		    character set is desired.
  * @return	    PJ_SUCCESS if sucessfull.
  */
Index: /pjproject/trunk/pjsip/include/pjsip/sip_dialog.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip/sip_dialog.h	(revision 2854)
+++ /pjproject/trunk/pjsip/include/pjsip/sip_dialog.h	(revision 2855)
@@ -184,7 +184,16 @@
  * @param ua		    The user agent module instance.
  * @param local_uri	    Dialog local URI (i.e. From header).
- * @param local_contact_uri Optional dialog local Contact URI. 
- *			    If this argument is NULL, the Contact will be
- *			    taken from the local URI.
+ * @param local_contact	    Optional dialog local Contact to be put as Contact
+ *			    header value, hence the format must follow
+ *			    RFC 3261 Section 20.10:
+ *			    When the header field value contains a display 
+ *			    name, the URI including all URI parameters is 
+ *			    enclosed in "<" and ">".  If no "<" and ">" are 
+ *			    present, all parameters after the URI are header
+ *			    parameters, not URI parameters.  The display name 
+ *			    can be tokens, or a quoted string, if a larger 
+ *			    character set is desired.
+ *			    If this argument is NULL, the Contact will be taken
+ *			    from the local URI.
  * @param remote_uri	    Dialog remote URI (i.e. To header).
  * @param target	    Optional initial remote target. If this argument
@@ -197,5 +206,5 @@
 PJ_DECL(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
 					   const pj_str_t *local_uri,
-					   const pj_str_t *local_contact_uri,
+					   const pj_str_t *local_contact,
 					   const pj_str_t *remote_uri,
 					   const pj_str_t *target,
@@ -221,6 +230,15 @@
  * @param rdata		    The incoming request that creates the dialog,
  *			    such as INVITE, SUBSCRIBE, or REFER.
- * @param contact	    Optional URI to be used as local Contact. If
- *			    this argument is NULL, the local contact will be
+ * @param contact	    Optional dialog local Contact to be put as Contact
+ *			    header value, hence the format must follow
+ *			    RFC 3261 Section 20.10:
+ *			    When the header field value contains a display 
+ *			    name, the URI including all URI parameters is 
+ *			    enclosed in "<" and ">".  If no "<" and ">" are 
+ *			    present, all parameters after the URI are header
+ *			    parameters, not URI parameters.  The display name 
+ *			    can be tokens, or a quoted string, if a larger 
+ *			    character set is desired.
+ *			    If this argument is NULL, the local contact will be
  *			    initialized from the value of To header in the
  *			    request.
Index: /pjproject/trunk/pjsip/include/pjsip/sip_util.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip/sip_util.h	(revision 2854)
+++ /pjproject/trunk/pjsip/include/pjsip/sip_util.h	(revision 2855)
@@ -244,5 +244,13 @@
  * @param from	    URL to put in From header.
  * @param to	    URL to put in To header.
- * @param contact   URL to put in Contact header.
+ * @param contact   Contact to be put as Contact header value, hence
+ *		    the format must follow RFC 3261 Section 20.10:
+ *		    When the header field value contains a display 
+ *		    name, the URI including all URI parameters is 
+ *		    enclosed in "<" and ">".  If no "<" and ">" are 
+ *		    present, all parameters after the URI are header
+ *		    parameters, not URI parameters.  The display name 
+ *		    can be tokens, or a quoted string, if a larger 
+ *		    character set is desired.
  * @param call_id   Optional Call-ID (put NULL to generate unique Call-ID).
  * @param cseq	    Optional CSeq (put -1 to generate random CSeq).
@@ -281,7 +289,7 @@
  * @param method    SIP Method.
  * @param target    Target URI.
- * @param from	    URL to put in From header.
- * @param to	    URL to put in To header.
- * @param contact   URL to put in Contact header.
+ * @param from	    From header.
+ * @param to	    To header.
+ * @param contact   Contact header.
  * @param call_id   Optional Call-ID (put NULL to generate unique Call-ID).
  * @param cseq	    Optional CSeq (put -1 to generate random CSeq).
Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 2854)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 2855)
@@ -2164,9 +2164,9 @@
 
 /**
- * Create a suitable URI to be put as Contact based on the specified
- * target URI for the specified account.
+ * Create a suitable Contact header value, based on the specified target URI 
+ * for the specified account.
  *
  * @param pool		Pool to allocate memory for the string.
- * @param contact	The string where the Contact URI will be stored.
+ * @param contact	The string where the Contact will be stored.
  * @param acc_id	Account ID.
  * @param uri		Destination URI of the request.
@@ -2182,9 +2182,9 @@
 
 /**
- * Create a suitable URI to be put as Contact based on the information
- * in the incoming request.
+ * Create a suitable Contact header value, based on the information in the 
+ * incoming request.
  *
  * @param pool		Pool to allocate memory for the string.
- * @param contact	The string where the Contact URI will be stored.
+ * @param contact	The string where the Contact will be stored.
  * @param acc_id	Account ID.
  * @param rdata		Incoming request.
Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 2854)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 2855)
@@ -119,5 +119,5 @@
     pj_str_t	     display;	    /**< Display name, if any.		*/
     pj_str_t	     user_part;	    /**< User part of local URI.	*/
-    pj_str_t	     contact;	    /**< Our Contact URI for REGISTER	*/
+    pj_str_t	     contact;	    /**< Our Contact header.		*/
 
     pj_str_t	     srv_domain;    /**< Host part of reg server.	*/
Index: /pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c	(revision 2854)
+++ /pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c	(revision 2855)
@@ -273,5 +273,5 @@
               pjsip_parse_hdr(regc->pool, &CONTACT, tmp.ptr, tmp.slen, NULL);
 	if (hdr == NULL) {
-	    PJ_LOG(4,(THIS_FILE, "Invalid Contact URI: \"%.*s\"", 
+	    PJ_LOG(4,(THIS_FILE, "Invalid Contact: \"%.*s\"", 
 		     (int)tmp.slen, tmp.ptr));
 	    return PJSIP_EINVALIDURI;
Index: /pjproject/trunk/pjsip/src/pjsip/sip_dialog.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_dialog.c	(revision 2854)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_dialog.c	(revision 2855)
@@ -44,4 +44,6 @@
 pj_bool_t pjsip_include_allow_hdr_in_dlg = PJSIP_INCLUDE_ALLOW_HDR_IN_DLG;
 
+/* Contact header string */
+static const pj_str_t HCONTACT = { "Contact", 7 };
 
 PJ_DEF(pj_bool_t) pjsip_method_creates_dialog(const pjsip_method *m)
@@ -211,10 +213,9 @@
 
     /* Init local contact. */
-    dlg->local.contact = pjsip_contact_hdr_create(dlg->pool);
     pj_strdup_with_null(dlg->pool, &tmp, 
 			local_contact ? local_contact : local_uri);
-    dlg->local.contact->uri = pjsip_parse_uri(dlg->pool, tmp.ptr, tmp.slen,
-					      PJSIP_PARSE_URI_AS_NAMEADDR);
-    if (!dlg->local.contact->uri) {
+    dlg->local.contact = pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr, 
+					 tmp.slen, NULL);
+    if (!dlg->local.contact) {
 	status = PJSIP_EINVALIDURI;
 	goto on_error;
@@ -391,9 +392,8 @@
 	pj_str_t tmp;
 
-	dlg->local.contact = pjsip_contact_hdr_create(dlg->pool);
 	pj_strdup_with_null(dlg->pool, &tmp, contact);
-	dlg->local.contact->uri = pjsip_parse_uri(dlg->pool, tmp.ptr, tmp.slen,
-						  PJSIP_PARSE_URI_AS_NAMEADDR);
-	if (!dlg->local.contact->uri) {
+	dlg->local.contact = pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr, 
+					     tmp.slen, NULL);
+	if (!dlg->local.contact) {
 	    status = PJSIP_EINVALIDURI;
 	    goto on_error;
@@ -1226,9 +1226,7 @@
 	    st_code==485) 
 	{
-	    pj_str_t hcontact = { "Contact", 7 };
-
 	    /* Add contact header only if one is not present. */
 	    if (pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL) == 0 &&
-		pjsip_msg_find_hdr_by_name(tdata->msg, &hcontact, NULL) == 0) 
+		pjsip_msg_find_hdr_by_name(tdata->msg, &HCONTACT, NULL) == 0) 
 	    {
 		hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, 
Index: /pjproject/trunk/pjsip/src/pjsip/sip_util.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_util.c	(revision 2854)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_util.c	(revision 2855)
@@ -308,4 +308,5 @@
     pj_str_t tmp;
     pj_status_t status;
+    const pj_str_t STR_CONTACT = { "Contact", 7 };
     PJ_USE_EXCEPTION;
 
@@ -349,9 +350,9 @@
 	/* Contact. */
 	if (param_contact) {
-	    contact = pjsip_contact_hdr_create(tdata->pool);
 	    pj_strdup_with_null(tdata->pool, &tmp, param_contact);
-	    contact->uri = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen,
-					    PJSIP_PARSE_URI_AS_NAMEADDR);
-	    if (contact->uri == NULL) {
+	    contact = (pjsip_contact_hdr*)
+		      pjsip_parse_hdr(tdata->pool, &STR_CONTACT, tmp.ptr, 
+				      tmp.slen, NULL);
+	    if (contact == NULL) {
 		status = PJSIP_EINVALIDHDR;
 		goto on_error;
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c	(revision 2854)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c	(revision 2855)
@@ -574,4 +574,6 @@
     pj_bool_t matched;
     pj_str_t srv_ip;
+    pjsip_contact_hdr *contact_hdr;
+    const pj_str_t STR_CONTACT = { "Contact", 7 };
 
     tp = param->rdata->tp_info.transport;
@@ -620,6 +622,9 @@
     /* Compare received and rport with the URI in our registration */
     pool = pjsua_pool_create("tmp", 512, 512);
-    uri = (pjsip_sip_uri*)
-	  pjsip_parse_uri(pool, acc->contact.ptr, acc->contact.slen, 0);
+    contact_hdr = (pjsip_contact_hdr*)
+		  pjsip_parse_hdr(pool, &STR_CONTACT, acc->contact.ptr, 
+				  acc->contact.slen, NULL);
+    pj_assert(contact_hdr != NULL);
+    uri = (pjsip_sip_uri*) contact_hdr->uri;
     pj_assert(uri != NULL);
     uri = (pjsip_sip_uri*) pjsip_uri_get_uri(uri);
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_im.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_im.c	(revision 2854)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_im.c	(revision 2855)
@@ -510,4 +510,5 @@
     pjsip_media_type media_type;
     pjsua_im_data *im_data;
+    pjsua_acc *acc;
     pj_str_t contact;
     pj_status_t status;
@@ -515,9 +516,11 @@
     /* To and message body must be specified. */
     PJ_ASSERT_RETURN(to && content, PJ_EINVAL);
+
+    acc = &pjsua_var.acc[acc_id];
 
     /* Create request. */
     status = pjsip_endpt_create_request(pjsua_var.endpt, 
 					&pjsip_message_method, to, 
-					&pjsua_var.acc[acc_id].cfg.id,
+					&acc->cfg.id,
 					to, NULL, NULL, -1, NULL, &tdata);
     if (status != PJ_SUCCESS) {
@@ -529,8 +532,8 @@
      * the request.
      */
-    if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) {
+    if (acc->cfg.transport_id != PJSUA_INVALID_ID) {
 	pjsip_tpselector tp_sel;
 
-	pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel);
+	pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel);
 	pjsip_tx_data_set_transport(tdata, &tp_sel);
     }
@@ -540,10 +543,16 @@
 		       (pjsip_hdr*)pjsua_im_create_accept(tdata->pool));
 
-    /* Add contact. */
-    status = pjsua_acc_create_uac_contact(tdata->pool, &contact, acc_id, to);
-    if (status != PJ_SUCCESS) {
-	pjsua_perror(THIS_FILE, "Unable to generate Contact header", status);
-	pjsip_tx_data_dec_ref(tdata);
-	return status;
+    /* Create suitable Contact header unless a Contact header has been
+     * set in the account.
+     */
+    if (acc->contact.slen) {
+	contact = acc->contact;
+    } else {
+	status = pjsua_acc_create_uac_contact(tdata->pool, &contact, acc_id, to);
+	if (status != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, "Unable to generate Contact header", status);
+	    pjsip_tx_data_dec_ref(tdata);
+	    return status;
+	}
     }
 
@@ -585,5 +594,5 @@
 
     /* Add route set */
-    pjsua_set_msg_route_set(tdata, &pjsua_var.acc[acc_id].route_set);
+    pjsua_set_msg_route_set(tdata, &acc->route_set);
 
     /* Send request (statefully) */
@@ -610,10 +619,13 @@
     pjsua_im_data *im_data;
     pjsip_tx_data *tdata;
+    pjsua_acc *acc;
     pj_str_t contact;
     pj_status_t status;
 
+    acc = &pjsua_var.acc[acc_id];
+
     /* Create request. */
     status = pjsip_endpt_create_request( pjsua_var.endpt, &pjsip_message_method,
-					 to, &pjsua_var.acc[acc_id].cfg.id,
+					 to, &acc->cfg.id,
 					 to, NULL, NULL, -1, NULL, &tdata);
     if (status != PJ_SUCCESS) {
@@ -626,8 +638,8 @@
      * the request.
      */
-    if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) {
+    if (acc->cfg.transport_id != PJSUA_INVALID_ID) {
 	pjsip_tpselector tp_sel;
 
-	pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel);
+	pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel);
 	pjsip_tx_data_set_transport(tdata, &tp_sel);
     }
@@ -638,10 +650,16 @@
 
 
-    /* Add contact. */
-    status = pjsua_acc_create_uac_contact(tdata->pool, &contact, acc_id, to);
-    if (status != PJ_SUCCESS) {
-	pjsua_perror(THIS_FILE, "Unable to generate Contact header", status);
-	pjsip_tx_data_dec_ref(tdata);
-	return status;
+    /* Create suitable Contact header unless a Contact header has been
+     * set in the account.
+     */
+    if (acc->contact.slen) {
+	contact = acc->contact;
+    } else {
+	status = pjsua_acc_create_uac_contact(tdata->pool, &contact, acc_id, to);
+	if (status != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, "Unable to generate Contact header", status);
+	    pjsip_tx_data_dec_ref(tdata);
+	    return status;
+	}
     }
 
@@ -659,5 +677,5 @@
 
     /* Add route set */
-    pjsua_set_msg_route_set(tdata, &pjsua_var.acc[acc_id].route_set);
+    pjsua_set_msg_route_set(tdata, &acc->route_set);
 
     /* Create data to reauthenticate */
