Index: trunk/psModules/src/concepts/pmConcepts.c
===================================================================
--- trunk/psModules/src/concepts/pmConcepts.c	(revision 7253)
+++ trunk/psModules/src/concepts/pmConcepts.c	(revision 7278)
@@ -44,5 +44,6 @@
                       )
 {
-    assert(blank);
+    PS_ASSERT_PTR_NON_NULL(blank, false);
+
     if (!conceptsInitialised) {
         pmConceptsInit();
@@ -80,4 +81,7 @@
                          )
 {
+    assert(specs);
+    assert(target);
+
     if (!conceptsInitialised) {
         pmConceptsInit();
@@ -119,4 +123,8 @@
                         )
 {
+    assert(specs);
+    assert(read);
+    assert(target);
+
     if (!conceptsInitialised) {
         pmConceptsInit();
@@ -156,4 +164,7 @@
                          )
 {
+    assert(specs);
+    assert(concepts);
+
     if (!conceptsInitialised) {
         pmConceptsInit();
@@ -180,4 +191,5 @@
                        )
 {
+    PS_ASSERT_PTR_NON_NULL(fpa, false);
     psTrace("psModule.concepts", 5, "Blanking FPA concepts: %x %x\n", conceptsFPA, fpa->concepts);
     return conceptsBlank(&conceptsFPA, fpa->concepts);
@@ -191,4 +203,5 @@
                       )
 {
+    PS_ASSERT_PTR_NON_NULL(fpa, false);
     psTrace("psModule.concepts", 5, "Reading FPA concepts: %x %x\n", conceptsFPA, fpa->concepts);
     return conceptsRead(&conceptsFPA, fpa, NULL, NULL, &fpa->conceptsRead, source, db, fpa->concepts);
@@ -201,4 +214,5 @@
                        )
 {
+    PS_ASSERT_PTR_NON_NULL(fpa, false);
     psTrace("psModule.concepts", 5, "Writing FPA concepts: %x %x\n", conceptsFPA, fpa->concepts);
     return conceptsWrite(&conceptsFPA, fpa, NULL, NULL, source, db, fpa->concepts);
@@ -209,4 +223,5 @@
                         )
 {
+    PS_ASSERT_PTR_NON_NULL(chip, false);
     psTrace("psModule.concepts", 5, "Blanking chip concepts: %x %x\n", conceptsChip, chip->concepts);
     return conceptsBlank(&conceptsChip, chip->concepts);
@@ -220,4 +235,5 @@
                        )
 {
+    PS_ASSERT_PTR_NON_NULL(chip, false);
     psTrace("psModule.concepts", 5, "Reading chip concepts: %x %x\n", conceptsChip, chip->concepts);
     pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
@@ -235,4 +251,5 @@
                         )
 {
+    PS_ASSERT_PTR_NON_NULL(chip, false);
     psTrace("psModule.concepts", 5, "Writing chip concepts: %x %x\n", conceptsChip, chip->concepts);
     pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
@@ -246,4 +263,5 @@
                         )
 {
+    PS_ASSERT_PTR_NON_NULL(cell, false);
     psTrace("psModule.concepts", 5, "Blanking cell concepts: %x %x\n", conceptsCell, cell->concepts);
     return conceptsBlank(&conceptsCell, cell->concepts);
@@ -257,4 +275,5 @@
                        )
 {
+    PS_ASSERT_PTR_NON_NULL(cell, false);
     psTrace("psModule.concepts", 5, "Reading cell concepts: %x %x\n", conceptsCell, cell->concepts);
     pmChip *chip = cell->parent;        // Chip to which the cell belongs
@@ -274,4 +293,5 @@
                         )
 {
+    PS_ASSERT_PTR_NON_NULL(cell, false);
     psTrace("psModule.concepts", 5, "Writing cell concepts: %x %x\n", conceptsCell, cell->concepts);
     pmChip *chip = cell->parent;        // Chip to which the cell belongs
@@ -336,6 +356,6 @@
         {
             psMetadataItem *fpaRa = psMetadataItemAllocF64("FPA.RA", "Right Ascension of boresight", NAN);
-            pmConceptRegister(fpaRa, (pmConceptParseFunc)pmConceptParse_FPA_Coords,
-                              (pmConceptFormatFunc)pmConceptFormat_FPA_Coords, PM_FPA_LEVEL_FPA);
+            pmConceptRegister(fpaRa, (pmConceptParseFunc)p_pmConceptParse_FPA_Coords,
+                              (pmConceptFormatFunc)p_pmConceptFormat_FPA_Coords, PM_FPA_LEVEL_FPA);
             psFree(fpaRa);
         }
@@ -344,6 +364,6 @@
         {
             psMetadataItem *fpaDec = psMetadataItemAllocF64("FPA.DEC", "Declination of boresight", NAN);
-            pmConceptRegister(fpaDec, (pmConceptParseFunc)pmConceptParse_FPA_Coords,
-                              (pmConceptFormatFunc)pmConceptFormat_FPA_Coords, PM_FPA_LEVEL_FPA);
+            pmConceptRegister(fpaDec, (pmConceptParseFunc)p_pmConceptParse_FPA_Coords,
+                              (pmConceptFormatFunc)p_pmConceptFormat_FPA_Coords, PM_FPA_LEVEL_FPA);
             psFree(fpaDec);
         }
@@ -446,6 +466,6 @@
                                           "Trim section", trimsec);
             psFree(trimsec);
-            pmConceptRegister(cellTrimsec, (pmConceptParseFunc)pmConceptParse_CELL_TRIMSEC,
-                              (pmConceptFormatFunc)pmConceptFormat_CELL_TRIMSEC, PM_FPA_LEVEL_CELL);
+            pmConceptRegister(cellTrimsec, (pmConceptParseFunc)p_pmConceptParse_CELL_TRIMSEC,
+                              (pmConceptFormatFunc)p_pmConceptFormat_CELL_TRIMSEC, PM_FPA_LEVEL_CELL);
             psFree(cellTrimsec);
         }
@@ -457,6 +477,6 @@
                                           "Bias sections", biassecs);
             psFree(biassecs);
-            pmConceptRegister(cellBiassec, (pmConceptParseFunc)pmConceptParse_CELL_BIASSEC,
-                              (pmConceptFormatFunc)pmConceptFormat_CELL_BIASSEC, PM_FPA_LEVEL_CELL);
+            pmConceptRegister(cellBiassec, (pmConceptParseFunc)p_pmConceptParse_CELL_BIASSEC,
+                              (pmConceptFormatFunc)p_pmConceptFormat_CELL_BIASSEC, PM_FPA_LEVEL_CELL);
             psFree(cellBiassec);
         }
@@ -465,6 +485,6 @@
         {
             psMetadataItem *cellXbin = psMetadataItemAllocS32("CELL.XBIN", "Binning in x", 0);
-            pmConceptRegister(cellXbin, (pmConceptParseFunc)pmConceptParse_CELL_Binning,
-                              (pmConceptFormatFunc)pmConceptFormat_CELL_XBIN, PM_FPA_LEVEL_CELL);
+            pmConceptRegister(cellXbin, (pmConceptParseFunc)p_pmConceptParse_CELL_Binning,
+                              (pmConceptFormatFunc)p_pmConceptFormat_CELL_XBIN, PM_FPA_LEVEL_CELL);
             psFree(cellXbin);
         }
@@ -473,6 +493,6 @@
         {
             psMetadataItem *cellYbin = psMetadataItemAllocS32("CELL.YBIN", "Binning in y", 0);
-            pmConceptRegister(cellYbin, (pmConceptParseFunc)pmConceptParse_CELL_Binning,
-                              (pmConceptFormatFunc)pmConceptFormat_CELL_YBIN, PM_FPA_LEVEL_CELL);
+            pmConceptRegister(cellYbin, (pmConceptParseFunc)p_pmConceptParse_CELL_Binning,
+                              (pmConceptFormatFunc)p_pmConceptFormat_CELL_YBIN, PM_FPA_LEVEL_CELL);
             psFree(cellYbin);
         }
@@ -481,6 +501,6 @@
         {
             psMetadataItem *cellTimesys = psMetadataItemAllocS32("CELL.TIMESYS", "Time system", -1);
-            pmConceptRegister(cellTimesys, (pmConceptParseFunc)pmConceptParse_CELL_TIMESYS,
-                              (pmConceptFormatFunc)pmConceptFormat_CELL_TIMESYS, PM_FPA_LEVEL_CELL);
+            pmConceptRegister(cellTimesys, (pmConceptParseFunc)p_pmConceptParse_CELL_TIMESYS,
+                              (pmConceptFormatFunc)p_pmConceptFormat_CELL_TIMESYS, PM_FPA_LEVEL_CELL);
             psFree(cellTimesys);
         }
@@ -495,6 +515,6 @@
                                        "Time of exposure", time);
             psFree(time);
-            pmConceptRegister(cellTime, (pmConceptParseFunc)pmConceptParse_CELL_TIME,
-                              (pmConceptFormatFunc)pmConceptFormat_CELL_TIME, PM_FPA_LEVEL_CELL);
+            pmConceptRegister(cellTime, (pmConceptParseFunc)p_pmConceptParse_CELL_TIME,
+                              (pmConceptFormatFunc)p_pmConceptFormat_CELL_TIME, PM_FPA_LEVEL_CELL);
             psFree(cellTime);
         }
@@ -503,6 +523,6 @@
         {
             psMetadataItem *cellX0 = psMetadataItemAllocS32("CELL.X0", "Position of (0,0) on the chip", 0);
-            pmConceptRegister(cellX0, (pmConceptParseFunc)pmConceptParse_CELL_Positions,
-                              (pmConceptFormatFunc)pmConceptFormat_CELL_Positions, PM_FPA_LEVEL_CELL);
+            pmConceptRegister(cellX0, (pmConceptParseFunc)p_pmConceptParse_CELL_Positions,
+                              (pmConceptFormatFunc)p_pmConceptFormat_CELL_Positions, PM_FPA_LEVEL_CELL);
             psFree(cellX0);
         }
@@ -511,6 +531,6 @@
         {
             psMetadataItem *cellY0 = psMetadataItemAllocS32("CELL.Y0", "Position of (0,0) on the chip", 0);
-            pmConceptRegister(cellY0, (pmConceptParseFunc)pmConceptParse_CELL_Positions,
-                              (pmConceptFormatFunc)pmConceptFormat_CELL_Positions, PM_FPA_LEVEL_CELL);
+            pmConceptRegister(cellY0, (pmConceptParseFunc)p_pmConceptParse_CELL_Positions,
+                              (pmConceptFormatFunc)p_pmConceptFormat_CELL_Positions, PM_FPA_LEVEL_CELL);
             psFree(cellY0);
         }
@@ -534,4 +554,7 @@
                       )
 {
+    PS_ASSERT_PTR_NON_NULL(target, false);
+    PS_ASSERT_PTR_NON_NULL(source, false);
+
     // Copy FPA concepts
     target->concepts = psMetadataCopy(target->concepts, source->concepts);
Index: trunk/psModules/src/concepts/pmConceptsRead.c
===================================================================
--- trunk/psModules/src/concepts/pmConceptsRead.c	(revision 7253)
+++ trunk/psModules/src/concepts/pmConceptsRead.c	(revision 7278)
@@ -1,3 +1,4 @@
 #include <stdio.h>
+#include <assert.h>
 
 #include "pslib.h"
@@ -21,4 +22,7 @@
                                  )
 {
+    assert(concept);
+    assert(pattern);
+
     switch (pattern->type) {
     case PS_DATA_STRING: {
@@ -53,39 +57,43 @@
                         )
 {
-    if (concept) {
-        psMetadataItem *parsed = NULL;  // The parsed concept
-        if (spec->parse) {
-            parsed = spec->parse(concept, spec->blank, cameraFormat, fpa, chip, cell);
-        } else {
-            parsed = parsePlain(concept, spec->blank);
-        }
-
-        // Plug the parsed concept into a new psMetadataItem, so each "concept" has its own version that can
-        // be altered without affecting the others.  Also, so that we maintain the template name and comment.
-        psMetadataItem *cleaned = NULL;     // Item that's been cleaned up --- correct name and comment
-        switch (spec->blank->type) {
-        case PS_DATA_STRING:
-            cleaned = psMetadataItemAllocStr(spec->blank->name, spec->blank->comment, parsed->data.V);
-            break;
-        case PS_DATA_S32:
-            cleaned = psMetadataItemAllocS32(spec->blank->name, spec->blank->comment, parsed->data.S32);
-            break;
-        case PS_DATA_F32:
-            cleaned = psMetadataItemAllocF32(spec->blank->name, spec->blank->comment, parsed->data.F32);
-            break;
-        case PS_DATA_F64:
-            cleaned = psMetadataItemAllocF64(spec->blank->name, spec->blank->comment, parsed->data.F64);
-            break;
-        default:
-            cleaned = psMetadataItemAlloc(spec->blank->name, parsed->type, spec->blank->comment,
-                                          parsed->data.V);
-        }
-        psFree(parsed);
-        psMetadataAddItem(target, cleaned, PS_LIST_TAIL, PS_META_REPLACE);
-        psFree(cleaned);                 // Drop reference
-        return true;
-    }
-
-    return false;
+    assert(spec);
+    assert(cameraFormat);
+    assert(target);
+
+    if (!concept) {
+        return false;
+    }
+
+    psMetadataItem *parsed = NULL;  // The parsed concept
+    if (spec->parse) {
+        parsed = spec->parse(concept, spec->blank, cameraFormat, fpa, chip, cell);
+    } else {
+        parsed = parsePlain(concept, spec->blank);
+    }
+
+    // Plug the parsed concept into a new psMetadataItem, so each "concept" has its own version that can
+    // be altered without affecting the others.  Also, so that we maintain the template name and comment.
+    psMetadataItem *cleaned = NULL;     // Item that's been cleaned up --- correct name and comment
+    switch (spec->blank->type) {
+    case PS_DATA_STRING:
+        cleaned = psMetadataItemAllocStr(spec->blank->name, spec->blank->comment, parsed->data.V);
+        break;
+    case PS_DATA_S32:
+        cleaned = psMetadataItemAllocS32(spec->blank->name, spec->blank->comment, parsed->data.S32);
+        break;
+    case PS_DATA_F32:
+        cleaned = psMetadataItemAllocF32(spec->blank->name, spec->blank->comment, parsed->data.F32);
+        break;
+    case PS_DATA_F64:
+        cleaned = psMetadataItemAllocF64(spec->blank->name, spec->blank->comment, parsed->data.F64);
+        break;
+    default:
+        cleaned = psMetadataItemAlloc(spec->blank->name, parsed->type, spec->blank->comment,
+                                      parsed->data.V);
+    }
+    psFree(parsed);
+    psMetadataAddItem(target, cleaned, PS_LIST_TAIL, PS_META_REPLACE);
+    psFree(cleaned);                 // Drop reference
+    return true;
 }
 
@@ -100,45 +108,48 @@
                              )
 {
-    if (cell) {
-        pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level
-        if (! hdu) {
-            return false;
-        }
-        psMetadata *cameraFormat = hdu->format; // The camera format
-        psMetadata *cellConfig = cell->config; // The camera configuration for this cell
-        psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
-        psMetadataItem *specItem = NULL;    // Item from the specs metadata
-        while ((specItem = psMetadataGetAndIncrement(specsIter))) {
-            pmConceptSpec *spec = specItem->data.V; // The specification
-            psString name = specItem->name; // The concept name
-            psMetadataItem *conceptItem = psMetadataLookup(cellConfig, name); // The concept, or NULL
-            psMetadataItem *value = NULL; // The value of the concept
-            if (conceptItem) {
-                if (conceptItem->type == PS_DATA_STRING) {
-                    // Check the SOURCE
-                    psString nameSource = NULL; // String with the concept name and ".SOURCE" added
-                    psStringAppend(&nameSource, "%s.SOURCE", name);
-                    bool mdok = true;       // Status of MD lookup
-                    psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
-                    psFree(nameSource);
-                    if (mdok && strlen(source) > 0 && strcasecmp(source, "VALUE") == 0) {
-                        value = conceptItem;
-                        conceptParse(spec, value, cameraFormat, target, NULL, NULL, cell);
-                    } else if (source && (strlen(source) == 0 || strcasecmp(source, "HEADER") != 0)) {
-                        // We leave "HEADER" to pmConceptsReadFromHeader
-                        psError(PS_ERR_IO, true, "%s isn't HEADER or VALUE --- can't read %s\n", source,
-                                name);
-                        continue;
-                    }
-                } else {
-                    // Another type --- should be OK
-                    conceptParse(spec, conceptItem, cameraFormat, target, NULL, NULL, cell);
+    PS_ASSERT_PTR_NON_NULL(specs, false);
+    PS_ASSERT_PTR_NON_NULL(target, false);
+    if (!cell) {
+        return false;
+    }
+
+    pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level
+    if (! hdu) {
+        return false;
+    }
+    psMetadata *cameraFormat = hdu->format; // The camera format
+    psMetadata *cellConfig = cell->config; // The camera configuration for this cell
+    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
+    psMetadataItem *specItem = NULL;    // Item from the specs metadata
+    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
+        pmConceptSpec *spec = specItem->data.V; // The specification
+        psString name = specItem->name; // The concept name
+        psMetadataItem *conceptItem = psMetadataLookup(cellConfig, name); // The concept, or NULL
+        psMetadataItem *value = NULL; // The value of the concept
+        if (conceptItem) {
+            if (conceptItem->type == PS_DATA_STRING) {
+                // Check the SOURCE
+                psString nameSource = NULL; // String with the concept name and ".SOURCE" added
+                psStringAppend(&nameSource, "%s.SOURCE", name);
+                bool mdok = true;       // Status of MD lookup
+                psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
+                psFree(nameSource);
+                if (mdok && strlen(source) > 0 && strcasecmp(source, "VALUE") == 0) {
+                    value = conceptItem;
+                    conceptParse(spec, value, cameraFormat, target, NULL, NULL, cell);
+                } else if (source && (strlen(source) == 0 || strcasecmp(source, "HEADER") != 0)) {
+                    // We leave "HEADER" to pmConceptsReadFromHeader
+                    psError(PS_ERR_IO, true, "%s isn't HEADER or VALUE --- can't read %s\n", source,
+                            name);
+                    continue;
                 }
+            } else {
+                // Another type --- should be OK
+                conceptParse(spec, conceptItem, cameraFormat, target, NULL, NULL, cell);
             }
         }
-        psFree(specsIter);
-        return true;
-    }
-    return false;
+    }
+    psFree(specsIter);
+    return true;
 }
 
@@ -151,4 +162,7 @@
                                )
 {
+    PS_ASSERT_PTR_NON_NULL(specs, false);
+    PS_ASSERT_PTR_NON_NULL(target, false);
+
     pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
     if (!hdu) {
@@ -158,19 +172,17 @@
     bool mdok = true;                   // Status of MD lookup
     psMetadata *defaults = psMetadataLookupMD(&mdok, cameraFormat, "DEFAULTS"); // The DEFAULTS spec
-    if (mdok && defaults) {
-        pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
-        psMetadata *cameraFormat = hdu->format; // The camera format
-        psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
-        psMetadataItem *specItem = NULL;    // Item from the specs metadata
-        while ((specItem = psMetadataGetAndIncrement(specsIter))) {
-            pmConceptSpec *spec = specItem->data.V; // The specification
-            psString name = specItem->name; // The concept name
-            psMetadataItem *conceptItem = psMetadataLookup(defaults, name); // The concept, or NULL
-            conceptParse(spec, conceptItem, cameraFormat, target, fpa, chip, cell);
-        }
-        psFree(specsIter);
-        return true;
-    }
-    return false;
+    if (!mdok || !defaults) {
+        return false;
+    }
+    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
+    psMetadataItem *specItem = NULL;    // Item from the specs metadata
+    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
+        pmConceptSpec *spec = specItem->data.V; // The specification
+        psString name = specItem->name; // The concept name
+        psMetadataItem *conceptItem = psMetadataLookup(defaults, name); // The concept, or NULL
+        conceptParse(spec, conceptItem, cameraFormat, target, fpa, chip, cell);
+    }
+    psFree(specsIter);
+    return true;
 }
 
@@ -183,4 +195,7 @@
                              )
 {
+    PS_ASSERT_PTR_NON_NULL(specs, false);
+    PS_ASSERT_PTR_NON_NULL(target, false);
+
     pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
     if (!hdu) {
@@ -190,57 +205,58 @@
     bool mdok = true;                   // Status of MD lookup
     psMetadata *transSpec = psMetadataLookupMD(&mdok, cameraFormat, "TRANSLATION"); // The TRANSLATION spec
-    if (mdok && transSpec) {
-        psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
-        psMetadataItem *specItem = NULL;    // Item from the specs metadata
-        while ((specItem = psMetadataGetAndIncrement(specsIter))) {
-            pmConceptSpec *spec = specItem->data.V; // The specification
-            psString name = specItem->name; // The concept name
-            psMetadataItem *headerItem = NULL; // The value of the concept from the header
-            // First check the cell configuration
-            if (cell && cell->config) {
-                psMetadataItem *conceptItem = psMetadataLookup(cell->config, name); // The concept, or NULL
-                if (conceptItem) {
-                    // Check the SOURCE
-                    psString nameSource = NULL; // String with the concept name and ".SOURCE" added
-                    psStringAppend(&nameSource, "%s.SOURCE", name);
-                    psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
-                    psFree(nameSource);
-                    if (mdok && strlen(source) && strcasecmp(source, "HEADER") == 0) {
-                        headerItem = psMetadataLookup(hdu->header, conceptItem->data.V);
+    if (!mdok || !transSpec) {
+        return false;
+    }
+
+    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
+    psMetadataItem *specItem = NULL;    // Item from the specs metadata
+    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
+        pmConceptSpec *spec = specItem->data.V; // The specification
+        psString name = specItem->name; // The concept name
+        psMetadataItem *headerItem = NULL; // The value of the concept from the header
+        // First check the cell configuration
+        if (cell && cell->config) {
+            psMetadataItem *conceptItem = psMetadataLookup(cell->config, name); // The concept, or NULL
+            if (conceptItem) {
+                // Check the SOURCE
+                psString nameSource = NULL; // String with the concept name and ".SOURCE" added
+                psStringAppend(&nameSource, "%s.SOURCE", name);
+                psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
+                psFree(nameSource);
+                if (mdok && strlen(source) && strcasecmp(source, "HEADER") == 0) {
+                    headerItem = psMetadataLookup(hdu->header, conceptItem->data.V);
+                }
+                // Leave the error handling to pmConceptsFromCamera, which should already have been called
+            }
+        }
+        if (! headerItem) {
+            psString keywords = psMetadataLookupStr(&mdok, transSpec, name); // The FITS keywords
+            if (mdok && strlen(keywords) > 0) {
+                // In case there are multiple headers
+                psList *keys = psStringSplit(keywords, " ,;", true); // List of keywords
+                if (keys->n == 1) {
+                    // Only one key --- proceed as usual
+                    headerItem = psMetadataLookup(hdu->header, keywords);
+                } else {
+                    psListIterator *keysIter = psListIteratorAlloc(keys, PS_LIST_HEAD, false); // Iterator
+                    psString key = NULL; // Item from iteration
+                    psList *values = psListAlloc(NULL); // List containing the values
+                    while ((key = psListGetAndIncrement(keysIter))) {
+                        psMetadataItem *value = psMetadataLookup(hdu->header, key);
+                        psListAdd(values, PS_LIST_TAIL, value);
                     }
-                    // Leave the error handling to pmConceptsFromCamera, which should already have been called
+                    psFree(keysIter);
+                    headerItem = psMetadataItemAlloc(name, PS_DATA_LIST, specItem->comment, values);
+                    psFree(values);
                 }
+                psFree(keys);
             }
-            if (! headerItem) {
-                psString keywords = psMetadataLookupStr(&mdok, transSpec, name); // The FITS keywords
-                if (mdok && strlen(keywords) > 0) {
-                    // In case there are multiple headers
-                    psList *keys = psStringSplit(keywords, " ,;", true); // List of keywords
-                    if (keys->n == 1) {
-                        // Only one key --- proceed as usual
-                        headerItem = psMetadataLookup(hdu->header, keywords);
-                    } else {
-                        psListIterator *keysIter = psListIteratorAlloc(keys, PS_LIST_HEAD, false); // Iterator
-                        psString key = NULL; // Item from iteration
-                        psList *values = psListAlloc(NULL); // List containing the values
-                        while ((key = psListGetAndIncrement(keysIter))) {
-                            psMetadataItem *value = psMetadataLookup(hdu->header, key);
-                            psListAdd(values, PS_LIST_TAIL, value);
-                        }
-                        psFree(keysIter);
-                        headerItem = psMetadataItemAlloc(name, PS_DATA_LIST, specItem->comment, values);
-                        psFree(values);
-                    }
-                    psFree(keys);
-                }
-            }
-
-            // This will also clean up the name
-            conceptParse(spec, headerItem, cameraFormat, target, fpa, chip, cell);
         }
-        psFree(specsIter);
-        return true;
-    }
-    return false;
+
+        // This will also clean up the name
+        conceptParse(spec, headerItem, cameraFormat, target, fpa, chip, cell);
+    }
+    psFree(specsIter);
+    return true;
 }
 
@@ -255,5 +271,9 @@
                                )
 {
+    PS_ASSERT_PTR_NON_NULL(specs, false);
+    PS_ASSERT_PTR_NON_NULL(target, false);
+
     #ifdef OMIT_PSDB
+
     return false;
     #else
@@ -266,343 +286,104 @@
     bool mdok = true;                   // Status of MD lookup
     psMetadata *dbSpec = psMetadataLookupMD(&mdok, cameraFormat, "DATABSE"); // The DATABASE spec
-    if (mdok && dbSpec) {
-        pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
-        psMetadata *cameraFormat = hdu->format; // The camera format
-        psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
-        psMetadataItem *specItem = NULL;    // Item from the specs metadata
-        while ((specItem = psMetadataGetAndIncrement(specsIter))) {
-            pmConceptSpec *spec = specItem->data.V; // The specification
-            psString name = specItem->name; // The concept name
-
-            psMetadata *dbLookup = psMetadataLookupMD(&mdok, dbSpec, name);
-            if (mdok && dbLookup) {
-                const char *tableName = psMetadataLookupStr(&mdok, dbLookup, "TABLE"); // Table name
-                // Names of the "where" columns
-                const char *givenCols = psMetadataLookupStr(&mdok, dbLookup, "GIVENDBCOL");
-                // Values of the "where" columns
-                const char *givenPS = psMetadataLookupStr(&mdok, dbLookup, "GIVENPS");
-
-                // Now, need to get the "given"s
-                if (strlen(givenCols) > 0 || strlen(givenPS) > 0) {
-                    psList *cols = psStringSplit(givenCols, ",;", true); // List of column names
-                    psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns
-                    psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB
-                    if (cols->n != values->n) {
+    if (!mdok || !dbSpec) {
+        return false;
+    }
+
+    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
+    psMetadataItem *specItem = NULL;    // Item from the specs metadata
+    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
+        pmConceptSpec *spec = specItem->data.V; // The specification
+        psString name = specItem->name; // The concept name
+
+        psMetadata *dbLookup = psMetadataLookupMD(&mdok, dbSpec, name);
+        if (mdok && dbLookup) {
+            const char *tableName = psMetadataLookupStr(&mdok, dbLookup, "TABLE"); // Table name
+            // Names of the "where" columns
+            const char *givenCols = psMetadataLookupStr(&mdok, dbLookup, "GIVENDBCOL");
+            // Values of the "where" columns
+            const char *givenPS = psMetadataLookupStr(&mdok, dbLookup, "GIVENPS");
+
+            // Now, need to get the "given"s
+            if (strlen(givenCols) > 0 || strlen(givenPS) > 0) {
+                psList *cols = psStringSplit(givenCols, ",;", true); // List of column names
+                psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns
+                psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB
+                if (cols->n != values->n) {
+                    psLogMsg(__func__, PS_LOG_WARN,
+                             "The GIVENDBCOL and GIVENPS entries for %s do not have "
+                             "the same number of entries --- ignored.\n", name);
+                } else {
+                    // Iterators for the lists
+                    psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);
+                    psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
+                    char *column = NULL;    // Name of the column
+                    while ((column = psListGetAndIncrement(colsIter))) {
+                        char *dependName = psListGetAndIncrement(valuesIter); // Name for the value
+                        if (!strlen(column) || !strlen(name)) {
+                            psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "
+                                     " empty --- ignored.\n", name);
+                        } else {
+                            // Search for the value name
+                            psMetadataItem *item = NULL; // The value
+                            if (!item && cell) {
+                                item = psMetadataLookup(cell->concepts, dependName);
+                            }
+                            if (!item && chip) {
+                                item = psMetadataLookup(chip->concepts, dependName);
+                            }
+                            if (!item && fpa) {
+                                item = psMetadataLookup(fpa->concepts, dependName);
+                            }
+                            if (! item) {
+                                psLogMsg(__func__, PS_LOG_ERROR, "Unable to find the value name %s for DB"
+                                         " lookup on %s --- ignored.\n", dependName, name);
+                            } else {
+                                // We need to create a new psMetadataItem.  I don't think we can't
+                                // simply hack the existing one, since that could conceivably cause
+                                // memory leaks
+                                psMetadataItem *newItem = psMetadataItemAlloc(name, item->type,
+                                                          item->comment,
+                                                          item->data.V);
+                                psMetadataAddItem(selection, newItem, PS_LIST_TAIL, PS_META_REPLACE);
+                                psFree(newItem);
+                            }
+                        }
+                        psFree(dependName);
+                        psFree(column);
+                    } // Iterating through the columns
+                    psFree(colsIter);
+                    psFree(valuesIter);
+
+                    psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result
+                    // Note that we use limit=2 in order to test if there are multiple rows returned
+
+                    psMetadataItem *conceptItem = NULL; // The final result of the DB lookup
+                    if (dbResult->n == 0) {
                         psLogMsg(__func__, PS_LOG_WARN,
-                                 "The GIVENDBCOL and GIVENPS entries for %s do not have "
-                                 "the same number of entries --- ignored.\n", name);
+                                 "Unable to find any rows in DB for %s --- ignored\n", name);
                     } else {
-                        // Iterators for the lists
-                        psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);
-                        psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
-                        char *column = NULL;    // Name of the column
-                        while ((column = psListGetAndIncrement(colsIter))) {
-                            char *dependName = psListGetAndIncrement(valuesIter); // Name for the value
-                            if (!strlen(column) || !strlen(name)) {
-                                psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "
-                                         " empty --- ignored.\n", name);
-                            } else {
-                                // Search for the value name
-                                psMetadataItem *item = NULL; // The value
-                                if (!item && cell) {
-                                    item = psMetadataLookup(cell->concepts, dependName);
-                                }
-                                if (!item && chip) {
-                                    item = psMetadataLookup(chip->concepts, dependName);
-                                }
-                                if (!item && fpa) {
-                                    item = psMetadataLookup(fpa->concepts, dependName);
-                                }
-                                if (! item) {
-                                    psLogMsg(__func__, PS_LOG_ERROR, "Unable to find the value name %s for DB"
-                                             " lookup on %s --- ignored.\n", dependName, name);
-                                } else {
-                                    // We need to create a new psMetadataItem.  I don't think we can't
-                                    // simply hack the existing one, since that could conceivably cause
-                                    // memory leaks
-                                    psMetadataItem *newItem = psMetadataItemAlloc(name, item->type,
-                                                              item->comment,
-                                                              item->data.V);
-                                    psMetadataAddItem(selection, newItem, PS_LIST_TAIL, PS_META_REPLACE);
-                                    psFree(newItem);
-                                }
-                            }
-                            psFree(dependName);
-                            psFree(column);
-                        } // Iterating through the columns
-                        psFree(colsIter);
-                        psFree(valuesIter);
-
-                        psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result
-                        // Note that we use limit=2 in order to test if there are multiple rows returned
-
-                        psMetadataItem *conceptItem = NULL; // The final result of the DB lookup
-                        if (dbResult->n == 0) {
+                        if (dbResult-> n > 1) {
                             psLogMsg(__func__, PS_LOG_WARN,
-                                     "Unable to find any rows in DB for %s --- ignored\n", name);
-                        } else {
-                            if (dbResult-> n > 1) {
-                                psLogMsg(__func__, PS_LOG_WARN,
-                                         "Multiple rows returned in DB lookup for %s --- "
-                                         " using the first one only.\n", name);
-                            }
-                            conceptItem = (psMetadataItem*)dbResult->data[0];
+                                     "Multiple rows returned in DB lookup for %s --- "
+                                     " using the first one only.\n", name);
                         }
-
-                        // Now we have the result
-                        conceptParse(spec, conceptItem, cameraFormat, target, fpa, chip, cell);
-
+                        conceptItem = (psMetadataItem*)dbResult->data[0];
                     }
-                    psFree(cols);
-                    psFree(values);
+
+                    // Now we have the result
+                    conceptParse(spec, conceptItem, cameraFormat, target, fpa, chip, cell);
+
                 }
-            } // Doing the "given"s.
-
-        } // Iterating through the concept specifications
-        psFree(specsIter);
-
-        return true;
-    }
-    return false;
+                psFree(cols);
+                psFree(values);
+            }
+        } // Doing the "given"s.
+
+    } // Iterating through the concept specifications
+    psFree(specsIter);
+
+    return true;
     #endif
 }
 
 
-
-
-#ifdef OLD
-
-psMetadataItem *pmConceptReadFromCamera(pmCell *cell, // The cell
-                                        const char *concept // Name of concept
-                                       )
-{
-    if (cell) {
-        psMetadata *camera = cell->config; // Camera configuration
-        psMetadataItem *item = psMetadataLookup(camera, concept);
-        return item;
-    }
-    return NULL;
-}
-
-psMetadataItem *pmConceptReadFromHeader(pmFPA *fpa, // The FPA that contains the chip
-                                        pmChip *chip, // The chip that contains the cell
-                                        pmCell *cell, // The cell
-                                        const char *concept // Name of concept
-                                       )
-{
-    bool mdStatus = true;               // Status of MD lookup
-    psMetadata *translation = psMetadataLookupMD(&mdStatus, fpa->camera, "TRANSLATION"); // FITS translation
-    if (! mdStatus) {
-        psError(PS_ERR_IO, false, "Unable to find TRANSLATION in camera configuration.\n");
-        return NULL;
-    }
-
-    // Look for how to translate the concept into a FITS header name
-    const char *keyword = psMetadataLookupStr(&mdStatus, translation, concept);
-    if (mdStatus && strlen(keyword) > 0) {
-        // We have a FITS header to look up --- search each level
-        if (cell && cell->hdu) {
-            psMetadataItem *cellItem = psMetadataLookup(cell->hdu->header, keyword);
-            if (cellItem) {
-                // XXX: Need to clean up before returning
-                return cellItem;
-            }
-        }
-
-        if (chip && chip->hdu) {
-            psMetadataItem *chipItem = psMetadataLookup(chip->hdu->header, keyword);
-            if (chipItem) {
-                // XXX: Need to clean up before returning
-                return chipItem;
-            }
-        }
-
-        if (fpa->hdu) {
-            psMetadataItem *fpaItem = psMetadataLookup(fpa->hdu->header, keyword);
-            if (fpaItem) {
-                // XXX: Need to clean up before returning
-                return fpaItem;
-            }
-        }
-    }
-
-    // No header value
-    return NULL;
-}
-
-
-// Look for a default
-psMetadataItem *pmConceptReadFromDefault(pmFPA *fpa, // The FPA that contains the chip
-        pmChip *chip, // The chip that contains the cell
-        pmCell *cell, // The cell
-        const char *concept // Name of concept
-                                        )
-{
-    bool mdOK = true;                   // Status of MD lookup
-    psMetadata *defaults = psMetadataLookupMD(&mdOK, fpa->camera, "DEFAULTS");
-    if (! mdOK) {
-        psError(PS_ERR_IO, false, "Unable to find DEFAULTS in camera configuration.\n");
-        return NULL;
-    }
-
-    psMetadataItem *defItem = psMetadataLookup(defaults, concept);
-    if (defItem) {
-        if (defItem->type == PS_DATA_METADATA) {
-            // A dependent default
-            psTrace(__func__, 7, "Evaluating dependent default....\n");
-            psMetadata *dependents = defItem->data.V; // The list of dependents
-            // Find out what it depends on
-            psString dependName = psStringCopy(concept);
-            psStringAppend(&dependName, ".DEPEND");
-            psString dependsOn = psMetadataLookupStr(&mdOK, defaults, dependName);
-            if (! mdOK) {
-                psError(PS_ERR_IO, false, "Unable to find %s in camera configuration for dependent default"
-                        " --- ignored\n", dependName);
-                // XXX: Need to clean up before returning
-                return NULL;
-            }
-            psFree(dependName);
-            // Find the value of the dependent concept
-            psMetadataItem *depItem = pmConceptReadFromHeader(fpa, chip, cell, dependsOn);
-            if (! depItem) {
-                psError(PS_ERR_IO, true, "Unable to find value for %s (required for %s)\n", dependsOn,
-                        concept);
-                return NULL;
-            }
-            if (depItem->type != PS_DATA_STRING) {
-                psError(PS_ERR_IO, true, "Value of %s is not of type string, as required for dependency"
-                        " --- ignored.\n", dependsOn);
-            }
-
-            defItem = psMetadataLookup(dependents, depItem->data.V);    // This is now what we were after
-        }
-    }
-
-    // XXX: Need to clean up before returning
-    return defItem;                     // defItem is either NULL or points to what was desired
-}
-
-
-// Look for a database lookup
-// XXX: Not tested
-psMetadataItem *pmConceptReadFromDB(pmFPA *fpa, // The FPA that contains the chip
-                                    pmChip *chip, // The chip that contains the cell
-                                    pmCell *cell, // The cell
-                                    psDB *db, // DB handle
-                                    const char *concept // Name of concept
-                                   )
-{
-    if (! db) {
-        // No database initialised
-        return NULL;
-    }
-
-    bool mdStatus = true;               // Status of MD lookup
-    psMetadata *database = psMetadataLookupMD(&mdStatus, fpa->camera, "DATABASE");
-    if (! mdStatus) {
-        // No error, because not everyone needs to use the DB
-        return NULL;
-    }
-
-    psMetadata *dbLookup = psMetadataLookupMD(&mdStatus, database, concept);
-    if (dbLookup) {
-        const char *tableName = psMetadataLookupStr(&mdStatus, dbLookup, "TABLE"); // Name of the table
-        // const char *colName = psMetadataLookupStr(&mdStatus, dbLookup, "COLUMN"); // Name of the column
-        const char *givenCols = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENDBCOL"); // Name of "where"
-        // columns
-        const char *givenPS = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENPS"); // Values for "where"
-        // columns
-
-        // Now, need to get the "given"s
-        if (strlen(givenCols) || strlen(givenPS)) {
-            psList *cols = psStringSplit(givenCols, ",;", true); // List of column names
-            psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns
-            psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB
-            if (cols->n != values->n) {
-                psLogMsg(__func__, PS_LOG_WARN, "The GIVENDBCOL and GIVENPS entries for %s do not have "
-                         "the same number of entries --- ignored.\n", concept);
-            } else {
-                // Iterators for the lists
-                psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);
-                psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
-                char *column = NULL;    // Name of the column
-                while ((column = psListGetAndIncrement(colsIter))) {
-                    char *name = psListGetAndIncrement(valuesIter); // Name for the value
-                    if (!strlen(column) || !strlen(name)) {
-                        psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "
-                                 " empty --- ignored.\n", concept);
-                    } else {
-                        // Search for the value name
-                        psMetadataItem *item = pmConceptReadFromHeader(fpa, chip, cell, name);
-                        if (! item) {
-                            item = pmConceptReadFromDefault(fpa, chip, cell, name);
-                        }
-                        if (! item) {
-                            psLogMsg(__func__, PS_LOG_ERROR, "Unable to find the value name %s for DB "
-                                     " lookup on %s --- ignored.\n", name, concept);
-                        } else {
-                            // We need to create a new psMetadataItem.  I don't think we can't simply hack
-                            // the existing one, since that could conceivably cause memory leaks
-                            psMetadataItem *newItem = psMetadataItemAlloc(concept, item->type,
-                                                      item->comment, item->data.V);
-                            psMetadataAddItem(selection, newItem, PS_LIST_TAIL, PS_META_REPLACE);
-                            psFree(newItem);
-                        }
-                    }
-                    psFree(name);
-                    psFree(column);
-                } // Iterating through the columns
-                psFree(colsIter);
-                psFree(valuesIter);
-
-                psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result
-                // Note that we use limit=2 in order to test if there are multiple rows returned
-
-                psMetadataItem *result = NULL; // The final result of the DB lookup
-                if (dbResult->n == 0) {
-                    psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- ignored\n",
-                             concept);
-                } else {
-                    if (dbResult-> n > 1) {
-                        psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s --- "
-                                 " using the first one only.\n", concept);
-                    }
-                    result = (psMetadataItem*)dbResult->data[0];
-                }
-                // XXX: Need to clean up before returning
-                return result;
-            }
-            psFree(cols);
-            psFree(values);
-        }
-    } // Doing the "given"s.
-
-    psAbort(__func__, "Shouldn't ever get here.\n");
-    return NULL;
-}
-
-
-// Concept lookup
-psMetadataItem *pmConceptRead(pmFPA *fpa, // The FPA
-                              pmChip *chip,// The chip
-                              pmCell *cell, // The cell
-                              psDB *db, // DB handle
-                              const char *name // Concept name
-                             )
-{
-    // Try headers, database, defaults in order
-    psMetadataItem *item = pmConceptReadFromCamera(cell, name);
-    if (! item) {
-        item = pmConceptReadFromHeader(fpa, chip, cell, name);
-    }
-    if (! item) {
-        item = pmConceptReadFromDB(fpa, chip, cell, db, name);
-    }
-    if (! item) {
-        item = pmConceptReadFromDefault(fpa, chip, cell, name);
-    }
-    return item; // item is either NULL, or points to what was desired
-}
-
-
-#endif
Index: trunk/psModules/src/concepts/pmConceptsStandard.c
===================================================================
--- trunk/psModules/src/concepts/pmConceptsStandard.c	(revision 7253)
+++ trunk/psModules/src/concepts/pmConceptsStandard.c	(revision 7278)
@@ -9,4 +9,7 @@
 #include "pmConceptsStandard.h"
 
+// The functions in this file are intended to be called solely within the psModules concepts code.  For this
+// reason, they use "assert" instead of the PS_ASSERT_WHATEVER functions --- if there's a problem, then
+// there's a BIG problem that affects all of the code.
 
 #define COMPARE_REGIONS(a,b) (((a)->x0 == (b)->x0 && \
@@ -38,5 +41,10 @@
 
 // FPA.RA and FPA.DEC
-psMetadataItem *pmConceptParse_FPA_Coords(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptParse_FPA_Coords(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     assert(concept);
@@ -102,8 +110,11 @@
 
 // FPA.RA and FPA.DEC
-psMetadataItem *pmConceptFormat_FPA_Coords(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat)
-{
-    assert(concept);
-    assert(pattern);
+psMetadataItem *p_pmConceptFormat_FPA_Coords(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
+{
+    assert(concept);
     assert(cameraFormat);
 
@@ -112,7 +123,9 @@
     // How to interpret the coordinates
     bool mdok = true;                   // Status of MD lookup
-    psMetadata *formats = psMetadataLookupMD(&mdok, cameraFormat, "FORMATS");
+    psMetadata *formats = psMetadataLookupMD(&mdok,
+                          cameraFormat,
+                          "FORMATS");
     if (mdok && formats) {
-        psString format = psMetadataLookupStr(&mdok, formats, pattern->name);
+        psString format = psMetadataLookupStr(&mdok,formats, concept->name);
         if (mdok && strlen(format) > 0) {
             if (strcasecmp(format, "HOURS") == 0) {
@@ -123,11 +136,11 @@
                 // No action required
             } else {
-                coords /= defaultCoordScaling(pattern);
+                coords /= defaultCoordScaling(concept);
             }
         } else {
-            coords /= defaultCoordScaling(pattern);
+            coords /= defaultCoordScaling(concept);
         }
     } else {
-        coords /= defaultCoordScaling(pattern);
+        coords /= defaultCoordScaling(concept);
     }
 
@@ -140,5 +153,5 @@
     psString coordString = NULL;        // String with the coordinates in sexagesimal format
     psStringAppend(&coordString, "%d:%d:%.2f", big, medium, small);
-    psMetadataItem *coordItem = psMetadataItemAllocStr(pattern->name, pattern->comment, coordString);
+    psMetadataItem *coordItem = psMetadataItemAllocStr(concept->name, concept->comment, coordString);
     psFree(coordString);
 
@@ -147,5 +160,10 @@
 
 
-psMetadataItem *pmConceptParse_CELL_TRIMSEC(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptParse_CELL_TRIMSEC(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     assert(concept);
@@ -167,5 +185,10 @@
 }
 
-psMetadataItem *pmConceptParse_CELL_BIASSEC(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptParse_CELL_BIASSEC(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     assert(concept);
@@ -218,5 +241,10 @@
 
 // CELL.XBIN and CELL.YBIN
-psMetadataItem *pmConceptParse_CELL_Binning(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptParse_CELL_Binning(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     assert(concept);
@@ -249,5 +277,10 @@
 
 
-psMetadataItem *pmConceptParse_CELL_TIMESYS(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptParse_CELL_TIMESYS(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     assert(concept);
@@ -274,5 +307,10 @@
 
 
-psMetadataItem *pmConceptParse_CELL_TIME(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptParse_CELL_TIME(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     assert(concept);
@@ -466,5 +504,10 @@
 }
 
-psMetadataItem *pmConceptParse_CELL_Positions(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptParse_CELL_Positions(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     assert(concept);
@@ -489,5 +532,9 @@
 
 
-psMetadataItem *pmConceptFormat_CELL_TRIMSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptFormat_CELL_TRIMSEC(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     assert(concept);
@@ -501,5 +548,9 @@
 }
 
-psMetadataItem *pmConceptFormat_CELL_BIASSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptFormat_CELL_BIASSEC(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     // Return a metadata item containing a list of metadata items of region strings
@@ -523,5 +574,9 @@
 // This function actually does both CELL.XBIN and CELL.YBIN if CELL.XBIN and CELL.YBIN are specified by the
 // same header.
-psMetadataItem *pmConceptFormat_CELL_XBIN(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptFormat_CELL_XBIN(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     assert(concept);
@@ -546,5 +601,9 @@
 
 // Only need to format if both if CELL.XBIN and CELL.YBIN are not specified by the same header.
-psMetadataItem *pmConceptFormat_CELL_YBIN(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptFormat_CELL_YBIN(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     assert(concept);
@@ -565,5 +624,9 @@
 
 
-psMetadataItem *pmConceptFormat_CELL_TIMESYS(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptFormat_CELL_TIMESYS(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     psString sys = NULL;            // String to store
@@ -590,5 +653,9 @@
 }
 
-psMetadataItem *pmConceptFormat_CELL_TIME(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptFormat_CELL_TIME(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     psTime *time = concept->data.V;     // The time
@@ -699,5 +766,9 @@
 }
 
-psMetadataItem *pmConceptFormat_CELL_Positions(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
+psMetadataItem *p_pmConceptFormat_CELL_Positions(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell)
 {
     assert(concept);
Index: trunk/psModules/src/concepts/pmConceptsStandard.h
===================================================================
--- trunk/psModules/src/concepts/pmConceptsStandard.h	(revision 7253)
+++ trunk/psModules/src/concepts/pmConceptsStandard.h	(revision 7278)
@@ -5,20 +5,88 @@
 #include "pmFPA.h"
 
+// Functions to parse and format the standard concepts
 
-psMetadataItem *pmConceptParse_FPA_Coords(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
-psMetadataItem *pmConceptFormat_FPA_Coords(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat);
-psMetadataItem *pmConceptParse_CELL_TRIMSEC(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
-psMetadataItem *pmConceptParse_CELL_BIASSEC(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
-psMetadataItem *pmConceptParse_CELL_Binning(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
-psMetadataItem *pmConceptParse_CELL_TIMESYS(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
-psMetadataItem *pmConceptParse_CELL_TIME(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
-psMetadataItem *pmConceptParse_CELL_Positions(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
-psMetadataItem *pmConceptFormat_CELL_TRIMSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
-psMetadataItem *pmConceptFormat_CELL_BIASSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
-psMetadataItem *pmConceptFormat_CELL_XBIN(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
-psMetadataItem *pmConceptFormat_CELL_YBIN(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
-psMetadataItem *pmConceptFormat_CELL_TIMESYS(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
-psMetadataItem *pmConceptFormat_CELL_TIME(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
-psMetadataItem *pmConceptFormat_CELL_Positions(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
+psMetadataItem *p_pmConceptParse_FPA_Coords(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptFormat_FPA_Coords(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptParse_CELL_TRIMSEC(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptParse_CELL_BIASSEC(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptParse_CELL_Binning(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptParse_CELL_TIMESYS(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptParse_CELL_TIME(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptParse_CELL_Positions(psMetadataItem *concept,
+        psMetadataItem *pattern,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptFormat_CELL_TRIMSEC(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptFormat_CELL_BIASSEC(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptFormat_CELL_XBIN(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptFormat_CELL_YBIN(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptFormat_CELL_TIMESYS(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptFormat_CELL_TIME(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
+psMetadataItem *p_pmConceptFormat_CELL_Positions(psMetadataItem *concept,
+        psMetadata *cameraFormat,
+        pmFPA *fpa,
+        pmChip *chip,
+        pmCell *cell);
 
 #endif
Index: trunk/psModules/src/concepts/pmConceptsWrite.c
===================================================================
--- trunk/psModules/src/concepts/pmConceptsWrite.c	(revision 7253)
+++ trunk/psModules/src/concepts/pmConceptsWrite.c	(revision 7278)
@@ -1,3 +1,4 @@
 #include <stdio.h>
+#include <assert.h>
 #include <strings.h>
 #include "pslib.h"
@@ -110,4 +111,7 @@
                                     )
 {
+    assert(spec);
+    assert(cameraFormat);
+
     if (concept) {
         psMetadataItem *formatted = NULL;  // The formatted concept
@@ -129,4 +133,8 @@
                              )
 {
+    assert(hdu);
+    assert(keyword && strlen(keyword) > 0);
+    assert(item);
+
     if (!hdu->header) {
         return false;
@@ -166,4 +174,8 @@
                        )
 {
+    assert(hdu);
+    assert(keywords);
+    assert(item);
+
     bool status = true;                 // Status of writing headers, to be returned
     if (item->type == PS_DATA_LIST) {
@@ -204,63 +216,66 @@
                             )
 {
-    if (cell) {
-        pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level
-        if (!hdu) {
-            return false;
-        }
-        psMetadata *cameraFormat = hdu->format; // The camera format
-        psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
-        psMetadataItem *specItem = NULL;    // Item from the specs metadata
-        while ((specItem = psMetadataGetAndIncrement(specsIter))) {
-            pmConceptSpec *spec = specItem->data.V; // The specification
-            psString name = specItem->name; // The concept name
-            psMetadataItem *cameraItem = psMetadataLookup(cell->config, name); // The concept from the camera,
-            // or NULL
-            if (cameraItem) {
-                // Grab the concept
-                psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The concept
-                // Formatted version
-                psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, NULL, NULL, cell);
-                if (!formatted) {
-                    continue;
-                }
-                psString nameSource = NULL; // String with the concept name and ".SOURCE" added
-                psStringAppend(&nameSource, "%s.SOURCE", name);
-                bool mdok = true;       // Status of MD lookup
-                psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
-                if (mdok && strlen(source) > 0) {
-                    psTrace(__func__, 8, "%s is %s\n", nameSource, source);
-                    if (strcasecmp(source, "HEADER") == 0) {
-                        if (cameraItem->type != PS_DATA_STRING) {
-                            psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by header, but is not "
-                                     "of type STR --- ignored.\n", conceptItem->name);
-                            continue;
-                        }
-                        psTrace(__func__, 8, "Writing %s to header %s\n", name, cameraItem->data.V);
-                        writeHeader(hdu, cameraItem->data.V, formatted);
-                    } else if (strcasecmp(source, "VALUE") == 0) {
-                        psTrace(__func__, 8, "Checking %s against camera format.\n", name);
-                        if (! compareConcepts(formatted, cameraItem)) {
-                            psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera "
-                                     "format, but the values don't match.\n", name);
-                        }
-                    } else {
-                        psLogMsg(__func__, PS_LOG_WARN, "Concept source %s isn't HEADER or VALUE --- can't "
-                                 "write\n", nameSource);
+    PS_ASSERT_PTR_NON_NULL(specs, false);
+    PS_ASSERT_PTR_NON_NULL(concepts, false);
+    if (!cell) {
+        return false;
+    }
+
+    pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level
+    if (!hdu) {
+        return false;
+    }
+    psMetadata *cameraFormat = hdu->format; // The camera format
+    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
+    psMetadataItem *specItem = NULL;    // Item from the specs metadata
+    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
+        pmConceptSpec *spec = specItem->data.V; // The specification
+        psString name = specItem->name; // The concept name
+        psMetadataItem *cameraItem = psMetadataLookup(cell->config, name); // The concept from the camera,
+        // or NULL
+        if (cameraItem) {
+            // Grab the concept
+            psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The concept
+            // Formatted version
+            psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, NULL, NULL, cell);
+            if (!formatted) {
+                continue;
+            }
+            psString nameSource = NULL; // String with the concept name and ".SOURCE" added
+            psStringAppend(&nameSource, "%s.SOURCE", name);
+            bool mdok = true;       // Status of MD lookup
+            psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
+            if (mdok && strlen(source) > 0) {
+                psTrace(__func__, 8, "%s is %s\n", nameSource, source);
+                if (strcasecmp(source, "HEADER") == 0) {
+                    if (cameraItem->type != PS_DATA_STRING) {
+                        psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by header, but is not "
+                                 "of type STR --- ignored.\n", conceptItem->name);
+                        continue;
                     }
-                } else if (! compareConcepts(formatted, cameraItem)) {
-                    // Assume it's specified by value
-                    psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera "
-                             "format, but the values don't match.\n", name);
-                }
-                psFree(formatted);
-                psFree(nameSource);
-            }
-
-        }
-        psFree(specsIter);
-        return true;
-    }
-    return false;
+                    psTrace(__func__, 8, "Writing %s to header %s\n", name, cameraItem->data.V);
+                    writeHeader(hdu, cameraItem->data.V, formatted);
+                } else if (strcasecmp(source, "VALUE") == 0) {
+                    psTrace(__func__, 8, "Checking %s against camera format.\n", name);
+                    if (! compareConcepts(formatted, cameraItem)) {
+                        psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera "
+                                 "format, but the values don't match.\n", name);
+                    }
+                } else {
+                    psLogMsg(__func__, PS_LOG_WARN, "Concept source %s isn't HEADER or VALUE --- can't "
+                             "write\n", nameSource);
+                }
+            } else if (! compareConcepts(formatted, cameraItem)) {
+                // Assume it's specified by value
+                psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera "
+                         "format, but the values don't match.\n", name);
+            }
+            psFree(formatted);
+            psFree(nameSource);
+        }
+
+    }
+    psFree(specsIter);
+    return true;
 }
 
@@ -272,4 +287,7 @@
                               )
 {
+    PS_ASSERT_PTR_NON_NULL(specs, false);
+    PS_ASSERT_PTR_NON_NULL(concepts, false);
+
     pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level
     if (!hdu) {
@@ -279,51 +297,50 @@
     bool mdok = true;                   // Status of MD lookup
     psMetadata *defaults = psMetadataLookupMD(&mdok, cameraFormat, "DEFAULTS"); // The DEFAULTS spec
-    if (mdok && defaults) {
-        pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
-        psMetadata *cameraFormat = hdu->format; // The camera format
-        psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
-        psMetadataItem *specItem = NULL;    // Item from the specs metadata
-        while ((specItem = psMetadataGetAndIncrement(specsIter))) {
-            pmConceptSpec *spec = specItem->data.V; // The specification
-            psString name = specItem->name; // The concept name
-            psMetadataItem *defaultItem = psMetadataLookup(defaults, name); // The item from the DEFAULTS
-            if (defaultItem) {
-                psMetadataItem *conceptItem = NULL; // The item from the concepts
-                if (defaultItem->type == PS_DATA_METADATA) {
-                    // It's a menu --- need to look up the .DEPEND
-                    psString dependName = NULL; // The concept name with ".DEPEND" on the end
-                    psStringAppend(&dependName, ".DEPEND");
-                    psString dependKey = psMetadataLookupStr(&mdok, defaults, dependName); // The keyword
-                    psFree(dependName);
-                    if (!mdok || !dependKey || strlen(dependKey) == 0) {
-                        psLogMsg(__func__, PS_LOG_WARN, "Can't find %s in the DEFAULTS for %s --- ignored.\n",
-                                 dependName, name);
-                        continue;
-                    }
-                    psString dependValue = psMetadataLookupStr(&mdok, concepts, dependName); // The value
-                    if (!mdok || !dependKey || strlen(dependKey) == 0) {
-                        psLogMsg(__func__, PS_LOG_WARN, "Concept %s specified by %s isn't of type STR -- "
-                                 "ignored.\n", name, dependName);
-                        continue;
-                    }
-                    conceptItem = psMetadataLookup(defaultItem->data.V, dependValue);
-                } else {
-                    conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
-                }
-                psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
-                if (!formatted) {
+    if (!mdok || !defaults) {
+        return false;
+    }
+
+    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
+    psMetadataItem *specItem = NULL;    // Item from the specs metadata
+    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
+        pmConceptSpec *spec = specItem->data.V; // The specification
+        psString name = specItem->name; // The concept name
+        psMetadataItem *defaultItem = psMetadataLookup(defaults, name); // The item from the DEFAULTS
+        if (defaultItem) {
+            psMetadataItem *conceptItem = NULL; // The item from the concepts
+            if (defaultItem->type == PS_DATA_METADATA) {
+                // It's a menu --- need to look up the .DEPEND
+                psString dependName = NULL; // The concept name with ".DEPEND" on the end
+                psStringAppend(&dependName, ".DEPEND");
+                psString dependKey = psMetadataLookupStr(&mdok, defaults, dependName); // The keyword
+                psFree(dependName);
+                if (!mdok || !dependKey || strlen(dependKey) == 0) {
+                    psLogMsg(__func__, PS_LOG_WARN, "Can't find %s in the DEFAULTS for %s --- ignored.\n",
+                             dependName, name);
                     continue;
                 }
-                if (! compareConcepts(formatted, defaultItem)) {
-                    psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by the DEFAULTS in the camera "
-                             "format, but the values don't match.\n", name);
-                }
-                psFree(formatted);
-            }
-        }
-        psFree(specsIter);
-        return true;
-    }
-    return false;
+                psString dependValue = psMetadataLookupStr(&mdok, concepts, dependName); // The value
+                if (!mdok || !dependKey || strlen(dependKey) == 0) {
+                    psLogMsg(__func__, PS_LOG_WARN, "Concept %s specified by %s isn't of type STR -- "
+                             "ignored.\n", name, dependName);
+                    continue;
+                }
+                conceptItem = psMetadataLookup(defaultItem->data.V, dependValue);
+            } else {
+                conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
+            }
+            psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
+            if (!formatted) {
+                continue;
+            }
+            if (! compareConcepts(formatted, defaultItem)) {
+                psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by the DEFAULTS in the camera "
+                         "format, but the values don't match.\n", name);
+            }
+            psFree(formatted);
+        }
+    }
+    psFree(specsIter);
+    return true;
 }
 
@@ -336,4 +353,7 @@
                             )
 {
+    PS_ASSERT_PTR_NON_NULL(specs, false);
+    PS_ASSERT_PTR_NON_NULL(concepts, false);
+
     pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level
     if (!hdu) {
@@ -343,54 +363,53 @@
     bool mdok = true;                   // Status of MD lookup
     psMetadata *translation = psMetadataLookupMD(&mdok, cameraFormat, "TRANSLATION"); // The TRANSLATION spec
-    if (mdok && translation) {
-        pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
-        psMetadata *cameraFormat = hdu->format; // The camera format
-        psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
-        psMetadataItem *specItem = NULL;    // Item from the specs metadata
-        while ((specItem = psMetadataGetAndIncrement(specsIter))) {
-            pmConceptSpec *spec = specItem->data.V; // The specification
-            psString name = specItem->name; // The concept name
-            psMetadataItem *headerItem = psMetadataLookup(translation, name); // The item from the TRANSLATION
-            if (headerItem) {
-                if (headerItem->type != PS_DATA_STRING) {
-                    psLogMsg(__func__, PS_LOG_WARN, "TRANSLATION keyword for concept %s isn't of type STR ---"
-                             " ignored.", name);
-                    continue;
-                }
-                psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
-                psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
-                if (!formatted) {
-                    continue;
-                }
-                psList *keywords = psStringSplit(headerItem->data.V, " ,;", true); // List of header keywords
-                if (formatted->type == PS_DATA_LIST) {
-                    psList *values = formatted->data.V; // The values for the headers
-                    if (values->n != keywords->n) {
-                        psLogMsg(__func__, PS_LOG_WARN, "Number of headers specified does not match number "
-                                 "of values for concept %s.\n", name);
+    if (!mdok || !translation) {
+        return false;
+    }
+
+    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
+    psMetadataItem *specItem = NULL;    // Item from the specs metadata
+    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
+        pmConceptSpec *spec = specItem->data.V; // The specification
+        psString name = specItem->name; // The concept name
+        psMetadataItem *headerItem = psMetadataLookup(translation, name); // The item from the TRANSLATION
+        if (headerItem) {
+            if (headerItem->type != PS_DATA_STRING) {
+                psLogMsg(__func__, PS_LOG_WARN, "TRANSLATION keyword for concept %s isn't of type STR ---"
+                         " ignored.", name);
+                continue;
+            }
+            psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
+            psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
+            if (!formatted) {
+                continue;
+            }
+            psList *keywords = psStringSplit(headerItem->data.V, " ,;", true); // List of header keywords
+            if (formatted->type == PS_DATA_LIST) {
+                psList *values = formatted->data.V; // The values for the headers
+                if (values->n != keywords->n) {
+                    psLogMsg(__func__, PS_LOG_WARN, "Number of headers specified does not match number "
+                             "of values for concept %s.\n", name);
+                }
+                psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); // Iterator
+                psListIterator *keywordsIter = psListIteratorAlloc(keywords, PS_LIST_HEAD, false);
+                psMetadataItem *valuesItem = NULL; // Item from list
+                while ((valuesItem = psListGetAndIncrement(valuesIter))) {
+                    psString keyword = psListGetAndIncrement(keywordsIter); // Keyword from the list
+                    if (strlen(keyword) > 0) {
+                        writeHeader(hdu, keyword, formatted);
                     }
-                    psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); // Iterator
-                    psListIterator *keywordsIter = psListIteratorAlloc(keywords, PS_LIST_HEAD, false);
-                    psMetadataItem *valuesItem = NULL; // Item from list
-                    while ((valuesItem = psListGetAndIncrement(valuesIter))) {
-                        psString keyword = psListGetAndIncrement(keywordsIter); // Keyword from the list
-                        if (strlen(keyword) > 0) {
-                            writeHeader(hdu, keyword, formatted);
-                        }
-                    }
-                    psFree(valuesIter);
-                    psFree(keywordsIter);
-                } else {
-                    psString keyword = psListGet(keywords, PS_LIST_HEAD); // The keyword
-                    writeHeader(hdu, keyword, formatted);
-                }
-                psFree(formatted);
-                psFree(keywords);
-            }
-        }
-        psFree(specsIter);
-        return true;
-    }
-    return false;
+                }
+                psFree(valuesIter);
+                psFree(keywordsIter);
+            } else {
+                psString keyword = psListGet(keywords, PS_LIST_HEAD); // The keyword
+                writeHeader(hdu, keyword, formatted);
+            }
+            psFree(formatted);
+            psFree(keywords);
+        }
+    }
+    psFree(specsIter);
+    return true;
 }
 
@@ -404,4 +423,11 @@
                               )
 {
+    PS_ASSERT_PTR_NON_NULL(specs, false);
+    PS_ASSERT_PTR_NON_NULL(concepts, false);
+
+    if (!db) {
+        return false;
+    }
+
     #ifdef OMIT_PSDB
     return false;
@@ -415,419 +441,111 @@
     bool mdok = true;                   // Status of MD lookup
     psMetadata *database = psMetadataLookupMD(&mdok, cameraFormat, "DATABASE"); // The DATABASE spec
-    if (mdok && database) {
-        pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
-        psMetadata *cameraFormat = hdu->format; // The camera format
-        psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
-        psMetadataItem *specItem = NULL;    // Item from the specs metadata
-        while ((specItem = psMetadataGetAndIncrement(specsIter))) {
-            pmConceptSpec *spec = specItem->data.V; // The specification
-            psString name = specItem->name; // The concept name
-
-            psMetadataItem *dbItem = psMetadataLookup(database, name); // The item from the DATABASE
-            if (dbItem) {
-                if (dbItem->type != PS_DATA_METADATA) {
-                    psLogMsg(__func__, PS_LOG_WARN, "DATABASE keyword for concept %s isn't of type METADATA "
-                             "--- ignored.\n", name);
-                    continue;
-                }
-
-                psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
-                psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
-                if (!formatted) {
-                    continue;
-                }
-
-                psMetadata *dbLookup = dbItem->data.V; // How to look up the value of interest
-                // Name of the table
-                const char *tableName = psMetadataLookupStr(&mdok, dbLookup, "TABLE");
-                // Name of "where" columns
-                const char *givenCols = psMetadataLookupStr(&mdok, dbLookup, "GIVENDBCOL");
-                // Values for "where" columns
-                const char *givenPS = psMetadataLookupStr(&mdok, dbLookup, "GIVENPS");
-
-                // Now, need to get the "given"s
-                if (strlen(givenCols) || strlen(givenPS)) {
-                    psList *cols = psStringSplit(givenCols, ",;", true); // List of column names
-                    psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns
-                    psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB
-                    if (cols->n != values->n) {
-                        psLogMsg(__func__, PS_LOG_WARN,
-                                 "The GIVENDBCOL and GIVENPS entries for %s do not have "
-                                 "the same number of entries --- ignored.\n", name);
+    if (!mdok || !database) {
+        return false;
+    }
+    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
+    psMetadataItem *specItem = NULL;    // Item from the specs metadata
+    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
+        pmConceptSpec *spec = specItem->data.V; // The specification
+        psString name = specItem->name; // The concept name
+
+        psMetadataItem *dbItem = psMetadataLookup(database, name); // The item from the DATABASE
+        if (dbItem) {
+            if (dbItem->type != PS_DATA_METADATA) {
+                psLogMsg(__func__, PS_LOG_WARN, "DATABASE keyword for concept %s isn't of type METADATA "
+                         "--- ignored.\n", name);
+                continue;
+            }
+
+            psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
+            psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
+            if (!formatted) {
+                continue;
+            }
+
+            psMetadata *dbLookup = dbItem->data.V; // How to look up the value of interest
+            // Name of the table
+            const char *tableName = psMetadataLookupStr(&mdok, dbLookup, "TABLE");
+            // Name of "where" columns
+            const char *givenCols = psMetadataLookupStr(&mdok, dbLookup, "GIVENDBCOL");
+            // Values for "where" columns
+            const char *givenPS = psMetadataLookupStr(&mdok, dbLookup, "GIVENPS");
+
+            // Now, need to get the "given"s
+            if (strlen(givenCols) || strlen(givenPS)) {
+                psList *cols = psStringSplit(givenCols, ",;", true); // List of column names
+                psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns
+                psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB
+                if (cols->n != values->n) {
+                    psLogMsg(__func__, PS_LOG_WARN,
+                             "The GIVENDBCOL and GIVENPS entries for %s do not have "
+                             "the same number of entries --- ignored.\n", name);
+                } else {
+                    // Iterators for the lists
+                    psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);
+                    psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
+                    char *column = NULL;    // Name of the column
+                    while ((column = psListGetAndIncrement(colsIter))) {
+                        char *dependName = psListGetAndIncrement(valuesIter); // Name for the value
+                        if (!strlen(column) || !strlen(name)) {
+                            psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "
+                                     " empty --- ignored.\n", name);
+                        } else {
+                            // Search for the value name
+                            psMetadataItem *item = NULL; // The value
+                            if (!item && cell) {
+                                item = psMetadataLookup(cell->concepts, dependName);
+                            }
+                            if (!item && chip) {
+                                item = psMetadataLookup(chip->concepts, dependName);
+                            }
+                            if (!item && fpa) {
+                                item = psMetadataLookup(fpa->concepts, dependName);
+                            }
+                            if (! item) {
+                                psLogMsg(__func__, PS_LOG_ERROR,
+                                         "Unable to find the value name %s for DB "
+                                         " lookup on %s --- ignored.\n", dependName, name);
+                            } else {
+                                // We need to create a new psMetadataItem.  I don't think we can't simply
+                                // hack the existing one, since that could conceivably cause memory leaks
+                                psMetadataAddItem(selection, formatted, PS_LIST_TAIL, PS_META_REPLACE);
+                                psFree(formatted);
+                            }
+                        }
+                        psFree(dependName);
+                        psFree(column);
+                    } // Iterating through the columns
+                    psFree(colsIter);
+                    psFree(valuesIter);
+
+                    // Check first to make sure we're only going to touch one row
+                    psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result
+                    // Note that we use limit=2 in order to test if there are multiple rows returned
+                    if (! dbResult || dbResult->n == 0) {
+                        psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- "
+                                 "ignored\n", name);
+                        return false;
                     } else {
-                        // Iterators for the lists
-                        psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);
-                        psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
-                        char *column = NULL;    // Name of the column
-                        while ((column = psListGetAndIncrement(colsIter))) {
-                            char *dependName = psListGetAndIncrement(valuesIter); // Name for the value
-                            if (!strlen(column) || !strlen(name)) {
-                                psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "
-                                         " empty --- ignored.\n", name);
-                            } else {
-                                // Search for the value name
-                                psMetadataItem *item = NULL; // The value
-                                if (!item && cell) {
-                                    item = psMetadataLookup(cell->concepts, dependName);
-                                }
-                                if (!item && chip) {
-                                    item = psMetadataLookup(chip->concepts, dependName);
-                                }
-                                if (!item && fpa) {
-                                    item = psMetadataLookup(fpa->concepts, dependName);
-                                }
-                                if (! item) {
-                                    psLogMsg(__func__, PS_LOG_ERROR,
-                                             "Unable to find the value name %s for DB "
-                                             " lookup on %s --- ignored.\n", dependName, name);
-                                } else {
-                                    // We need to create a new psMetadataItem.  I don't think we can't simply
-                                    // hack the existing one, since that could conceivably cause memory leaks
-                                    psMetadataAddItem(selection, formatted, PS_LIST_TAIL, PS_META_REPLACE);
-                                    psFree(formatted);
-                                }
-                            }
-                            psFree(dependName);
-                            psFree(column);
-                        } // Iterating through the columns
-                        psFree(colsIter);
-                        psFree(valuesIter);
-
-                        // Check first to make sure we're only going to touch one row
-                        psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result
-                        // Note that we use limit=2 in order to test if there are multiple rows returned
-                        if (! dbResult || dbResult->n == 0) {
-                            psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- "
-                                     "ignored\n", name);
-                            return false;
-                        } else {
-                            if (dbResult->n > 1) {
-                                psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s "
-                                         "--- ignored.\n", name);
-                            }
-                            // Update the DB
-                            psMetadata *update = psMetadataAlloc();
-                            psMetadataAddItem(update, conceptItem, PS_LIST_HEAD, 0);
-                            psDBUpdateRows(db, tableName, selection, update);
-                            psFree(update);
-                            return true;
+                        if (dbResult->n > 1) {
+                            psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s "
+                                     "--- ignored.\n", name);
                         }
+                        // Update the DB
+                        psMetadata *update = psMetadataAlloc();
+                        psMetadataAddItem(update, conceptItem, PS_LIST_HEAD, 0);
+                        psDBUpdateRows(db, tableName, selection, update);
+                        psFree(update);
+                        return true;
                     }
-                    psFree(cols);
-                    psFree(values);
-                } // Doing the "given"s.
-            }
-        }
-        psFree(specsIter);
-        return true;
-    }
-    return false;
+                }
+                psFree(cols);
+                psFree(values);
+            } // Doing the "given"s.
+        }
+    }
+    psFree(specsIter);
+    return true;
     #endif
 }
 
-
-
-
-#if 0
-
-// Well, not really "write", but check to make sure it's there and matches
-bool pmConceptWriteToCamera(pmCell *cell, // The cell
-                            psMetadataItem *concept // Concept
-                           )
-{
-    if (! cell->config) {
-        return false;
-    }
-    if (cell) {
-        psMetadataItem *item = psMetadataLookup(cell->config, concept->name); // Info we want
-        return compareConcepts(item, concept);
-    }
-
-    return false;
-}
-
-// Write the concept to the header in the appropriate location
-bool pmConceptWriteToHeader(pmFPA *fpa, // The FPA that contains the chip
-                            pmChip *chip, // The chip that contains the cell
-                            pmCell *cell, // The cell
-                            psMetadataItem *concept // Concept
-                           )
-{
-    bool mdok = true;                   // Status of MD lookup
-    bool status = false;                // Status of setting header
-    if (! fpa->camera) {
-        return false;
-    }
-    psMetadata *translation = psMetadataLookupMD(&mdok, fpa->camera, "TRANSLATION"); // FITS translation
-    if (! mdok) {
-        psError(PS_ERR_IO, false, "Unable to find TRANSLATION in camera configuration.\n");
-        return false;
-    }
-
-    // Look for how to translate the concept into a FITS header name
-    const char *keyword = psMetadataLookupStr(&mdok, translation, concept->name);
-    if (mdok && strlen(keyword) > 0) {
-        psTrace(__func__, 6, "It's in keyword %s\n", keyword);
-        psMetadataItem *headerItem = NULL; // Item to add to header
-        // XXX: Need to expand range of types
-        switch (concept->type) {
-        case PS_DATA_STRING:
-            headerItem = psMetadataItemAllocStr(keyword, concept->comment, concept->data.V);
-            break;
-        case PS_DATA_S32:
-            headerItem = psMetadataItemAllocS32(keyword, concept->comment, concept->data.S32);
-            break;
-        case PS_DATA_F32:
-            headerItem = psMetadataItemAllocF32(keyword, concept->comment, concept->data.F32);
-            break;
-        case PS_DATA_F64:
-            headerItem = psMetadataItemAllocF64(keyword, concept->comment, concept->data.F64);
-            break;
-        default:
-            headerItem = psMetadataItemAlloc(keyword, concept->type, concept->comment,
-                                             concept->data.V); // Item for the header
-        }
-
-        // We have a FITS header to look up --- search each level
-        if (cell && cell->hdu) {
-            psTrace(__func__, 7, "Adding to the cell level header...\n");
-            psMetadataAddItem(cell->hdu->header, headerItem, PS_LIST_TAIL, PS_META_REPLACE);
-            status = true;
-        } else if (chip && chip->hdu) {
-            psTrace(__func__, 7, "Adding to the chip level header...\n");
-            psMetadataAddItem(chip->hdu->header, headerItem, PS_LIST_TAIL, PS_META_REPLACE);
-            status = true;
-        } else if (fpa->hdu) {
-            psTrace(__func__, 7, "Adding to the FPA level header...\n");
-            psMetadataAddItem(fpa->hdu->header, headerItem, PS_LIST_TAIL, PS_META_REPLACE);
-            status = true;
-        }
-        psFree(headerItem);
-    }
-
-    // No header value
-    return status;
-}
-
-
-// Well, not really "write", but check to see if it's there, and matches
-bool pmConceptWriteToDefault(pmFPA *fpa, // The FPA that contains the chip
-                             pmChip *chip, // The chip that contains the cell
-                             pmCell *cell, // The cell
-                             psMetadataItem *concept // Concept
-                            )
-{
-    bool mdOK = true;                   // Status of MD lookup
-    if (! fpa->camera) {
-        return false;
-    }
-    psMetadata *defaults = psMetadataLookupMD(&mdOK, fpa->camera, "DEFAULTS");
-    if (! mdOK || ! defaults) {
-        psError(PS_ERR_IO, false, "Unable to find DEFAULTS in camera configuration.\n");
-        return false;
-    }
-
-    psMetadataItem *defItem = psMetadataLookup(defaults, concept->name);
-    bool status = false;                // Result of checking the database
-    if (defItem) {
-        if (defItem->type == PS_DATA_METADATA) {
-            // A dependent default
-            psTrace(__func__, 7, "Evaluating dependent default....\n");
-            psMetadata *dependents = defItem->data.V; // The list of dependents
-            // Find out what it depends on
-            psString dependName = psStringCopy(concept->name);
-            psStringAppend(&dependName, ".DEPEND");
-            psString dependsOn = psMetadataLookupStr(&mdOK, defaults, dependName);
-            if (! mdOK) {
-                psError(PS_ERR_IO, false, "Unable to find %s in camera configuration for dependent default"
-                        " --- ignored\n", dependName);
-                // XXX: Need to clean up before returning
-                return false;
-            }
-            psFree(dependName);
-            // Find the value of the dependent concept
-            psMetadataItem *depItem = pmConceptReadFromHeader(fpa, chip, cell, dependsOn);
-            if (! depItem) {
-                psError(PS_ERR_IO, true, "Unable to find value for %s (required for %s)\n", dependsOn,
-                        concept->name);
-                return false;
-            }
-            if (depItem->type != PS_DATA_STRING) {
-                psError(PS_ERR_IO, true, "Value of %s is not of type string, as required for dependency"
-                        " --- ignored.\n", dependsOn);
-            }
-
-            defItem = psMetadataLookup(dependents, depItem->data.V); // This is now what we were after
-        }
-
-        status = compareConcepts(defItem, concept);
-        if (! status) {
-            psError(PS_ERR_IO, true, "Concept %s is specified by default in the camera configuration, "
-                    "but doesn't match the actual value.\n", concept->name);
-        }
-    }
-
-    // XXX: Need to clean up before returning
-    return status;
-}
-
-
-// XXX: Not tested at all
-// XXX I WOULD NOT TRUST THIS FUNCTION IN THE SLIGHTEST YET! --- PAP
-bool pmConceptWriteToDB(pmFPA *fpa, // The FPA that contains the chip
-                        pmChip *chip, // The chip that contains the cell
-                        pmCell *cell, // The cell
-                        psDB *db,    // DB handle
-                        psMetadataItem *concept // Concept
-                       )
-{
-    if (! db) {
-        // No database initialised
-        return false;
-    }
-
-    bool mdStatus = true;               // Status of MD lookup
-    if (! fpa->camera) {
-        return false;
-    }
-    psMetadata *database = psMetadataLookupMD(&mdStatus, fpa->camera, "DATABASE");
-    if (! mdStatus) {
-        // No error, because not everyone needs to use the DB
-        return NULL;
-    }
-
-    psMetadata *dbLookup = psMetadataLookupMD(&mdStatus, database, concept->name);
-    if (dbLookup) {
-        const char *tableName = psMetadataLookupStr(&mdStatus, dbLookup, "TABLE"); // Name of the table
-        //        const char *colName = psMetadataLookupStr(&mdStatus, dbLookup, "COLUMN"); // Name of the column
-        const char *givenCols = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENDBCOL"); // Name of "where"
-        // columns
-        const char *givenPS = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENPS"); // Values for "where"
-        // columns
-
-        // Now, need to get the "given"s
-        if (strlen(givenCols) || strlen(givenPS)) {
-            psList *cols = psStringSplit(givenCols, ",;", true); // List of column names
-            psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns
-            psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB
-            if (cols->n != values->n) {
-                psLogMsg(__func__, PS_LOG_WARN, "The GIVENDBCOL and GIVENPS entries for %s do not have "
-                         "the same number of entries --- ignored.\n", concept);
-            } else {
-                // Iterators for the lists
-                psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);
-                psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
-                char *column = NULL;    // Name of the column
-                while ((column = psListGetAndIncrement(colsIter))) {
-                    char *name = psListGetAndIncrement(valuesIter); // Name for the value
-                    if (!strlen(column) || !strlen(name)) {
-                        psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "
-                                 " empty --- ignored.\n", concept);
-                    } else {
-                        // Search for the value name
-                        psMetadataItem *item = pmConceptReadFromHeader(fpa, chip, cell, name);
-                        if (! item) {
-                            item = pmConceptReadFromDefault(fpa, chip, cell, name);
-                        }
-                        if (! item) {
-                            psLogMsg(__func__, PS_LOG_ERROR, "Unable to find the value name %s for DB "
-                                     " lookup on %s --- ignored.\n", name, concept);
-                        } else {
-                            // We need to create a new psMetadataItem.  I don't think we can't simply hack
-                            // the existing one, since that could conceivably cause memory leaks
-                            psMetadataItem *newItem = psMetadataItemAlloc(concept->name, item->type,
-                                                      item->comment, item->data.V);
-                            psMetadataAddItem(selection, newItem, PS_LIST_TAIL, PS_META_REPLACE);
-                            psFree(newItem);
-                        }
-                    }
-                    psFree(name);
-                    psFree(column);
-                } // Iterating through the columns
-                psFree(colsIter);
-                psFree(valuesIter);
-
-                // Check first to make sure we're only going to touch one row
-                psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result
-                // Note that we use limit=2 in order to test if there are multiple rows returned
-                if (! dbResult || dbResult->n == 0) {
-                    psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- ignored\n",
-                             concept->name);
-                    return false;
-                } else {
-                    if (dbResult->n > 1) {
-                        psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s --- "
-                                 " ignored.\n", concept->name);
-                    }
-                    // Update the DB
-                    psMetadata *update = psMetadataAlloc();
-                    psMetadataAddItem(update, concept, PS_LIST_HEAD, 0);
-                    psDBUpdateRows(db, tableName, selection, update);
-                    psFree(update);
-                    return true;
-                }
-            }
-            psFree(cols);
-            psFree(values);
-        }
-    } // Doing the "given"s.
-
-    psAbort(__func__, "Shouldn't ever get here?\n");
-    return false;
-}
-
-
-// Concept write from item
-bool pmConceptWriteItem(pmFPA *fpa,     // The FPA
-                        pmChip *chip,   // The chip
-                        pmCell *cell,   // The cell
-                        psDB *db,       // DB handle
-                        psMetadataItem *concept // Concept item
-                       )
-{
-    if (! fpa->camera) {
-        return false;
-    }
-
-    // Try headers, database, defaults in order
-    psTrace(__func__, 3, "Trying to set concept %s...\n", concept->name);
-    bool status = pmConceptWriteToCamera(cell, concept); // Status for return
-    if (! status) {
-        psTrace(__func__, 5, "Trying header....\n");
-        status = pmConceptWriteToHeader(fpa, chip, cell, concept);
-    }
-    if (! status) {
-        psTrace(__func__, 5, "Trying database....\n");
-        status = pmConceptWriteToDB(fpa, chip, cell, db, concept);
-    }
-    if (! status) {
-        psTrace(__func__, 5, "Checking defaults....\n");
-        status = pmConceptWriteToDefault(fpa, chip, cell, concept);
-    }
-
-    if (! status) {
-        psError(PS_ERR_IO, true, "Unable to set %s (%s).\n", concept->name, concept->comment);
-    }
-
-    return status;
-}
-
-
-// Concept write
-bool pmConceptWrite(pmFPA *fpa, // The FPA
-                    pmChip *chip,// The chip
-                    pmCell *cell,    // The cell
-                    psDB *db, // DB handle
-                    psMetadata *concepts, // Concepts MD from which to set
-                    const char *name // Name of the concept
-                   )
-{
-    psMetadataItem *concept = psMetadataLookup(concepts, name);
-    if (! concept) {
-        psError(PS_ERR_IO, true, "No such concept as %s\n", name);
-        return false;
-    }
-    return pmConceptWriteItem(fpa, chip, cell, db, concept);
-}
-
-#endif
