Index: /pjproject/trunk/pjsip/include/pjsip/sip_parser.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip/sip_parser.h	(revision 2192)
+++ /pjproject/trunk/pjsip/include/pjsip/sip_parser.h	(revision 2193)
@@ -359,4 +359,5 @@
     pj_cis_t pjsip_DISPLAY_SPEC;	/**< Used when searching for display
 					     name.			*/
+    pj_cis_t pjsip_OTHER_URI_CONTENT;	/**< Generic URI content.	*/
 
 } pjsip_parser_const_t;
Index: /pjproject/trunk/pjsip/include/pjsip/sip_uri.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip/sip_uri.h	(revision 2192)
+++ /pjproject/trunk/pjsip/include/pjsip/sip_uri.h	(revision 2193)
@@ -415,11 +415,40 @@
 				      const pjsip_name_addr *rhs);
 
-
-
-
 /**
  * @}
  */
 
+/**
+ * @defgroup PJSIP_OTHER_URI Other URI schemes
+ * @ingroup PJSIP_URI
+ * @brief Container for non SIP/tel URI scheme (e.g. "http:", "mailto:")
+ * @{
+ */
+
+/**
+ * Generic URI container for non SIP/tel URI scheme.
+ */
+typedef struct pjsip_other_uri 
+{
+    pjsip_uri_vptr *vptr;	/**< Pointer to virtual function table.	*/
+    pj_str_t scheme;		/**< The URI scheme (e.g. "mailto")	*/
+    pj_str_t content;		/**< The whole URI content		*/
+} pjsip_other_uri;
+
+
+/**
+ * Create a generic URI object.
+ *
+ * @param pool	    The pool to allocate memory from.
+ *
+ * @return	    The URI instance.
+ */
+PJ_DECL(pjsip_other_uri*) pjsip_other_uri_create(pj_pool_t *pool);
+
+
+/**
+ * @}
+ */
+
 PJ_END_DECL
 
Index: /pjproject/trunk/pjsip/src/pjsip/sip_parser.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_parser.c	(revision 2192)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_parser.c	(revision 2193)
@@ -48,4 +48,9 @@
 #define HNV_UNRESERVED	    "[]/?:+$"
 #define HDR_CHAR	    HNV_UNRESERVED UNRESERVED ESCAPED
+
+/* A generic URI can consist of (For a complete BNF see RFC 2396):
+     #?;:@&=+-_.!~*'()%$,/
+ */
+#define GENERIC_URI_CHARS   "#?;:@&=+-_.!~*'()%$,/" "%"
 
 #define PJSIP_VERSION		"SIP/2.0"
@@ -153,4 +158,7 @@
                     int_parse_name_addr( pj_scanner *scanner, 
 					 pj_pool_t *pool );
+static void*	    int_parse_other_uri(pj_scanner *scanner, 
+					pj_pool_t *pool,
+					pj_bool_t parse_params);
 static void	    parse_hdr_end( pj_scanner *scanner );
 
@@ -377,4 +385,8 @@
     pj_cis_invert(&pconst.pjsip_DISPLAY_SPEC);
 
+    status = pj_cis_dup(&pconst.pjsip_OTHER_URI_CONTENT, &pconst.pjsip_ALNUM_SPEC);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_str( &pconst.pjsip_OTHER_URI_CONTENT, GENERIC_URI_CHARS);
+
     /*
      * Register URI parsers.
@@ -691,5 +703,5 @@
 	    return uri_handler[i].parse;
     }
-    return NULL;
+    return &int_parse_other_uri;
 }
 
@@ -1464,4 +1476,31 @@
 
 
+/* Parse other URI */
+static void* int_parse_other_uri(pj_scanner *scanner, 
+				 pj_pool_t *pool,
+				 pj_bool_t parse_params)
+{
+    pjsip_other_uri *uri = 0;
+    const pjsip_parser_const_t *pc = pjsip_parser_const();
+    int skip_ws = scanner->skip_ws;
+
+    PJ_UNUSED_ARG(parse_params);
+
+    scanner->skip_ws = 0;
+    
+    uri = pjsip_other_uri_create(pool); 
+    
+    pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &uri->scheme);
+    if (pj_scan_get_char(scanner) != ':') {
+	PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
+    }
+    
+    pj_scan_get(scanner, &pc->pjsip_OTHER_URI_CONTENT, &uri->content);
+    scanner->skip_ws = skip_ws;
+    
+    return uri;
+}
+
+
 /* Parse SIP request line. */
 static void int_parse_req_line( pj_scanner *scanner, pj_pool_t *pool,
Index: /pjproject/trunk/pjsip/src/pjsip/sip_uri.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_uri.c	(revision 2192)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_uri.c	(revision 2193)
@@ -618,2 +618,95 @@
 }
 
+///////////////////////////////////////////////////////////////////////////////
+
+static const pj_str_t *other_uri_get_scheme( const pjsip_other_uri*);
+static void *other_uri_get_uri( pjsip_other_uri*);
+static pj_ssize_t other_uri_print( pjsip_uri_context_e context,
+				   const pjsip_other_uri *url, 
+				   char *buf, pj_size_t size);
+static int other_uri_cmp( pjsip_uri_context_e context,
+			  const pjsip_other_uri *url1, 
+			  const pjsip_other_uri *url2);
+static pjsip_other_uri* other_uri_clone( pj_pool_t *pool, 
+					 const pjsip_other_uri *rhs);
+
+static pjsip_uri_vptr other_uri_vptr = 
+{
+    (P_GET_SCHEME)  &other_uri_get_scheme,
+    (P_GET_URI)	    &other_uri_get_uri,
+    (P_PRINT_URI)   &other_uri_print,
+    (P_CMP_URI)	    &other_uri_cmp,
+    (P_CLONE) 	    &other_uri_clone
+};
+
+
+PJ_DEF(pjsip_other_uri*) pjsip_other_uri_create(pj_pool_t *pool) 
+{
+    pjsip_other_uri *uri = PJ_POOL_ZALLOC_T(pool, pjsip_other_uri);
+    uri->vptr = &other_uri_vptr;
+    return uri;
+}
+
+static const pj_str_t *other_uri_get_scheme( const pjsip_other_uri *uri )
+{
+	return &uri->scheme;
+}
+
+static void *other_uri_get_uri( pjsip_other_uri *uri )
+{
+    return uri;
+}
+
+static pj_ssize_t other_uri_print(pjsip_uri_context_e context,
+				  const pjsip_other_uri *uri, 
+				  char *buf, pj_size_t size)
+{
+    char *startbuf = buf;
+    char *endbuf = buf + size;
+    
+    PJ_UNUSED_ARG(context);
+    
+    if (uri->scheme.slen + uri->content.slen + 1 > (int)size)
+	return -1;
+
+    /* Print scheme. */
+    copy_advance(buf, uri->scheme);
+    *buf++ = ':';
+    
+    /* Print content. */
+    copy_advance(buf, uri->content);
+    
+    return (buf - startbuf);
+}
+
+static int other_uri_cmp(pjsip_uri_context_e context,
+			 const pjsip_other_uri *uri1,
+			 const pjsip_other_uri *uri2)
+{
+    PJ_UNUSED_ARG(context);
+    
+    /* Scheme must match. */
+    if (pj_stricmp(&uri1->scheme, &uri2->scheme) != 0) {
+	return PJSIP_ECMPSCHEME;
+    }
+    
+    /* Content must match. */
+    if(pj_stricmp(&uri1->content, &uri2->content) != 0) {
+	return -1;
+    }
+    
+    /* Equal. */
+    return 0;
+}
+
+/* Clone *: URI */
+static pjsip_other_uri* other_uri_clone(pj_pool_t *pool, 
+					const pjsip_other_uri *rhs) 
+{
+    pjsip_other_uri *uri = pjsip_other_uri_create(pool);
+    pj_strdup(pool, &uri->scheme, &rhs->scheme);
+    pj_strdup(pool, &uri->content, &rhs->content);
+
+    return uri;
+}
+
