Index: src/backend/sql/gnc-slots-sql.c
===================================================================
--- src/backend/sql/gnc-slots-sql.c	(revision 19699)
+++ src/backend/sql/gnc-slots-sql.c	(working copy)
@@ -46,6 +46,11 @@
 #define TABLE_NAME "slots"
 #define TABLE_VERSION 3
 
+typedef enum {
+    FRAME,
+    LIST
+} context_t;
+
 typedef struct
 {
     /*@ dependent @*/ GncSqlBackend* be;
@@ -53,6 +58,8 @@
     gboolean is_ok;
     /*@ dependent @*/ KvpFrame* pKvpFrame;
     KvpValueType value_type;
+    /*@ dependent @*/
+    context_t context;
     /*@ dependent @*/ KvpValue* pKvpValue;
     GString* path;
 } slot_info_t;
@@ -61,7 +68,7 @@
 static void set_obj_guid( void );
 static /*@ null @*/ gpointer get_path( gpointer pObject );
 static void set_path( gpointer pObject, /*@ null @*/ gpointer pValue );
-static /*@ null @*/ gpointer get_slot_type( gpointer pObject );
+static KvpValueType get_slot_type( gpointer pObject );
 static void set_slot_type( gpointer pObject, /*@ null @*/ gpointer pValue );
 static gint64 get_int64_val( gpointer pObject );
 static void set_int64_val( gpointer pObject, gint64 pValue );
@@ -77,14 +84,17 @@
 static void set_numeric_val( gpointer pObject, gnc_numeric value );
 static GDate* get_gdate_val( gpointer pObject );
 static void set_gdate_val( gpointer pObject, GDate* value );
+static slot_info_t *slot_info_copy( slot_info_t *pInfo, GncGUID *guid );
+static void slots_load_info( slot_info_t *pInfo );
 
 #define SLOT_MAX_PATHNAME_LEN 4096
 #define SLOT_MAX_STRINGVAL_LEN 4096
 
 static const GncSqlColumnTableEntry col_table[] =
 {
+/* col_name, col_type, size, flags, g0bj_param_name, qof_param_name, getter, setter */
     /*@ -full_init_block @*/
-    { "id",           CT_INT,      0,                     COL_PKEY | COL_NNUL | COL_AUTOINC },
+    { "id",             CT_INT,      0, COL_PKEY | COL_NNUL | COL_AUTOINC },
     {
         "obj_guid",     CT_GUID,     0,                     COL_NNUL, NULL, NULL,
         (QofAccessFunc)get_obj_guid,     (QofSetterFunc)set_obj_guid
@@ -190,14 +200,15 @@
     pInfo->path = g_string_new( (gchar*)pValue );
 }
 
-static /*@ null @*/ gpointer
+static KvpValueType
 get_slot_type( gpointer pObject )
 {
     slot_info_t* pInfo = (slot_info_t*)pObject;
 
-    g_return_val_if_fail( pObject != NULL, NULL );
+    g_return_val_if_fail( pObject != NULL, 0 );
 
-    return (gpointer)kvp_value_get_type( pInfo->pKvpValue );
+//    return (gpointer)kvp_value_get_type( pInfo->pKvpValue );
+    return pInfo->value_type;
 }
 
 static void
@@ -235,10 +246,15 @@
 
     g_return_if_fail( pObject != NULL );
 
-    if ( pInfo->value_type == KVP_TYPE_GINT64 )
+    if ( pInfo->value_type != KVP_TYPE_GINT64 ) return;
+    if ( pInfo->context == FRAME )
     {
         kvp_frame_set_gint64( pInfo->pKvpFrame, pInfo->path->str, value );
     }
+    else
+    {
+        kvp_frame_add_gint64( pInfo->pKvpFrame, pInfo->path->str, value );
+    }
 }
 
 static /*@ null @*/ gpointer
@@ -265,10 +281,17 @@
 
     g_return_if_fail( pObject != NULL );
 
-    if ( pInfo->value_type == KVP_TYPE_STRING && pValue != NULL )
+    if ( pInfo->value_type != KVP_TYPE_STRING || pValue == NULL ) return;
+    if ( pInfo->context == FRAME )
     {
-        kvp_frame_set_string( pInfo->pKvpFrame, pInfo->path->str, (const gchar*)pValue );
+        kvp_frame_set_string( pInfo->pKvpFrame, pInfo->path->str,
+			      (const gchar*)pValue );
     }
+    else
+    {
+        kvp_frame_add_string( pInfo->pKvpFrame, pInfo->path->str,
+			      (const gchar*)pValue );
+    }
 }
 
 static /*@ dependent @*//*@ null @*/ gpointer
@@ -297,10 +320,17 @@
 
     g_return_if_fail( pObject != NULL );
 
-    if ( pInfo->value_type == KVP_TYPE_DOUBLE && pValue != NULL )
+    if ( pInfo->value_type != KVP_TYPE_DOUBLE || pValue == NULL ) return;
+    if ( pInfo->context == FRAME )
     {
-        kvp_frame_set_double( pInfo->pKvpFrame, pInfo->path->str, *(double*)pValue );
+        kvp_frame_set_double( pInfo->pKvpFrame, pInfo->path->str, 
+			      *(double*)pValue );
     }
+    else 
+    {
+        kvp_frame_add_double( pInfo->pKvpFrame, pInfo->path->str,
+			      *(double*)pValue );
+    }
 }
 
 static Timespec
@@ -321,10 +351,15 @@
 
     g_return_if_fail( pObject != NULL );
 
-    if ( pInfo->value_type == KVP_TYPE_TIMESPEC )
+    if ( pInfo->value_type != KVP_TYPE_TIMESPEC ) return;
+    if ( pInfo->context == FRAME )
     {
         kvp_frame_set_timespec( pInfo->pKvpFrame, pInfo->path->str, ts );
     }
+    else
+    {
+        kvp_frame_add_timespec( pInfo->pKvpFrame, pInfo->path->str, ts );
+    }
 }
 
 static /*@ null @*/ gpointer
@@ -348,13 +383,56 @@
 set_guid_val( gpointer pObject, /*@ null @*/ gpointer pValue )
 {
     slot_info_t* pInfo = (slot_info_t*)pObject;
-
+ 
     g_return_if_fail( pObject != NULL );
+    if ( pValue == NULL ) return;
 
-    if ( pInfo->value_type == KVP_TYPE_GUID && pValue != NULL )
+    switch ( pInfo->value_type)
     {
-        kvp_frame_set_guid( pInfo->pKvpFrame, pInfo->path->str, (GncGUID*)pValue );
+    case KVP_TYPE_GUID:
+	if ( pInfo->context == FRAME )
+	{
+	    kvp_frame_set_guid( pInfo->pKvpFrame, pInfo->path->str, 
+				(GncGUID*)pValue );
+	} 
+	else
+	{
+	    kvp_frame_add_guid( pInfo->pKvpFrame, pInfo->path->str, 
+				(GncGUID*)pValue );
+	}
+	break;
+    case KVP_TYPE_GLIST:
+    {
+	slot_info_t *newInfo = slot_info_copy( pInfo, (GncGUID*)pValue );
+	newInfo->context = LIST;
+
+	slots_load_info( newInfo );
+	g_slice_free( slot_info_t, newInfo );
+	break;
     }
+    case KVP_TYPE_FRAME:
+    {
+	slot_info_t *newInfo = slot_info_copy( pInfo, (GncGUID*)pValue ) ;
+	KvpFrame *newFrame = kvp_frame_new();
+	newInfo->pKvpFrame = newFrame;
+
+	if (pInfo->context == FRAME )
+	{
+	    kvp_frame_set_frame( pInfo->pKvpFrame, pInfo->path->str, newFrame );
+	}
+	else
+	{
+	    newInfo->context = FRAME;
+	    kvp_frame_add_frame( pInfo->pKvpFrame, pInfo->path->str, newFrame );
+	}
+
+	slots_load_info ( newInfo );
+	g_slice_free( slot_info_t, newInfo );
+	break;
+    }
+    default:
+	break;
+    }
 }
 
 static gnc_numeric
@@ -381,10 +459,15 @@
 
     g_return_if_fail( pObject != NULL );
 
-    if ( pInfo->value_type == KVP_TYPE_NUMERIC )
+    if ( pInfo->value_type != KVP_TYPE_NUMERIC ) return;
+    if ( pInfo->context == FRAME )
     {
         kvp_frame_set_numeric( pInfo->pKvpFrame, pInfo->path->str, value );
     }
+    else
+    {
+        kvp_frame_set_numeric( pInfo->pKvpFrame, pInfo->path->str, value );
+    }
 }
 
 static GDate*
@@ -413,12 +496,33 @@
 
     g_return_if_fail( pObject != NULL );
 
-    if ( pInfo->value_type == KVP_TYPE_GDATE )
+    if ( pInfo->value_type != KVP_TYPE_GDATE ) return;
+    if ( pInfo->context == FRAME )
     {
         kvp_frame_set_gdate( pInfo->pKvpFrame, pInfo->path->str, *value );
     }
+    else
+    {
+        kvp_frame_add_gdate( pInfo->pKvpFrame, pInfo->path->str, *value );
+    }
 }
 
+static slot_info_t *
+slot_info_copy( slot_info_t *pInfo, GncGUID *guid )
+{
+    slot_info_t *newSlot;
+    g_return_val_if_fail( pInfo != NULL, NULL );
+    newSlot = g_slice_new(slot_info_t);
+    newSlot->be = pInfo->be;
+    newSlot->guid = guid == NULL ? pInfo->guid : guid;
+    newSlot->pKvpFrame = pInfo->pKvpFrame;
+    newSlot->value_type = pInfo->value_type;
+    newSlot->context = pInfo->context;
+    newSlot->pKvpValue = pInfo->pKvpValue;
+    newSlot->path = pInfo->path;
+    return newSlot;
+}
+
 static void
 save_slot( const gchar* key, KvpValue* value, gpointer data )
 {
@@ -442,19 +546,59 @@
         (void)g_string_append( pSlot_info->path, "/" );
     }
     (void)g_string_append( pSlot_info->path, key );
+    pSlot_info->value_type = kvp_value_get_type( value );
 
-    if ( kvp_value_get_type( value ) == KVP_TYPE_FRAME )
+    switch ( pSlot_info->value_type )
     {
+    case KVP_TYPE_FRAME:
+    {
         KvpFrame* pKvpFrame = kvp_value_get_frame( value );
-        kvp_frame_for_each_slot( pKvpFrame, save_slot, pSlot_info );
+	GncGUID guid = guid_new_return();
+	slot_info_t *pNewInfo = slot_info_copy( pSlot_info, &guid );
+	KvpValue *oldValue = pSlot_info->pKvpValue;
+	pSlot_info->pKvpValue = kvp_value_new_guid( &guid );
+        pSlot_info->is_ok = gnc_sql_do_db_operation( pSlot_info->be,
+						     OP_DB_INSERT, TABLE_NAME,
+						     TABLE_NAME, pSlot_info,
+						     col_table );
+	g_return_if_fail( pSlot_info->is_ok );
+        kvp_frame_for_each_slot( pKvpFrame, save_slot, pNewInfo );
+	kvp_value_delete( pSlot_info->pKvpValue );
+	pSlot_info->pKvpValue = oldValue;
+	g_slice_free( slot_info_t, pNewInfo );
     }
-    else
+    break;
+    case KVP_TYPE_GLIST:
     {
+        GList *cursor;
+	GncGUID guid = guid_new_return();
+	slot_info_t *pNewInfo = slot_info_copy( pSlot_info, &guid );
+	KvpValue *oldValue = pSlot_info->pKvpValue;
+	pSlot_info->pKvpValue = kvp_value_new_guid( &guid );
         pSlot_info->is_ok = gnc_sql_do_db_operation( pSlot_info->be,
-                            OP_DB_INSERT, TABLE_NAME,
-                            TABLE_NAME, pSlot_info,
-                            col_table );
+						     OP_DB_INSERT, TABLE_NAME,
+						     TABLE_NAME, pSlot_info,
+						     col_table );
+	g_return_if_fail( pSlot_info->is_ok );
+	for (cursor = kvp_value_get_glist(value); cursor; cursor = cursor->next)
+	{
+            kvp_value *val = (kvp_value*)cursor->data;
+	    save_slot("", val, pNewInfo);
+	}
+	kvp_value_delete( pSlot_info->pKvpValue );
+	pSlot_info->pKvpValue = oldValue;
+	g_slice_free( slot_info_t, pNewInfo );
     }
+    break;
+    default:
+    {
+        pSlot_info->is_ok = gnc_sql_do_db_operation( pSlot_info->be,
+						     OP_DB_INSERT, TABLE_NAME,
+						     TABLE_NAME, pSlot_info,
+						     col_table );
+    }
+    break;
+    }
 
     (void)g_string_truncate( pSlot_info->path, curlen );
 }
@@ -502,49 +646,63 @@
 }
 
 static void
-load_slot( GncSqlBackend* be, GncSqlRow* row, KvpFrame* pFrame )
+load_slot( slot_info_t *pInfo, GncSqlRow* row )
 {
-    slot_info_t slot_info;
+    slot_info_t *slot_info = slot_info_copy( pInfo, NULL );
 
-    g_return_if_fail( be != NULL );
+    g_return_if_fail( pInfo != NULL );
+    g_return_if_fail( pInfo->be != NULL );
     g_return_if_fail( row != NULL );
-    g_return_if_fail( pFrame != NULL );
+    g_return_if_fail( pInfo->pKvpFrame != NULL );
 
-    slot_info.be = be;
-    slot_info.pKvpFrame = pFrame;
-    slot_info.path = NULL;
+    slot_info->path = NULL;
 
-    gnc_sql_load_object( be, row, TABLE_NAME, &slot_info, col_table );
+    gnc_sql_load_object( pInfo->be, row, TABLE_NAME, slot_info, col_table );
 
-    if ( slot_info.path != NULL )
+    if ( slot_info->path != NULL )
     {
-        (void)g_string_free( slot_info.path, TRUE );
+        (void)g_string_free( slot_info->path, TRUE );
     }
+    g_slice_free( slot_info_t, slot_info );
 }
 
 void
 gnc_sql_slots_load( GncSqlBackend* be, QofInstance* inst )
 {
+    slot_info_t info;
+    g_return_if_fail( be != NULL );
+    g_return_if_fail( inst != NULL );
+
+    info.be = be;
+    info.guid = qof_instance_get_guid( inst );
+    info.pKvpFrame = qof_instance_get_slots( inst );
+    info.context = FRAME;
+    
+    slots_load_info( &info );
+}
+
+static void
+slots_load_info ( slot_info_t *pInfo )
+{
     gchar* buf;
     GncSqlResult* result;
     gchar guid_buf[GUID_ENCODING_LENGTH+1];
     GncSqlStatement* stmt;
-    const GncGUID* guid;
-    KvpFrame* pFrame;
 
-    g_return_if_fail( be != NULL );
-    g_return_if_fail( inst != NULL );
+    g_return_if_fail( pInfo != NULL );
+    g_return_if_fail( pInfo->be != NULL );
+    g_return_if_fail( pInfo->guid != NULL );
+    g_return_if_fail( pInfo->pKvpFrame != NULL );
 
-    guid = qof_instance_get_guid( inst );
-    pFrame = qof_instance_get_slots( inst );
-    (void)guid_to_string_buff( guid, guid_buf );
+    (void)guid_to_string_buff( pInfo->guid, guid_buf );
 
-    buf = g_strdup_printf( "SELECT * FROM %s WHERE obj_guid='%s'", TABLE_NAME, guid_buf );
-    stmt = gnc_sql_create_statement_from_sql( be, buf );
+    buf = g_strdup_printf( "SELECT * FROM %s WHERE obj_guid='%s'", 
+			   TABLE_NAME, guid_buf );
+    stmt = gnc_sql_create_statement_from_sql( pInfo->be, buf );
     g_free( buf );
     if ( stmt != NULL )
     {
-        result = gnc_sql_execute_select_statement( be, stmt );
+        result = gnc_sql_execute_select_statement( pInfo->be, stmt );
         gnc_sql_statement_dispose( stmt );
         if ( result != NULL )
         {
@@ -552,7 +710,7 @@
 
             while ( row != NULL )
             {
-                load_slot( be, row, pFrame );
+                load_slot( pInfo, row );
                 row = gnc_sql_result_get_next_row( result );
             }
             gnc_sql_result_dispose( result );
Index: src/libqof/qof/kvp_frame.c
===================================================================
--- src/libqof/qof/kvp_frame.c	(revision 19699)
+++ src/libqof/qof/kvp_frame.c	(working copy)
@@ -605,6 +605,16 @@
 }
 
 void
+kvp_frame_add_gdate(KvpFrame * frame, const char * path, GDate nval)
+{
+    KvpValue *value;
+    value = kvp_value_new_gdate (nval);
+    frame = kvp_frame_add_value_nc (frame, path, value);
+    if (!frame) kvp_value_delete (value);
+}
+
+
+void
 kvp_frame_add_string(KvpFrame * frame, const char * path, const char* str)
 {
     KvpValue *value;
Index: src/libqof/qof/kvp_frame.h
===================================================================
--- src/libqof/qof/kvp_frame.h	(revision 19699)
+++ src/libqof/qof/kvp_frame.h	(working copy)
@@ -279,6 +279,7 @@
 
 void kvp_frame_add_numeric(KvpFrame * frame, const gchar * path, gnc_numeric nval);
 void kvp_frame_add_timespec(KvpFrame * frame, const gchar * path, Timespec ts);
+void kvp_frame_add_gdate(KvpFrame * frame, const gchar * path, GDate date);
 
 /** \deprecated
 
