Index: /trunk/psModules/src/concepts/pmConcepts.c
===================================================================
--- /trunk/psModules/src/concepts/pmConcepts.c	(revision 9571)
+++ /trunk/psModules/src/concepts/pmConcepts.c	(revision 9572)
@@ -25,8 +25,6 @@
 }
 
-pmConceptSpec *pmConceptSpecAlloc(psMetadataItem *blank, // Blank value; contains the name
-                                  pmConceptParseFunc parse, // Function to call to parse the concept
-                                  pmConceptFormatFunc format // Function to call to format the concept
-                                 )
+pmConceptSpec *pmConceptSpecAlloc(psMetadataItem *blank, pmConceptParseFunc parse,
+                                  pmConceptFormatFunc format)
 {
     pmConceptSpec *spec = psAlloc(sizeof(pmConceptSpec));
@@ -41,9 +39,6 @@
 
 
-bool pmConceptRegister(psMetadataItem *blank, // Blank value; contains the name
-                       pmConceptParseFunc parse, // Function to call to parse the concept
-                       pmConceptFormatFunc format, // Function to call to format the concept
-                       pmFPALevel level // Level at which to store concept in the FPA hierarchy
-                      )
+bool pmConceptRegister(psMetadataItem *blank, pmConceptParseFunc parse,
+                       pmConceptFormatFunc format, pmFPALevel level)
 {
     PS_ASSERT_PTR_NON_NULL(blank, false);
@@ -185,10 +180,10 @@
 // Write all registered concepts for the specified level
 static bool conceptsWrite(psMetadata **specs, // One of the concepts specifications
-                          pmFPA *fpa,   // The FPA
-                          pmChip *chip, // The chip
-                          pmCell *cell, // The cell
+                          const pmFPA *fpa,   // The FPA
+                          const pmChip *chip, // The chip
+                          const pmCell *cell, // The cell
                           pmConceptSource source, // The source of the concepts to write
                           psDB *db,      // Database handle
-                          psMetadata *concepts // The concepts to write out
+                          const psMetadata *concepts // The concepts to write out
                          )
 {
@@ -218,20 +213,6 @@
 }
 
-// Set the concepts for a given FPA to blanks
-bool pmConceptsBlankFPA(pmFPA *fpa    // FPA for which to set blank concepts
-                       )
-{
-    PS_ASSERT_PTR_NON_NULL(fpa, false);
-    psTrace("psModules.concepts", 5, "Blanking FPA concepts: %p %p\n", conceptsFPA, fpa->concepts);
-    return conceptsBlank(&conceptsFPA, fpa->concepts);
-}
-
-// Read the concepts for the given set of fpa, chip, cell
-bool pmConceptsRead(pmFPA *fpa,         // FPA for which to read concepts
-                    pmChip *chip,       // Chip for which to read concepts, or NULL
-                    pmCell *cell,       // Cell for which to read concepts, or NULL
-                    pmConceptSource source, // The source of the concepts to read
-                    psDB *db            // Database handle
-                   )
+
+bool pmConceptsRead(pmFPA *fpa, pmChip *chip, pmCell *cell, pmConceptSource source, psDB *db)
 {
     PS_ASSERT_PTR_NON_NULL(fpa, false);
@@ -248,10 +229,13 @@
 
 
-// Read the concepts for a given FPA
-bool pmConceptsReadFPA(pmFPA *fpa,      // FPA for which to read concepts
-                       pmConceptSource source, // The source of the concepts to read
-                       bool propagateDown, // Propagate to lower levels?
-                       psDB *db        // Database handle
-                      )
+bool pmConceptsBlankFPA(pmFPA *fpa)
+{
+    PS_ASSERT_PTR_NON_NULL(fpa, false);
+    psTrace("psModules.concepts", 5, "Blanking FPA concepts: %p %p\n", conceptsFPA, fpa->concepts);
+    return conceptsBlank(&conceptsFPA, fpa->concepts);
+}
+
+
+bool pmConceptsReadFPA(pmFPA *fpa, pmConceptSource source, bool propagateDown, psDB *db)
 {
     PS_ASSERT_PTR_NON_NULL(fpa, false);
@@ -271,10 +255,5 @@
 }
 
-// Read the concepts for a given FPA
-bool pmConceptsWriteFPA(pmFPA *fpa,     // FPA for which to write concepts
-                        pmConceptSource source, // The source of the concepts to read
-                        bool propagateDown, // Propagate to lower levels?
-                        psDB *db        // Database handle
-                       )
+bool pmConceptsWriteFPA(const pmFPA *fpa, pmConceptSource source, bool propagateDown, psDB *db)
 {
     PS_ASSERT_PTR_NON_NULL(fpa, false);
@@ -293,7 +272,5 @@
 }
 
-// Set the concepts for a given chip to blanks
-bool pmConceptsBlankChip(pmChip *chip // FPA for which to set blank concepts
-                        )
+bool pmConceptsBlankChip(pmChip *chip)
 {
     PS_ASSERT_PTR_NON_NULL(chip, false);
@@ -302,11 +279,6 @@
 }
 
-// Read the concepts for a given FPA
-bool pmConceptsReadChip(pmChip *chip,   // Chip for which to read concepts
-                        pmConceptSource source, // The source of the concepts to read
-                        bool propagateUp, // Propagate to higher levels?
-                        bool propagateDown, // Propagate to lower levels?
-                        psDB *db        // Database handle
-                       )
+bool pmConceptsReadChip(pmChip *chip, pmConceptSource source, bool propagateUp,
+                        bool propagateDown, psDB *db)
 {
     PS_ASSERT_PTR_NON_NULL(chip, false);
@@ -330,11 +302,6 @@
 }
 
-// Read the concepts for a given FPA
-bool pmConceptsWriteChip(pmChip *chip,  // Chip for which to write concepts
-                         pmConceptSource source, // The source of the concepts to read
-                         bool propagateUp, // Propagate to higher levels?
-                         bool propagateDown, // Propagate to lower levels?
-                         psDB *db        // Database handle
-                        )
+bool pmConceptsWriteChip(const pmChip *chip, pmConceptSource source, bool propagateUp,
+                         bool propagateDown, psDB *db)
 {
     PS_ASSERT_PTR_NON_NULL(chip, false);
@@ -357,7 +324,5 @@
 }
 
-// Set the concepts for a given chip to blanks
-bool pmConceptsBlankCell(pmCell *cell // Cell for which to set blank concepts
-                        )
+bool pmConceptsBlankCell(pmCell *cell)
 {
     PS_ASSERT_PTR_NON_NULL(cell, false);
@@ -366,10 +331,5 @@
 }
 
-// Read the concepts for a given FPA
-bool pmConceptsReadCell(pmCell *cell,   // Cell for which to read concepts
-                        pmConceptSource source, // The source of the concepts to read
-                        bool propagateUp, // Propagate to higher levels?
-                        psDB *db        // Database handle
-                       )
+bool pmConceptsReadCell(pmCell *cell, pmConceptSource source, bool propagateUp, psDB *db)
 {
     PS_ASSERT_PTR_NON_NULL(cell, false);
@@ -394,10 +354,5 @@
 }
 
-// Read the concepts for a given FPA
-bool pmConceptsWriteCell(pmCell *cell,  // FPA for which to write concepts
-                         pmConceptSource source, // The source of the concepts to read
-                         bool propagateUp, // Propagate to higher levels?
-                         psDB *db       // Database handle
-                        )
+bool pmConceptsWriteCell(const pmCell *cell, pmConceptSource source, bool propagateUp, psDB *db)
 {
     PS_ASSERT_PTR_NON_NULL(cell, false);
@@ -423,4 +378,6 @@
 {
     conceptsInitialised = true;
+
+    p_psMemAllocatePersistent(true);
 
     bool init = false;                  // Did we initialise anything?
@@ -761,4 +718,6 @@
     }
 
+    p_psMemAllocatePersistent(false);
+
     return init;
 }
@@ -777,8 +736,5 @@
 
 
-// Copy concepts from one FPA to another
-bool pmFPACopyConcepts(pmFPA *target,   // The target FPA
-                       pmFPA *source    // The target FPA
-                      )
+bool pmFPACopyConcepts(pmFPA *target, const pmFPA *source)
 {
     PS_ASSERT_PTR_NON_NULL(target, false);
Index: /trunk/psModules/src/concepts/pmConcepts.h
===================================================================
--- /trunk/psModules/src/concepts/pmConcepts.h	(revision 9571)
+++ /trunk/psModules/src/concepts/pmConcepts.h	(revision 9572)
@@ -2,101 +2,174 @@
 #define PM_CONCEPTS_H
 
-#include "pslib.h"
+#include <pslib.h>
 #include "pmFPA.h"
 
-// Function to call to parse a concept once it has been read
-typedef psMetadataItem* (*pmConceptParseFunc)(const psMetadataItem *concept, const psMetadataItem *pattern, const psMetadata *cameraFormat, const pmFPA *fpa, const pmChip *chip, const pmCell *cell);
-// Function to call to format a concept for writing
-typedef psMetadataItem* (*pmConceptFormatFunc)(const psMetadataItem *concept, const psMetadata *cameraFormat, const pmFPA *fpa, const pmChip *chip, const pmCell *cell);
+/// Function to call to parse a concept once it has been read
+typedef psMetadataItem* (*pmConceptParseFunc)(const psMetadataItem *concept, ///< Concept to parse
+        const psMetadataItem *pattern, ///< Pattern for parsing
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                             );
 
-// A "concept" specification
+/// Function to call to format a concept for writing
+typedef psMetadataItem* (*pmConceptFormatFunc)(const psMetadataItem *concept, ///< Concept to format
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                              );
+
+
+/// A "concept" specification
+///
+/// Defines the name, default comment, blank value, and functions to parse (after reading) and format (before
+/// writing) the concept.
 typedef struct
 {
-    psMetadataItem *blank;              // Blank value of concept; also contains the name
-    pmConceptParseFunc parse;           // Function to call to read the concept
-    pmConceptFormatFunc format;         // Function to call to write the concept
+    psMetadataItem *blank;              ///< Blank value of concept; also contains the name and comment
+    pmConceptParseFunc parse;           ///< Function to call to read the concept
+    pmConceptFormatFunc format;         ///< Function to call to write the concept
 }
 pmConceptSpec;
 
-// Allocator
-pmConceptSpec *pmConceptSpecAlloc(psMetadataItem *blank, // Blank value; contains the name
-                                  pmConceptParseFunc parse, // Function to call to parse the concept
-                                  pmConceptFormatFunc format // Function to call to format the concept
+/// Allocator for pmConceptSpec
+pmConceptSpec *pmConceptSpecAlloc(psMetadataItem *blank, ///< Blank value; contains the name
+                                  pmConceptParseFunc parse, ///< Function to call to parse the concept
+                                  pmConceptFormatFunc format ///< Function to call to format the concept
                                  );
 
-// Register a new concept
-bool pmConceptRegister(psMetadataItem *blank, // Blank value; contains the name
-                       pmConceptParseFunc parse, // Function to call to parse the concept
-                       pmConceptFormatFunc format, // Function to call to format the concept
-                       pmFPALevel level // Level at which to store concept in the FPA hierarchy
+/// Register a new concept for parsing and formatting
+///
+/// Defines a new concept, based on the blank value (with name and default comment), and functions to parse
+/// and format the concept.  The new concept is registered at the specified level (FPA, chip or cell).
+bool pmConceptRegister(psMetadataItem *blank, ///< Blank value; contains the name and default comment
+                       pmConceptParseFunc parse, ///< Function to call to parse the concept
+                       pmConceptFormatFunc format, ///< Function to call to format the concept
+                       pmFPALevel level ///< Level at which to store concept in the FPA hierarchy
                       );
 
-// Some specificity to reading and writing concepts
+/// Source for concepts when reading and writing.
+///
+/// Since some sources become available at different times from others, we need to provide some specificity to
+/// reading and writing concepts (or we're forced to wait until everything's available, which we don't want to
+/// do).  Concepts may be read from or written to multiple sources at once by OR-ing them.
 typedef enum {
-    PM_CONCEPT_SOURCE_NONE     = 0x00,  // No concepts
-    PM_CONCEPT_SOURCE_CELLS    = 0x01,  // Concept comes from the camera information
-    PM_CONCEPT_SOURCE_DEFAULTS = 0x02,  // Concept comes from defaults
-    PM_CONCEPT_SOURCE_PHU      = 0x04,  // Concept comes from PHU
-    PM_CONCEPT_SOURCE_HEADER   = 0x08,  // Concept comes from FITS header
-    PM_CONCEPT_SOURCE_DATABASE = 0x10,  // Concept comes from database
-    PM_CONCEPT_SOURCE_ALL      = 0xff   // All concepts
+    PM_CONCEPT_SOURCE_NONE     = 0x00,  ///< No concepts
+    PM_CONCEPT_SOURCE_CELLS    = 0x01,  ///< Concept comes from the camera information
+    PM_CONCEPT_SOURCE_DEFAULTS = 0x02,  ///< Concept comes from defaults
+    PM_CONCEPT_SOURCE_PHU      = 0x04,  ///< Concept comes from PHU
+    PM_CONCEPT_SOURCE_HEADER   = 0x08,  ///< Concept comes from FITS header
+    PM_CONCEPT_SOURCE_DATABASE = 0x10,  ///< Concept comes from database
+    PM_CONCEPT_SOURCE_ALL      = 0xff   ///< All concepts
 } pmConceptSource;
 
-// Read the concepts for the given set of fpa, chip, cell
-bool pmConceptsRead(pmFPA *fpa,         // FPA for which to read concepts
-                    pmChip *chip,       // Chip for which to read concepts, or NULL
-                    pmCell *cell,       // Cell for which to read concepts, or NULL
-                    pmConceptSource source, // The source of the concepts to read
-                    psDB *db            // Database handle
+/// Read the concepts for the given set of fpa, chip, cell
+///
+/// Attempts to read as many concepts as possible from the specified source for the specified FPA, chip and
+/// cell.  That is, it will read chip- and cell-level concepts in addition to fpa-level concepts, if the chip
+/// and cell are provided.
+bool pmConceptsRead(pmFPA *fpa,         ///< FPA for which to read concepts
+                    pmChip *chip,       ///< Chip for which to read concepts, or NULL
+                    pmCell *cell,       ///< Cell for which to read concepts, or NULL
+                    pmConceptSource source, ///< The source of the concepts to read
+                    psDB *db            ///< Database handle
                    );
 
-// Set blanks, read or write concepts at the appropriate level
-bool pmConceptsBlankFPA(pmFPA *fpa      // FPA for which to set blank concepts
+/// Set the concepts within the FPA to the blank value
+bool pmConceptsBlankFPA(pmFPA *fpa      ///< FPA for which to set blank concepts
                        );
-bool pmConceptsReadFPA(pmFPA *fpa,      // FPA for which to read concepts
-                       pmConceptSource source, // Source for concepts
-                       bool propagateDown, // Propagate to lower levels?
-                       psDB *db         // Database handle
+
+/// Read concepts for an FPA; optionally, read concepts at all lower levels.
+///
+/// Once concepts should be available for reading at the FPA-level, this function attempts to read the
+/// concepts from the specified source.  It also allows concepts to be read at lower levels by iterating over
+/// the components.
+bool pmConceptsReadFPA(pmFPA *fpa,      ///< FPA for which to read concepts
+                       pmConceptSource source, ///< Source for concepts
+                       bool propagateDown, ///< Propagate to lower levels?
+                       psDB *db         ///< Database handle
                       );
-bool pmConceptsWriteFPA(pmFPA *fpa,     // FPA for which to write concepts
-                        pmConceptSource source, // Source for concepts
-                        bool propagateDown, // Propagate to lower levels?
-                        psDB *db        // Database handle
+
+/// Write concepts for an FPA; optionally, write concepts at all lower levels.
+///
+/// This function writes all concepts for the FPA to the specified "source".  It also allows concepts to be
+/// written for all lower levels by iterating over the components.
+bool pmConceptsWriteFPA(const pmFPA *fpa,     ///< FPA for which to write concepts
+                        pmConceptSource source, ///< Source for concepts
+                        bool propagateDown, ///< Propagate to lower levels?
+                        psDB *db        ///< Database handle
                        );
-bool pmConceptsBlankChip(pmChip *chip   // FPA for which to set blank concepts
-                        );
-bool pmConceptsReadChip(pmChip *chip,   // Chip for which to read concepts
-                        pmConceptSource source, // Source for concepts
-                        bool propagateUp, // Propagate to higher levels?
-                        bool propagateDown, // Propagate to lower levels?
-                        psDB *db        // Database handle
-                       );
-bool pmConceptsWriteChip(pmChip *chip,  // Chip for which to write concepts
-                         pmConceptSource source, // Source for concepts
-                         bool propagateUp,// Propagate to higher levels?
-                         bool propagateDown, // Propagate to lower levels?
-                         psDB *db       // Database handle
-                        );
-bool pmConceptsBlankCell(pmCell *cell   // Cell for which to set blank concepts
-                        );
-bool pmConceptsReadCell(pmCell *cell,   // Cell for which to read concepts
-                        pmConceptSource source, // Source for concepts
-                        bool propagateUp, // Propagate to higher levels?
-                        psDB *db        // Database handle
-                       );
-bool pmConceptsWriteCell(pmCell *cell,  // FPA for which to write concepts
-                         pmConceptSource source, // Source for concepts
-                         bool propagateUp, // Propagate to higher levels?
-                         psDB *db       // Database handle
+
+/// Set the concepts within the chip to the blank value
+bool pmConceptsBlankChip(pmChip *chip   ///< FPA for which to set blank concepts
                         );
 
-// Set up the blank concepts
+/// Read concepts for a chip; optionally, read concepts at the FPA and cell levels.
+///
+/// Once concepts should be available for reading at the FPA-level, this function attempts to read the
+/// concepts from the specified source.  It also allows concepts to be read at the fpa level (through the
+/// parent), and the cell level by iterating over the components.
+bool pmConceptsReadChip(pmChip *chip,   ///< Chip for which to read concepts
+                        pmConceptSource source, ///< Source for concepts
+                        bool propagateUp, ///< Propagate to higher levels?
+                        bool propagateDown, ///< Propagate to lower levels?
+                        psDB *db        ///< Database handle
+                       );
+
+/// Write concepts for a chip; optionally, write concepts at the FPA and cell levels.
+///
+/// This function writes all concepts for the chip to the specified "source".  It also allows concepts to be
+/// written for the FPA, and the cell level by iterating over the components.
+bool pmConceptsWriteChip(const pmChip *chip,  ///< Chip for which to write concepts
+                         pmConceptSource source, ///< Source for concepts
+                         bool propagateUp,///< Propagate to higher levels?
+                         bool propagateDown, ///< Propagate to lower levels?
+                         psDB *db       ///< Database handle
+                        );
+
+/// Set the concepts within the cell to the blank value
+bool pmConceptsBlankCell(pmCell *cell   ///< Cell for which to set blank concepts
+                        );
+
+/// Read concepts for a cell; optionally, read concepts for the parents.
+///
+/// Once concepts should be available for reading at the FPA-level, this function attempts to read the
+/// concepts from the specified source.  It also allows concepts to be read at upper levels through the
+/// parents (note, it would not read concepts for all chips, but only the parent of this cell).
+bool pmConceptsReadCell(pmCell *cell,   ///< Cell for which to read concepts
+                        pmConceptSource source, ///< Source for concepts
+                        bool propagateUp, ///< Propagate to higher levels?
+                        psDB *db        ///< Database handle
+                       );
+
+/// Write concepts for a cell; optionally, write concepts for the parents.
+///
+/// This function writes all concepts for the chip to the specified "source".  It also allows concepts to be
+/// written for the upper levels through the parents (note, it would not write concepts for all chips, but
+/// only the parent of this cell).
+bool pmConceptsWriteCell(const pmCell *cell,  ///< FPA for which to write concepts
+                         pmConceptSource source, ///< Source for concepts
+                         bool propagateUp, ///< Propagate to higher levels?
+                         psDB *db       ///< Database handle
+                        );
+
+/// Initialise the concepts system.
+///
+/// Register the standard concepts, so that concepts may be read and written.  This function is called
+/// automatically the first time the concepts functions are used.
 bool pmConceptsInit(void);
-// Free the concept specs so there's no memory leak
+
+/// Signifies that the user is done with the concepts system.
+///
+/// Frees the registered concepts so there is no memory leak when the user checks "persistent" memory.
 void pmConceptsDone(void);
 
-// Copy all the concepts within an FPA to another FPA
-bool pmFPACopyConcepts(pmFPA *target,   // The target FPA
-                       pmFPA *source    // The target FPA
+/// Copy all the concepts within an FPA to another FPA
+///
+/// Iterates over all components of the FPA, and copies the concepts metadata from the source to the target.
+bool pmFPACopyConcepts(pmFPA *target,   ///< The target FPA
+                       const pmFPA *source    ///< The source FPA
                       );
 
Index: /trunk/psModules/src/concepts/pmConceptsAverage.c
===================================================================
--- /trunk/psModules/src/concepts/pmConceptsAverage.c	(revision 9571)
+++ /trunk/psModules/src/concepts/pmConceptsAverage.c	(revision 9572)
@@ -21,9 +21,5 @@
 
 // Set a variety of concepts in a cell by averaging over several
-bool pmConceptsAverageCells(pmCell *target,// Target cell
-                            psList *sources, // List of source cells
-                            psRegion *trimsec, // The trim section
-                            psRegion *biassec // The bias section
-                           )
+bool pmConceptsAverageCells(pmCell *target, psList *sources, psRegion *trimsec, psRegion *biassec)
 {
     PS_ASSERT_PTR_NON_NULL(target, false);
Index: /trunk/psModules/src/concepts/pmConceptsAverage.h
===================================================================
--- /trunk/psModules/src/concepts/pmConceptsAverage.h	(revision 9571)
+++ /trunk/psModules/src/concepts/pmConceptsAverage.h	(revision 9572)
@@ -5,9 +5,24 @@
 #include "pmFPA.h"
 
-// Set a variety of concepts in a cell by averaging over several
-bool pmConceptsAverageCells(pmCell *target,// Target cell
-                            psList *sources, // List of source cells
-                            psRegion *trimsec, // The trim section
-                            psRegion *biassec // The bias section
+/// Set a variety of concepts in a cell by averaging over several
+///
+/// In some instances, we want to combine the values of a concept for several cells into a single concept for
+/// a single cell (e.g., when mosaicking multiple cells into a chip with one "cell").  This function averages
+/// the values of various concepts:
+/// - CELL.GAIN
+/// - CELL.READNOISE
+/// - CELL.EXPOSURE
+/// - CELL.DARKTIME
+/// - CELL.TIME
+/// For other concepts, it ensures the values are consistent:
+/// - CELL.READDIR
+/// - CELL.TIMESYS
+/// And for others, it takes the "worst" possible value:
+/// - CELL.SATURATION
+/// - CELL.BAD
+bool pmConceptsAverageCells(pmCell *target,///< Target cell
+                            psList *sources, ///< List of source cells
+                            psRegion *trimsec, ///< The new trim section
+                            psRegion *biassec ///< The new bias section
                            );
 
Index: /trunk/psModules/src/concepts/pmConceptsPhotcode.c
===================================================================
--- /trunk/psModules/src/concepts/pmConceptsPhotcode.c	(revision 9571)
+++ /trunk/psModules/src/concepts/pmConceptsPhotcode.c	(revision 9572)
@@ -4,26 +4,31 @@
 
 #include <stdio.h>
+#include <string.h>
 #include <pslib.h>
 
 #include "pmConceptsPhotcode.h"
 
-char *pmConceptsPhotcodeForView (pmConfig *config, pmFPAfile *file, pmFPAview *view)
+psString pmConceptsPhotcodeForView(pmConfig *config, pmFPAfile *file, pmFPAview *view)
 {
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+    PS_ASSERT_PTR_NON_NULL(file, NULL);
+    PS_ASSERT_PTR_NON_NULL(view, NULL);
 
     if (view->chip < -1) {
-        psError(PS_ERR_IO, true, "photcodes undefined for FPA: defined by chip\n");
+        psError(PS_ERR_IO, true, "Photcodes undefined for FPA: defined by chip\n");
         return NULL;
     }
 
     // select recipe options supplied on command line
-    psMetadata *recipe  = psMetadataLookupPtr (NULL, config->recipes, "PHASE2");
-    if (recipe == NULL) {
-        psError(PS_ERR_IO, true, "recipe PHASE2 not found\n");
+    bool mdok;                          // Status of MD lookup
+    psMetadata *recipe  = psMetadataLookupPtr(&mdok, config->recipes, "PHASE2");
+    if (!mdok || !recipe) {
+        psError(PS_ERR_IO, true, "Recipe PHASE2 not found\n");
         return NULL;
     }
 
     // select photcode rule from recipe
-    char *rule = psMetadataLookupStr (NULL, recipe, "PHOTCODE.RULE");
-    if (rule == NULL) {
+    char *rule = psMetadataLookupStr(&mdok, recipe, "PHOTCODE.RULE");
+    if (!mdok || !rule || strlen(rule) == 0) {
         psError(PS_ERR_IO, true, "PHOTCODE.RULE not found in PHASE2 recipe\n");
         return NULL;
@@ -31,5 +36,5 @@
 
     // convert rule to real photcode
-    char *photcode = pmFPAfileNameFromRule (rule, file, view);
+    psString photcode = pmFPAfileNameFromRule(rule, file, view);
 
     return photcode;
Index: /trunk/psModules/src/concepts/pmConceptsPhotcode.h
===================================================================
--- /trunk/psModules/src/concepts/pmConceptsPhotcode.h	(revision 9571)
+++ /trunk/psModules/src/concepts/pmConceptsPhotcode.h	(revision 9572)
@@ -2,10 +2,15 @@
 #define PM_CONCEPTS_PHOTCODE_H
 
-#include "pslib.h"
+#include <pslib.h>
 #include "pmConfig.h"
 #include "pmFPAview.h"
 #include "pmFPAfile.h"
 
-char *pmConceptsPhotcodeForView (pmConfig *config, pmFPAfile *file, pmFPAview *view);
+/// Return the photcode based on the PHOTCODE.RULE in the PHASE2 recipe
+///
+/// A photometry code ("photcode") is a string that represents the combination of filter and detector (chip).
+/// This functions generates a photcode for a particular chip within the FPA, based on the PHOTCODE.RULE in
+/// the PHASE2 recipe.  Interpolation using the usual syntax (e.g., "{CHIP.NAME}") is permitted.
+psString pmConceptsPhotcodeForView(pmConfig *config, pmFPAfile *file, pmFPAview *view);
 
 # endif
Index: /trunk/psModules/src/concepts/pmConceptsStandard.c
===================================================================
--- /trunk/psModules/src/concepts/pmConceptsStandard.c	(revision 9571)
+++ /trunk/psModules/src/concepts/pmConceptsStandard.c	(revision 9572)
@@ -30,5 +30,5 @@
 
 
-static double defaultCoordScaling(psMetadataItem *pattern)
+static double defaultCoordScaling(const psMetadataItem *pattern)
 {
     if (strcmp(pattern->name, "FPA.RA") == 0) {
@@ -46,10 +46,10 @@
 
 // FPA.RA and FPA.DEC
-psMetadataItem *p_pmConceptParse_FPA_Coords(psMetadataItem *concept,
-        psMetadataItem *pattern,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell)
+psMetadataItem *p_pmConceptParse_FPA_Coords(const psMetadataItem *concept,
+        const psMetadataItem *pattern,
+        const psMetadata *cameraFormat,
+        const pmFPA *fpa,
+        const pmChip *chip,
+        const pmCell *cell)
 {
     assert(concept);
@@ -115,9 +115,9 @@
 
 // FPA.RA and FPA.DEC
-psMetadataItem *p_pmConceptFormat_FPA_Coords(psMetadataItem *concept,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell)
+psMetadataItem *p_pmConceptFormat_FPA_Coords(const psMetadataItem *concept,
+        const psMetadata *cameraFormat,
+        const pmFPA *fpa,
+        const pmChip *chip,
+        const pmCell *cell)
 {
     assert(concept);
@@ -165,10 +165,10 @@
 
 
-psMetadataItem *p_pmConceptParse_CELL_TRIMSEC(psMetadataItem *concept,
-        psMetadataItem *pattern,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell)
+psMetadataItem *p_pmConceptParse_CELL_TRIMSEC(const psMetadataItem *concept,
+        const psMetadataItem *pattern,
+        const psMetadata *cameraFormat,
+        const pmFPA *fpa,
+        const pmChip *chip,
+        const pmCell *cell)
 {
     assert(concept);
@@ -189,10 +189,10 @@
 }
 
-psMetadataItem *p_pmConceptParse_CELL_BIASSEC(psMetadataItem *concept,
-        psMetadataItem *pattern,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell)
+psMetadataItem *p_pmConceptParse_CELL_BIASSEC(const psMetadataItem *concept,
+        const psMetadataItem *pattern,
+        const psMetadata *cameraFormat,
+        const pmFPA *fpa,
+        const pmChip *chip,
+        const pmCell *cell)
 {
     assert(concept);
@@ -245,10 +245,10 @@
 
 // CELL.XBIN and CELL.YBIN
-psMetadataItem *p_pmConceptParse_CELL_Binning(psMetadataItem *concept,
-        psMetadataItem *pattern,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell)
+psMetadataItem *p_pmConceptParse_CELL_Binning(const psMetadataItem *concept,
+        const psMetadataItem *pattern,
+        const psMetadata *cameraFormat,
+        const pmFPA *fpa,
+        const pmChip *chip,
+        const pmCell *cell)
 {
     assert(concept);
@@ -282,10 +282,10 @@
 
 
-psMetadataItem *p_pmConceptParse_TIMESYS(psMetadataItem *concept,
-        psMetadataItem *pattern,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell)
+psMetadataItem *p_pmConceptParse_TIMESYS(const psMetadataItem *concept,
+        const psMetadataItem *pattern,
+        const psMetadata *cameraFormat,
+        const pmFPA *fpa,
+        const pmChip *chip,
+        const pmCell *cell)
 {
     assert(concept);
@@ -311,10 +311,10 @@
 }
 
-psMetadataItem *p_pmConceptParse_TIME(psMetadataItem *concept,
-                                      psMetadataItem *pattern,
-                                      psMetadata *cameraFormat,
-                                      pmFPA *fpa,
-                                      pmChip *chip,
-                                      pmCell *cell)
+psMetadataItem *p_pmConceptParse_TIME(const psMetadataItem *concept,
+                                      const psMetadataItem *pattern,
+                                      const psMetadata *cameraFormat,
+                                      const pmFPA *fpa,
+                                      const pmChip *chip,
+                                      const pmCell *cell)
 {
     assert(concept);
@@ -523,5 +523,5 @@
 
 // Correct a position --- in case the user wants FORTRAN indexing (like the FITS standard...)
-static int fortranCorr(psMetadata *cameraFormat, // The camera format description
+static int fortranCorr(const psMetadata *cameraFormat, // The camera format description
                        const char *name // Name of concept to check for FORTRAN indexing
                       )
@@ -538,10 +538,10 @@
 }
 
-psMetadataItem *p_pmConceptParse_Positions(psMetadataItem *concept,
-        psMetadataItem *pattern,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell)
+psMetadataItem *p_pmConceptParse_Positions(const psMetadataItem *concept,
+        const psMetadataItem *pattern,
+        const psMetadata *cameraFormat,
+        const pmFPA *fpa,
+        const pmChip *chip,
+        const pmCell *cell)
 {
     assert(concept);
@@ -572,9 +572,9 @@
 
 
-psMetadataItem *p_pmConceptFormat_CELL_TRIMSEC(psMetadataItem *concept,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell)
+psMetadataItem *p_pmConceptFormat_CELL_TRIMSEC(const psMetadataItem *concept,
+        const psMetadata *cameraFormat,
+        const pmFPA *fpa,
+        const pmChip *chip,
+        const pmCell *cell)
 {
     assert(concept);
@@ -588,9 +588,9 @@
 }
 
-psMetadataItem *p_pmConceptFormat_CELL_BIASSEC(psMetadataItem *concept,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell)
+psMetadataItem *p_pmConceptFormat_CELL_BIASSEC(const psMetadataItem *concept,
+        const psMetadata *cameraFormat,
+        const pmFPA *fpa,
+        const pmChip *chip,
+        const pmCell *cell)
 {
     // Return a metadata item containing a list of metadata items of region strings
@@ -614,9 +614,9 @@
 // This function actually does both CELL.XBIN and CELL.YBIN if CELL.XBIN and CELL.YBIN are specified by the
 // same header.
-psMetadataItem *p_pmConceptFormat_CELL_XBIN(psMetadataItem *concept,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell)
+psMetadataItem *p_pmConceptFormat_CELL_XBIN(const psMetadataItem *concept,
+        const psMetadata *cameraFormat,
+        const pmFPA *fpa,
+        const pmChip *chip,
+        const pmCell *cell)
 {
     assert(concept);
@@ -637,13 +637,13 @@
 
     // Otherwise, there's no formatting required
-    return psMemIncrRefCounter(concept);
+    return psMetadataItemCopy(concept);
 }
 
 // Only need to format if both if CELL.XBIN and CELL.YBIN are not specified by the same header.
-psMetadataItem *p_pmConceptFormat_CELL_YBIN(psMetadataItem *concept,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell)
+psMetadataItem *p_pmConceptFormat_CELL_YBIN(const psMetadataItem *concept,
+        const psMetadata *cameraFormat,
+        const pmFPA *fpa,
+        const pmChip *chip,
+        const pmCell *cell)
 {
     assert(concept);
@@ -660,13 +660,13 @@
 
     // No formatting required
-    return psMemIncrRefCounter(concept);
-}
-
-
-psMetadataItem *p_pmConceptFormat_TIMESYS(psMetadataItem *concept,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell)
+    return psMetadataItemCopy(concept);
+}
+
+
+psMetadataItem *p_pmConceptFormat_TIMESYS(const psMetadataItem *concept,
+        const psMetadata *cameraFormat,
+        const pmFPA *fpa,
+        const pmChip *chip,
+        const pmCell *cell)
 {
     psString sys = NULL;            // String to store
@@ -693,9 +693,9 @@
 }
 
-psMetadataItem *p_pmConceptFormat_TIME(psMetadataItem *concept,
-                                       psMetadata *cameraFormat,
-                                       pmFPA *fpa,
-                                       pmChip *chip,
-                                       pmCell *cell)
+psMetadataItem *p_pmConceptFormat_TIME(const psMetadataItem *concept,
+                                       const psMetadata *cameraFormat,
+                                       const pmFPA *fpa,
+                                       const pmChip *chip,
+                                       const pmCell *cell)
 {
     psTime *time = concept->data.V;     // The time
@@ -808,9 +808,9 @@
 }
 
-psMetadataItem *p_pmConceptFormat_Positions(psMetadataItem *concept,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell)
+psMetadataItem *p_pmConceptFormat_Positions(const psMetadataItem *concept,
+        const psMetadata *cameraFormat,
+        const pmFPA *fpa,
+        const pmChip *chip,
+        const pmCell *cell)
 {
     assert(concept);
Index: /trunk/psModules/src/concepts/pmConceptsStandard.h
===================================================================
--- /trunk/psModules/src/concepts/pmConceptsStandard.h	(revision 9571)
+++ /trunk/psModules/src/concepts/pmConceptsStandard.h	(revision 9572)
@@ -2,91 +2,136 @@
 #define PM_CONCEPTS_STANDARD_H
 
-#include "pslib.h"
+#include <pslib.h>
 #include "pmFPA.h"
 
 // Functions to parse and format the standard concepts
 
-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_TIMESYS(psMetadataItem *concept,
-        psMetadataItem *pattern,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell);
-psMetadataItem *p_pmConceptParse_TIME(psMetadataItem *concept,
-                                      psMetadataItem *pattern,
-                                      psMetadata *cameraFormat,
-                                      pmFPA *fpa,
-                                      pmChip *chip,
-                                      pmCell *cell);
-psMetadataItem *p_pmConceptParse_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_TIMESYS(psMetadataItem *concept,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell);
-psMetadataItem *p_pmConceptFormat_TIME(psMetadataItem *concept,
-                                       psMetadata *cameraFormat,
-                                       pmFPA *fpa,
-                                       pmChip *chip,
-                                       pmCell *cell);
-psMetadataItem *p_pmConceptFormat_Positions(psMetadataItem *concept,
-        psMetadata *cameraFormat,
-        pmFPA *fpa,
-        pmChip *chip,
-        pmCell *cell);
+
+/// Parse the coordinates concepts: FPA.RA and FPA.DEC
+psMetadataItem *p_pmConceptParse_FPA_Coords(const psMetadataItem *concept, ///< Concept to parse
+        const psMetadataItem *pattern, ///< Pattern to use in parsing
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                           );
+
+/// Format the coordinates concepts: FPA.RA and FPA.DEC
+psMetadataItem *p_pmConceptFormat_FPA_Coords(const psMetadataItem *concept, ///< Concept to format
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                            );
+
+/// Parse the CELL.TRIMSEC concept
+psMetadataItem *p_pmConceptParse_CELL_TRIMSEC(const psMetadataItem *concept, ///< Concept to parse
+        const psMetadataItem *pattern, ///< Pattern to use in parsing
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                             );
+
+/// Parse the CELL.BIASSEC concept
+psMetadataItem *p_pmConceptParse_CELL_BIASSEC(const psMetadataItem *concept, ///< Concept to parse
+        const psMetadataItem *pattern, ///< Pattern to use in parsing
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                             );
+
+/// Parse the cell binning concepts: CELL.XBIN, CELL.YBIN
+psMetadataItem *p_pmConceptParse_CELL_Binning(const psMetadataItem *concept, ///< Concept to parse
+        const psMetadataItem *pattern, ///< Pattern to use in parsing
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                             );
+
+/// Parse the time system concepts: FPA.TIMESYS and CELL.TIMESYS
+psMetadataItem *p_pmConceptParse_TIMESYS(const psMetadataItem *concept, ///< Concept to parse
+        const psMetadataItem *pattern, ///< Pattern to use in parsing
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                        );
+
+/// Parse the time concepts: FPA.TIME and CELL.TIME
+psMetadataItem *p_pmConceptParse_TIME(const psMetadataItem *concept, ///< Concept to parse
+                                      const psMetadataItem *pattern, ///< Pattern to use in parsing
+                                      const psMetadata *cameraFormat, ///< Camera format definition
+                                      const pmFPA *fpa, ///< FPA for concept, or NULL
+                                      const pmChip *chip, ///< Chip for concept, or NULL
+                                      const pmCell *cell ///< Cell for concept, or NULL
+                                     );
+
+/// Parse a cell position concept, e.g., CELL.X0
+psMetadataItem *p_pmConceptParse_Positions(const psMetadataItem *concept, ///< Concept to parse
+        const psMetadataItem *pattern, ///< Pattern to use in parsing
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                          );
+
+/// Format the CELL.TRIMSEC concept
+psMetadataItem *p_pmConceptFormat_CELL_TRIMSEC(const psMetadataItem *concept, ///< Concept to format
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                              );
+
+/// Format the CELL.BIASSEC concept
+psMetadataItem *p_pmConceptFormat_CELL_BIASSEC(const psMetadataItem *concept, ///< Concept to format
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                              );
+
+/// Format the CELL.XBIN concept
+psMetadataItem *p_pmConceptFormat_CELL_XBIN(const psMetadataItem *concept, ///< Concept to format
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                           );
+
+/// Format the CELL.YBIN concept
+psMetadataItem *p_pmConceptFormat_CELL_YBIN(const psMetadataItem *concept, ///< Concept to format
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                           );
+
+/// Format the time system concepts: FPA.TIMESYS and CELL.TIMESYS
+psMetadataItem *p_pmConceptFormat_TIMESYS(const psMetadataItem *concept, ///< Concept to format
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                         );
+
+/// Format the time concepts: FPA.TIME and CELL.TIME
+psMetadataItem *p_pmConceptFormat_TIME(const psMetadataItem *concept, ///< Concept to format
+                                       const psMetadata *cameraFormat, ///< Camera format definition
+                                       const pmFPA *fpa, ///< FPA for concept, or NULL
+                                       const pmChip *chip, ///< Chip for concept, or NULL
+                                       const pmCell *cell ///< Cell for concept, or NULL
+                                      );
+
+/// Format a cell position concept, e.g., CELL.X0
+psMetadataItem *p_pmConceptFormat_Positions(const psMetadataItem *concept, ///< Concept to format
+        const psMetadata *cameraFormat, ///< Camera format definition
+        const pmFPA *fpa, ///< FPA for concept, or NULL
+        const pmChip *chip, ///< Chip for concept, or NULL
+        const pmCell *cell ///< Cell for concept, or NULL
+                                           );
 
 #endif
Index: /trunk/psModules/src/concepts/pmConceptsWrite.c
===================================================================
--- /trunk/psModules/src/concepts/pmConceptsWrite.c	(revision 9571)
+++ /trunk/psModules/src/concepts/pmConceptsWrite.c	(revision 9572)
@@ -18,6 +18,6 @@
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-static bool compareConcepts(psMetadataItem *compare, // Item to compare
-                            psMetadataItem *standard // Standard for comparison
+static bool compareConcepts(const psMetadataItem *compare, // Item to compare
+                            const psMetadataItem *standard // Standard for comparison
                            )
 {
@@ -105,10 +105,10 @@
 
 // Format a single concept
-static psMetadataItem *conceptFormat(pmConceptSpec *spec, // The concept specification
-                                     psMetadataItem *concept, // The concept to parse
-                                     psMetadata *cameraFormat, // The camera format
-                                     pmFPA *fpa, // The FPA
-                                     pmChip *chip, // The chip
-                                     pmCell *cell // The cell
+static psMetadataItem *conceptFormat(const pmConceptSpec *spec, // The concept specification
+                                     const psMetadataItem *concept, // The concept to parse
+                                     const psMetadata *cameraFormat, // The camera format
+                                     const pmFPA *fpa, // The FPA
+                                     const pmChip *chip, // The chip
+                                     const pmCell *cell // The cell
                                     )
 {
@@ -121,5 +121,5 @@
             formatted = spec->format(concept, cameraFormat, fpa, chip, cell);
         } else {
-            formatted = psMemIncrRefCounter(concept);
+            formatted = psMemIncrRefCounter((const psPtr)concept);
         }
 
@@ -132,5 +132,5 @@
 static bool writeSingleHeader(pmHDU *hdu, // HDU for which to add to the header
                               const char *keyword, // Keyword to add
-                              psMetadataItem *item // Item to add to the header; may be NULL
+                              const psMetadataItem *item // Item to add to the header; may be NULL
                              )
 {
@@ -182,5 +182,5 @@
 static bool writeHeader(pmHDU *hdu,     // HDU for which to add to the header
                         const char *keywords, // Keywords to add
-                        psMetadataItem *item // Item to add to the header
+                        const psMetadataItem *item // Item to add to the header
                        )
 {
@@ -220,8 +220,5 @@
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-bool p_pmConceptsWriteToCells(psMetadata *specs, // The concept specifications
-                              pmCell *cell,   // The cell
-                              psMetadata *concepts // The concepts
-                             )
+bool p_pmConceptsWriteToCells(const psMetadata *specs, const pmCell *cell, const psMetadata *concepts)
 {
     PS_ASSERT_PTR_NON_NULL(specs, false);
@@ -230,6 +227,7 @@
         return false;
     }
-    if (!cell->config)
-        return false;
+    if (!cell->config) {
+        return false;
+    }
 
     pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level
@@ -291,10 +289,6 @@
 }
 
-bool p_pmConceptsWriteToDefaults(psMetadata *specs, // The concept specifications
-                                 pmFPA *fpa, // The FPA
-                                 pmChip *chip, // The chip
-                                 pmCell *cell, // The cell
-                                 psMetadata *concepts // The concepts
-                                )
+bool p_pmConceptsWriteToDefaults(const psMetadata *specs, const pmFPA *fpa, const pmChip *chip,
+                                 const pmCell *cell, psMetadata *concepts)
 {
     PS_ASSERT_PTR_NON_NULL(specs, false);
@@ -357,10 +351,6 @@
 
 
-bool p_pmConceptsWriteToHeader(psMetadata *specs, // The concept specifications
-                               pmFPA *fpa, // The FPA
-                               pmChip *chip, // The chip
-                               pmCell *cell, // The cell
-                               psMetadata *concepts // The concepts
-                              )
+bool p_pmConceptsWriteToHeader(const psMetadata *specs, const pmFPA *fpa, const pmChip *chip,
+                               const pmCell *cell, const psMetadata *concepts)
 {
     PS_ASSERT_PTR_NON_NULL(specs, false);
@@ -405,11 +395,6 @@
 
 // XXX Warning: This code has not been tested at all
-bool p_pmConceptsWriteToDatabase(psMetadata *specs, // The concept specifications
-                                 pmFPA *fpa, // The FPA
-                                 pmChip *chip, // The chip
-                                 pmCell *cell, // The cell
-                                 psDB *db,// The database handle
-                                 psMetadata *concepts // The concepts
-                                )
+bool p_pmConceptsWriteToDatabase(const psMetadata *specs, const pmFPA *fpa, const pmChip *chip,
+                                 const pmCell *cell, psDB *db, const psMetadata *concepts)
 {
     PS_ASSERT_PTR_NON_NULL(specs, false);
Index: /trunk/psModules/src/concepts/pmConceptsWrite.h
===================================================================
--- /trunk/psModules/src/concepts/pmConceptsWrite.h	(revision 9571)
+++ /trunk/psModules/src/concepts/pmConceptsWrite.h	(revision 9572)
@@ -5,26 +5,46 @@
 #include "pmFPA.h"
 
-bool p_pmConceptsWriteToCells(psMetadata *specs, // The concept specifications
-                              pmCell *cell,   // The cell
-                              psMetadata *concepts // The concepts
+/// "Write" concepts to (actually, check against) the camera format file's CELLS.
+///
+/// Examines the CELLS metadata in the camera format file for the current type of cell, and checks that the
+/// concepts as defined there match the ones defined in the cell.  A warning is produced if the concepts do
+/// not match.
+bool p_pmConceptsWriteToCells(const psMetadata *specs, ///< The concept specifications
+                              const pmCell *cell, ///< The cell
+                              const psMetadata *concepts ///< The concepts
                              );
-bool p_pmConceptsWriteToDefaults(psMetadata *specs, // The concept specifications
-                                 pmFPA *fpa, // The FPA
-                                 pmChip *chip, // The chip
-                                 pmCell *cell, // The cell
-                                 psMetadata *concepts // The concepts
+
+/// "Write" concepts to (actually, check against) the camera format file's DEFAULTS.
+///
+/// Examines the DEFAULTS metadata in the camera format file, and checks that the concepts as defined there
+/// match the ones defined in the cell.  A warning is produced if the concepts do not match.
+bool p_pmConceptsWriteToDefaults(const psMetadata *specs, ///< The concept specifications
+                                 const pmFPA *fpa, ///< The FPA
+                                 const pmChip *chip, ///< The chip
+                                 const pmCell *cell, ///< The cell
+                                 const psMetadata *concepts ///< The concepts
                                 );
-bool p_pmConceptsWriteToHeader(psMetadata *specs, // The concept specifications
-                               pmFPA *fpa, // The FPA
-                               pmChip *chip, // The chip
-                               pmCell *cell, // The cell
-                               psMetadata *concepts // The concepts
+
+/// "Write" concepts to (actually, add to, pending a later write) the FITS header.
+///
+/// Examines the FITS header TRANSLATION metadata in the camera format file, and writes concepts to the
+/// appropriate FITS headers in the HDU, in preparation for a future write of the HDU.
+bool p_pmConceptsWriteToHeader(const psMetadata *specs, ///< The concept specifications
+                               const pmFPA *fpa, ///< The FPA
+                               const pmChip *chip, ///< The chip
+                               const pmCell *cell, ///< The cell
+                               const psMetadata *concepts ///< The concepts
                               );
-bool p_pmConceptsWriteToDatabase(psMetadata *specs, // The concept specifications
-                                 pmFPA *fpa, // The FPA
-                                 pmChip *chip, // The chip
-                                 pmCell *cell, // The cell
-                                 psDB *db,// The database handle
-                                 psMetadata *concepts // The concepts
+
+/// Write concepts to the database.
+///
+/// Examines the DATABASE metadata in the camera format file, and writes concepts to the database.
+/// Warning: This function has not been tested; use at your own risk.
+bool p_pmConceptsWriteToDatabase(const psMetadata *specs, ///< The concept specifications
+                                 const pmFPA *fpa, ///< The FPA
+                                 const pmChip *chip, ///< The chip
+                                 const pmCell *cell, ///< The cell
+                                 psDB *db,///< The database handle
+                                 const psMetadata *concepts ///< The concepts
                                 );
 
