Index: freeDiameter/tests/testdisp.c
===================================================================
--- freeDiameter/tests/testdisp.c	(revision 90)
+++ freeDiameter/tests/testdisp.c	(revision 639)
@@ -36,16 +36,19 @@
 #include "tests.h"
 	
-#define Define_cb( __int, __extra )										\
-int cb_##__int( struct msg ** msg, struct avp * avp, struct session * session, enum disp_action * action )	\
-{														\
-	CHECK( 1, msg ? 1 : 0 );										\
-	CHECK( 1, action ? 1 : 0 );										\
-	CHECK( sess, session );											\
-	*action = DISP_ACT_CONT;										\
-	cbcalled[__int] += 1;											\
-	do {													\
-		__extra ;											\
-	} while (0);												\
-	return 0;												\
+#define Define_cb( __int, __extra )												\
+int cb_##__int( struct msg ** msg, struct avp * avp, struct session * session, void * opaque, enum disp_action * action )	\
+{																\
+	CHECK( 1, msg ? 1 : 0 );												\
+	CHECK( 1, action ? 1 : 0 );												\
+	CHECK( sess, session );													\
+	if (opaque) {														\
+		CHECK( 1, opaque == g_opaque ? 1 : 0 );										\
+	}															\
+	*action = DISP_ACT_CONT;												\
+	cbcalled[__int] += 1;													\
+	do {															\
+		__extra ;													\
+	} while (0);														\
+	return 0;														\
 }
 
@@ -53,4 +56,5 @@
 char cbcalled[NB_CB];
 struct session * sess;
+void * g_opaque = (void *)"test";
 
 /* cb_0 */  Define_cb( 0, );
@@ -142,9 +146,9 @@
 	/* Register first handler, very simple test */
 	{
-		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, NULL, &hdl[0] ) );
+		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, NULL, NULL, &hdl[0] ) );
 		CHECK( 1, hdl[0] ? 1 : 0 );
-		CHECK( 0, fd_disp_unregister( &hdl[0] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
 		CHECK( NULL, hdl[0] );
-		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, NULL, &hdl[0] ) );
+		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, NULL, NULL, &hdl[0] ) );
 	
 		/* Check this handler is called for a message */
@@ -157,18 +161,18 @@
 		/* Delete the message */
 		CHECK( 0, fd_msg_free( msg ) );
-		CHECK( 0, fd_disp_unregister( &hdl[0] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
 	}
 	
 	/* Handlers for applications */
 	{
-		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, &hdl[0] ) );
+		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) );
 		when.app = app1;
-		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_APPID, &when, &hdl[1] ) );
+		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_APPID, &when, NULL, &hdl[1] ) );
 		when.app = app2;
-		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_APPID, &when, &hdl[2] ) );
+		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_APPID, &when, NULL, &hdl[2] ) );
 		when.avp = avp2;
-		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_APPID, &when, &hdl[3] ) );
+		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_APPID, &when, NULL, &hdl[3] ) );
 		when.avp = avp1;
-		CHECK( 0, fd_disp_register( cb_4, DISP_HOW_APPID, &when, &hdl[4] ) );
+		CHECK( 0, fd_disp_register( cb_4, DISP_HOW_APPID, &when, NULL, &hdl[4] ) );
 	
 		/* Check the callbacks are called as appropriate */
@@ -206,9 +210,9 @@
 		CHECK( 0, fd_msg_free( msg ) );
 		
-		CHECK( 0, fd_disp_unregister( &hdl[0] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[1] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[2] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[3] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[4] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[4], NULL ) );
 	}
 	
@@ -217,14 +221,14 @@
 		when.app = NULL;
 		when.command = NULL;
-		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, &hdl[0] ) );
-		CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_CC, &when, &hdl[1] ) );
+		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) );
+		CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_CC, &when, NULL, &hdl[1] ) );
 		when.command = cmd1;
-		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_CC, &when, &hdl[1] ) ); /* cmd1 */
+		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_CC, &when, NULL, &hdl[1] ) ); /* cmd1 */
 		when.app = app2;
-		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_CC, &when, &hdl[2] ) ); /* app2 + cmd1 */
+		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_CC, &when, NULL, &hdl[2] ) ); /* app2 + cmd1 */
 		when.command = cmd2;
 		when.app = NULL;
 		when.avp = avp1;
-		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_CC, &when, &hdl[3] ) ); /* cmd2 (avp1 ignored) */
+		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_CC, &when, NULL, &hdl[3] ) ); /* cmd2 (avp1 ignored) */
 		
 		/* Check the callbacks are called as appropriate */
@@ -269,8 +273,8 @@
 		CHECK( 0, fd_msg_free( msg ) );
 		
-		CHECK( 0, fd_disp_unregister( &hdl[0] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[1] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[2] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[3] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
 	}
 	
@@ -281,19 +285,19 @@
 		when.avp = NULL;
 	
-		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, &hdl[0] ) ); /* all */
-		CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_AVP, &when, &hdl[1] ) );
+		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) ); /* all */
+		CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_AVP, &when, NULL, &hdl[1] ) );
 		
 		when.avp = avp1;
-		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_AVP, &when, &hdl[1] ) ); /* avp1 */
+		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_AVP, &when, NULL, &hdl[1] ) ); /* avp1 */
 		
 		when.command = cmd1;
-		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_AVP, &when, &hdl[2] ) ); /* avp1 + cmd1 */
+		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_AVP, &when, NULL, &hdl[2] ) ); /* avp1 + cmd1 */
 		
 		when.command = NULL;
 		when.app = app1;
-		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_AVP, &when, &hdl[3] ) ); /* avp1 + app1 */
+		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_AVP, &when, NULL, &hdl[3] ) ); /* avp1 + app1 */
 		
 		when.command = cmd1;
-		CHECK( 0, fd_disp_register( cb_4, DISP_HOW_AVP, &when, &hdl[4] ) ); /* avp1 + cmd1 + app1 */
+		CHECK( 0, fd_disp_register( cb_4, DISP_HOW_AVP, &when, NULL, &hdl[4] ) ); /* avp1 + cmd1 + app1 */
 		
 		when.app = NULL;
@@ -301,8 +305,8 @@
 		when.avp = avp2;
 		when.value = enu1;
-		CHECK( 0, fd_disp_register( cb_5, DISP_HOW_AVP, &when, &hdl[5] ) ); /* avp2 */
+		CHECK( 0, fd_disp_register( cb_5, DISP_HOW_AVP, &when, NULL, &hdl[5] ) ); /* avp2 */
 		
 		when.value = enu2;
-		CHECK( 0, fd_disp_register( cb_7, DISP_HOW_AVP, &when, &hdl[6] ) ); /* avp2 */
+		CHECK( 0, fd_disp_register( cb_7, DISP_HOW_AVP, &when, NULL, &hdl[6] ) ); /* avp2 */
 		
 		
@@ -396,11 +400,11 @@
 		CHECK( 0, fd_msg_free( msg ) );
 		
-		CHECK( 0, fd_disp_unregister( &hdl[0] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[1] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[2] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[3] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[4] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[5] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[6] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[4], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[5], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[6], NULL ) );
 	}
 		
@@ -412,20 +416,20 @@
 		when.value = NULL;
 		
-		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, &hdl[0] ) ); /* all */
-		CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, &hdl[1] ) );
+		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) ); /* all */
+		CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[1] ) );
 		when.value = enu1;
-		CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, &hdl[1] ) );
+		CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[1] ) );
 		when.avp = avp1;
-		CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, &hdl[1] ) );
+		CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[1] ) );
 		when.avp = avp2;
-		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, &hdl[1] ) ); /* avp2, enu1 */
+		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[1] ) ); /* avp2, enu1 */
 		
 		when.command = cmd1;
-		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_AVP_ENUMVAL, &when, &hdl[2] ) ); /* avp2, enu1 + cmd1 */
+		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[2] ) ); /* avp2, enu1 + cmd1 */
 		
 		when.command = NULL;
 		when.app = app1;
 		when.value = enu2;
-		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_AVP_ENUMVAL, &when, &hdl[3] ) ); /* avp2, enu2 + app1 */
+		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[3] ) ); /* avp2, enu2 + app1 */
 		
 		/* Check the callbacks are called as appropriate */
@@ -498,17 +502,17 @@
 		CHECK( 0, fd_msg_free( msg ) );
 		
-		CHECK( 0, fd_disp_unregister( &hdl[0] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[1] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[2] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[3] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
 	}
 	
 	/* Test behavior of handlers */
 	{
-		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, &hdl[0] ) );
-		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_ANY, &when, &hdl[1] ) );
-		CHECK( 0, fd_disp_register( cb_6, DISP_HOW_ANY, &when, &hdl[2] ) );
-		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_ANY, &when, &hdl[3] ) );
-		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_ANY, &when, &hdl[4] ) );
+		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) );
+		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_ANY, &when, NULL, &hdl[1] ) );
+		CHECK( 0, fd_disp_register( cb_6, DISP_HOW_ANY, &when, NULL, &hdl[2] ) );
+		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_ANY, &when, NULL, &hdl[3] ) );
+		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_ANY, &when, NULL, &hdl[4] ) );
 		
 		memset(cbcalled, 0, sizeof(cbcalled));
@@ -522,15 +526,15 @@
 		CHECK( 0, fd_msg_free( msg ) );
 		
-		CHECK( 0, fd_disp_unregister( &hdl[0] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[1] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[2] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[3] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[4] ) );
-		
-		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, &hdl[0] ) );
-		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_ANY, &when, &hdl[1] ) );
-		CHECK( 0, fd_disp_register( cb_8, DISP_HOW_ANY, &when, &hdl[2] ) );
-		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_ANY, &when, &hdl[3] ) );
-		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_ANY, &when, &hdl[4] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[4], NULL ) );
+		
+		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) );
+		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_ANY, &when, NULL, &hdl[1] ) );
+		CHECK( 0, fd_disp_register( cb_8, DISP_HOW_ANY, &when, NULL, &hdl[2] ) );
+		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_ANY, &when, NULL, &hdl[3] ) );
+		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_ANY, &when, NULL, &hdl[4] ) );
 		
 		memset(cbcalled, 0, sizeof(cbcalled));
@@ -544,15 +548,15 @@
 		CHECK( NULL, msg );
 		
-		CHECK( 0, fd_disp_unregister( &hdl[0] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[1] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[2] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[3] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[4] ) );
-		
-		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, &hdl[0] ) );
-		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_ANY, &when, &hdl[1] ) );
-		CHECK( 0, fd_disp_register( cb_9, DISP_HOW_ANY, &when, &hdl[2] ) );
-		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_ANY, &when, &hdl[3] ) );
-		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_ANY, &when, &hdl[4] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[4], NULL ) );
+		
+		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) );
+		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_ANY, &when, NULL, &hdl[1] ) );
+		CHECK( 0, fd_disp_register( cb_9, DISP_HOW_ANY, &when, NULL, &hdl[2] ) );
+		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_ANY, &when, NULL, &hdl[3] ) );
+		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_ANY, &when, NULL, &hdl[4] ) );
 		
 		memset(cbcalled, 0, sizeof(cbcalled));
@@ -567,9 +571,9 @@
 		CHECK( 0, fd_msg_free( msg ) );
 		
-		CHECK( 0, fd_disp_unregister( &hdl[0] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[1] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[2] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[3] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[4] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[4], NULL ) );
 	}
 		
@@ -581,9 +585,9 @@
 		when.value = enu2;
 		
-		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, &hdl[0] ) );
-		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, &hdl[1] ) );
-		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_AVP, &when, &hdl[2] ) );
-		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_CC, &when, &hdl[3] ) );
-		CHECK( 0, fd_disp_register( cb_4, DISP_HOW_APPID, &when, &hdl[4] ) );
+		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) );
+		CHECK( 0, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[1] ) );
+		CHECK( 0, fd_disp_register( cb_2, DISP_HOW_AVP, &when, NULL, &hdl[2] ) );
+		CHECK( 0, fd_disp_register( cb_3, DISP_HOW_CC, &when, NULL, &hdl[3] ) );
+		CHECK( 0, fd_disp_register( cb_4, DISP_HOW_APPID, &when, NULL, &hdl[4] ) );
 		
 		memset(cbcalled, 0, sizeof(cbcalled));
@@ -598,5 +602,5 @@
 		CHECK( 0, fd_msg_free( msg ) );
 		
-		CHECK( 0, fd_disp_register( cb_9, DISP_HOW_ANY, &when, &hdl[5] ) );
+		CHECK( 0, fd_disp_register( cb_9, DISP_HOW_ANY, &when, NULL, &hdl[5] ) );
 		memset(cbcalled, 0, sizeof(cbcalled));
 		msg = new_msg( 2, cmd2, avp1, avp2, 2 );
@@ -609,7 +613,7 @@
 		CHECK( 1, cbcalled[9] );
 		CHECK( 0, fd_msg_free( msg ) );
-		CHECK( 0, fd_disp_unregister( &hdl[5] ) );
-		
-		CHECK( 0, fd_disp_register( cb_9, DISP_HOW_AVP_ENUMVAL, &when, &hdl[5] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[5], NULL ) );
+		
+		CHECK( 0, fd_disp_register( cb_9, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[5] ) );
 		memset(cbcalled, 0, sizeof(cbcalled));
 		msg = new_msg( 2, cmd2, avp1, avp2, 2 );
@@ -622,7 +626,7 @@
 		CHECK( 1, cbcalled[9] );
 		CHECK( 0, fd_msg_free( msg ) );
-		CHECK( 0, fd_disp_unregister( &hdl[5] ) );
-		
-		CHECK( 0, fd_disp_register( cb_9, DISP_HOW_AVP, &when, &hdl[5] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[5], NULL ) );
+		
+		CHECK( 0, fd_disp_register( cb_9, DISP_HOW_AVP, &when, NULL, &hdl[5] ) );
 		memset(cbcalled, 0, sizeof(cbcalled));
 		msg = new_msg( 2, cmd2, avp1, avp2, 2 );
@@ -635,7 +639,7 @@
 		CHECK( 1, cbcalled[9] );
 		CHECK( 0, fd_msg_free( msg ) );
-		CHECK( 0, fd_disp_unregister( &hdl[5] ) );
-		
-		CHECK( 0, fd_disp_register( cb_9, DISP_HOW_CC, &when, &hdl[5] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[5], NULL ) );
+		
+		CHECK( 0, fd_disp_register( cb_9, DISP_HOW_CC, &when, NULL, &hdl[5] ) );
 		memset(cbcalled, 0, sizeof(cbcalled));
 		msg = new_msg( 2, cmd2, avp1, avp2, 2 );
@@ -648,7 +652,7 @@
 		CHECK( 1, cbcalled[9] );
 		CHECK( 0, fd_msg_free( msg ) );
-		CHECK( 0, fd_disp_unregister( &hdl[5] ) );
-		
-		CHECK( 0, fd_disp_register( cb_9, DISP_HOW_APPID, &when, &hdl[5] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[5], NULL ) );
+		
+		CHECK( 0, fd_disp_register( cb_9, DISP_HOW_APPID, &when, NULL, &hdl[5] ) );
 		memset(cbcalled, 0, sizeof(cbcalled));
 		msg = new_msg( 2, cmd2, avp1, avp2, 2 );
@@ -661,11 +665,11 @@
 		CHECK( 1, cbcalled[9] );
 		CHECK( 0, fd_msg_free( msg ) );
-		CHECK( 0, fd_disp_unregister( &hdl[5] ) );
-		
-		CHECK( 0, fd_disp_unregister( &hdl[0] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[1] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[2] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[3] ) );
-		CHECK( 0, fd_disp_unregister( &hdl[4] ) );
+		CHECK( 0, fd_disp_unregister( &hdl[5], NULL ) );
+		
+		CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
+		CHECK( 0, fd_disp_unregister( &hdl[4], NULL ) );
 	}			
 	
@@ -698,4 +702,22 @@
 	}
 	
+	/* Test opaque pointer management */
+	{
+		void * ptr;
+		CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, NULL, g_opaque, &hdl[0] ) );
+	
+		/* Check this handler is called for a message */
+		msg = new_msg( 0, cmd1, avp1, NULL, 0 );
+		memset(cbcalled, 0, sizeof(cbcalled));
+		CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec ) );
+		CHECK( 1, cbcalled[0] );
+		CHECK( DISP_ACT_CONT, action );
+		
+		/* Delete the message */
+		CHECK( 0, fd_msg_free( msg ) );
+		CHECK( 0, fd_disp_unregister( &hdl[0], &ptr ) );
+		CHECK( 1, ptr == g_opaque ? 1 : 0 );
+	}
+	
 	/* That's all for the tests yet */
 	PASSTEST();
