Index: /trunk/psLib/src/types/psMetadata.c
===================================================================
--- /trunk/psLib/src/types/psMetadata.c	(revision 8785)
+++ /trunk/psLib/src/types/psMetadata.c	(revision 8786)
@@ -12,6 +12,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.131 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-08-30 00:54:51 $
+ *  @version $Revision: 1.132 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-09-10 08:53:07 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -532,4 +532,11 @@
         // the incoming entry is PS_DATA_METADATA_MULTI
 
+        //Shouldn't have a second reference to the same MULTI in a single Metadata!
+        if (item == existingEntry) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    "Cannot have 2 references to the same MULTI in a single Metadata!");
+            return false;
+        }
+
         // force the hash entry to be PS_DATA_METADATA_MULTI
         existingEntry = makeMetaMulti(mdTable,key,existingEntry);
@@ -559,5 +566,7 @@
             // add to the hash's list of duplicate entries
             if (! psListAdd(existingEntry->data.list, PS_LIST_TAIL, (psPtr)item) ) {
-                psError(PS_ERR_UNKNOWN,false,_("Failed to add metadata item, %s, to metadata collection list."),key);
+                psError(PS_ERR_UNKNOWN, false,
+                        _("Failed to add metadata item, %s, to metadata collection list."),
+                        key);
                 return false;
             }
@@ -569,8 +578,12 @@
 
             // treat as if new (added to list below)
-            if(!psHashAdd(mdTable, key, (psPtr)item)) {
-                psError(PS_ERR_UNKNOWN,false,_("Failed to add metadata item, %s, to items table."),key);
-                return false;
-            }
+            /*  The following is unneeded.  HashAdd can't return false with non-null inputs.
+                        if(!psHashAdd(mdTable, key, (psPtr)item)) {
+                            psError(PS_ERR_UNKNOWN,false,
+                                _("Failed to add metadata item, %s, to items table."),key);
+                            return false;
+                        }
+            */
+            psHashAdd(mdTable, key, (psPtr)item);
 
             // Generate warning that item has been replaced
@@ -583,5 +596,6 @@
             }
             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
-                    _("Duplicate metadata item name is not allowed.  Use a psMetadataFlags option to allow such action."));
+                    _("Duplicate metadata item name is not allowed.  "
+                      "Use a psMetadataFlags option to allow such action."));
             return false;
         }
@@ -590,9 +604,13 @@
 
         // Node doesn't exist - Add new metadata item to metadata collection's hash
-        if(!psHashAdd(mdTable, key, (psPtr)item)) {
-            psError(PS_ERR_UNKNOWN,false,_("Failed to add metadata item, %s, to items table."),key);
-            return false;
-        }
-
+        /*  The following is unneeded.  HashAdd can't return false with non-null inputs.
+         
+                if(!psHashAdd(mdTable, key, (psPtr)item)) {
+                    psError(PS_ERR_UNKNOWN,false,
+                            _("Failed to add metadata item, %s, to items table."),key);
+                    return false;
+                }
+        */
+        psHashAdd(mdTable, key, (psPtr)item);
         // Create a multi, if required
         if (flags & PS_META_DUPLICATE_OK) {
@@ -602,5 +620,6 @@
 
     if(!psListAdd(mdList, location, (psPtr)item)) {
-        psError(PS_ERR_UNKNOWN,false,_("Failed to add metadata item, %s, to metadata collection list."),key);
+        psError(PS_ERR_UNKNOWN, false,
+                _("Failed to add metadata item, %s, to metadata collection list."), key);
         return false;
     }
@@ -1403,5 +1422,5 @@
 psPolynomial2D *psPolynomial2DfromMD (psMetadata *folder)
 {
-
+    PS_ASSERT_PTR_NON_NULL(folder, NULL);
     bool status;
     char keyword[80];
@@ -1410,5 +1429,9 @@
     // XXX add status failures tests
     int nXorder = psMetadataLookupS32 (&status, folder, "NORDER_X");
+    if (!status)
+        return NULL;
     int nYorder = psMetadataLookupS32 (&status, folder, "NORDER_Y");
+    if (!status)
+        return NULL;
 
     psPolynomial2D *poly = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, nXorder, nYorder);
@@ -1418,7 +1441,14 @@
             sprintf (keyword, "VAL_X%02d_Y%02d", nx, ny);
             poly->coeff[nx][ny] = psMetadataLookupF64 (&status, folder, keyword);
-            if (!status)
-                poly->mask[nx][ny] = 1;
-
+            if (!status) {
+                //XXX: Setting the mask of a corrupted polynomial doesn't make sense.
+                //The polynomial is garbage if ANY coeff-element is lost!!!
+                //                    poly->mask[nx][ny] = 1;
+                psError(PS_ERR_BAD_PARAMETER_VALUE, false,
+                        "psPolynomial2D in metadata has lost a coefficient somewhere!"
+                        " >>position= [x,y] = %02d, %02d", nx, ny);
+                psFree(poly);
+                return NULL;
+            }
             sprintf (keyword, "ERR_X%02d_Y%02d", nx, ny);
             poly->coeffErr[nx][ny] = psMetadataLookupF64 (&status, folder, keyword);
@@ -1434,4 +1464,12 @@
                          ...)
 {
+    PS_ASSERT_PTR_NON_NULL(md, false);
+    PS_ASSERT_PTR_NON_NULL(poly, false);
+    //XXX:  Current implementation only supports ordinary polynomials.
+    if (poly->type != PS_POLYNOMIAL_ORD)
+        return false;
+    //Make sure polynomial isn't 0, completely empty
+    if (poly->nX == 0 && poly->nY == 0 && poly->coeff[0][0] == 0)
+        return false;
 
     int Nbyte;
@@ -1444,5 +1482,5 @@
     va_end (argp);
 
-    if (!Nbyte)
+    if (Nbyte <= 0)
         return false;
 
@@ -1459,13 +1497,17 @@
     psMetadataAdd (folder, PS_LIST_TAIL, "NORDER_Y", PS_DATA_S32, "number of y orders", poly->nY);
 
+    char namespace[80];
+    char namespace_err[80];
     // place polynomial entries on folder
     for (int nx = 0; nx < poly->nX + 1; nx++) {
         for (int ny = 0; ny < poly->nY + 1; ny++) {
-            if (poly->mask[nx][ny])
-                continue;
-            psMetadataAdd (folder, PS_LIST_TAIL, "VAL_X%02d_Y%02d", PS_DATA_F64,
-                           "polynomial coefficient", poly->coeff[nx][ny], nx, ny);
-            psMetadataAdd (folder, PS_LIST_TAIL, "ERR_X%02d_Y%02d", PS_DATA_F64,
-                           "polynomial coefficient error", poly->coeffErr[nx][ny], nx, ny);
+            if (poly->mask[nx][ny] == 0) {
+                sprintf(namespace, "VAL_X%02d_Y%02d", nx, ny);
+                sprintf(namespace_err, "ERR_X%02d_Y%02d", nx, ny);
+                psMetadataAdd (folder, PS_LIST_TAIL, namespace, PS_DATA_F64,
+                               "polynomial coefficient", poly->coeff[nx][ny]);
+                psMetadataAdd (folder, PS_LIST_TAIL, namespace_err, PS_DATA_F64,
+                               "polynomial coefficient error", poly->coeffErr[nx][ny]);
+            }
         }
     }
@@ -1478,4 +1520,5 @@
 psPolynomial3D *psPolynomial3DfromMD (psMetadata *folder)
 {
+    PS_ASSERT_PTR_NON_NULL(folder, NULL);
 
     bool status;
@@ -1485,6 +1528,12 @@
     // XXX add status failures tests
     int nXorder = psMetadataLookupS32 (&status, folder, "NORDER_X");
+    if (!status)
+        return NULL;
     int nYorder = psMetadataLookupS32 (&status, folder, "NORDER_Y");
+    if (!status)
+        return NULL;
     int nZorder = psMetadataLookupS32 (&status, folder, "NORDER_Z");
+    if (!status)
+        return NULL;
 
     psPolynomial3D *poly = psPolynomial3DAlloc (PS_POLYNOMIAL_ORD, nXorder, nYorder, nZorder);
@@ -1495,7 +1544,14 @@
                 sprintf (keyword, "VAL_X%02d_Y%02d_Z%02d", nx, ny, nz);
                 poly->coeff[nx][ny][nz] = psMetadataLookupF64 (&status, folder, keyword);
-                if (!status)
-                    poly->mask[nx][ny][nz] = 1;
-
+                if (!status) {
+                    //XXX: Setting the mask of a corrupted polynomial doesn't make sense.
+                    //The polynomial is garbage if ANY coeff-element is lost!!!
+                    //                    poly->mask[nx][ny][nz] = 1;
+                    psError(PS_ERR_BAD_PARAMETER_VALUE, false,
+                            "psPolynomial3D in metadata has lost a coefficient somewhere!"
+                            " >>position= [x,y,z] = %02d, %02d, %02d", nx, ny, nz);
+                    psFree(poly);
+                    return NULL;
+                }
                 sprintf (keyword, "ERR_X%02d_Y%02d_Z%02d", nx, ny, nz);
                 poly->coeffErr[nx][ny][nz] = psMetadataLookupF64 (&status, folder, keyword);
@@ -1506,6 +1562,17 @@
 }
 
-bool psPolynomial3DtoMD (psMetadata *md, psPolynomial3D *poly, char *format, ...)
-{
+bool psPolynomial3DtoMD (psMetadata *md,
+                         psPolynomial3D *poly,
+                         char *format,
+                         ...)
+{
+    PS_ASSERT_PTR_NON_NULL(md, false);
+    PS_ASSERT_PTR_NON_NULL(poly, false);
+    //XXX:  Current implementation only supports ordinary polynomials.
+    if (poly->type != PS_POLYNOMIAL_ORD)
+        return false;
+    //Make sure polynomial isn't 0, completely empty
+    if (poly->nX == 0 && poly->nY == 0 && poly->nZ == 0 && poly->coeff[0][0][0] == 0)
+        return false;
 
     int Nbyte;
@@ -1518,5 +1585,5 @@
     va_end (argp);
 
-    if (!Nbyte)
+    if (Nbyte <= 0)
         return false;
 
@@ -1528,6 +1595,4 @@
 
     psMetadata *folder = psMetadataAlloc ();
-    psMetadataAdd (md, PS_LIST_TAIL, root, PS_DATA_METADATA, "folder for 3D polynomial", folder);
-    psFree (root);
 
     // specify the polynomial orders
@@ -1536,15 +1601,27 @@
     psMetadataAdd (folder, PS_LIST_TAIL, "NORDER_Z", PS_DATA_S32, "number of z orders", poly->nZ);
 
+    char namespace[80];
+    char namespace_err[80];
     // place polynomial entries on folder
     for (int nx = 0; nx < poly->nX + 1; nx++) {
         for (int ny = 0; ny < poly->nY + 1; ny++) {
             for (int nz = 0; nz < poly->nZ + 1; nz++) {
-                if (poly->mask[nx][ny][nz])
-                    continue;
-                psMetadataAdd (folder, PS_LIST_TAIL, "VAL_X%02d_Y%02d_Z%02d", PS_DATA_F64, "polynomial coefficient", poly->coeff[nx][ny][nz], nx, ny, nz);
-                psMetadataAdd (folder, PS_LIST_TAIL, "ERR_X%02d_Y%02d_Z%02d", PS_DATA_F64, "polynomial coeffficient error", poly->coeffErr[nx][ny][nz], nx, ny, nz);
-            }
-        }
-    }
+                if (poly->mask[nx][ny][nz] == 0) {
+                    sprintf(namespace, "VAL_X%02d_Y%02d_Z%02d", nx, ny, nz);
+                    sprintf(namespace_err, "ERR_X%02d_Y%02d_Z%02d", nx, ny, nz);
+                    psMetadataAdd (folder, PS_LIST_TAIL, namespace,
+                                   PS_DATA_F64, "polynomial coefficient",
+                                   poly->coeff[nx][ny][nz], nx, ny, nz);
+                    psMetadataAdd (folder, PS_LIST_TAIL, namespace_err,
+                                   PS_DATA_F64, "polynomial coeffficient error",
+                                   poly->coeffErr[nx][ny][nz], nx, ny, nz);
+                }
+            }
+        }
+    }
+
+    psMetadataAdd (md, PS_LIST_TAIL, root, PS_DATA_METADATA, "folder for 3D polynomial", folder);
+    psFree(root);
+    psFree(folder);
     return true;
 }
@@ -1553,4 +1630,5 @@
 psPolynomial4D *psPolynomial4DfromMD (psMetadata *folder)
 {
+    PS_ASSERT_PTR_NON_NULL(folder, NULL);
 
     bool status;
@@ -1560,9 +1638,18 @@
     // XXX add status failures tests
     int nXorder = psMetadataLookupS32 (&status, folder, "NORDER_X");
+    if (!status)
+        return NULL;
     int nYorder = psMetadataLookupS32 (&status, folder, "NORDER_Y");
+    if (!status)
+        return NULL;
     int nZorder = psMetadataLookupS32 (&status, folder, "NORDER_Z");
+    if (!status)
+        return NULL;
     int nTorder = psMetadataLookupS32 (&status, folder, "NORDER_T");
-
-    psPolynomial4D *poly = psPolynomial4DAlloc (PS_POLYNOMIAL_ORD, nXorder, nYorder, nZorder, nTorder);
+    if (!status)
+        return NULL;
+
+    psPolynomial4D *poly = psPolynomial4DAlloc(PS_POLYNOMIAL_ORD,
+                           nXorder, nYorder, nZorder, nTorder);
 
     for (int nx = 0; nx < poly->nX + 1; nx++) {
@@ -1572,6 +1659,14 @@
                     sprintf (keyword, "VAL_X%02d_Y%02d_Z%02d_T%02d", nx, ny, nz, nt);
                     poly->coeff[nx][ny][nz][nt] = psMetadataLookupF64 (&status, folder, keyword);
-                    if (!status)
-                        poly->mask[nx][ny][nz][nt] = 1;
+                    if (!status) {
+                        //XXX: Setting the mask of a corrupted polynomial doesn't make sense.
+                        //The polynomial is garbage if ANY coeff-element is lost!!!
+                        //                    poly->mask[nx][ny][nz][nt] = 1;
+                        psError(PS_ERR_BAD_PARAMETER_VALUE, false,
+                                "psPolynomial4D in metadata has lost a coefficient somewhere!"
+                                " >>position= [x,y,z,t] = %02d, %02d, %02d, %02d", nx,ny,nz,nt);
+                        psFree(poly);
+                        return NULL;
+                    }
 
                     sprintf (keyword, "ERR_X%02d_Y%02d_Z%02d_T%02d", nx, ny, nz, nt);
@@ -1584,6 +1679,19 @@
 }
 
-bool psPolynomial4DtoMD (psMetadata *md, psPolynomial4D *poly, char *format, ...)
-{
+bool psPolynomial4DtoMD (psMetadata *md,
+                         psPolynomial4D *poly,
+                         char *format,
+                         ...)
+{
+    PS_ASSERT_PTR_NON_NULL(md, false);
+    PS_ASSERT_PTR_NON_NULL(poly, false);
+    //XXX:  Current implementation only supports ordinary polynomials.
+    if (poly->type != PS_POLYNOMIAL_ORD)
+        return false;
+    //Make sure polynomial isn't 0, completely empty
+    if (poly->nX == 0 && poly->nY == 0 && poly->nZ == 0 && poly->nT == 0
+            && poly->coeff[0][0][0][0] == 0)
+        return false;
+
 
     int Nbyte;
@@ -1596,5 +1704,5 @@
     va_end (argp);
 
-    if (!Nbyte)
+    if (Nbyte <= 0)
         return false;
 
@@ -1606,6 +1714,4 @@
 
     psMetadata *folder = psMetadataAlloc ();
-    psMetadataAdd (md, PS_LIST_TAIL, root, PS_DATA_METADATA, "folder for 4D polynomial", folder);
-    psFree (root);
 
     // specify the polynomial orders
@@ -1613,6 +1719,8 @@
     psMetadataAdd (folder, PS_LIST_TAIL, "NORDER_Y", PS_DATA_S32, "number of y orders", poly->nY);
     psMetadataAdd (folder, PS_LIST_TAIL, "NORDER_Z", PS_DATA_S32, "number of z orders", poly->nZ);
-    psMetadataAdd (folder, PS_LIST_TAIL, "NORDER_T", PS_DATA_S32, "number of z orders", poly->nT);
-
+    psMetadataAdd (folder, PS_LIST_TAIL, "NORDER_T", PS_DATA_S32, "number of t orders", poly->nT);
+
+    char namespace[80];
+    char namespace_err[80];
     // place polynomial entries on folder
     for (int nx = 0; nx < poly->nX + 1; nx++) {
@@ -1620,12 +1728,21 @@
             for (int nz = 0; nz < poly->nZ + 1; nz++) {
                 for (int nt = 0; nt < poly->nT + 1; nt++) {
-                    if (poly->mask[nx][ny][nz][nt])
-                        continue;
-                    psMetadataAdd (folder, PS_LIST_TAIL, "VAL_X%02d_Y%02d_Z%02d_T%02d", PS_DATA_F64, "polynomial coefficient", poly->coeff[nx][ny][nz][nt], nx, ny, nz, nt);
-                    psMetadataAdd (folder, PS_LIST_TAIL, "ERR_X%02d_Y%02d_Z%02d_T%02d", PS_DATA_F64, "polynomial coeffficient error", poly->coeffErr[nx][ny][nz][nt], nx, ny, nz, nt);
+                    if (poly->mask[nx][ny][nz][nt] == 0) {
+                        sprintf(namespace, "VAL_X%02d_Y%02d_Z%02d_T%02d", nx, ny, nz, nt);
+                        sprintf(namespace_err, "ERR_X%02d_Y%02d_Z%02d_T%02d", nx, ny, nz, nt);
+                        psMetadataAdd (folder, PS_LIST_TAIL, namespace,
+                                       PS_DATA_F64, "polynomial coefficient",
+                                       poly->coeff[nx][ny][nz][nt], nx, ny, nz, nt);
+                        psMetadataAdd (folder, PS_LIST_TAIL, namespace_err,
+                                       PS_DATA_F64, "polynomial coeffficient error",
+                                       poly->coeffErr[nx][ny][nz][nt], nx, ny, nz, nt);
+                    }
                 }
             }
         }
     }
+    psMetadataAdd (md, PS_LIST_TAIL, root, PS_DATA_METADATA, "folder for 4D polynomial", folder);
+    psFree(root);
+    psFree(folder);
     return true;
 }
Index: /trunk/psLib/src/types/psMetadata.h
===================================================================
--- /trunk/psLib/src/types/psMetadata.h	(revision 8785)
+++ /trunk/psLib/src/types/psMetadata.h	(revision 8786)
@@ -11,6 +11,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.84 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2006-08-26 03:15:15 $
+*  @version $Revision: 1.85 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2006-09-10 08:53:07 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -1066,17 +1066,108 @@
 bool psMetadataPrint(
     FILE *fd,                          ///< File Descriptor or NULL
-    const psMetadata *md,               ///< Metadata collection to print.
+    const psMetadata *md,              ///< Metadata collection to print.
     int level                          ///< the level of metadata items.
 );
 
-
-psPolynomial2D *psPolynomial2DfromMD (psMetadata *folder);
-bool psPolynomial2DtoMD (psMetadata *md, psPolynomial2D *poly, char *format, ...);
-
-psPolynomial3D *psPolynomial3DfromMD (psMetadata *folder);
-bool psPolynomial3DtoMD (psMetadata *md, psPolynomial3D *poly, char *format, ...);
-
-psPolynomial4D *psPolynomial4DfromMD (psMetadata *folder);
-bool psPolynomial4DtoMD (psMetadata *md, psPolynomial4D *poly, char *format, ...);
+/** Allocates a new psPolynomial2D structure with information from a psMetadata.
+ *
+ *  Parses a psMetadata container with psPolynomial2D information.  The first two
+ *  elements of the metadata folder specify the order of the x & y variables.  (ie,
+ *  NORDER_X, NORDER_Y).  The following elements are the values of the coefficients
+ *  and the coefficient errors.  (ie, VAL_X00_Y00, ERR_X00_Y00, etc.).  If the orders
+ *  or any coefficients are missing or have incorrect syntax, NULL is returned.
+ *
+ *  @return psPolynomial2D*:        Newly allocated psPolynomial2D from metadata.
+ */
+psPolynomial2D *psPolynomial2DfromMD(
+    psMetadata *folder                 ///< folder containing the polynomial info.
+);
+
+/** Stores the information from a psPolynomial2D structure in a psMetadata container.
+ *
+ *  Creates a psMetadata folder with psPolynomial2D information.  The first two
+ *  elements of the metadata folder specify the order of the x & y variables.  (ie,
+ *  NORDER_X, NORDER_Y).  The following elements are the values of the coefficients
+ *  and the coefficient errors.  (ie, VAL_X00_Y00, ERR_X00_Y00, etc.).  The input
+ *  polynomial must be of ordinary type and have a valid name format.  False is also
+ *  returned if any inputs are NULL.  *If a particular mask element is non-zero, that
+ *  polynomial coefficient (and error) are skipped.
+ *
+ *  @return bool:       True if successful, otherwise false.
+ */
+bool psPolynomial2DtoMD(
+    psMetadata *md,                    ///< Metadata container for polynomial storage.
+    psPolynomial2D *poly,              ///< Polynomial information to be stored.
+    char *format,                      ///< Name of polynomial folder.
+    ...                                ///< Arguments for name formatting.
+);
+
+/** Allocates a new psPolynomial3D structure with information from a psMetadata.
+ *
+ *  Parses a psMetadata container with psPolynomial3D information.  The first three
+ *  elements of the metadata folder specify the order of the x, y, & z variables.  (ie,
+ *  NORDER_X, NORDER_Y, NORDER_Z).  The following elements are the values of the
+ *  coefficients and the coefficient errors.  (ie, VAL_X00_Y00_Z00, ERR_X00_Y00_Z00,
+ *  etc.).  If the orders or any coefficients are missing or have incorrect syntax,
+ *  NULL is returned.
+ *
+ *  @return psPolynomial3D*:        Newly allocated psPolynomial3D from metadata.
+ */
+psPolynomial3D *psPolynomial3DfromMD(
+    psMetadata *folder                 ///< folder containing the polynomial info.
+);
+
+/** Stores the information from a psPolynomial3D structure in a psMetadata container.
+ *
+ *  Creates a psMetadata folder with psPolynomial3D information.  The first three
+ *  elements of the metadata folder specify the order of the x, y, & z variables.  (ie,
+ *  NORDER_X, NORDER_Y, NORDER_Z).  The following elements are the values of the
+ *  coefficients and the coefficient errors.  (ie, VAL_X00_Y00_Z00, ERR_X00_Y00_Z00,
+ *  etc.).  The input polynomial must be of ordinary type and have a valid name format.
+ *  False is also returned if any inputs are NULL.  *If a particular mask element is
+ *  non-zero, that polynomial coefficient (and error) are skipped.
+ *
+ *  @return bool:       True if successful, otherwise false.
+ */
+bool psPolynomial3DtoMD(
+    psMetadata *md,                    ///< Metadata container for polynomial storage.
+    psPolynomial3D *poly,              ///< Polynomial information to be stored.
+    char *format,                      ///< Name of polynomial folder.
+    ...                                ///< Arguments for name formatting.
+);
+
+/** Allocates a new psPolynomial4D structure with information from a psMetadata.
+ *
+ *  Parses a psMetadata container with psPolynomial4D information.  The first four
+ *  elements of the metadata folder specify the order of the x, y, z, & t variables.
+ *  (ie, NORDER_X, NORDER_Y, NORDER_Z, NORDER_T).  The following elements are the
+ *  values of the coefficients and the coefficient errors.  (ie, VAL_X00_Y00_Z00_T00,
+ *  ERR_X00_Y00_Z00_T00, etc.).  If the orders or any coefficients are missing or
+ *  have incorrect syntax, NULL is returned.
+ *
+ *  @return psPolynomial4D*:        Newly allocated psPolynomial4D from metadata.
+ */
+psPolynomial4D *psPolynomial4DfromMD(
+    psMetadata *folder                 ///< folder containing the polynomial info.
+);
+
+/** Stores the information from a psPolynomial4D structure in a psMetadata container.
+ *
+ *  Creates a psMetadata folder with psPolynomial4D information.  The first four
+ *  elements of the metadata folder specify the order of the x, y, z, & t variables.
+ *  (ie, NORDER_X, NORDER_Y, NORDER_Z, NORDER_T).  The following elements are the values
+ *  of the coefficients and the coefficient errors.  (ie, VAL_X00_Y00_Z00_T00,
+ *  ERR_X00_Y00_Z00_T00, etc.).  The input polynomial must be of ordinary type and have
+ *  a valid name format.  False is also returned if any inputs are NULL.  *If a particular
+ *  mask element is non-zero, that polynomial coefficient (and error) are skipped.
+ *
+ *  @return bool:       True if successful, otherwise false.
+ */
+bool psPolynomial4DtoMD(
+    psMetadata *md,                    ///< Metadata container for polynomial storage.
+    psPolynomial4D *poly,              ///< Polynomial information to be stored.
+    char *format,                      ///< Name of polynomial folder.
+    ...                                ///< Arguments for name formatting.
+);
 
 
Index: /trunk/psLib/test/types/Makefile.am
===================================================================
--- /trunk/psLib/test/types/Makefile.am	(revision 8785)
+++ /trunk/psLib/test/types/Makefile.am	(revision 8786)
@@ -26,6 +26,4 @@
 	tap_psArray_all
 
-check_PROGRAMS = $(TESTS)
-
 check_DATA = \
 	test.config \
@@ -44,4 +42,6 @@
 	tableU8.dat \
     mdcfgwrt.verified
+
+check_PROGRAMS = $(TESTS)
 
 EXTRA_DIST = \
Index: /trunk/psLib/test/types/execute_tap
===================================================================
--- /trunk/psLib/test/types/execute_tap	(revision 8785)
+++ /trunk/psLib/test/types/execute_tap	(revision 8786)
@@ -10,2 +10,3 @@
 ./tap_psMetadata_manip
 ./tap_psMetadata_printing
+./tap_psMetadata_polynomials
Index: /trunk/psLib/test/types/tap_psListIterator.c
===================================================================
--- /trunk/psLib/test/types/tap_psListIterator.c	(revision 8785)
+++ /trunk/psLib/test/types/tap_psListIterator.c	(revision 8786)
@@ -71,5 +71,5 @@
 int main (void)
 {
-    plan_tests(158);
+    plan_tests(66);
 
     diag("psListIterator tests");
Index: /trunk/psLib/test/types/tap_psMetadata_creating.c
===================================================================
--- /trunk/psLib/test/types/tap_psMetadata_creating.c	(revision 8785)
+++ /trunk/psLib/test/types/tap_psMetadata_creating.c	(revision 8786)
@@ -24,5 +24,5 @@
 int main(void)
 {
-    plan_tests(35);
+    plan_tests(42);
 
     diag("psMetadata & psMetadataItem Creation Functions");
@@ -37,5 +37,5 @@
 void testItemAllocs(void)
 {
-    diag("  >>>Test 1:  psMetadataItemAlloc & Free Fxns");
+    diag("  >>>Test 1:  psMetadataItemAlloc Fxns");
     psMetadataItem *itemStr = psMetadataItemAllocStr("itemStr", "", "itemStr");
     psMetadataItem *itemF32 = psMetadataItemAllocF32("itemF32", "", 6.66);
@@ -262,7 +262,6 @@
 void testMDAlloc_AddItem(void)
 {
-    diag("  >>>Test 2:  psMetadataAlloc, psMemCheckMetadata, & psMetadataAdd Fxns");
+    diag("  >>>Test 2:  psMetadataAlloc & psMetadataAdd Fxns");
     psMetadata *md = NULL;
-    //Attempt to free a null metadata
     md = psMetadataAlloc();
     psMetadata *md1 = psMetadataAlloc();
@@ -271,5 +270,5 @@
     {
         ok( psMemCheckMetadata(md),
-            "psMemCheckMetadata:  return true for valid Metadata.");
+            "psMemCheckMetadata:       return true for valid Metadata.");
     }
     //Make sure MemCheck worked.  Try primitive type.  Expect false.
@@ -277,20 +276,19 @@
         int j = 2;
         ok( !psMemCheckMetadata(&j),
-            "psMemCheckMetadata:  return false for non-Metadata input.");
+            "psMemCheckMetadata:       return false for non-Metadata input.");
     }
     //Return false for attempt to add a psMetadataItem with no name.
     {
         ok( !psMetadataAdd(md1, PS_LIST_HEAD, NULL, PS_DATA_S32, "", 1),
-            "psMetadataAdd:       return false for adding item with no name.");
+            "psMetadataAdd:            return false for adding item with no name.");
     }
     psFree(md1);
     md1 = psMetadataAlloc();
 
-    diag("  >>>Test 3:  psMetadataAddItem");
     //Return false for NULL metadata input
     psMetadataItem *item = psMetadataItemAllocBool("item", "", true);
     {
         ok( !psMetadataAddItem(NULL, item, PS_LIST_HEAD, PS_META_DEFAULT),
-            "psMetadataAddItem:   return false for NULL metadata input.");
+            "psMetadataAddItem:        return false for NULL metadata input.");
     }
     //Return false for metadata with NULL hash
@@ -299,5 +297,5 @@
     {
         ok( !psMetadataAddItem(md1, item, PS_LIST_HEAD, PS_META_DEFAULT),
-            "psMetadataAddItem:   return false for metadata with no hash.");
+            "psMetadataAddItem:        return false for metadata with no hash.");
     }
     psFree(md1);
@@ -307,5 +305,5 @@
     {
         ok( !psMetadataAddItem(md2, item, PS_LIST_HEAD, PS_META_DEFAULT),
-            "psMetadataAddItem:   return false for metadata with no list.");
+            "psMetadataAddItem:        return false for metadata with no list.");
     }
     psFree(md2);
@@ -313,5 +311,5 @@
     {
         ok( !psMetadataAddItem(md, NULL, PS_LIST_HEAD, PS_META_DEFAULT),
-            "psMetadataAddItem:   return false for NULL item input.");
+            "psMetadataAddItem:        return false for NULL item input.");
     }
     //Return false for psMetadataItem with NULL name
@@ -320,13 +318,10 @@
     {
         ok( !psMetadataAddItem(md, item, PS_LIST_HEAD, PS_META_DEFAULT),
-            "psMetadataAddItem:   return false for item with no name.");
+            "psMetadataAddItem:        return false for item with no name.");
     }
     psFree(item);
 
-    //item type=PS_DATA_METADATA_MULTI
-    //    psMetadataAddS32(md, PS_LIST_TAIL, "S32", PS_META_DUPLICATE_OK, "", 1);
     psMetadata *itemMD = psMetadataAlloc();
     psMetadataAddS32(itemMD, PS_LIST_HEAD, "s", PS_META_DUPLICATE_OK, "", 2);
-    //    psMetadataItem *item2 = psMetadataItemAlloc("multi", PS_DATA_METADATA_MULTI, "", itemMD);
     psMetadataItem *item2 = psMetadataItemAllocS32("s", "", 2);
 
@@ -334,7 +329,6 @@
     {
         ok( psMetadataAddItem(md, item2, PS_LIST_TAIL, PS_META_DUPLICATE_OK),
-            "psMetadataAddItem:   return true for addition of PS_DATA_METADATA_MULTI.");
-    }
-    //    printf("\n  >>Memory leakage coming from above test for METADATA_MULTI\n\n");
+            "psMetadataAddItem:        return true for addition of PS_DATA_METADATA_MULTI.");
+    }
     psFree(item2);
     psFree(itemMD);
@@ -343,31 +337,92 @@
     psMetadataAddS32(md, PS_LIST_HEAD, "S32", 0, "", 1);
     item2 = psMetadataItemAllocS32("S32", "", 1);
+    //FLAG = PS_META_REPLACE
+    {
+        ok( psMetadataAddItem(md, item2, PS_LIST_TAIL, PS_META_REPLACE),
+            "psMetadataAddItem:        return true for PS_META_REPLACE flag.");
+    }
     //FLAG = PS_META_DUPLICATE_OK
     {
         ok( psMetadataAddItem(md, item2, PS_LIST_TAIL, PS_META_DUPLICATE_OK),
-            "psMetadataAddItem:   return true for PS_META_DUPLICATE_OK flag.");
-    }
-    //FLAG = PS_META_REPLACE
-    {
-        ok( psMetadataAddItem(md, item2, PS_LIST_TAIL, PS_META_REPLACE),
-            "psMetadataAddItem:   return true for PS_META_REPLACE flag.");
-    }
+            "psMetadataAddItem:        return true for PS_META_DUPLICATE_OK flag.");
+    }
+    /*        SEE BELOW.  TEST CASE REDONE b/c item2 in md was already a MULTI
     //FLAG = PS_META_NO_REPLACE
     {
         ok( psMetadataAddItem(md, item2, PS_LIST_TAIL, PS_META_NO_REPLACE),
-            "psMetadataAddItem:   return true for PS_META_NO_REPLACE flag.");
-    }
+            "psMetadataAddItem:        return true for PS_META_NO_REPLACE flag.");
+    }
+    */
     //FLAG = PS_META_DEFAULT
     {
         ok( psMetadataAddItem(md, item2, PS_LIST_TAIL, PS_META_DEFAULT),
-            "psMetadataAddItem:   return false for PS_META_DEFAULT flag.");
-    }
+            "psMetadataAddItem:        return false for PS_META_DEFAULT flag.");
+    }
+
+    //Return false for attempting to add an element twice with flag NO_REPLACE
+    {
+        psMetadata *norep = psMetadataAlloc();
+        psMetadataAddS32(norep, PS_LIST_HEAD, "S32", 0, "", 1);
+        psMetadataItem *item666 = psMetadataItemAllocS32("S32", "", 1);
+        ok( psMetadataAddItem(norep, item666, PS_LIST_TAIL, PS_META_NO_REPLACE),
+            "psMetadataAddItem:        return true for PS_META_NO_REPLACE flag.");
+        psFree(item666);
+        psFree(norep);
+    }
+    //Return false for bad list location
+    {
+        psMetadata *emptymeta = psMetadataAlloc();
+        psMetadataItem *item666 = psMetadataItemAllocS32("S32", "", 1);
+        ok( !psMetadataAddItem(emptymeta, item666, -100, PS_META_NO_REPLACE),
+            "psMetadataAddItem:        return false for invalid list location.");
+        psFree(item666);
+        psFree(emptymeta);
+    }
+    //Return false for trying to add to MULTI with broken list element.
+    {
+        psMetadata *broken_list = psMetadataAlloc();
+        psMetadataAddS32(broken_list, PS_LIST_HEAD, "S32", 0, "", 1);
+        psMetadataAddS32(broken_list, PS_LIST_TAIL, "S32", PS_META_DUPLICATE_OK, "", 1);
+        psMetadataItem *brokenptr = psMetadataLookup(broken_list, "S32");
+        if (brokenptr->type != PS_DATA_METADATA_MULTI)
+            printf("\nError, Error\n");
+        else
+        {
+            psFree(brokenptr->data.list);
+            brokenptr->data.list = NULL;
+        }
+        psMetadataItem *item666 = psMetadataItemAllocS32("S32", "", 1);
+        ok( !psMetadataAddItem(broken_list, item666, PS_LIST_TAIL, PS_META_DUPLICATE_OK),
+            "psMetadataAddItem:        return false for MULTI with NULL list.");
+        psFree(item666);
+        psFree(broken_list);
+    }
+
+    //Attempt to add a MULTI
+    psFree(item2);
+    item2 = NULL;
+    psMetadata *xxx = psMetadataAlloc();
+    psMetadataAddS32(xxx, PS_LIST_TAIL, "new S32", 0, "", 1);
+    item2 = psMetadataItemAllocS32("new S32", "", 1);
+    psMetadataAddItem(xxx, item2, PS_LIST_TAIL, PS_META_DUPLICATE_OK);
+    psFree(item2);
+    item2 = psMetadataLookup(xxx, "new S32");
+    {
+        ok( psMetadataAddItem(md, item2, PS_LIST_TAIL, PS_META_DUPLICATE_OK),
+            "psMetadataAddItem:        return true for new MULTI item");
+    }
+    //Attempt to add a 2nd reference of a MULTI to the originating metadata container
+    {
+        ok( !psMetadataAddItem(xxx, item2, PS_LIST_TAIL, PS_META_NO_REPLACE),
+            "psMetadataAddItem:        return false for attempt to add 2nd reference"
+            " of a MULTI");
+    }
+    psFree(xxx);
 
     //No existing entries or duplicates found
-    psFree(item2);
     item2 = psMetadataItemAllocS32("new", "", 2);
     {
         ok( psMetadataAddItem(md, item2, PS_LIST_TAIL, PS_META_DUPLICATE_OK),
-            "psMetadataAddItem:   return true for new item.");
+            "psMetadataAddItem:        return true for new item.");
     }
 
@@ -382,5 +437,5 @@
 void testIterAlloc(void)
 {
-    diag("  >>>Test 4:  psMetadataIteratorAlloc");
+    diag("  >>>Test 3:  psMetadataIteratorAlloc");
     psMetadata *md = psMetadataAlloc();
     psMetadata *md2 = NULL;
@@ -412,5 +467,24 @@
             "psMetadataIteratorAlloc:  return valid iterator for valid inputs, regex=NULL.");
     }
-
+    //Return NULL for attempt to allocate an iterator with unfound regex.
+    psFree(iter);
+    iter = NULL;
+    {
+        iter = psMetadataIteratorAlloc(md, PS_LIST_HEAD, "IPP.machines.sky");
+        ok( iter == NULL,
+            "psMetadataIteratorAlloc:  return NULL for not-found regex input");
+    }
+    //Return NULL for invalid regex input.
+    {
+        iter = psMetadataIteratorAlloc(md, PS_LIST_HEAD, "IPP.machines.sky\\");
+        ok( iter == NULL,
+            "psMetadataIteratorAlloc:  return NULL for invalid regex input");
+    }
+    //Return properly allocated iterator for valid non-null regex input.
+    {
+        iter = psMetadataIteratorAlloc(md, PS_LIST_HEAD, "S32_");
+        ok( iter != NULL,
+            "psMetadataIteratorAlloc:  return valid iterator for valid regex input");
+    }
 
     //Check for Memory leaks
Index: /trunk/psLib/test/types/tap_psMetadata_polynomials.c
===================================================================
--- /trunk/psLib/test/types/tap_psMetadata_polynomials.c	(revision 8785)
+++ /trunk/psLib/test/types/tap_psMetadata_polynomials.c	(revision 8786)
@@ -22,5 +22,5 @@
 int main(void)
 {
-    plan_tests(1);
+    plan_tests(58);
 
     diag("psPolynomial(2D, 3D, & 4D)(to/from)MD tests");
@@ -37,33 +37,140 @@
     diag("  >>>Test 1:  psPolynomial2DtoMD & psPolynomial2DfromMD functions");
     psMetadata *md = psMetadataAlloc();
-    psMetadata *out = NULL;
     psPolynomial2D *p2d = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, 1, 1);
-    psPolynomial2D *polly = NULL;
-
     p2d->coeff[0][0] = 1.1;
     p2d->coeff[0][1] = 2.2;
-    p2d->coeff[1][0] = 2.1;
-    p2d->coeff[1][1] = 1.2;
-
-    if (!psPolynomial2DtoMD(md, p2d, "polyMD") )
-        printf("\nnot true\n");
-    else
-        psMetadataPrint(NULL, md, 2);
-
-
-
-    //Return true for valid case
-    {
-        //        ok( psPolynomial2DtoMD(md, p2d, "%f", ...);
-    }
-
-
-
+    p2d->coeff[1][0] = 3.3;
+    p2d->coeff[1][1] = 4.4;
+    p2d->coeffErr[0][0] = 0.1;
+    p2d->coeffErr[0][1] = 0.2;
+    p2d->coeffErr[1][0] = 0.3;
+    p2d->coeffErr[1][1] = 0.4;
+
+    //psPolynomial2DtoMD
+    //Return a valid metadata containing a polynomial-metadata structure
+    {
+        ok( psPolynomial2DtoMD(md, p2d, "polyMD"),
+            "psPolynomial2DtoMD:      return true for valid inputs.");
+        psMetadata *polyMDtemp = psMetadataLookupMD(NULL, md, "polyMD");
+        skip_start( polyMDtemp == NULL , 1,
+                    "Skipping 1 tests because psPolynomial2DtoMD has errors");
+        psMetadataItem *polyItem = psMetadataGet(polyMDtemp, 0);
+        skip_start( polyItem == NULL, 2,
+                    "Skipping 2 tests because psPolynomial2DtoMD has errors in order elements");
+        ok( !strncmp(polyItem->name, "NORDER_X", 10) && polyItem->data.S32 == 1,
+            "psPolynomial2DtoMD:      return correct number of x orders.");
+        polyItem = psMetadataGet(polyMDtemp, 1);
+        ok( !strncmp(polyItem->name, "NORDER_Y", 10) && polyItem->data.S32 == 1,
+            "psPolynomial2DtoMD:      return correct number of y orders.");
+        skip_end();
+        polyItem = psMetadataGet(polyMDtemp, 2);
+        skip_start( polyItem == NULL, 2,
+                    "Skipping 2 tests because psPolynomial2DtoMD has errors in coeff elements");
+        ok( !strncmp(polyItem->name, "VAL_X00_Y00", 14) &&
+            abs(polyItem->data.F64-1.1) < DBL_EPSILON,
+            "psPolynomial2DtoMD:      return correct first element.");
+        polyItem = psMetadataGet(polyMDtemp, PS_LIST_TAIL);
+        ok( !strncmp(polyItem->name, "ERR_X01_Y01", 14) &&
+            abs(polyItem->data.F64-0.4) < DBL_EPSILON,
+            "psPolynomial2DtoMD:      return correct last element.");
+        skip_end();
+        skip_end();
+    }
+
+    //Return false for no-name polynomial
+    {
+        ok( !psPolynomial2DtoMD(md, p2d, ""),
+            "psPolynomial2DtoMD:      return false for no-name.");
+    }
+    //Return false for NULL-name polynomial
+    {
+        ok( !psPolynomial2DtoMD(md, p2d, NULL),
+            "psPolynomial2DtoMD:      return false for NULL name input.");
+    }
+    //Return false for NULL metadata input
+    {
+        ok( !psPolynomial2DtoMD(NULL, p2d, "polyMD"),
+            "psPolynomial2DtoMD:      return false for NULL metadata input.");
+    }
+    //Return false for NULL polynomial input
+    {
+        ok( !psPolynomial2DtoMD(md, NULL, "polyMD"),
+            "psPolynomial2DtoMD:      return false for NULL polynomial input.");
+    }
+    //Return false for empty polynomial
+    {
+        psPolynomial2D *emptyPoly = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, 0, 0);
+        ok( !psPolynomial2DtoMD(md, emptyPoly, "polyMD"),
+            "psPolynomial2DtoMD:     return false for empty polynomial input.");
+        psFree(emptyPoly);
+    }
+    //Return true for polynomial with 1 element, a constant
+    {
+        psPolynomial2D *constPoly = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, 0, 0);
+        constPoly->coeff[0][0] = 6.66;
+        ok( psPolynomial2DtoMD(md, constPoly, "polyMD"),
+            "psPolynomial2DtoMD:     return true for constant polynomial (1 element != 0).");
+        psFree(constPoly);
+    }
+    //Return false for non-ordinary polynomial
+    {
+        psPolynomial2D *p2d2 = psPolynomial2DAlloc(PS_POLYNOMIAL_CHEB, 1, 1);
+        p2d2->coeff[0][0] = 1.1;
+        ok( !psPolynomial2DtoMD(md, p2d2, "polyMD"),
+            "psPolynomial2DtoMD:     return false for chebyshev polynomial");
+        psFree(p2d2);
+    }
+
+    //psPolynomial2DfromMD Tests
+    //Return NULL for NULL metadata input.
+    {
+        psPolynomial2D *emptyPoly2D = NULL;
+        emptyPoly2D = psPolynomial2DfromMD(NULL);
+        ok( emptyPoly2D == NULL,
+            "psPolynomial2DfromMD:   return NULL for NULL metadata input.");
+    }
+    //Get a polynomial from Metadata.
+    psPolynomial2D *outPoly = NULL;
+    psMetadata *polyMDtemp = psMetadataLookupMD(NULL, md, "polyMD");
+    outPoly = psPolynomial2DfromMD(polyMDtemp);
+    {
+        skip_start( outPoly == NULL, 1,
+                    "Skipping 1 tests because psPolynomial2DfromMD has errors.");
+        ok( outPoly->type == PS_POLYNOMIAL_ORD && outPoly->nX == 1 &&
+            outPoly->nY == 1 && abs(outPoly->coeff[0][0] - 1.1) < DBL_EPSILON,
+            "psPolynomial2DfromMD:   return correct polynomial from metadata");
+        skip_end();
+    }
+    //Set poly->mask[1][1] = 1 for missing [1][1] element in metadata
+    psMetadataRemoveIndex(polyMDtemp, PS_LIST_TAIL-1);
+    psFree(outPoly);
+    outPoly = NULL;
+    outPoly = psPolynomial2DfromMD(polyMDtemp);
+    {
+        //        ok( outPoly->mask[1][1] == 1,
+        //            "psPolynomial2DfromMD:   return mask[1][1] == 1 for metadata-polynomial",
+        //            " with missing element");
+        ok( outPoly == NULL,
+            "psPolynomial2DfromMD:   return NULL for polynomial with missing coeff");
+    }
+    //Return NULL for polynomial in metadata with no y-order
+    psMetadataRemoveKey(polyMDtemp, "NORDER_Y");
+    outPoly = psPolynomial2DfromMD(polyMDtemp);
+    {
+        ok( outPoly == NULL,
+            "psPolynomial2DfromMD:   return NULL for metadata-polynomial with no y-order");
+    }
+    //Return NULL for polynomial in metadata with no x-order
+    psMetadataRemoveKey(polyMDtemp, "NORDER_X");
+    outPoly = psPolynomial2DfromMD(polyMDtemp);
+    {
+        ok( outPoly == NULL,
+            "psPolynomial2DfromMD:   return NULL for metadata-polynomial with no x-order");
+    }
 
     //Check for Memory leaks
     {
+        psFree(outPoly);
         psFree(p2d);
-        psFree(polly);
-        psFree(out);
         psFree(md);
         checkMem();
@@ -75,12 +182,158 @@
     diag("  >>>Test 2:  psPolynomial3DtoMD & psPolynomial3DfromMD functions");
     psMetadata *md = psMetadataAlloc();
-    psMetadata *out = NULL;
-
-
-
+    psPolynomial3D *p3d = psPolynomial3DAlloc(PS_POLYNOMIAL_ORD, 1, 1, 1);
+    p3d->coeff[0][0][0] = 1.1;
+    p3d->coeff[1][0][0] = 2.2;
+    p3d->coeff[0][1][0] = 3.3;
+    p3d->coeff[0][0][1] = 4.4;
+    p3d->coeff[1][1][0] = 5.5;
+    p3d->coeff[1][0][1] = 6.6;
+    p3d->coeff[0][1][1] = 7.7;
+    p3d->coeff[1][1][1] = 8.8;
+    p3d->coeffErr[0][0][0] = 0.1;
+    p3d->coeffErr[1][0][0] = 0.2;
+    p3d->coeffErr[0][1][0] = 0.3;
+    p3d->coeffErr[0][0][1] = 0.4;
+    p3d->coeffErr[1][1][0] = 0.5;
+    p3d->coeffErr[1][0][1] = 0.6;
+    p3d->coeffErr[0][1][1] = 0.7;
+    p3d->coeffErr[1][1][1] = 0.8;
+
+    //psPolynomial3DtoMD
+    //Return a valid metadata containing a polynomial-metadata structure
+    {
+        ok( psPolynomial3DtoMD(md, p3d, "polyMD"),
+            "psPolynomial3DtoMD:     return true for valid inputs.");
+        psMetadata *polyMDtemp = psMetadataLookupMD(NULL, md, "polyMD");
+        skip_start( polyMDtemp == NULL , 1,
+                    "Skipping 1 tests because psPolynomial3DtoMD has errors");
+        psMetadataItem *polyItem = psMetadataGet(polyMDtemp, 0);
+        skip_start( polyItem == NULL, 2,
+                    "Skipping 3 tests because psPolynomial3DtoMD has errors in order elements");
+        ok( !strncmp(polyItem->name, "NORDER_X", 10) && polyItem->data.S32 == 1,
+            "psPolynomial3DtoMD:     return correct number of x orders.");
+        polyItem = psMetadataGet(polyMDtemp, 1);
+        ok( !strncmp(polyItem->name, "NORDER_Y", 10) && polyItem->data.S32 == 1,
+            "psPolynomial3DtoMD:     return correct number of y orders.");
+        polyItem = psMetadataGet(polyMDtemp, 2);
+        ok( !strncmp(polyItem->name, "NORDER_Z", 10) && polyItem->data.S32 == 1,
+            "psPolynomial3DtoMD:     return correct number of z orders.");
+        skip_end();
+        polyItem = psMetadataGet(polyMDtemp, 3);
+        skip_start( polyItem == NULL, 2,
+                    "Skipping 2 tests because psPolynomial3DtoMD has errors in coeff elements");
+        ok( !strncmp(polyItem->name, "VAL_X00_Y00_Z00", 14) &&
+            abs(polyItem->data.F64-1.1) < DBL_EPSILON,
+            "psPolynomial3DtoMD:     return correct first element.");
+        polyItem = psMetadataGet(polyMDtemp, PS_LIST_TAIL);
+        ok( !strncmp(polyItem->name, "ERR_X01_Y01_Z01", 14) &&
+            abs(polyItem->data.F64-0.8) < DBL_EPSILON,
+            "psPolynomial3DtoMD:     return correct last element.");
+        skip_end();
+        skip_end();
+    }
+    //Return false for no-name polynomial
+    {
+        ok( !psPolynomial3DtoMD(md, p3d, ""),
+            "psPolynomial3DtoMD:     return false for no-name.");
+    }
+    //Return false for NULL-name polynomial
+    {
+        ok( !psPolynomial3DtoMD(md, p3d, NULL),
+            "psPolynomial3DtoMD:     return false for NULL name input.");
+    }
+    //Return false for NULL metadata input
+    {
+        ok( !psPolynomial3DtoMD(NULL, p3d, "polyMD"),
+            "psPolynomial3DtoMD:     return false for NULL metadata input.");
+    }
+    //Return false for NULL polynomial input
+    {
+        ok( !psPolynomial3DtoMD(md, NULL, "polyMD"),
+            "psPolynomial3DtoMD:     return false for NULL polynomial input.");
+    }
+    //Return false for empty polynomial
+    {
+        psPolynomial3D *emptyPoly = psPolynomial3DAlloc(PS_POLYNOMIAL_ORD, 0, 0, 0);
+        ok( !psPolynomial3DtoMD(md, emptyPoly, "polyMD"),
+            "psPolynomial3DtoMD:     return false for empty polynomial input.");
+        psFree(emptyPoly);
+    }
+    //Return true for polynomial with 1 element, a constant
+    {
+        psPolynomial3D *constPoly = psPolynomial3DAlloc(PS_POLYNOMIAL_ORD, 0, 0, 0);
+        constPoly->coeff[0][0][0] = 6.66;
+        ok( psPolynomial3DtoMD(md, constPoly, "polyMD"),
+            "psPolynomial3DtoMD:     return true for constant polynomial (1 element != 0).");
+        psFree(constPoly);
+    }
+    //Return false for non-ordinary polynomial
+    {
+        psPolynomial3D *p3d2 = psPolynomial3DAlloc(PS_POLYNOMIAL_CHEB, 1, 1, 1);
+        p3d2->coeff[0][0][0] = 1.1;
+        ok( !psPolynomial3DtoMD(md, p3d2, "polyMD"),
+            "psPolynomial3DtoMD:     return false for chebyshev polynomial");
+        psFree(p3d2);
+    }
+
+    //psPolynomial3DfromMD Tests
+    //Return NULL for NULL metadata input.
+    {
+        psPolynomial3D *emptyPoly2D = NULL;
+        emptyPoly2D = psPolynomial3DfromMD(NULL);
+        ok( emptyPoly2D == NULL,
+            "psPolynomial3DfromMD:   return NULL for NULL metadata input.");
+    }
+    //Get a polynomial from Metadata.
+    psPolynomial3D *outPoly = NULL;
+    psMetadata *polyMDtemp = psMetadataLookupMD(NULL, md, "polyMD");
+    outPoly = psPolynomial3DfromMD(polyMDtemp);
+    {
+        skip_start( outPoly == NULL, 1,
+                    "Skipping 1 tests because psPolynomial3DfromMD has errors.");
+        ok( outPoly->type == PS_POLYNOMIAL_ORD && outPoly->nX == 1 &&
+            outPoly->nY == 1 && outPoly->nZ == 1 &&
+            abs(outPoly->coeff[0][0][0] - 1.1) < DBL_EPSILON,
+            "psPolynomial3DfromMD:   return correct polynomial from metadata");
+        skip_end();
+    }
+    //Return NULL for polynomial with missing coefficient
+    psMetadataRemoveIndex(polyMDtemp, PS_LIST_TAIL-1);
+    psFree(outPoly);
+    outPoly = NULL;
+    outPoly = psPolynomial3DfromMD(polyMDtemp);
+    {
+        //        ok( outPoly->mask[1][1][1] == 1,
+        //            "psPolynomial3DfromMD:   return mask[1][1][1] == 1 for metadata-polynomial"
+        //            " with missing element");
+        ok( outPoly == NULL,
+            "psPolynomial3DfromMD:   return NULL for polynomial with missing coeff");
+    }
+    //Return NULL for polynomial in metadata with no z-order
+    psMetadataRemoveKey(polyMDtemp, "NORDER_Z");
+    outPoly = psPolynomial3DfromMD(polyMDtemp);
+    {
+        ok( outPoly == NULL,
+            "psPolynomial3DfromMD:   return NULL for metadata-polynomial with no z-order");
+    }
+    //Return NULL for polynomial in metadata with no y-order
+    psMetadataRemoveKey(polyMDtemp, "NORDER_Y");
+    outPoly = psPolynomial3DfromMD(polyMDtemp);
+    {
+        ok( outPoly == NULL,
+            "psPolynomial3DfromMD:   return NULL for metadata-polynomial with no y-order");
+    }
+    //Return NULL for polynomial in metadata with no x-order
+    psMetadataRemoveKey(polyMDtemp, "NORDER_X");
+    outPoly = psPolynomial3DfromMD(polyMDtemp);
+    {
+        ok( outPoly == NULL,
+            "psPolynomial3DfromMD:   return NULL for metadata-polynomial with no x-order");
+    }
 
     //Check for Memory leaks
     {
-        psFree(out);
+        psFree(outPoly);
+        psFree(p3d);
         psFree(md);
         checkMem();
@@ -92,12 +345,191 @@
     diag("  >>>Test 3:  psPolynomial4DtoMD & psPolynomial4DfromMD functions");
     psMetadata *md = psMetadataAlloc();
-    psMetadata *out = NULL;
-
-
-
+    psPolynomial4D *p4d = psPolynomial4DAlloc(PS_POLYNOMIAL_ORD, 1, 1, 1, 1);
+    p4d->coeff[0][0][0][0] = 1.1;
+    p4d->coeff[0][0][0][1] = 2.2;
+    p4d->coeff[0][0][1][0] = 3.3;
+    p4d->coeff[0][1][0][0] = 4.4;
+    p4d->coeff[1][0][0][0] = 5.5;
+
+    p4d->coeff[0][0][1][1] = 6.6;
+    p4d->coeff[0][1][0][1] = 7.7;
+    p4d->coeff[1][0][0][1] = 8.8;
+    p4d->coeff[0][1][1][0] = 9.9;
+    p4d->coeff[1][0][1][0] = 10.10;
+    p4d->coeff[1][1][0][0] = 11.11;
+
+    p4d->coeff[0][1][1][1] = 12.12;
+    p4d->coeff[1][0][1][1] = 13.13;
+    p4d->coeff[1][1][0][1] = 14.14;
+    p4d->coeff[1][1][1][0] = 15.15;
+
+    p4d->coeff[1][1][1][1] = 16.16;
+
+    p4d->coeffErr[0][0][0][0] = 0.1;
+    p4d->coeffErr[0][0][0][1] = 0.2;
+    p4d->coeffErr[0][0][1][0] = 0.3;
+    p4d->coeffErr[0][1][0][0] = 0.4;
+    p4d->coeffErr[1][0][0][0] = 0.5;
+
+    p4d->coeffErr[0][0][1][1] = 0.6;
+    p4d->coeffErr[0][1][0][1] = 0.7;
+    p4d->coeffErr[1][0][0][1] = 0.8;
+    p4d->coeffErr[0][1][1][0] = 0.9;
+    p4d->coeffErr[1][0][1][0] = 0.10;
+    p4d->coeffErr[1][1][0][0] = 0.11;
+
+    p4d->coeffErr[0][1][1][1] = 0.12;
+    p4d->coeffErr[1][0][1][1] = 0.13;
+    p4d->coeffErr[1][1][0][1] = 0.14;
+    p4d->coeffErr[1][1][1][0] = 0.15;
+
+    p4d->coeffErr[1][1][1][1] = 0.16;
+
+    //psPolynomial4DtoMD
+    //Return a valid metadata containing a polynomial-metadata structure
+    {
+        ok( psPolynomial4DtoMD(md, p4d, "polyMD"),
+            "psPolynomial4DtoMD:     return true for valid inputs.");
+        psMetadata *polyMDtemp = psMetadataLookupMD(NULL, md, "polyMD");
+        skip_start( polyMDtemp == NULL , 1,
+                    "Skipping 1 tests because psPolynomial4DtoMD has errors");
+        psMetadataItem *polyItem = psMetadataGet(polyMDtemp, 0);
+        skip_start( polyItem == NULL, 2,
+                    "Skipping 4 tests because psPolynomial4DtoMD has errors in order elements");
+        ok( !strncmp(polyItem->name, "NORDER_X", 10) && polyItem->data.S32 == 1,
+            "psPolynomial4DtoMD:     return correct number of x orders.");
+        polyItem = psMetadataGet(polyMDtemp, 1);
+        ok( !strncmp(polyItem->name, "NORDER_Y", 10) && polyItem->data.S32 == 1,
+            "psPolynomial4DtoMD:     return correct number of y orders.");
+        polyItem = psMetadataGet(polyMDtemp, 2);
+        ok( !strncmp(polyItem->name, "NORDER_Z", 10) && polyItem->data.S32 == 1,
+            "psPolynomial4DtoMD:     return correct number of z orders.");
+        polyItem = psMetadataGet(polyMDtemp, 3);
+        ok( !strncmp(polyItem->name, "NORDER_T", 10) && polyItem->data.S32 == 1,
+            "psPolynomial4DtoMD:     return correct number of t orders.");
+        skip_end();
+        polyItem = psMetadataGet(polyMDtemp, 4);
+        skip_start( polyItem == NULL, 2,
+                    "Skipping 2 tests because psPolynomial4DtoMD has errors in coeff elements");
+        ok( !strncmp(polyItem->name, "VAL_X00_Y00_Z00_T00", 14) &&
+            abs(polyItem->data.F64-1.1) < DBL_EPSILON,
+            "psPolynomial4DtoMD:     return correct first element.");
+        polyItem = psMetadataGet(polyMDtemp, PS_LIST_TAIL);
+        ok( !strncmp(polyItem->name, "ERR_X01_Y01_Z01_T01", 14) &&
+            abs(polyItem->data.F64-0.16) < DBL_EPSILON,
+            "psPolynomial4DtoMD:     return correct last element.");
+        skip_end();
+        skip_end();
+    }
+    //Return false for no-name polynomial
+    {
+        ok( !psPolynomial4DtoMD(md, p4d, ""),
+            "psPolynomial4DtoMD:     return false for no-name.");
+    }
+    //Return false for NULL-name polynomial
+    {
+        ok( !psPolynomial4DtoMD(md, p4d, NULL),
+            "psPolynomial4DtoMD:     return false for NULL name input.");
+    }
+    //Return false for NULL metadata input
+    {
+        ok( !psPolynomial4DtoMD(NULL, p4d, "polyMD"),
+            "psPolynomial4DtoMD:     return false for NULL metadata input.");
+    }
+    //Return false for NULL polynomial input
+    {
+        ok( !psPolynomial4DtoMD(md, NULL, "polyMD"),
+            "psPolynomial4DtoMD:     return false for NULL polynomial input.");
+    }
+    //Return false for empty polynomial
+    {
+        psPolynomial4D *emptyPoly = psPolynomial4DAlloc(PS_POLYNOMIAL_ORD, 0, 0, 0, 0);
+        ok( !psPolynomial4DtoMD(md, emptyPoly, "polyMD"),
+            "psPolynomial4DtoMD:     return false for empty polynomial input.");
+        psFree(emptyPoly);
+    }
+    //Return true for polynomial with 1 element, a constant
+    {
+        psPolynomial4D *constPoly = psPolynomial4DAlloc(PS_POLYNOMIAL_ORD, 0, 0, 0, 0);
+        constPoly->coeff[0][0][0][0] = 6.66;
+        ok( psPolynomial4DtoMD(md, constPoly, "polyMD"),
+            "psPolynomial4DtoMD:     return true for constant polynomial (1 element != 0).");
+        psFree(constPoly);
+    }
+    //Return false for non-ordinary polynomial
+    {
+        psPolynomial4D *p4d2 = psPolynomial4DAlloc(PS_POLYNOMIAL_CHEB, 1, 1, 1, 1);
+        p4d2->coeff[0][0][0][0] = 1.1;
+        ok( !psPolynomial4DtoMD(md, p4d2, "polyMD"),
+            "psPolynomial4DtoMD:     return false for chebyshev polynomial");
+        psFree(p4d2);
+    }
+
+    //psPolynomial4DfromMD Tests
+    //Return NULL for NULL metadata input.
+    {
+        psPolynomial4D *emptyPoly2D = NULL;
+        emptyPoly2D = psPolynomial4DfromMD(NULL);
+        ok( emptyPoly2D == NULL,
+            "psPolynomial4DfromMD:   return NULL for NULL metadata input.");
+    }
+    //Get a polynomial from Metadata.
+    psPolynomial4D *outPoly = NULL;
+    psMetadata *polyMDtemp = psMetadataLookupMD(NULL, md, "polyMD");
+    outPoly = psPolynomial4DfromMD(polyMDtemp);
+    {
+        skip_start( outPoly == NULL, 1,
+                    "Skipping 1 tests because psPolynomial4DfromMD has errors.");
+        ok( outPoly->type == PS_POLYNOMIAL_ORD && outPoly->nX == 1 &&
+            outPoly->nY == 1 && outPoly->nZ == 1 && outPoly->nT == 1 &&
+            abs(outPoly->coeff[0][0][0][0] - 1.1) < DBL_EPSILON,
+            "psPolynomial4DfromMD:   return correct polynomial from metadata");
+        skip_end();
+    }
+    //Return NULL for polynomial with missing coefficient
+    psMetadataRemoveIndex(polyMDtemp, PS_LIST_TAIL-1);
+    psFree(outPoly);
+    outPoly = NULL;
+    outPoly = psPolynomial4DfromMD(polyMDtemp);
+    {
+        //        ok( outPoly->mask[1][1][1] == 1,
+        //            "psPolynomial4DfromMD:   return mask[1][1][1] == 1 for metadata-polynomial"
+        //            " with missing element");
+        ok( outPoly == NULL,
+            "psPolynomial4DfromMD:   return NULL for polynomial with missing coeff");
+    }
+    //Return NULL for polynomial in metadata with no t-order
+    psMetadataRemoveKey(polyMDtemp, "NORDER_T");
+    outPoly = psPolynomial4DfromMD(polyMDtemp);
+    {
+        ok( outPoly == NULL,
+            "psPolynomial4DfromMD:   return NULL for metadata-polynomial with no t-order");
+    }
+    //Return NULL for polynomial in metadata with no z-order
+    psMetadataRemoveKey(polyMDtemp, "NORDER_Z");
+    outPoly = psPolynomial4DfromMD(polyMDtemp);
+    {
+        ok( outPoly == NULL,
+            "psPolynomial4DfromMD:   return NULL for metadata-polynomial with no z-order");
+    }
+    //Return NULL for polynomial in metadata with no y-order
+    psMetadataRemoveKey(polyMDtemp, "NORDER_Y");
+    outPoly = psPolynomial4DfromMD(polyMDtemp);
+    {
+        ok( outPoly == NULL,
+            "psPolynomial4DfromMD:   return NULL for metadata-polynomial with no y-order");
+    }
+    //Return NULL for polynomial in metadata with no x-order
+    psMetadataRemoveKey(polyMDtemp, "NORDER_X");
+    outPoly = psPolynomial4DfromMD(polyMDtemp);
+    {
+        ok( outPoly == NULL,
+            "psPolynomial4DfromMD:   return NULL for metadata-polynomial with no x-order");
+    }
 
     //Check for Memory leaks
     {
-        psFree(out);
+        psFree(outPoly);
+        psFree(p4d);
         psFree(md);
         checkMem();
