Index: trunk/archive/scripts/src/phase2/psAdditionals.c
===================================================================
--- trunk/archive/scripts/src/phase2/psAdditionals.c	(revision 5633)
+++ trunk/archive/scripts/src/phase2/psAdditionals.c	(revision 5651)
@@ -3,4 +3,75 @@
 #include "pslib.h"
 #include "psAdditionals.h"
+
+
+psMetadata *psMetadataCopy(psMetadata *out,
+                           const psMetadata *in)
+{
+    PS_ASSERT_PTR_NON_NULL(in,NULL);
+    if (out ==  NULL) {
+        out = psMetadataAlloc();
+    }
+    psMetadataItem *inItem = NULL;
+    psMetadataIterator *iter = psMetadataIteratorAlloc(*(psMetadata**)&in, PS_LIST_HEAD, NULL);
+    unsigned long numPointers = 0;	// Number of pointers we were forced to copy
+    while (inItem = psMetadataGetAndIncrement(iter)) {
+	psMetadataItem *outItem = NULL;
+
+	// Need to look for MULTI, which won't be picked up using the iterator.
+	psMetadataItem *multiCheckItem = psMetadataLookup(in, inItem->name);
+	int multiFlag = 0;		// Flag to indicate MULTI or not
+	if (multiCheckItem->type == PS_DATA_METADATA_MULTI) {
+	    multiFlag = PS_DATA_METADATA_MULTI;
+	}
+
+#define PS_METADATA_COPY_CASE(NAME,TYPE) \
+          case PS_TYPE_##NAME: \
+            psMetadataAdd(out, PS_LIST_TAIL, inItem->name, PS_TYPE_##NAME | multiFlag, inItem->comment, \
+			  inItem->data.TYPE); \
+            break;
+
+	switch (inItem->type) {
+	    // Numerical types
+	    PS_METADATA_COPY_CASE(BOOL,B);
+	    PS_METADATA_COPY_CASE(S8, S8);
+	    PS_METADATA_COPY_CASE(S16, S16);
+	    PS_METADATA_COPY_CASE(S32, S32);
+	    PS_METADATA_COPY_CASE(U8, U8);
+	    PS_METADATA_COPY_CASE(U16, U16);
+	    PS_METADATA_COPY_CASE(U32, U32);
+	    PS_METADATA_COPY_CASE(F32, F32);
+	    PS_METADATA_COPY_CASE(F64, F64);
+
+	    // String: relying on the fact that this will copy the string, not point at it.
+	  case PS_DATA_STRING:
+            psMetadataAdd(out, PS_LIST_TAIL, inItem->name, PS_DATA_STRING | multiFlag, inItem->comment,
+			  inItem->data.V);
+            break;
+
+	    // Metadata: copy the next level and stuff that in too
+	  case PS_DATA_METADATA:
+	    {
+		psMetadata *metadata = psMetadataCopy(NULL, inItem->data.md);
+		psMetadataAdd(out, PS_LIST_TAIL, inItem->name, PS_DATA_METADATA | multiFlag, inItem->comment,
+			      metadata);
+		break;
+	    }
+	    // Other kinds of pointers
+	  default:
+	    numPointers++;
+	    psMetadataItemAlloc(inItem->name, inItem->type, inItem->comment, inItem->data.V);
+	    break;
+	}
+    }
+    psFree(iter);
+
+    if (numPointers > 0) {
+	psLogMsg(__func__, PS_LOG_WARN, "Forced to copy %d pointers when copying metadata.  Updating the "
+		 "copied psMetadata will affect the original!\n");
+    }
+
+    return out;
+}
+
 
 psMetadata *psMetadataLookupMD(bool *status, const psMetadata *md, const char *key)
