Index: extensions/dbg_interactive/CMakeLists.txt
===================================================================
--- extensions/dbg_interactive/CMakeLists.txt	(revision 624)
+++ extensions/dbg_interactive/CMakeLists.txt	(revision 625)
@@ -42,5 +42,5 @@
     "fDpy-inc.c"
     MAIN_DEPENDENCY "${swig_extra_generated_files}"
-    COMMENT "Converting swig proxy class to C string") 
+    COMMENT "Shadow definitions") 
 
 # Ensure that the generated source files are removed
@@ -55,2 +55,9 @@
 TARGET_LINK_LIBRARIES(dbg_interactive ${PYTHON_LIBRARIES})
 
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dbg_interactive
+	LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+	COMPONENT freeDiameter-debug-tools)
Index: extensions/dbg_interactive/dbg_interactive.c
===================================================================
--- extensions/dbg_interactive/dbg_interactive.c	(revision 624)
+++ extensions/dbg_interactive/dbg_interactive.c	(revision 625)
@@ -57,11 +57,14 @@
 	TRACE_ENTRY("%p", arg);
 	
-	fd_log_threadname ( "[dbg_interactive python interpreter]" );
+	fd_log_threadname ( "fDpy" );
 	
-	sleep(1);
-	fd_log_debug("\nStarting python interpreter [experimental].\n");
-	fd_log_debug("Example syntax:\n>>> print fd_config_cnf_diamid_get(cvar.fd_g_config)\n\n");
+	CHECK_FCT_DO(fd_wait_initialization_complete(), goto end);
+	
+	fd_log_debug("\nStarting interactive python interpreter [experimental].\n");
+	if (!arg) 
+		fd_log_debug("Example syntax:\n   >>> print cvar.fd_g_config.cnf_diamid\n   '%s'\n", fd_g_config->cnf_diamid);
 	Py_Main(arg ? 2 : 1, dum);
 	
+end:	
 	/* Upon exit, issue the order of terminating to fD */
 	CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, 0, NULL), );
@@ -100,9 +103,4 @@
 		free(shadow_hlp);
 		
-	
-	if (TRACE_BOOL(INFO)) {
-		PyRun_SimpleString("print \"[dbg_interactive] \",FD_PROJECT_NAME,FD_PROJECT_VERSION_MAJOR,FD_PROJECT_VERSION_MINOR,FD_PROJECT_VERSION_REV\n");
-	}
-	
 	CHECK_POSIX( pthread_create(&pyinterp, NULL, myinterp, conffile) );
  
Index: extensions/dbg_interactive/dbg_interactive.i
===================================================================
--- extensions/dbg_interactive/dbg_interactive.i	(revision 624)
+++ extensions/dbg_interactive/dbg_interactive.i	(revision 625)
@@ -47,5 +47,4 @@
 /* Include standard types & functions used in freeDiameter headers */
 %include <stdint.i>
-%include <cpointer.i>
 %include <cdata.i>
 %include <cstring.i>
@@ -64,18 +63,28 @@
 %immutable peer_state_str;
 
-/* Overwrite a few functions prototypes for usability: default parameters values, OUTPUT typemaps, ... */
-extern void fd_list_init ( struct fd_list * list, void * obj = NULL );
-
-
-/*
-extern int fd_dict_new ( struct dictionary * dict, enum dict_object_type type, void * data, struct dict_object * parent, struct dict_object ** OUTPUT );
-extern int fd_dict_search ( struct dictionary * dict, enum dict_object_type type, int criteria, void * what, struct dict_object ** OUTPUT, int retval );
-extern int fd_dict_get_error_cmd(struct dictionary * dict, struct dict_object ** OUTPUT);
-extern int fd_dict_getval ( struct dict_object * object, void * INOUT);
-//extern int fd_dict_gettype ( struct dict_object * object, enum dict_object_type * OUTPUT);
-extern int fd_dict_getdict ( struct dict_object * object, struct dictionary ** OUTPUT);
-*/
-
-/* Retrieve the compile-time definitions of freeDiameter */
+
+
+/***********************************
+ Some types & typemaps for usability 
+ ***********************************/
+
+/* for fd_hash */
+%apply (char *STRING, size_t LENGTH) { ( char * string, size_t len ) };
+
+/* for dictionary functions */
+%typemap(in, numinputs=0,noblock=1) SWIGTYPE ** OUTPUT (void *temp = NULL) {
+	$1 = (void *)&temp;
+}
+%typemap(argout,noblock=1) SWIGTYPE ** OUTPUT {
+	%append_output(SWIG_NewPointerObj(*$1, $*1_descriptor, 0));
+}
+%apply SWIGTYPE ** OUTPUT { struct dict_object ** ref };
+%apply SWIGTYPE ** OUTPUT { struct dict_object ** result };
+
+
+
+/*********************************************************
+ Now, create wrappers for (almost) all objects from fD API 
+ *********************************************************/
 %include "freeDiameter/freeDiameter-host.h"
 %include "freeDiameter/libfreeDiameter.h"
@@ -83,29 +92,14 @@
 
 
-/* Some pointer types that are useful */
-%pointer_functions(int, int_ptr);
-%pointer_functions(uint8_t *, uint8_t_pptr);
-%pointer_cast(char *, void *, char_to_void);
-
-%pointer_functions(struct fd_list *, fd_list_pptr);
-
-%pointer_functions(enum dict_object_type, dict_object_type_ptr);
-%pointer_functions(struct dict_object *, dict_object_pptr);
-
-%pointer_functions(struct session *, session_pptr);
-%pointer_functions(struct session_handler *, session_handler_pptr);
-%pointer_functions(session_state *, session_state_pptr);
-
-%pointer_functions(struct rt_data *, rt_data_pptr);
-%pointer_cast(struct fd_list *, struct rtd_candidate *, fd_list_to_rtd_candidate);
-
-%pointer_functions(struct msg *, msg_pptr);
-%pointer_functions(struct msg_hdr *, msg_hdr_pptr);
-%pointer_functions(struct avp *, avp_pptr);
-%pointer_functions(struct avp_hdr *, avp_hdr_pptr);
-
-
-/* Extend some structures for usability/debug in python */
+
+/**********************************************************/
+/* The remaining of this file allows easier manipulation of
+the structures and functions of fD by providing wrapper-specific
+extensions to the freeDiameter API.
+
+/****** LISTS *********/
+
 %extend fd_list {
+	/* allow a parameter in the constructor, and perform the fd_list_init operation */
 	fd_list(void * o = NULL) {
 		struct fd_list * li;
@@ -119,8 +113,10 @@
 		return li;
 	}
+	/* Unlink before freeing */
 	~fd_list() {
 		fd_list_unlink($self);
 		free($self);
 	}
+	/* For debug, show the values of the list */
 	void dump() {
 		fd_log_debug("list: %p\n", $self);
@@ -132,55 +128,131 @@
 };
 
+/****** DICTIONARY *********/
+
+struct dictionary {
+};
+
+%extend dictionary {
+	dictionary() {
+		struct dictionary * r = NULL;
+		int ret = fd_dict_init(&r);
+		if (ret != 0) {
+			fd_log_debug("Error: %s\n", strerror(ret));
+			PyErr_SetString(PyExc_MemoryError,"Not enough memory");
+			return NULL;
+		}
+		return r;
+	}
+	~dictionary() {
+		if (self) {
+			struct dictionary *d = self;
+			int ret = fd_dict_fini(&d);
+			if (ret != 0) {
+				fd_log_debug("Error: %s\n", strerror(ret));
+			}
+			return;
+		}
+	}
+	void dump() {
+		if ($self) {
+			fd_dict_dump($self);
+		}
+	}
+	PyObject * vendors_list() {
+		uint32_t *list = NULL, *li;
+		PyObject * ret;
+		if (!$self) {
+			PyErr_SetString(PyExc_SyntaxError,"dict_object cannot be created directly. Use fd_dict_new.");
+			return NULL;
+		}
+		ret = PyList_New(0);
+		list = fd_dict_get_vendorid_list($self);
+		for (li = list; *li != 0; li++) {
+			PyList_Append(ret, PyInt_FromLong((long)*li));
+		}
+		free(list);
+		return ret;
+	}
+	
+}
+
+struct dict_object {
+};
+
+%extend dict_object {
+	dict_object() {
+		fd_log_debug("Error: dict_object cannot be created directly. Use fd_dict_new\n");
+		PyErr_SetString(PyExc_SyntaxError,"dict_object cannot be created directly. Use fd_dict_new.");
+		return NULL;
+	}
+	~dict_object() {
+		fd_log_debug("Error: dict_object cannot be destroyed directly. Destroy the parent dictionary.\n");
+		return;
+	}
+	void dump() {
+		if ($self) {
+			fd_dict_dump_object($self);
+		}
+	}
+}
+
+/* overload the search function to allow passing integers & string criteria directly */
+%rename(fd_dict_search) fd_dict_search_int;
 %inline %{
-void dict_object_type_ptr_dump(enum dict_object_type * t) {
-	#define CASE_STR(x)  case x: fd_log_debug(#x "\n"); break;
-	switch (*t) {
-		CASE_STR(DICT_VENDOR)
-		CASE_STR(DICT_APPLICATION)
-		CASE_STR(DICT_TYPE)
-		CASE_STR(DICT_ENUMVAL)
-		CASE_STR(DICT_AVP)
-		CASE_STR(DICT_COMMAND)
-		CASE_STR(DICT_RULE)
-		default: 
-			fd_log_debug("Invalid value (%d)", *t); 
-			PyErr_SetString(PyExc_IndexError,"Invalid dictionary type object");
-	}
-}
-%}
+int fd_dict_search_int ( struct dictionary * dict, enum dict_object_type type, int criteria, int what_by_val, struct dict_object ** result, int retval ) {
+	return fd_dict_search ( dict, type, criteria, &what_by_val, result, retval );
+}
+%}
+%rename(fd_dict_search) fd_dict_search_string;
+%inline %{
+int fd_dict_search_string ( struct dictionary * dict, enum dict_object_type type, int criteria, char * what_by_string, struct dict_object ** result, int retval ) {
+	return fd_dict_search ( dict, type, criteria, what_by_string, result, retval );
+}
+%}
+
 
 %extend avp_value_os {
-	void fromstr(char * string) {
-		if ($self->data) free($self->data);
-		$self->data = (uint8_t *)strdup(string);
-		if (!$self->data) {
+	~avp_value_os() {
+		if (self)
+			free(self->data);
+	}
+	void dump() {
+		if ($self) {
+			%#define LEN_MAX 20
+			int i, n=LEN_MAX;
+			if ($self->len < LEN_MAX)
+				n = $self->len;
+			fd_log_debug("l:%u, v:[", $self->len);
+			for (i=0; i < n; i++)
+				fd_log_debug("%02.2X", $self->data[i]);
+			fd_log_debug("] '%.*s%s'\n", n, $self->data, n == LEN_MAX ? "..." : "");
+		}
+	}
+}
+
+%extend avp_value {
+	void os_set(char *STRING, size_t LENGTH) {
+		free($self->os.data);
+		$self->os.data = malloc(LENGTH);
+		if (!$self->os.data) {
 			fd_log_debug("Out of memory!\n");
 			PyErr_SetString(PyExc_MemoryError,"Not enough memory");
-			$self->len = 0;
 			return;
 		}
-		$self->len = strlen(string);
-	}
-	%newobject as_str;
-	char * tostr() {
-		char * r;
-		if ($self->len == 0)
-			return NULL;
-		r = malloc($self->len + 1);
-		if (r) {
-			strncpy(r, (char *)$self->data, $self->len + 1);
-		} else {
+		memcpy($self->os.data, STRING, LENGTH);
+		$self->os.len = LENGTH;
+	}
+	void os_set(avp_value_os * os) {
+		free($self->os.data);
+		$self->os.data = malloc(os->len);
+		if (!$self->os.data) {
 			fd_log_debug("Out of memory!\n");
 			PyErr_SetString(PyExc_MemoryError,"Not enough memory");
-		}
-		return r;
-	}
-};	
-
-%extend avp_value {
-	void os_set(void * os) {
-		memcpy(&$self->os, os, sizeof($self->os));
-	}
-};	
+			return;
+		}
+		memcpy($self->os.data, os->data, os->len);
+		$self->os.len = os->len;
+	}
+};
 
 %cstring_output_allocate_size(char ** swig_buffer, size_t * swig_len, free(*$1))
