Index: extensions/dbg_msg_timings/dbg_msg_timings.c
===================================================================
--- extensions/dbg_msg_timings/dbg_msg_timings.c	(revision 1103)
+++ extensions/dbg_msg_timings/dbg_msg_timings.c	(revision 1121)
@@ -78,14 +78,13 @@
 			TS_DIFFERENCE( &delay, &qpmd->sent_on, &pmd->received_on );
 			CHECK_MALLOC_DO( fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), return );
-			LOG_N("[TIMING] RCV ANS %ld.%06ld sec: %s", (long)delay.tv_sec, delay.tv_nsec / 1000, buf);
+			LOG_N("[TIMING] RCV ANS %ld.%06ld sec <-'%s': %s", (long)delay.tv_sec, delay.tv_nsec / 1000, peer ? peer->info.pi_diamid : "<unidentified>", buf);
 		}
 	} else if (type == HOOK_MESSAGE_SENT) {
 		DiamId_t source = NULL;
-		size_t slen = 0;
 		
 		(void)clock_gettime(CLOCK_REALTIME, &pmd->sent_on);
 		
 		/* Is this a forwarded message ? */
-		CHECK_FCT_DO( fd_msg_source_get(msg, &source, &slen), return );
+		CHECK_FCT_DO( fd_msg_source_get(msg, &source, NULL), return );
 		if (source) {
 			struct timespec delay;
@@ -93,5 +92,5 @@
 			TS_DIFFERENCE( &delay, &pmd->received_on, &pmd->sent_on );
 			CHECK_MALLOC_DO( fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), return );
-			LOG_N("[TIMING] FWD %ld.%06ld sec: %s", (long)delay.tv_sec, delay.tv_nsec / 1000, buf);
+			LOG_N("[TIMING] FWD %ld.%06ld sec '%s'->'%s': %s", (long)delay.tv_sec, delay.tv_nsec / 1000, source, peer ? peer->info.pi_diamid : "<unidentified>", buf);
 		} else if (hdr->msg_flags & CMD_FLAG_REQUEST) {
 			/* We are sending a request issued locally, nothing special to log */
@@ -103,5 +102,5 @@
 				TS_DIFFERENCE( &delay, &qpmd->received_on, &pmd->sent_on );
 				CHECK_MALLOC_DO( fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), return );
-				LOG_N("[TIMING] ANS %ld.%06ld sec: %s", (long)delay.tv_sec, delay.tv_nsec / 1000, buf);
+				LOG_N("[TIMING] ANS %ld.%06ld sec ->'%s': %s", (long)delay.tv_sec, delay.tv_nsec / 1000, peer ? peer->info.pi_diamid : "<unidentified>", buf);
 			}
 		}
Index: extensions/dict_mip6a/dict_mip6a.c
===================================================================
--- extensions/dict_mip6a/dict_mip6a.c	(revision 1120)
+++ extensions/dict_mip6a/dict_mip6a.c	(revision 1121)
@@ -405,5 +405,5 @@
 			struct dict_object * 	 type;
 			struct dict_type_data 	 tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP-Algorithm-Type)", NULL, NULL, NULL };
-			struct dict_enumval_data t_2 = { "HMAC-SHA-1", { .i32 = 2 }};
+			struct dict_enumval_data t_2 = { "HMAC-SHA-1 [HMAC]", { .i32 = 2 }};
 			struct dict_avp_data data = {
 					345, 					/* Code */
Index: libfdproto/dictionary.c
===================================================================
--- libfdproto/dictionary.c	(revision 1119)
+++ libfdproto/dictionary.c	(revision 1121)
@@ -1909,11 +1909,17 @@
 	if (ret != 0) {
 		char * buf = NULL;
-		size_t len = 0;
-		
-		CHECK_MALLOC( dict_obj_info[CHECK_TYPE(type) ? type : 0].dump_data(&buf, &len, NULL, data) );
+		size_t len = 0, offset=0;
+		
+		if (type == DICT_ENUMVAL) {
+			CHECK_MALLOC( dump_enumval_data ( &buf, &len, &offset, data, parent->data.type.type_base ));
+		} else {
+			CHECK_MALLOC( dict_obj_info[CHECK_TYPE(type) ? type : 0].dump_data(&buf, &len, &offset, data) );
+		}
+	
 		TRACE_DEBUG(INFO, "An error occurred while adding the following data in the dictionary: %s", buf);
 		
 		if (ret == EEXIST) {
-			CHECK_MALLOC( dump_object(&buf, &len, NULL, locref, 0, 0, 0) );
+			offset=0;
+			CHECK_MALLOC( dump_object(&buf, &len, &offset, locref, 0, 0, 0) );
 			TRACE_DEBUG(INFO, "Conflicting entry in the dictionary: %s", buf);
 		}
Index: libfdproto/messages.c
===================================================================
--- libfdproto/messages.c	(revision 1120)
+++ libfdproto/messages.c	(revision 1121)
@@ -885,5 +885,4 @@
 			while (inavp) {
 				struct avp * nextavp = NULL;
-				CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL);
 				CHECK_FCT_DO(  fd_msg_browse ( inavp, MSG_BRW_NEXT, &nextavp, NULL ), inavp = NULL  );
 				CHECK_MALLOC_DO( avp_format_treeview(FD_DUMP_STD_PARAMS, inavp, level + 1, first, nextavp ? 0 : 1), return NULL);
Index: tests/testmesg_stress.c
===================================================================
--- tests/testmesg_stress.c	(revision 1119)
+++ tests/testmesg_stress.c	(revision 1121)
@@ -35,4 +35,12 @@
 
 #include "tests.h"
+#include <dirent.h>
+#include <libgen.h>
+#include <dlfcn.h>
+
+#ifndef BUILD_DIR
+#error "Missing BUILD_DIR information"
+#endif /* BUILD_DIR */
+
 
 /* The number of times each operation is repeated to measure the average operation time */
@@ -47,5 +55,136 @@
 }
 
-
+struct ext_info {
+	struct fd_list	chain;		/* link in the list */
+	void 		*handler;	/* object returned by dlopen() */
+	int 		(*init_cb)(int, int, char *);
+	char		*ext_name;	/* points to the extension name, either inside depends, or basename(filename) */
+	int		free_ext_name;	/* must be freed if it was malloc'd */
+	const char 	**depends;	/* names of the other extensions this one depends on (if provided) */
+};
+	
+static void load_all_extensions(char * prefix)
+{
+	DIR *dir;
+	struct dirent *dp;
+	char fullname[512];
+	int pathlen;
+	struct fd_list all_extensions = FD_LIST_INITIALIZER(all_extensions);
+	struct fd_list ext_with_depends = FD_LIST_INITIALIZER(ext_with_depends);
+
+	/* Find all extensions which have been compiled along the test */
+	LOG_D("Loading %s*.fdx from: '%s'", BUILD_DIR "/extensions", prefix ?: "");
+	CHECK( 0, (dir = opendir (BUILD_DIR "/extensions")) == NULL ? 1 : 0 );
+	pathlen = snprintf(fullname, sizeof(fullname), BUILD_DIR "/extensions/");
+	
+	while ((dp = readdir (dir)) != NULL) {
+		char * dot = strrchr(dp->d_name, '.');
+		if (dot && ((!prefix) || !(strncmp(dp->d_name, prefix, strlen(prefix)))) && (!(strcmp(dot, ".fdx")))) {
+			/* We found a file with name dict_*.fdx, attempt to load it */
+			struct ext_info * new = malloc(sizeof(struct ext_info));
+			CHECK( 1, new ? 1:0);
+			fd_list_init(&new->chain, new);
+			
+			snprintf(fullname + pathlen, sizeof(fullname) - pathlen, "%s", dp->d_name);
+			
+			LOG_D("Extension: '%s'", dp->d_name);
+			
+			/* load */
+			new->handler = dlopen(fullname, RTLD_NOW | RTLD_GLOBAL);
+			if (!new->handler) {
+				TRACE_DEBUG(INFO, "Unable to load '%s': %s.", fullname, dlerror());
+			}
+			CHECK( 0, new->handler == NULL ? 1 : 0 );
+			
+			/* resolve entry */
+			new->init_cb = dlsym( new->handler, "fd_ext_init" );
+			if (!new->init_cb) {
+				TRACE_DEBUG(INFO, "No 'fd_ext_init' entry point in '%s': %s.", fullname, dlerror());
+			}
+			CHECK( 0, new->init_cb == NULL ? 1 : 0 );
+			
+			new->depends = dlsym( new->handler, "fd_ext_depends" );
+			if (new->depends) {
+				new->ext_name = (char *)new->depends[0];
+				new->free_ext_name = 0;
+				if ( new->depends[1] ) {
+					fd_list_insert_before(&ext_with_depends, &new->chain);
+				} else {
+					fd_list_insert_before(&all_extensions, &new->chain);
+				}
+			} else {
+				new->ext_name = strdup(basename(dp->d_name));
+				new->free_ext_name = 1;
+				fd_list_insert_before(&all_extensions, &new->chain);
+			}
+			
+		}
+	}
+	
+	/* Now, reorder the list by dependencies */
+	{
+		int count, prevcount = 0;
+		struct fd_list * li;
+		do {
+			count = 0;
+			for (li=ext_with_depends.next; li != &ext_with_depends; li=li->next) {
+				struct ext_info * e = li->o;
+				int d;
+				int satisfied=0;
+				
+				/* Can we satisfy all dependencies? */
+				for (d=1;  ;d++) {
+					struct fd_list * eli;
+					if (!e->depends[d]) {
+						satisfied = 1;
+						break;
+					}
+					
+					/* can we find this dependency in the list? */
+					for (eli=all_extensions.next; eli != &all_extensions; eli = eli->next) {
+						struct ext_info * de = eli->o;
+						if (!strcasecmp(de->ext_name, e->depends[d]))
+							break; /* this dependency is satisfied */
+					}
+					
+					if (eli == &all_extensions) {
+						satisfied = 0;
+						break;
+					}
+				}
+				
+				if (satisfied) {
+					/* OK, we have all our dependencies in the list */
+					li=li->prev;
+					fd_list_unlink(&e->chain);
+					fd_list_insert_before(&all_extensions, &e->chain);
+				} else {
+					count++;
+				}
+			}
+			
+			if (prevcount && (prevcount == count)) {
+				LOG_E("Some extensions cannot have their dependencies satisfied, e.g.: %s", ((struct ext_info *)ext_with_depends.next->o)->ext_name);
+				CHECK(0, 1);
+			}
+			prevcount = count;
+			
+			if (FD_IS_LIST_EMPTY(&ext_with_depends))
+				break;
+		} while (1);
+	}
+	
+	/* Now, load all the extensions */
+	{
+		struct fd_list * li;
+		for (li=all_extensions.next; li != &all_extensions; li=li->next) {
+			struct ext_info * e = li->o;
+			int ret = (*e->init_cb)( FD_PROJECT_VERSION_MAJOR, FD_PROJECT_VERSION_MINOR, NULL );
+			LOG_N("Initializing extension '%s': %s", e->ext_name, ret ? strerror(ret) : "Success");
+		}
+	}
+	
+	/* We should probably clean the list here ? */
+}
 
 /* Main test routine */
@@ -55,8 +194,14 @@
 	unsigned char * buf = NULL;
 	
+	int dictionaries_loaded = 0;
+	
 	test_parameter = DEFAULT_NUMBER_OF_SAMPLES;
 	
 	/* First, initialize the daemon modules */
 	INIT_FD();
+	CHECK( 0, fd_queues_init()  );
+	CHECK( 0, fd_msg_init()  );
+	CHECK( 0, fd_rtdisp_init()  );
+	
 	
 	{
@@ -379,5 +524,5 @@
 	
 	/* We have our "buf" now, length is 344 -- cf. testmesg.c. */
-	
+redo:	
 	/* Test the throughput of the different functions function */
 	{
@@ -531,5 +676,11 @@
 		free(stress_array);
 	}
-		
+	
+	if (!dictionaries_loaded) {
+		load_all_extensions("dict_");
+		dictionaries_loaded = 1;
+		printf("Loaded all dictionary extensions, restarting...\n");
+		goto redo;
+	}
 	
 	/* That's all for the tests yet */
