fix bug 643638
[claws.git] / src / addrbook.c
index 91d7f6e093e3af83656c4cd5e5a82d6e7d61d674..138b9b62e4110bb1ab7c9f430f5a86eb362613f8 100644 (file)
@@ -18,7 +18,7 @@
  */
 
 /*
- * General functions for accessing external address book files.
+ * General functions for accessing address book files.
  */
 
 #include <glib.h>
@@ -34,6 +34,7 @@
 #include "addritem.h"
 #include "addrcache.h"
 #include "addrbook.h"
+#include "adbookbase.h"
 
 #ifndef DEV_STANDALONE
 #include "prefs.h"
@@ -53,18 +54,15 @@ AddressBookFile *addrbook_create_book() {
        AddressBookFile *book;
 
        book = g_new0( AddressBookFile, 1 );
-       book->name = NULL;
+       book->type = ADBOOKTYPE_BOOK;
+       book->addressCache = addrcache_create();
+       book->retVal = MGU_SUCCESS;
        book->path = NULL;
        book->fileName = NULL;
-       book->retVal = MGU_SUCCESS;
-       book->addressCache = addrcache_create();
-
+       book->maxValue = 0;
        book->tempList = NULL;
-       book->readFlag = FALSE;
-       book->dirtyFlag = FALSE;
-       book->modifyFlag = TRUE;
-       book->accessFlag = FALSE;
        book->tempHash = NULL;
+       book->addressCache->modified = TRUE;
        return book;
 }
 
@@ -73,33 +71,45 @@ AddressBookFile *addrbook_create_book() {
 */
 void addrbook_set_name( AddressBookFile *book, const gchar *value ) {
        g_return_if_fail( book != NULL );
-       book->name = mgu_replace_string( book->name, value );
+       addrcache_set_name( book->addressCache, value );
+}
+gchar *addrbook_get_name( AddressBookFile *book ) {
+       g_return_val_if_fail( book != NULL, NULL );
+       return addrcache_get_name( book->addressCache );
 }
 void addrbook_set_path( AddressBookFile *book, const gchar *value ) {
        g_return_if_fail( book != NULL );
        book->path = mgu_replace_string( book->path, value );
-       book->dirtyFlag = TRUE;
+       addrcache_set_dirty( book->addressCache, TRUE );
 }
 void addrbook_set_file( AddressBookFile *book, const gchar *value ) {
        g_return_if_fail( book != NULL );
        book->fileName = mgu_replace_string( book->fileName, value );
-       book->dirtyFlag = TRUE;
-}
-void addrbook_set_accessed( AddressBookFile *book, const gboolean value ) {
-       g_return_if_fail( book != NULL );
-       book->accessFlag = value;
+       addrcache_set_dirty( book->addressCache, TRUE );
 }
 gboolean addrbook_get_modified( AddressBookFile *book ) {
        g_return_val_if_fail( book != NULL, FALSE );
-       return book->modifyFlag;
+       return book->addressCache->modified;
+}
+void addrbook_set_modified( AddressBookFile *book, const gboolean value ) {
+       g_return_if_fail( book != NULL );
+       book->addressCache->modified = value;
 }
 gboolean addrbook_get_accessed( AddressBookFile *book ) {
        g_return_val_if_fail( book != NULL, FALSE );
-       return book->accessFlag;
+       return book->addressCache->accessFlag;
+}
+void addrbook_set_accessed( AddressBookFile *book, const gboolean value ) {
+       g_return_if_fail( book != NULL );
+       book->addressCache->accessFlag = value;
 }
 gboolean addrbook_get_read_flag( AddressBookFile *book ) {
        g_return_val_if_fail( book != NULL, FALSE );
-       return book->readFlag;
+       return book->addressCache->dataRead;
+}
+void addrbook_set_read_flag( AddressBookFile *book, const gboolean value ) {
+       g_return_if_fail( book != NULL );
+       book->addressCache->dataRead = value;
 }
 gint addrbook_get_status( AddressBookFile *book ) {
        g_return_val_if_fail( book != NULL, -1 );
@@ -117,37 +127,13 @@ GList *addrbook_get_list_person( AddressBookFile *book ) {
        g_return_val_if_fail( book != NULL, NULL );
        return addrcache_get_list_person( book->addressCache );
 }
-gchar *addrbook_get_name( AddressBookFile *book ) {
-       g_return_val_if_fail( book != NULL, NULL );
-       return book->name;
-}
-
-static gint addrcache_free_item_vis( gpointer key, gpointer value, gpointer data ) {
-       AddrItemObject *obj = ( AddrItemObject * ) value;
-
-       if( ADDRITEM_TYPE(obj) == ITEMTYPE_PERSON ) {
-               addritem_free_item_person( ( ItemPerson * ) obj );
-       }
-       else if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) {
-               addritem_free_item_group( ( ItemGroup * ) obj );
-       }
-       else if( ADDRITEM_TYPE(obj) == ITEMTYPE_FOLDER ) {
-               addritem_free_item_folder( ( ItemFolder * ) obj );
-       }
-       key = NULL;
-       value = NULL;
-       return 0;
+gboolean addrbook_get_dirty( AddressBookFile *book ) {
+       g_return_val_if_fail( book != NULL, FALSE );
+       return addrcache_get_dirty( book->addressCache );
 }
-
-/*
-* Free hash table of address book items.
-*/
-static void addrcache_free_item_hash( GHashTable *table ) {
-       g_return_if_fail( table != NULL );
-       g_hash_table_freeze( table );
-       g_hash_table_foreach_remove( table, addrcache_free_item_vis, NULL );
-       g_hash_table_thaw( table );
-       g_hash_table_destroy( table );
+void addrbook_set_dirty( AddressBookFile *book, const gboolean value ) {
+       g_return_if_fail( book != NULL );
+       addrcache_set_dirty( book->addressCache, value );
 }
 
 /*
@@ -156,19 +142,18 @@ static void addrcache_free_item_hash( GHashTable *table ) {
 void addrbook_empty_book( AddressBookFile *book ) {
        g_return_if_fail( book != NULL );
 
-       // Free up folders and hash table
+       /* Free up internal objects */
        addrcache_clear( book->addressCache );
-
+       addrcache_set_dirty( book->addressCache, FALSE );
        g_list_free( book->tempList );
-       book->tempList = NULL;
 
-       // Reset to initial state
-       book->retVal = MGU_SUCCESS;
+       /* Reset to initial state */
+       book->tempList = NULL;
        book->tempHash = NULL;
-       book->readFlag = FALSE;
-       book->dirtyFlag = FALSE;
-       book->modifyFlag = FALSE;
-       book->accessFlag = FALSE;
+       book->addressCache->dataRead = FALSE;
+       book->addressCache->modified = FALSE;
+       book->addressCache->accessFlag = FALSE;
+       book->retVal = MGU_SUCCESS;
 }
 
 /*
@@ -177,26 +162,24 @@ void addrbook_empty_book( AddressBookFile *book ) {
 void addrbook_free_book( AddressBookFile *book ) {
        g_return_if_fail( book != NULL );
 
-       g_free( book->name );
+       /* Clear cache */
+       addrcache_clear( book->addressCache );
+       addrcache_free( book->addressCache );
+
+       /* Free up internal objects */
        g_free( book->path );
        g_free( book->fileName );
-       book->name = NULL;
+       g_list_free( book->tempList );
+
        book->path = NULL;
        book->fileName = NULL;
-
-       // Free up folders and hash table
-       addrcache_free( book->addressCache );
-       book->addressCache = NULL;
-
-       g_list_free( book->tempList );
+       book->maxValue = 0;
        book->tempList = NULL;
+       book->tempHash = NULL;
 
+       book->type = ADBOOKTYPE_NONE;
+       book->addressCache = NULL;
        book->retVal = MGU_SUCCESS;
-       book->tempHash = NULL;
-       book->readFlag = FALSE;
-       book->dirtyFlag = FALSE;
-       book->modifyFlag = FALSE;
-       book->accessFlag = FALSE;
 
        g_free( book );
 }
@@ -230,7 +213,6 @@ void addrbook_print_book( AddressBookFile *book, FILE *stream ) {
        g_return_if_fail( book != NULL );
 
        fprintf( stream, "AddressBook:\n" );
-       fprintf( stream, "\tname  : '%s'\n", book->name );
        fprintf( stream, "\tpath  : '%s'\n", book->path );
        fprintf( stream, "\tfile  : '%s'\n", book->fileName );
        fprintf( stream, "\tstatus: %d : '%s'\n", book->retVal, mgu_error2string( book->retVal ) );
@@ -256,13 +238,8 @@ void addrbook_dump_book( AddressBookFile *book, FILE *stream ) {
 * return: Group, or NULL if not found. Note that object should still be freed.
 */
 ItemGroup *addrbook_remove_group( AddressBookFile *book, ItemGroup *group ) {
-       ItemGroup *item;
-
        g_return_val_if_fail( book != NULL, NULL );
-
-       item = addrcache_remove_group( book->addressCache, group );
-       if( item ) book->dirtyFlag = TRUE;
-       return item;
+       return addrcache_remove_group( book->addressCache, group );
 }
 
 /*
@@ -271,13 +248,8 @@ ItemGroup *addrbook_remove_group( AddressBookFile *book, ItemGroup *group ) {
 * return: Person, or NULL if not found. Note that object should still be freed.
 */
 ItemPerson *addrbook_remove_person( AddressBookFile *book, ItemPerson *person ) {
-       ItemPerson *item;
-
        g_return_val_if_fail( book != NULL, NULL );
-
-       item = addrcache_remove_person( book->addressCache, person );
-       if( item ) book->dirtyFlag = TRUE;
-       return item;
+       return addrcache_remove_person( book->addressCache, person );
 }
 
 /*
@@ -287,13 +259,8 @@ ItemPerson *addrbook_remove_person( AddressBookFile *book, ItemPerson *person )
 * return: EMail object, or NULL if not found. Note that object should still be freed.
 */
 ItemEMail *addrbook_person_remove_email( AddressBookFile *book, ItemPerson *person, ItemEMail *email ) {
-       ItemEMail *item;
-
        g_return_val_if_fail( book != NULL, NULL );
-
-       item = addrcache_person_remove_email( book->addressCache, person, email );
-       if( item ); book->dirtyFlag = TRUE;
-       return item;
+       return addrcache_person_remove_email( book->addressCache, person, email );
 }
 
 /* **********************************************************************
@@ -328,7 +295,7 @@ ItemEMail *addrbook_person_remove_email( AddressBookFile *book, ItemPerson *pers
 * ***********************************************************************
 */
 
-// Element tag names
+/* Element tag names */
 #define AB_ELTAG_ADDRESS         "address"
 #define AB_ELTAG_ATTRIBUTE       "attribute"
 #define AB_ELTAG_ATTRIBUTE_LIST  "attribute-list"
@@ -342,7 +309,7 @@ ItemEMail *addrbook_person_remove_email( AddressBookFile *book, ItemPerson *pers
 #define AB_ELTAG_GROUP           "group"
 #define AB_ELTAG_FOLDER          "folder"
 
-// Attribute tag names
+/* Attribute tag names */
 #define AB_ATTAG_TYPE            "type"
 #define AB_ATTAG_UID             "uid"
 #define AB_ATTAG_NAME            "name"
@@ -356,7 +323,7 @@ ItemEMail *addrbook_person_remove_email( AddressBookFile *book, ItemPerson *pers
 #define AB_ATTAG_EID             "eid"
 #define AB_ATTAG_PID             "pid"
 
-// Attribute values
+/* Attribute values */
 #define AB_ATTAG_VAL_PERSON      "person"
 #define AB_ATTAG_VAL_GROUP       "group"
 #define AB_ATTAG_VAL_FOLDER      "folder"
@@ -508,7 +475,7 @@ static void addrbook_parse_person( AddressBookFile *book, XMLFile *file ) {
                }
                attr = g_list_next( attr );
        }
-       if( xml_parse_next_tag( file ) ) {      // Consume closing tag
+       if( xml_parse_next_tag( file ) ) {      /* Consume closing tag */
                longjmp( book->jumper, 1 );
        }
        if( xml_compare_tag( file, AB_ELTAG_ADDRESS_LIST ) ) {
@@ -517,7 +484,7 @@ static void addrbook_parse_person( AddressBookFile *book, XMLFile *file ) {
                        addrcache_hash_add_person( book->addressCache, person );
                }
        }
-       if( xml_parse_next_tag( file ) ) {      // Consume closing tag
+       if( xml_parse_next_tag( file ) ) {      /* Consume closing tag */
                longjmp( book->jumper, 1 );
        }
        if( xml_compare_tag( file, AB_ELTAG_ATTRIBUTE_LIST ) ) {
@@ -546,7 +513,8 @@ static void addrbook_parse_member( AddressBookFile *book, XMLFile *file, ItemGro
                }
                attr = g_list_next( attr );
        }
-       email = addrcache_get_email( book->addressCache, pid, eid );
+       /* email = addrcache_get_email( book->addressCache, pid, eid ); */
+       email = addrcache_get_email( book->addressCache, eid );
        if( email ) {
                if( group ) {
                        addrcache_group_add_email( book->addressCache, group, email );
@@ -606,7 +574,7 @@ static void addrbook_parse_group( AddressBookFile *book, XMLFile *file ) {
                }
                attr = g_list_next( attr );
        }
-       if( xml_parse_next_tag( file ) ) {      // Consume closing tag
+       if( xml_parse_next_tag( file ) ) {      /* Consume closing tag */
                longjmp( book->jumper, 1 );
        }
        if( xml_compare_tag( file, AB_ELTAG_MEMBER_LIST ) ) {
@@ -691,14 +659,14 @@ static void addrbook_parse_folder( AddressBookFile *book, XMLFile *file ) {
                }
                attr = g_list_next( attr );
        }
-       if( xml_parse_next_tag( file ) ) {      // Consume closing tag
+       if( xml_parse_next_tag( file ) ) {      /* Consume closing tag */
                longjmp( book->jumper, 1 );
        }
        if( xml_compare_tag( file, AB_ELTAG_ITEM_LIST ) ) {
                if( folder ) {
                        if( addrcache_hash_add_folder( book->addressCache, folder ) ) {
                                book->tempList = g_list_append( book->tempList, folder );
-                               ADDRITEM_PARENT(folder) = NULL; // We will resolve folder later
+                               ADDRITEM_PARENT(folder) = NULL; /* We will resolve folder later */
                        }
                }
                addrbook_parse_folder_list( book, file, folder );
@@ -738,7 +706,7 @@ static gboolean addrbook_read_tree( AddressBookFile *book, XMLFile *file ) {
        retVal = TRUE;
        for (;;) {
                if (! file->level ) break;
-               // Get next item tag (person, group or folder)
+               /* Get next item tag (person, group or folder) */
                if( xml_parse_next_tag( file ) ) {
                        longjmp( book->jumper, 1 );
                }
@@ -808,19 +776,19 @@ static void addrbook_resolve_folder_items( AddressBookFile *book ) {
                                        folder->listGroup = g_list_append( folder->listGroup, item );
                                        ADDRITEM_PARENT(item) = ADDRITEM_OBJECT(folder);
                                }
-                               // Replace data with pointer to item
+                               /* Replace data with pointer to item */
                                g_free( uid );
                                node->data = aio;
                        }
                        else {
-                               // Not found, append to remove list.
+                               /* Not found, append to remove list. */
                                listRemove = g_list_append( listRemove, uid );
                        }
                        node = g_list_next( node );
                }
                rootFolder->listFolder = g_list_append( rootFolder->listFolder, folder );
 
-               // Process remove list
+               /* Process remove list */
                node = listRemove;
                while( node ) {
                        gchar *uid = node->data;
@@ -832,23 +800,23 @@ static void addrbook_resolve_folder_items( AddressBookFile *book ) {
                nodeFolder = g_list_next( nodeFolder );
        }
 
-       // Remove folders with parents.
+       /* Remove folders with parents. */
        listRemove = NULL;
        node = rootFolder->listFolder;
        while( node ) {
                ItemFolder *folder = ( ItemFolder * ) node->data;
                if( ADDRITEM_PARENT(folder) ) {
-                       // Remove folders with parents
+                       /* Remove folders with parents */
                        listRemove = g_list_append( listRemove, folder );
                }
                else {
-                       // Add to root folder
+                       /* Add to root folder */
                        ADDRITEM_PARENT(folder) = ADDRITEM_OBJECT(book->addressCache->rootFolder);
                }
                node = g_list_next( node );
        }
 
-       // Process remove list
+       /* Process remove list */
        node = listRemove;
        while( node ) {
                rootFolder->listFolder = g_list_remove( rootFolder->listFolder, node->data );
@@ -856,10 +824,10 @@ static void addrbook_resolve_folder_items( AddressBookFile *book ) {
        }
        g_list_free( listRemove );
 
-       // Move all unparented persons and groups into root folder
+       /* Move all unparented persons and groups into root folder */
        g_hash_table_foreach( book->addressCache->itemHash, addrbook_res_items_vis, book );
 
-       // Free up some more
+       /* Free up some more */
        nodeFolder = book->tempList;
        while( nodeFolder ) {
                ItemFolder *folder = nodeFolder->data;
@@ -881,16 +849,22 @@ gint addrbook_read_data( AddressBookFile *book ) {
 
        g_return_val_if_fail( book != NULL, -1 );
 
+       /*
+       printf( "...addrbook_read_data :%s:\t:%s:\n", book->fileName,
+               addrcache_get_name( book->addressCache ) );
+       */
+
        fileSpec = g_strconcat( book->path, G_DIR_SEPARATOR_S, book->fileName, NULL );
        book->retVal = MGU_OPEN_FILE;
-       book->accessFlag = FALSE;
-       book->modifyFlag = FALSE;
+       addrcache_clear( book->addressCache );
+       book->addressCache->modified = FALSE;
+       book->addressCache->accessFlag = FALSE;
        file = xml_open_file( fileSpec );
        g_free( fileSpec );
        if( file ) {
                book->tempList = NULL;
 
-               // Trap for parsing errors.
+               /* Trap for parsing errors. */
                if( setjmp( book->jumper ) ) {
                        xml_close_file( file );
                        return book->retVal;
@@ -898,11 +872,12 @@ gint addrbook_read_data( AddressBookFile *book ) {
                addrbook_read_tree( book, file );
                xml_close_file( file );
 
-               // Resolve folder items
+               /* Resolve folder items */
                addrbook_resolve_folder_items( book );
                book->tempList = NULL;
-               book->readFlag = TRUE;
-               book->dirtyFlag = FALSE;
+               book->addressCache->modified = FALSE;
+               book->addressCache->dataRead = TRUE;
+               addrcache_set_dirty( book->addressCache, FALSE );
        }
        return book->retVal;
 }
@@ -950,7 +925,7 @@ static void addrbook_write_item_person_vis( gpointer key, gpointer value, gpoint
                        addrbook_write_attr( fp, AB_ATTAG_COMMON_NAME, ADDRITEM_NAME(person) );
                        fputs( " >\n", fp);
 
-                       // Output email addresses
+                       /* Output email addresses */
                        addrbook_write_elem_s( fp, 2, AB_ELTAG_ADDRESS_LIST );
                        fputs( ">\n", fp );
                        node = person->listEMail;
@@ -966,7 +941,7 @@ static void addrbook_write_item_person_vis( gpointer key, gpointer value, gpoint
                        }
                        addrbook_write_elem_e( fp, 2, AB_ELTAG_ADDRESS_LIST );
 
-                       // Output user attributes
+                       /* Output user attributes */
                        addrbook_write_elem_s( fp, 2, AB_ELTAG_ATTRIBUTE_LIST );
                        fputs( ">\n", fp );
                        node = person->listAttrib;
@@ -986,48 +961,6 @@ static void addrbook_write_item_person_vis( gpointer key, gpointer value, gpoint
        }
 }
 
-/*
-* Output all groups in folder.
-*/
-static void addrbook_write_folder_group( ItemFolder *parent, FILE *fp ) {
-       GList *nodeGrp = parent->listGroup;
-       GList *node;
-
-       while( nodeGrp ) {
-               ItemGroup *group = nodeGrp->data;
-               if( group ) {
-                       addrbook_write_elem_s( fp, 1, AB_ELTAG_GROUP );
-                       addrbook_write_attr( fp, AB_ATTAG_UID, ADDRITEM_ID(group) );
-                       addrbook_write_attr( fp, AB_ATTAG_NAME, ADDRITEM_NAME(group) );
-                       addrbook_write_attr( fp, AB_ATTAG_REMARKS, group->remarks );
-                       fputs( " >\n", fp );
-
-                       // Output email address links
-                       addrbook_write_elem_s( fp, 2, AB_ELTAG_MEMBER_LIST );
-                       fputs( ">\n", fp );
-                       node = group->listEMail;
-                       while ( node ) {
-                               ItemEMail *email = node->data;
-                               ItemPerson *person = ( ItemPerson * ) ADDRITEM_PARENT(email);
-                               addrbook_write_elem_s( fp, 3, AB_ELTAG_MEMBER );
-                               addrbook_write_attr( fp, AB_ATTAG_PID, ADDRITEM_ID(person) );
-                               addrbook_write_attr( fp, AB_ATTAG_EID, ADDRITEM_ID(email) );
-                               fputs( " />\n", fp );
-                               node = g_list_next( node );
-                       }
-                       addrbook_write_elem_e( fp, 2, AB_ELTAG_MEMBER_LIST );
-                       addrbook_write_elem_e( fp, 1, AB_ELTAG_GROUP );
-               }
-               nodeGrp = g_list_next( nodeGrp );
-       }
-       node = parent->listFolder;
-       while( node ) {
-               ItemFolder *folder = node->data;
-               addrbook_write_folder_group( folder, fp );
-               node = g_list_next( node );
-       }
-}
-
 /*
 * Write file hash table visitor function.
 */
@@ -1046,7 +979,7 @@ static void addrbook_write_item_group_vis( gpointer key, gpointer value, gpointe
                        addrbook_write_attr( fp, AB_ATTAG_REMARKS, group->remarks );
                        fputs( " >\n", fp );
 
-                       // Output email address links
+                       /* Output email address links */
                        addrbook_write_elem_s( fp, 2, AB_ELTAG_MEMBER_LIST );
                        fputs( ">\n", fp );
                        node = group->listEMail;
@@ -1065,64 +998,6 @@ static void addrbook_write_item_group_vis( gpointer key, gpointer value, gpointe
        }
 }
 
-/*
-* Output all folders in folder.
-*/
-static void addrbook_write_folder_folder( ItemFolder *parent, FILE *fp ) {
-       GList *nodeFold = parent->listFolder;
-       GList *node;
-
-       while( nodeFold ) {
-               ItemFolder *folder = nodeFold->data;
-               addrbook_write_folder_folder( folder, fp );
-               if( folder ) {
-                       addrbook_write_elem_s( fp, 1, AB_ELTAG_FOLDER );
-                       addrbook_write_attr( fp, AB_ATTAG_UID, ADDRITEM_ID(folder) );
-                       addrbook_write_attr( fp, AB_ATTAG_NAME, ADDRITEM_NAME(folder) );
-                       addrbook_write_attr( fp, AB_ATTAG_REMARKS, folder->remarks );
-                       fputs( " >\n", fp );
-                       addrbook_write_elem_s( fp, 2, AB_ELTAG_ITEM_LIST );
-                       fputs( ">\n", fp );
-
-                       // Output persons
-                       node = folder->listPerson;
-                       while ( node ) {
-                               ItemPerson *item = node->data;
-                               addrbook_write_elem_s( fp, 2, AB_ELTAG_ITEM );
-                               addrbook_write_attr( fp, AB_ATTAG_TYPE,  AB_ATTAG_VAL_PERSON );
-                               addrbook_write_attr( fp, AB_ATTAG_UID, ADDRITEM_ID(item ) );
-                               fputs( " />\n", fp );
-                               node = g_list_next( node );
-                       }
-
-                       // Output groups
-                       node = folder->listGroup;
-                       while ( node ) {
-                               ItemGroup *item = node->data;
-                               addrbook_write_elem_s( fp, 2, AB_ELTAG_ITEM );
-                               addrbook_write_attr( fp, AB_ATTAG_TYPE, AB_ATTAG_VAL_GROUP );
-                               addrbook_write_attr( fp, AB_ATTAG_UID, ADDRITEM_ID(item ) );
-                               fputs( " />\n", fp );
-                               node = g_list_next( node );
-                       }
-
-                       // Output folders
-                       node = folder->listFolder;
-                       while ( node ) {
-                               ItemFolder *item = node->data;
-                               addrbook_write_elem_s( fp, 2, AB_ELTAG_ITEM );
-                               addrbook_write_attr( fp, AB_ATTAG_TYPE, AB_ATTAG_VAL_FOLDER );
-                               addrbook_write_attr( fp, AB_ATTAG_UID, ADDRITEM_ID(item ) );
-                               fputs( " />\n", fp );
-                               node = g_list_next( node );
-                       }
-                       addrbook_write_elem_e( fp, 2, AB_ELTAG_ITEM_LIST );
-                       addrbook_write_elem_e( fp, 1, AB_ELTAG_FOLDER );
-               }
-               nodeFold = g_list_next( nodeFold );
-       }
-}
-
 /*
 * Write file hash table visitor function.
 */
@@ -1143,7 +1018,7 @@ static void addrbook_write_item_folder_vis( gpointer key, gpointer value, gpoint
                        addrbook_write_elem_s( fp, 2, AB_ELTAG_ITEM_LIST );
                        fputs( ">\n", fp );
 
-                       // Output persons
+                       /* Output persons */
                        node = folder->listPerson;
                        while ( node ) {
                                ItemPerson *item = node->data;
@@ -1154,7 +1029,7 @@ static void addrbook_write_item_folder_vis( gpointer key, gpointer value, gpoint
                                node = g_list_next( node );
                        }
 
-                       // Output groups
+                       /* Output groups */
                        node = folder->listGroup;
                        while ( node ) {
                                ItemGroup *item = node->data;
@@ -1165,7 +1040,7 @@ static void addrbook_write_item_folder_vis( gpointer key, gpointer value, gpoint
                                node = g_list_next( node );
                        }
 
-                       // Output folders
+                       /* Output folders */
                        node = folder->listFolder;
                        while ( node ) {
                                ItemFolder *item = node->data;
@@ -1199,7 +1074,7 @@ gint addrbook_write_to( AddressBookFile *book, gchar *newFile ) {
 
        book->retVal = MGU_OPEN_FILE;
 #ifdef DEV_STANDALONE
-       fp = fopen( fileSpec, "w" );
+       fp = fopen( fileSpec, "wb" );
        g_free( fileSpec );
        if( fp ) {
                fputs( "<?xml version=\"1.0\" ?>\n", fp );
@@ -1212,19 +1087,17 @@ gint addrbook_write_to( AddressBookFile *book, gchar *newFile ) {
                                conv_get_current_charset_str() );
 #endif
                addrbook_write_elem_s( fp, 0, AB_ELTAG_ADDRESS_BOOK );
-               addrbook_write_attr( fp, AB_ATTAG_NAME, book->name );
+               addrbook_write_attr( fp, AB_ATTAG_NAME, addrcache_get_name( book->addressCache ) );
                fputs( " >\n", fp );
 
-               // Output all persons
+               /* Output all persons */
                g_hash_table_foreach( book->addressCache->itemHash, addrbook_write_item_person_vis, fp );
 
-               // Output all groups
+               /* Output all groups */
                g_hash_table_foreach( book->addressCache->itemHash, addrbook_write_item_group_vis, fp );
-               // addrbook_write_folder_group( book->rootFolder, fp );
 
-               // Output all folders
+               /* Output all folders */
                g_hash_table_foreach( book->addressCache->itemHash, addrbook_write_item_folder_vis, fp );
-               // addrbook_write_folder_folder( book->rootFolder, fp );
 
                addrbook_write_elem_e( fp, 0, AB_ELTAG_ADDRESS_BOOK );
                book->retVal = MGU_SUCCESS;
@@ -1254,7 +1127,7 @@ gint addrbook_save_data( AddressBookFile *book ) {
 
        addrbook_write_to( book, book->fileName );
        if( book->retVal == MGU_SUCCESS ) {
-               book->dirtyFlag = FALSE;
+               addrcache_set_dirty( book->addressCache, FALSE );
        }
        return book->retVal;
 }
@@ -1280,7 +1153,7 @@ ItemEMail *addrbook_move_email_before( AddressBookFile *book, ItemPerson *person
 
        email = addritem_move_email_before( person, itemMove, itemTarget );
        if( email ) {
-               book->dirtyFlag = TRUE;
+               addrcache_set_dirty( book->addressCache, TRUE );
        }
        return email;
 }
@@ -1301,15 +1174,17 @@ ItemEMail *addrbook_move_email_after( AddressBookFile *book, ItemPerson *person,
 
        email = addritem_move_email_after( person, itemMove, itemTarget );
        if( email ) {
-               book->dirtyFlag = TRUE;
+               addrcache_set_dirty( book->addressCache, TRUE );
        }
        return email;
 }
 
 /*
-* Hash table visitor function.
+* Hash table visitor function for deletion of hashtable entries.
 */
-static gboolean addrbook_free_simple_hash_vis( gpointer *key, gpointer *value, gpointer *data ) {
+static gboolean addrbook_free_simple_hash_vis(
+       gpointer *key, gpointer *value, gpointer *data )
+{
        g_free( key );
        key = NULL;
        value = NULL;
@@ -1320,55 +1195,47 @@ static gboolean addrbook_free_simple_hash_vis( gpointer *key, gpointer *value, g
 * Update address book email list for specified person.
 * Enter: book      Address book.
 *        person    Person to update.
-*        listEMail New list of email addresses.
+*        listEMail List of new email addresses.
 * Note: The existing email addresses are replaced with the new addresses. Any references
 * to old addresses in the groups are re-linked to the new addresses. All old addresses
 * linked to the person are removed.
 */
-void addrbook_update_address_list( AddressBookFile *book, ItemPerson *person, GList *listEMail ) {
+void addrbook_update_address_list(
+       AddressBookFile *book, ItemPerson *person, GList *listEMail )
+{
        GList *node;
-       GList *oldData;
+       GList *listDelete;
        GList *listGroup;
 
        g_return_if_fail( book != NULL );
        g_return_if_fail( person != NULL );
 
-       // Remember old list
-       oldData = person->listEMail;
-
-       // Attach new address list to person.
-       node = listEMail;
-       while( node ) {
-               ItemEMail *email = node->data;
-               if( ADDRITEM_ID(email) == NULL ) {
-                       // Allocate an ID
-                       addrcache_id_email( book->addressCache, email );
-               }
-               ADDRITEM_PARENT(email) = ADDRITEM_OBJECT(person);
-               node = g_list_next( node );
-       }
-       person->listEMail = listEMail;
-
-       // Get groups where person's email is listed
+       /* Get groups where person's existing email addresses are listed */
        listGroup = addrcache_get_group_for_person( book->addressCache, person );
        if( listGroup ) {
                GHashTable *hashEMail;
+               GHashTable *hashEMailAlias;
                GList *nodeGrp;
 
-               // Load hash table with new address entries
+               /* Load hash table with new address entries */
                hashEMail = g_hash_table_new( g_str_hash, g_str_equal );
+               hashEMailAlias = g_hash_table_new( g_str_hash, g_str_equal );
                node = listEMail;
                while( node ) {
                        ItemEMail *email = node->data;
                        gchar *addr = g_strdup( email->address );
+                       gchar *alias = email->obj.name ;
                        g_strdown( addr );
                        if( ! g_hash_table_lookup( hashEMail, addr ) ) {
                                g_hash_table_insert( hashEMail, addr, email );
                        }
+                       if ( *alias != '\0' && ! g_hash_table_lookup( hashEMailAlias, alias ) ) {
+                               g_hash_table_insert( hashEMailAlias, alias, email );
+                       }
                        node = g_list_next( node );
                }
 
-               // Re-parent new addresses to existing groups, where email address match.
+               /* Re-parent new addresses to existing groups, where email address match. */
                nodeGrp = listGroup;
                while( nodeGrp ) {
                        ItemGroup *group = ( ItemGroup * ) nodeGrp->data;
@@ -1376,31 +1243,45 @@ void addrbook_update_address_list( AddressBookFile *book, ItemPerson *person, GL
                        GList *nodeGrpEM;
                        GList *listRemove = NULL;
 
-                       // Process each email item linked to group
+                       /* Process each email item linked to group */
                        nodeGrpEM = groupEMail;
                        while( nodeGrpEM ) {
                                ItemEMail *emailGrp = ( ItemEMail * ) nodeGrpEM->data;
+
                                if( ADDRITEM_PARENT(emailGrp) == ADDRITEM_OBJECT(person) ) {
-                                       // Found an email address for this person
+                                       /* Found an email address for this person */
                                        ItemEMail *emailNew = NULL;
-                                       gchar *addr = g_strdup( emailGrp->address );
+                                       gchar *addr = g_strdup( emailGrp->address );
+                                       gchar *alias = emailGrp->obj.name;
                                        g_strdown( addr );
-                                       emailNew = ( ItemEMail * ) g_hash_table_lookup( hashEMail, addr );
+                                       emailNew = ( ItemEMail * )
+                                               g_hash_table_lookup( hashEMail, addr );
                                        g_free( addr );
+                                       /* If no match by e-mail, try to match by e-mail alias */
+                                       if( ! emailNew && *alias != '\0' ) {
+                                               emailNew = ( ItemEMail * )
+                                                       g_hash_table_lookup( hashEMailAlias, alias);
+                                       }
+                                       
                                        if( emailNew ) {
-                                               // Point to this entry
+                                               /* Point to this entry */
                                                nodeGrpEM->data = emailNew;
                                        }
+                                       else if(g_hash_table_size(hashEMail)==1) {
+                                               /* If the person has just one e-mail address, then 
+                                                  change e-mail address in group list */
+                                               nodeGrpEM->data = listEMail->data;
+                                       } 
                                        else {
-                                               // Mark for removal
+                                               /* Mark for removal */
                                                listRemove = g_list_append( listRemove, emailGrp );
                                        }
                                }
-                               // Move on to next email link
+                               /* Move on to next email link */
                                nodeGrpEM = g_list_next( nodeGrpEM );
                        }
 
-                       // Process all removed links in current group
+                       /* Process all removed links in current group */
                        nodeGrpEM = listRemove;
                        while( nodeGrpEM ) {
                                ItemEMail *emailGrp = nodeGrpEM->data;
@@ -1408,23 +1289,65 @@ void addrbook_update_address_list( AddressBookFile *book, ItemPerson *person, GL
                                nodeGrpEM = g_list_next( nodeGrpEM );
                        }
 
-                       // Move on to next group
+                       g_list_free( listRemove );
+
+                       /* Move on to next group */
                        nodeGrp = g_list_next( nodeGrp );
 
                }
 
-               // Clear hash table
-               g_hash_table_foreach_remove( hashEMail, ( GHRFunc ) addrbook_free_simple_hash_vis, NULL );
+               /* Clear hash table */
+               g_hash_table_foreach_remove(
+                       hashEMail, ( GHRFunc ) addrbook_free_simple_hash_vis, NULL );
                g_hash_table_destroy( hashEMail );
                hashEMail = NULL;
+               g_hash_table_destroy( hashEMailAlias );
+               hashEMailAlias = NULL;
                g_list_free( listGroup );
                listGroup = NULL;
        }
 
-       // Free up old data
-       addritem_free_list_email( oldData );
-       oldData = NULL;
-       book->dirtyFlag = TRUE;
+       /* Remove old addresses from person and cache */
+       listDelete = NULL;
+       node = person->listEMail;
+       while( node ) {
+               ItemEMail *email = node->data;
+
+               if( addrcache_person_remove_email( book->addressCache, person, email ) ) {
+                       addrcache_remove_email( book->addressCache, email );
+               }
+               listDelete = g_list_append( listDelete, email );
+               node = person->listEMail;
+       }
+
+       /* Add new address entries */
+       node = listEMail;
+       while( node ) {
+               ItemEMail *email = node->data;
+
+               if( ADDRITEM_ID(email) == NULL ) {
+                       /* Allocate an ID for new address */
+                       addrcache_id_email( book->addressCache, email );
+               }
+               addrcache_person_add_email( book->addressCache, person, email );
+               node = g_list_next( node );
+       }
+
+       addrcache_set_dirty( book->addressCache, TRUE );
+
+       /* Free up memory */
+       g_list_free( listEMail );
+       listEMail = NULL;
+
+       node = listDelete;
+       while( node ) {
+               ItemEMail *email = node->data;
+
+               addritem_free_item_email( email );
+               node = g_list_next( node );
+       }
+       g_list_free( listDelete );
+       listDelete = NULL;
 
 }
 
@@ -1458,35 +1381,9 @@ ItemPerson *addrbook_add_address_list( AddressBookFile *book, ItemFolder *folder
                addrcache_person_add_email( book->addressCache, person, email );
                node = g_list_next( node );
        }
-       book->dirtyFlag = TRUE;
        return person;
 }
 
-/*
-* Load hash table visitor function.
-*/
-static void addrbook_load_hash_table_email_vis( gpointer key, gpointer value, gpointer data ) {
-       AddrItemObject *obj = ( AddrItemObject * ) value;
-
-       if( ADDRITEM_TYPE(obj) == ITEMTYPE_EMAIL ) {
-               GHashTable *table = ( GHashTable * ) data;
-               gchar *newKey = g_strdup( key );
-               ItemEMail *email = ( ItemEMail * ) obj;
-               if( ! g_hash_table_lookup( table, newKey ) ) {
-                       g_hash_table_insert( table, newKey, email );
-               }
-       }
-}
-
-/*
-* Load hash table with links to email addresses.
-*/
-static void addrbook_load_hash_table_email( AddressBookFile *book, GHashTable *table ) {
-       g_return_if_fail( book != NULL );
-       g_return_if_fail( table != NULL );
-       g_hash_table_foreach( book->addressCache->itemHash, addrbook_load_hash_table_email_vis, table );
-}
-
 /*
 * Build available email list visitor function.
 */
@@ -1499,7 +1396,7 @@ static void addrbook_build_avail_email_vis( gpointer key, gpointer value, gpoint
                GList *node = person->listEMail;
                while( node ) {
                        ItemEMail *email = node->data;
-                       //gchar *newKey = g_strdup( ADDRITEM_ID(email) );
+                       /* gchar *newKey = g_strdup( ADDRITEM_ID(email) ); */
 
                        if( ! g_hash_table_lookup( book->tempHash, ADDRITEM_ID(email) ) ) {
                                book->tempList = g_list_append( book->tempList, email );
@@ -1522,7 +1419,7 @@ GList *addrbook_get_available_email_list( AddressBookFile *book, ItemGroup *grou
 
        g_return_val_if_fail( book != NULL, NULL );
 
-       // Load hash table with group email entries
+       /* Load hash table with group email entries */
        table = g_hash_table_new( g_str_hash, g_str_equal );
        if( group ) {
                list = group->listEMail;
@@ -1533,7 +1430,7 @@ GList *addrbook_get_available_email_list( AddressBookFile *book, ItemGroup *grou
                }
        }
 
-       // Build list of available email addresses which exclude those already in groups
+       /* Build list of available email addresses which exclude those already in groups */
        book->tempList = NULL;
        book->tempHash = table;
        g_hash_table_foreach( book->addressCache->itemHash, addrbook_build_avail_email_vis, book );
@@ -1541,7 +1438,7 @@ GList *addrbook_get_available_email_list( AddressBookFile *book, ItemGroup *grou
        book->tempList = NULL;
        book->tempHash = NULL;
 
-       // Clear hash table
+       /* Clear hash table */
        g_hash_table_destroy( table );
        table = NULL;
 
@@ -1563,12 +1460,13 @@ void addrbook_update_group_list( AddressBookFile *book, ItemGroup *group, GList
        g_return_if_fail( book != NULL );
        g_return_if_fail( group != NULL );
 
-       // Remember old list
+       addrcache_set_dirty( book->addressCache, TRUE );
+
+       /* Remember old list */
        oldData = group->listEMail;
        group->listEMail = listEMail;
        mgu_clear_list( oldData );
        oldData = NULL;
-       book->dirtyFlag = TRUE;
 }
 
 /*
@@ -1592,7 +1490,6 @@ ItemGroup *addrbook_add_group_list( AddressBookFile *book, ItemFolder *folder, G
        addrcache_id_group( book->addressCache, group );
        addrcache_folder_add_group( book->addressCache, f, group );
        group->listEMail = listEMail;
-       book->dirtyFlag = TRUE;
        return group;
 }
 
@@ -1614,7 +1511,7 @@ ItemFolder *addrbook_add_new_folder( AddressBookFile *book, ItemFolder *parent )
        if( addrcache_hash_add_folder( book->addressCache, folder ) ) {
                p->listFolder = g_list_append( p->listFolder, folder );
                ADDRITEM_PARENT(folder) = ADDRITEM_OBJECT(p);
-               book->dirtyFlag = TRUE;
+               addrcache_set_dirty( book->addressCache, TRUE );
        }
        else {
                addritem_free_item_folder( folder );
@@ -1638,25 +1535,25 @@ void addrbook_update_attrib_list( AddressBookFile *book, ItemPerson *person, GLi
        g_return_if_fail( book != NULL );
        g_return_if_fail( person != NULL );
 
-       // Remember old list
+       /* Remember old list */
        oldData = person->listAttrib;
 
-       // Attach new address list to person.
+       /* Attach new address list to person. */
        node = listAttrib;
        while( node ) {
                UserAttribute *attrib = node->data;
                if( attrib->uid == NULL ) {
-                       // Allocate an ID
+                       /* Allocate an ID */
                        addrcache_id_attribute( book->addressCache, attrib );
                }
                node = g_list_next( node );
        }
        person->listAttrib = listAttrib;
+       addrcache_set_dirty( book->addressCache, TRUE );
 
-       // Free up old data
+       /* Free up old data */
        addritem_free_list_attribute( oldData );
        oldData = NULL;
-       book->dirtyFlag = TRUE;
 
 }
 
@@ -1682,7 +1579,7 @@ void addrbook_add_attrib_list( AddressBookFile *book, ItemPerson *person, GList
                addritem_person_add_attribute( person, attrib );
                node = g_list_next( node );
        }
-       book->dirtyFlag = TRUE;
+       addrcache_set_dirty( book->addressCache, TRUE );
 }
 
 /*
@@ -1726,7 +1623,6 @@ ItemFolder *addrbook_remove_folder( AddressBookFile *book, ItemFolder *folder )
        g_return_val_if_fail( book != NULL, NULL );
 
        f = addrcache_remove_folder( book->addressCache, folder );
-       if( f ) book->dirtyFlag = TRUE;
        return f;
 }
 
@@ -1741,7 +1637,6 @@ ItemFolder *addrbook_remove_folder_delete( AddressBookFile *book, ItemFolder *fo
        g_return_val_if_fail( book != NULL, NULL );
 
        f = addrcache_remove_folder_delete( book->addressCache, folder );
-       if( f ) book->dirtyFlag = TRUE;
        return f;
 }
 
@@ -1806,6 +1701,7 @@ GList *addrbook_get_bookfile_list( AddressBookFile *book ) {
                        if( strncmp( entry->d_name, ADDRBOOK_PREFIX, lenpre ) == 0 ) {
                                if( strncmp( (entry->d_name) + lennum, ADDRBOOK_SUFFIX, lensuf ) == 0 ) {
                                        strncpy( numbuf, (entry->d_name) + lenpre, FILE_NUMDIGITS );
+                                       numbuf[ FILE_NUMDIGITS ] = '\0';
                                        flg = TRUE;
                                        for( i = 0; i < FILE_NUMDIGITS; i++ ) {
                                                if( ! strchr( ADDRBOOK_DIGITS, numbuf[i] ) ) {
@@ -1814,7 +1710,7 @@ GList *addrbook_get_bookfile_list( AddressBookFile *book ) {
                                                }
                                        }
                                        if( flg ) {
-                                               // Get value
+                                               /* Get value */
                                                val = strtol( numbuf, &endptr, 10 );
                                                if( endptr  && val > -1 ) {
                                                        if( val > maxval ) maxval = val;
@@ -1847,8 +1743,8 @@ gchar *addrbook_gen_new_file_name( gint fileNum ) {
        if( n < 1 ) n = 1;
        nmax = -1 + (long int) pow( 10, FILE_NUMDIGITS );
        if( fileNum > nmax ) return NULL;
-       sprintf( fmt, "%%s%%0%dd%%s", FILE_NUMDIGITS );
-       sprintf( buf, fmt, ADDRBOOK_PREFIX, n, ADDRBOOK_SUFFIX );
+       g_snprintf( fmt, sizeof(fmt), "%%s%%0%dd%%s", FILE_NUMDIGITS );
+       g_snprintf( buf, sizeof(buf), fmt, ADDRBOOK_PREFIX, n, ADDRBOOK_SUFFIX );
        return g_strdup( buf );
 }
 
@@ -1857,16 +1753,6 @@ gchar *addrbook_gen_new_file_name( gint fileNum ) {
 * ***********************************************************************
 */
 
-static void addrbook_show_attribs( GList *attr ) {
-       while( attr ) {
-               gchar *name = ((XMLAttr *)attr->data)->name;
-               gchar *value = ((XMLAttr *)attr->data)->value;
-               printf( "\tn/v = %s : %s\n", name, value );
-               attr = g_list_next( attr );
-       }
-       printf( "\t---\n" );
-}
-
 /*
 * Test email address list.
 */
@@ -1881,7 +1767,7 @@ static void addrbook_chkparse_addr_list( AddressBookFile *book, XMLFile *file ){
                }
                if (file->level < prev_level) return;
                attr = xml_get_current_tag_attr(file);
-               // addrbook_show_attribs( attr );
+               /* addrbook_show_attribs( attr ); */
                if( xml_compare_tag( file, AB_ELTAG_ADDRESS ) ) {
                        addrbook_chkparse_addr_list( book, file );
                }
@@ -1896,9 +1782,9 @@ static void addrbook_chkparse_attribute( AddressBookFile *book, XMLFile *file )
        gchar *element;
 
        attr = xml_get_current_tag_attr(file);
-       // addrbook_show_attribs( attr );
+       /* addrbook_show_attribs( attr ); */
        element = xml_get_element( file );
-       // printf( "\t\tattrib value : %s\n", element );
+       /* printf( "\t\tattrib value : %s\n", element ); */
 }
 
 /*
@@ -1927,14 +1813,14 @@ static void addrbook_chkparse_person( AddressBookFile *book, XMLFile *file ) {
        GList *attr;
 
        attr = xml_get_current_tag_attr(file);
-       // addrbook_show_attribs( attr );
-       if( xml_parse_next_tag( file ) ) {      // Consume closing tag
+       /* addrbook_show_attribs( attr ); */
+       if( xml_parse_next_tag( file ) ) {      /* Consume closing tag */
                longjmp( book->jumper, 1 );
        }
        if( xml_compare_tag( file, AB_ELTAG_ADDRESS_LIST ) ) {
                addrbook_chkparse_addr_list( book, file );
        }
-       if( xml_parse_next_tag( file ) ) {      // Consume closing tag
+       if( xml_parse_next_tag( file ) ) {      /* Consume closing tag */
                longjmp( book->jumper, 1 );
        }
        if( xml_compare_tag( file, AB_ELTAG_ATTRIBUTE_LIST ) ) {
@@ -1957,12 +1843,12 @@ static void addrbook_chkparse_member_list( AddressBookFile *book, XMLFile *file
                if (file->level < prev_level) return;
                if( xml_compare_tag( file, AB_ELTAG_MEMBER ) ) {
                        attr = xml_get_current_tag_attr(file);
-                       // addrbook_show_attribs( attr );
+                       /* addrbook_show_attribs( attr ); */
                        addrbook_chkparse_member_list( book, file );
                }
                else {
                        attr = xml_get_current_tag_attr( file );
-                       // addrbook_show_attribs( attr );
+                       /* addrbook_show_attribs( attr ); */
                }
        }
 }
@@ -1974,8 +1860,8 @@ static void addrbook_chkparse_group( AddressBookFile *book, XMLFile *file ) {
        GList *attr;
 
        attr = xml_get_current_tag_attr(file);
-       // addrbook_show_attribs( attr );
-       if( xml_parse_next_tag( file ) ) {      // Consume closing tag
+       /* addrbook_show_attribs( attr ); */
+       if( xml_parse_next_tag( file ) ) {      /* Consume closing tag */
                longjmp( book->jumper, 1 );
        }
        if( xml_compare_tag( file, AB_ELTAG_MEMBER_LIST ) ) {
@@ -1998,12 +1884,12 @@ static void addrbook_chkparse_folder_list( AddressBookFile *book, XMLFile *file
                if (file->level < prev_level) return;
                if( xml_compare_tag( file, AB_ELTAG_ITEM ) ) {
                        attr = xml_get_current_tag_attr(file);
-                       // addrbook_show_attribs( attr );
+                       /* addrbook_show_attribs( attr ); */
                        addrbook_chkparse_folder_list( book, file );
                }
                else {
                        attr = xml_get_current_tag_attr( file );
-                       // addrbook_show_attribs( attr );
+                       /* addrbook_show_attribs( attr ); */
                }
        }
 }
@@ -2015,8 +1901,8 @@ static void addrbook_chkparse_folder( AddressBookFile *book, XMLFile *file ) {
        GList *attr;
 
        attr = xml_get_current_tag_attr(file);
-       // addrbook_show_attribs( attr );
-       if( xml_parse_next_tag( file ) ) {      // Consume closing tag
+       /* addrbook_show_attribs( attr ); */
+       if( xml_parse_next_tag( file ) ) {      /* Consume closing tag */
                longjmp( book->jumper, 1 );
        }
        if( xml_compare_tag( file, AB_ELTAG_ITEM_LIST ) ) {
@@ -2043,19 +1929,16 @@ static gboolean addrbook_chkread_tree( AddressBookFile *book, XMLFile *file ) {
        }
 
        attr = xml_get_current_tag_attr(file);
-       // addrbook_show_attribs( attr );
+       /* addrbook_show_attribs( attr ); */
 
        retVal = TRUE;
        for (;;) {
                if (! file->level ) break;
-               // Get item tag
-               if( xml_parse_next_tag( file ) ) {
-                       longjmp( book->jumper, 1 );
-               }
-               // Get next tag (person, group or folder)
+               /* Get item tag */
                if( xml_parse_next_tag( file ) ) {
                        longjmp( book->jumper, 1 );
                }
+               /* Get next tag (person, group or folder) */
                if( xml_compare_tag( file, AB_ELTAG_PERSON ) ) {
                        addrbook_chkparse_person( book, file );
                }
@@ -2065,10 +1948,6 @@ static gboolean addrbook_chkread_tree( AddressBookFile *book, XMLFile *file ) {
                else if( xml_compare_tag( file, AB_ELTAG_FOLDER ) ) {
                        addrbook_chkparse_folder( book, file );
                }
-               else {
-                       // Item not recognized
-                       retVal = FALSE;
-               }
        }
        return retVal;
 }
@@ -2092,7 +1971,7 @@ gint addrbook_test_read_file( AddressBookFile *book, gchar *fileName ) {
        if( file ) {
                book->retVal = MGU_BAD_FORMAT;
                if( setjmp( book->jumper ) ) {
-                       // printf( "Caught Ya!!!\n" );
+                       /* printf( "Caught Ya!!!\n" ); */
                        xml_close_file( file );
                        return book->retVal;
                }
@@ -2128,15 +2007,32 @@ GList *addrbook_get_all_persons( AddressBookFile *book ) {
 ItemPerson *addrbook_add_contact( AddressBookFile *book, ItemFolder *folder, const gchar *name,
                const gchar *address, const gchar *remarks )
 {
-       ItemPerson *person = NULL;
-
        g_return_val_if_fail( book != NULL, NULL );
+       return addrcache_add_contact( book->addressCache, folder, name, address, remarks );
+}
 
-       person = addrcache_add_contact( book->addressCache, folder, name, address, remarks );
-       if( person ) book->dirtyFlag = TRUE;
-       return person;
+/*
+ * Return file name for next address book file.
+ * Enter:  book Address book.
+ * Return: File name, or NULL if could not create. This should be g_free()
+ *         when done.
+ */
+gchar *addrbook_guess_next_file( AddressBookFile *book ) {
+       gchar *newFile = NULL;
+       GList *fileList = NULL;
+       gint fileNum = 1;
+       fileList = addrbook_get_bookfile_list( book );
+       if( fileList ) {
+               fileNum = 1 + book->maxValue;
+       }
+       newFile = addrbook_gen_new_file_name( fileNum );
+       g_list_free( fileList );
+       fileList = NULL;
+       return newFile;
 }
 
 /*
 * End of Source.
 */
+
+