Index: trunk/psLib/src/collections/psMetadata.c
===================================================================
--- trunk/psLib/src/collections/psMetadata.c	(revision 1447)
+++ trunk/psLib/src/collections/psMetadata.c	(revision 1458)
@@ -12,6 +12,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2004-08-10 01:43:05 $
+*  @version $Revision: 1.22 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-08-10 23:32:51 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -19,7 +19,5 @@
 
 /******************************************************************************/
-
 /*  INCLUDE FILES                                                             */
-
 /******************************************************************************/
 #include<stdio.h>
@@ -38,7 +36,5 @@
 
 /******************************************************************************/
-
 /*  DEFINE STATEMENTS                                                         */
-
 /******************************************************************************/
 
@@ -60,7 +56,5 @@
 
 /******************************************************************************/
-
 /*  TYPE DEFINITIONS                                                          */
-
 /******************************************************************************/
 
@@ -68,7 +62,5 @@
 
 /*****************************************************************************/
-
 /*  GLOBAL VARIABLES                                                         */
-
 /*****************************************************************************/
 
@@ -76,7 +68,5 @@
 
 /*****************************************************************************/
-
 /*  FILE STATIC VARIABLES                                                    */
-
 /*****************************************************************************/
 
@@ -84,8 +74,7 @@
 
 /*****************************************************************************/
-
 /*  FUNCTION IMPLEMENTATION - LOCAL                                          */
-
 /*****************************************************************************/
+
 static void metadataItemFree(psMetadataItem* metadataItem)
 {
@@ -119,7 +108,5 @@
 
 /*****************************************************************************/
-
 /* FUNCTION IMPLEMENTATION - PUBLIC                                          */
-
 /*****************************************************************************/
 
@@ -175,7 +162,9 @@
     // Set metadata item value
     switch (type) {
+    case PS_META_ITEM_SET:
+        metadataItem->data.V = NULL;
+        break;
     case PS_META_BOOL:
-        metadataItem->data.B = (bool) va_arg(argPtr, int);
-
+        metadataItem->data.B = (bool)va_arg(argPtr, int);
         break;
     case PS_META_S32:
@@ -183,5 +172,5 @@
         break;
     case PS_META_F32:
-        metadataItem->data.F32 = (psF32) va_arg(argPtr, psF64);
+        metadataItem->data.F32 = (psF32)va_arg(argPtr, psF64);
         break;
     case PS_META_F64:
@@ -190,5 +179,4 @@
     case PS_META_STR:
         metadataItem->data.V = psStringNCopy(va_arg(argPtr, char *), MAX_STRING_LENGTH);
-
         break;
     case PS_META_IMG:
@@ -242,72 +230,117 @@
 }
 
-bool psMetadataAddItem(psMetadata* restrict md, int where, psMetadataItem* restrict metadataItem)
-{
-    char *key = NULL;
-    psHash* mdTable = NULL;
-    psList* mdList = NULL;
-    psMetadataItem* value = NULL;
-    psMetadataType type = PS_META_ITEM_SET;
-
-    if (md == NULL) {
-        psError(__func__, "Null metadata collection not allowed");
-        return false;
-    }
-
-    if (metadataItem == NULL) {
-        psError(__func__, "Null metadata item not allowed");
-        return false;
-    }
-
-    type = metadataItem->type;
+bool psMetadataAddItem( psMetadata *restrict md, int where, psMetadataItem *restrict metadataItem )
+{
+    char * key = NULL;
+    psHash *mdTable = NULL;
+    psList *mdList = NULL;
+    psMetadataItem *existingEntry = NULL;
+    psMetadataItem *newFolderEntry = NULL;
+    psMetadataType newType = PS_META_ITEM_SET;
+
+    if(md == NULL) {
+        psError( __func__, "Null metadata collection not allowed" );
+        return false;
+    }
+
+    if(metadataItem == NULL) {
+        psError( __func__, "Null metadata item not allowed" );
+        return false;
+    }
+
+    newType = metadataItem->type;
 
     mdTable = md->table;
-    if (mdTable == NULL) {
-        psError(__func__, "Null metadata table not allowed");
+    if(mdTable == NULL) {
+        psError( __func__, "Null metadata table not allowed" );
         return false;
     }
 
     mdList = md->list;
-    if (mdList == NULL) {
-        psError(__func__, "Null metadata list not allowed");
+    if(mdList == NULL) {
+        psError( __func__, "Null metadata list not allowed");
         return false;
     }
 
     key = metadataItem->name;
-    if (key == NULL) {
+    if(key == NULL) {
         psError(__func__, "Null key item not allowed");
         return false;
     }
-    // Check if key is already in table
-    value = (psMetadataItem* ) psHashLookup(mdTable, key);
-    if (value != NULL && type != PS_META_ITEM_SET) {
-
-        // The key was found and the new metadata item is a leaf node (its type isn't PS_META_ITEM_SET), so
-        // add the new metadata item to hash as a child of the existing metadata item folder node.
-        if (!psListAdd(value->items, metadataItem, where)) {
-            psError(__func__, "Couldn't add metadata item to items list. Name: %s", metadataItem->name);
+
+    // See if key is already in table
+    existingEntry = (psMetadataItem*)psHashLookup(mdTable, key);
+    if(existingEntry != NULL) {
+
+        if(existingEntry->type == PS_META_ITEM_SET) {
+
+            // Add leaf node to existing folder node
+            if(!psListAdd(existingEntry->items, metadataItem, PS_LIST_TAIL)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s",
+                         metadataItem->name );
+                return false;
+            }
+        } else if(existingEntry->type != PS_META_ITEM_SET && newType!= PS_META_ITEM_SET) {
+
+            // Leaf node replaces another leaf. Make new folder node and add leaves.
+            newFolderEntry = psMetadataItemAlloc(key, PS_META_ITEM_SET, NULL, NULL);
+
+            if(!psListAdd(newFolderEntry->items, existingEntry, PS_LIST_TAIL)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psListAdd(newFolderEntry->items, metadataItem, PS_LIST_TAIL)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError( __func__, "Couldn't remove metadata item from metadata table. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, newFolderEntry)) {
+                psError( __func__, "Couldn't add metadata item to metadata table. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            // Remove local reference to new folder node
+            psMemDecrRefCounter(newFolderEntry);
+        } else {
+
+            // Folder node replaces leaf or folder node - Put old node into new folder and remove from table
+            if(!psListAdd(metadataItem->items, existingEntry, PS_LIST_TAIL)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s", key);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError( __func__, "Couldn't remove metadata item from metadata table. Name: %s", key);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, metadataItem)) {
+                psError( __func__, "Couldn't add metadata item to metadata table. Name: %s", key);
+                return false;
+            }
+        }
+    } else {
+
+        // Node doesn't exist - Add new metadata item to metadata collection's hash
+        if(!psHashAdd(mdTable, key, metadataItem)) {
+            psError( __func__, "Couldn't add metadata item to metadata table. Name: %s", key);
             return false;
         }
-    } else if (value != NULL) {
-
-        // The key was found and the new metadata item is a folder node. Don't add new metadata item, since
-        // it will wipe out existing node.
-        psError(__func__, "Metadata already exists in metadata collection. Item not added. Name: %s",
-                metadataItem->name);
-        return false;
-    } else {
-
-        // Duplicate key not found. Add new metadata item to metadata collection's hash
-        if (!psHashAdd(mdTable, key, metadataItem)) {
-            psError(__func__, "Couldn't add metadata item to metadata collection table. Name: %s",
-                    metadataItem->name);
-            return false;
-        }
     }
 
     // Add all items to metadata collection's list, even if they have the same metadata item names
-    if (!psListAdd(md->list, metadataItem, where)) {
-        psError(__func__, "Couldn't add metadata item to metadata collection list. Name: %s",
-                metadataItem->name);
+    if(!psListAdd( mdList, metadataItem, where )) {
+        psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s",
+                 metadataItem->name );
         return false;
     }
@@ -338,4 +371,6 @@
     return true;
 }
+
+
 
 bool psMetadataRemove(psMetadata* restrict md, int where, const char *restrict key)
