Index: trunk/psModules/src/concepts/pmConceptsWrite.c
===================================================================
--- trunk/psModules/src/concepts/pmConceptsWrite.c	(revision 12890)
+++ trunk/psModules/src/concepts/pmConceptsWrite.c	(revision 17911)
@@ -6,5 +6,5 @@
 #include <assert.h>
 #include <string.h>
-#include <strings.h>		/* for strn?casecmp */
+#include <strings.h>            /* for strn?casecmp */
 #include <pslib.h>
 
@@ -340,53 +340,31 @@
         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, "%s.DEPEND", defaultItem->name);
-                psString dependKey = psMetadataLookupStr(&mdok, defaults, dependName); // The keyword
-                if (!mdok || !dependKey || strlen(dependKey) == 0) {
-                    psWarning("Can't find %s in the DEFAULTS for %s --- ignored.\n",
-                             dependName, name);
-                    psFree(dependName);
-                    continue;
-                }
-                psString dependValue = psMetadataLookupStr(&mdok, concepts, dependKey); // The value
-                if (!mdok || !dependValue || strlen(dependValue) == 0) {
-                    psWarning("Concept %s specified by %s isn't of type STR -- "
-                             "ignored.\n", dependKey, dependName);
-                    psFree(dependName);
-                    continue;
-                }
-                // Get the actual item of interest, and correct the name to match the concept name
-                defaultItem = psMetadataLookup(defaultItem->data.md, dependValue);
-                if (!defaultItem) {
-                    psWarning("Concept dependency name %s is not found "
-                             "in concept table for %s -- ignored.\n", dependValue, dependName);
-                    psFree(dependName);
-                    continue;
-                }
-                defaultItem = psMetadataItemCopy(defaultItem);
-                psFree(dependName);
-                psFree(defaultItem->name);
-                defaultItem->name = psStringCopy(name);
-            } else {
-                psMemIncrRefCounter(defaultItem);
-            }
-            conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
-            psMetadataItem *formatted = conceptFormat(spec, conceptItem, PM_CONCEPT_SOURCE_DEFAULTS,
-                                                      cameraFormat, fpa, chip, cell);
-            if (!formatted) {
-                continue;
-            }
-            if (! compareConcepts(formatted, defaultItem)) {
-                psWarning("Concept %s is specified by the DEFAULTS in the camera "
-                         "format, but the values don't match.\n", name);
-            }
-            psFree(defaultItem);
-            psFree(formatted);
-        }
+
+        psMetadataItem *defaultItem = p_pmConceptsReadSingleFromDefaults(name, defaults, fpa, chip, cell);
+        if (!defaultItem) {
+            continue;
+        }
+        psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
+        psMetadataItem *formatted = conceptFormat(spec, conceptItem, PM_CONCEPT_SOURCE_DEFAULTS,
+                                                  cameraFormat, fpa, chip, cell);
+        if (!formatted) {
+            continue;
+        }
+
+        if (strcmp(defaultItem->name, name) != 0) {
+            // Correct the name to match the concept name
+            defaultItem = psMetadataItemCopy(defaultItem);
+            psFree(defaultItem->name);
+            defaultItem->name = psStringCopy(name);
+        } else {
+            psMemIncrRefCounter(defaultItem);
+        }
+
+        if (!compareConcepts(formatted, defaultItem)) {
+            psWarning("Concept %s is specified by the DEFAULTS in the camera "
+                      "format, but the values don't match.\n", name);
+        }
+        psFree(defaultItem);
+        psFree(formatted);
     }
     psFree(specsIter);
@@ -418,20 +396,28 @@
         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) {
-                psWarning("TRANSLATION keyword for concept %s isn't of type STR ---"
-                         " ignored.", name);
+        if (!headerItem) {
+            continue;
+        }
+        if (headerItem->type == PS_DATA_METADATA) {
+            // This is a menu
+            psTrace("psModules.concepts", 5, "%s is of type METADATA.\n", name);
+            headerItem = p_pmConceptsDepend(name, headerItem->data.md, translation, fpa, chip, cell);
+            if (!headerItem) {
                 continue;
             }
-            psTrace("psModules.concepts", 3, "Writing %s to header %s\n", name, headerItem->data.str);
-            psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
-            psMetadataItem *formatted = conceptFormat(spec, conceptItem, PM_CONCEPT_SOURCE_HEADER,
-                                                      cameraFormat, fpa, chip, cell);
-            if (!formatted) {
-                continue;
-            }
-            writeHeader(hdu, headerItem->data.V, formatted);
-            psFree(formatted);
-        }
+        }
+        if (headerItem->type != PS_DATA_STRING) {
+            psWarning("TRANSLATION keyword for concept %s isn't of type STR --- ignored.", name);
+            continue;
+        }
+        psTrace("psModules.concepts", 3, "Writing %s to header %s\n", name, headerItem->data.str);
+        psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
+        psMetadataItem *formatted = conceptFormat(spec, conceptItem, PM_CONCEPT_SOURCE_HEADER,
+                                                  cameraFormat, fpa, chip, cell);
+        if (!formatted) {
+            continue;
+        }
+        writeHeader(hdu, headerItem->data.V, formatted);
+        psFree(formatted);
     }
     psFree(specsIter);
@@ -470,99 +456,31 @@
         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) {
-                psWarning("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, PM_CONCEPT_SOURCE_DATABASE,
-                                                      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)) {
-                            psWarning("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) {
-                        psWarning("Unable to find any rows in DB for %s --- "
-                                 "ignored\n", name);
-                        return false;
-                    } else {
-                        if (dbResult->n > 1) {
-                            psWarning("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.
-        }
+        psMetadataItem *dbItem = p_pmConceptsReadSingleFromDatabase(name, database, db, fpa, chip, cell);
+        if (!dbItem) {
+            continue;
+        }
+
+        psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
+        psMetadataItem *formatted = conceptFormat(spec, conceptItem, PM_CONCEPT_SOURCE_DATABASE,
+                                                  cameraFormat, fpa, chip, cell);
+        if (!formatted) {
+            continue;
+        }
+
+        if (strcmp(dbItem->name, name) != 0) {
+            // Correct the name to match the concept name
+            dbItem = psMetadataItemCopy(dbItem);
+            psFree(dbItem->name);
+            dbItem->name = psStringCopy(name);
+        } else {
+            psMemIncrRefCounter(dbItem);
+        }
+
+        if (!compareConcepts(formatted, dbItem)) {
+            psWarning("Concept %s is specified by the DATABASE in the camera "
+                      "format, but the values don't match.\n", name);
+        }
+        psFree(dbItem);
+        psFree(formatted);
     }
     psFree(specsIter);
@@ -570,3 +488,2 @@
     #endif
 }
-
