Index: branches/tap_branches/ppSub/src/ppSub.c
===================================================================
--- branches/tap_branches/ppSub/src/ppSub.c	(revision 25900)
+++ branches/tap_branches/ppSub/src/ppSub.c	(revision 27838)
@@ -24,13 +24,14 @@
 int main(int argc, char *argv[])
 {
-    psExit exitValue = PS_EXIT_SUCCESS; // Exit value
+    psLibInit(NULL);
     psTimerStart("ppSub");
-    psLibInit(NULL);
+
+    pmErrorRegister();
+    ppSubErrorRegister();
+    psphotErrorRegister();
 
     ppSubData *data = NULL;             // Processing data
     pmConfig *config = pmConfigRead(&argc, argv, PPSUB_RECIPE); // Configuration
     if (!config) {
-        psErrorStackPrint(stderr, "Error reading configuration.");
-        exitValue = PS_EXIT_CONFIG_ERROR;
         goto die;
     }
@@ -39,6 +40,5 @@
 
     if (!pmModelClassInit()) {
-        psErrorStackPrint(stderr, "Error initialising model classes.\n");
-        exitValue = PS_EXIT_PROG_ERROR;
+        psError(PPSUB_ERR_PROG, false, "Unable to initialise model classes.");
         psFree(config);
         goto die;
@@ -46,6 +46,5 @@
 
     if (!psphotInit()) {
-        psErrorStackPrint(stderr, "Error initialising psphot.\n");
-        exitValue = PS_EXIT_PROG_ERROR;
+        psError(PPSUB_ERR_PROG, false, "Error initialising psphot.");
         psFree(config);
         goto die;
@@ -55,39 +54,63 @@
 
     if (!ppSubArguments(argc, argv, data)) {
-        psErrorStackPrint(stderr, "Error reading arguments.\n");
-        exitValue = PS_EXIT_CONFIG_ERROR;
+        psError(psErrorCodeLast(), false, "Error reading arguments.");
         goto die;
     }
 
     if (!ppSubCamera(data)) {
-        psErrorStackPrint(stderr, "Error setting up camera.\n");
-        exitValue = PS_EXIT_CONFIG_ERROR;
         goto die;
     }
 
     if (!ppSubLoop(data)) {
-        psErrorStackPrint(stderr, "Error performing subtraction.\n");
-        exitValue = PS_EXIT_SYS_ERROR;
         goto die;
     }
 
  die:
-    psTrace("ppSub", 1, "Finished at %f sec\n", psTimerMark("ppSub"));
-    psTimerStop();
+    {
+        psExit exitValue = ppSubExitCode(PS_EXIT_SUCCESS); // Exit code
 
-    psString dump_file = psMetadataLookupStr(NULL, data->config->arguments, "-dumpconfig");
-    if (dump_file) {
-        if (!pmConfigDump(data->config, dump_file)) {
-            psErrorStackPrint(stderr, "Unable to dump configuration.\n");
-            exitValue = PS_EXIT_SYS_ERROR;
+        if (data && data->stats && data->statsFile) {
+            psString stats = psMetadataConfigFormat(data->stats); // Statistics to output
+            if (!stats || strlen(stats) == 0) {
+                psError(PPSUB_ERR_IO, false, "Unable to format statistics file");
+            } else if (fprintf(data->statsFile, "%s", stats) != strlen(stats)) {
+                psError(PPSUB_ERR_IO, true, "Unable to write statistics file");
+            }
+            psFree(stats);
+            if (fclose(data->statsFile) == EOF) {
+                psError(PPSUB_ERR_IO, true, "Unable to close statistics file");
+            }
+            data->statsFile = NULL;
+            pmConfigRunFilenameAddWrite(data->config, "STATS", data->statsName);
+            exitValue = ppSubExitCode(exitValue);
         }
+
+        if (config && !ppSubFilesIterateUp(config, PPSUB_FILES_ALL)) {
+            psError(psErrorCodeLast(), false, "Unable to close files.");
+            exitValue = ppSubExitCode(exitValue);
+            pmFPAfileFreeSetStrict(false);
+        }
+
+        if (data) {
+            psString dump_file = psMetadataLookupStr(NULL, data->config->arguments, "-dumpconfig");
+            if (dump_file) {
+                if (!pmConfigDump(data->config, dump_file)) {
+                    psError(PPSUB_ERR_IO, false, "Unable to dump configuration.");
+                    exitValue = ppSubExitCode(exitValue);
+                }
+            }
+            psFree(data);
+        }
+
+        psTrace("ppSub", 1, "Finished at %f sec\n", psTimerMark("ppSub"));
+        psTimerStop();
+
+        pmVisualClose(); //close plot windows, if -visual is set
+        pmModelClassCleanup();
+        pmConfigDone();
+        psLibFinalize();
+
+        exitValue = ppSubExitCode(exitValue);
+        exit(exitValue);
     }
-    psFree(data);
-
-    pmVisualClose(); //close plot windows, if -visual is set
-    pmModelClassCleanup();
-    pmConfigDone();
-    psLibFinalize();
-
-    exit(exitValue);
 }
