Index: branches/eam_branches/20090522/ippTools/src/Makefile.am
===================================================================
--- branches/eam_branches/20090522/ippTools/src/Makefile.am	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/Makefile.am	(revision 24557)
@@ -20,5 +20,6 @@
 	stacktool \
 	warptool \
-	receivetool
+	receivetool \
+	pubtool
 
 
@@ -59,5 +60,6 @@
 	regtool.h \
 	stacktool.h \
-	warptool.h
+	warptool.h \
+	pubtool.h
 
 lib_LTLIBRARIES = libpxtools.la
@@ -220,4 +222,10 @@
     receivetoolConfig.c
 
+pubtool_CFLAGS = $(PSLIB_CFLAGS) $(PSMODULES_CFLAGS) $(IPPDB_CFLAGS)
+pubtool_LDADD = $(PSLIB_LIBS) $(PSMODULES_LIBS) $(IPPDB_LIBS) libpxtools.la
+pubtool_SOURCES = \
+    pubtool.c \
+    pubtoolConfig.c
+
 clean-local:
 	-rm -f TAGS
Index: branches/eam_branches/20090522/ippTools/src/chiptool.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/chiptool.c	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/chiptool.c	(revision 24557)
@@ -473,5 +473,5 @@
     PXOPT_LOOKUP_F32(n_cr, config->args,           "-n_cr", false, false);
     PXOPT_LOOKUP_STR(path_base, config->args,      "-path_base", false, false);
-    PXOPT_LOOKUP_BOOL(magicked, config->args,      "-magicked", false);
+    PXOPT_LOOKUP_S64(magicked, config->args,       "-magicked", false, false);
 
     // default values
@@ -601,5 +601,5 @@
     PXOPT_COPY_STR(config->args, where, "-reduction", "chipRun.reduction", "==");
     pxAddLabelSearchArgs (config, where, "-label", "chipRun.label", "LIKE");
-    PXOPT_COPY_S32(config->args, where, "-magicked", "chipRun.magicked", "==");
+    PXOPT_COPY_S64(config->args, where, "-magicked", "chipRun.magicked", "==");
 
     if (!psListLength(where->list) &&
Index: branches/eam_branches/20090522/ippTools/src/difftool.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/difftool.c	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/difftool.c	(revision 24557)
@@ -49,5 +49,5 @@
 static bool importrunMode(pxConfig *config);
 
-static bool setdiffRunState(pxConfig *config, psS64 diff_id, const char *state, bool magicked);
+static bool setdiffRunState(pxConfig *config, psS64 diff_id, const char *state, psS64 magicked);
 static bool diffRunComplete(pxConfig *config);
 
@@ -512,5 +512,5 @@
     PXOPT_LOOKUP_STR(hostname, config->args, "-hostname", false, false);
     PXOPT_LOOKUP_F32(good_frac, config->args, "-good_frac", false, false);
-    PXOPT_LOOKUP_BOOL(magicked, config->args, "-magicked", false);
+    PXOPT_LOOKUP_S64(magicked, config->args, "-magicked", false, false);
 
     if (!psDBTransaction(config->dbh)) {
@@ -739,5 +739,5 @@
 
 
-static bool setdiffRunState(pxConfig *config, psS64 diff_id, const char *state, bool magicked)
+static bool setdiffRunState(pxConfig *config, psS64 diff_id, const char *state, psS64 magicked)
 {
     PS_ASSERT_PTR_NON_NULL(state, false);
@@ -749,5 +749,5 @@
     }
 
-    char *query = "UPDATE diffRun SET state = '%s', magicked = %d WHERE diff_id = %"PRId64;
+    char *query = "UPDATE diffRun SET state = '%s', magicked = %" PRId64 " WHERE diff_id = %"PRId64;
 
     if (!p_psDBRunQueryF(config->dbh, query, state, magicked, diff_id)) {
@@ -803,5 +803,5 @@
             false,
             false,
-            false       // magicked
+            0       // magicked
     );
 
@@ -1190,5 +1190,5 @@
                 false,                  // bothways
                 true,                   // exposure
-                false       // magicked
+                0       // magicked
         );
 
@@ -1805,5 +1805,5 @@
 
         psS64 diff_id = psMetadataLookupS64(NULL, row, "diff_id");
-        bool magicked = psMetadataLookupBool(NULL, row, "magicked");
+        psS64 magicked = psMetadataLookupS64(NULL, row, "magicked");
 
         // set diffRun.state to 'stop'
Index: branches/eam_branches/20090522/ippTools/src/disttool.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/disttool.c	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/disttool.c	(revision 24557)
@@ -488,5 +488,9 @@
     PXOPT_COPY_STR(config->args, where, "-state", "state", "==");
     PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
-    PXOPT_COPY_S16(config->args, where, "-fault", "fault", "==");
+
+    // we need to disambiguate fault so make a copy of the where list before adding fault
+    psMetadata *whereComponent = psMetadataCopy(NULL, where);
+    PXOPT_COPY_S16(config->args, where,  "-fault", "distRun.fault", "==");
+    PXOPT_COPY_S16(config->args, whereComponent, "-fault", "distComponent.fault", "==");
 
     // It might be useful to be able to query by the parameters of the underlying runs
@@ -533,15 +537,4 @@
 
         numUpdated = psDBAffectedRows(config->dbh);
-
-#ifdef notdef
-        // don't need this. distRun.state may still be in 'new' state
-        if (numUpdated < 1) {
-            psError(PS_ERR_UNKNOWN, false, "should have affected at least 1 row");
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
-            return false;
-        }
-#endif
     }
 
@@ -560,6 +553,6 @@
         }
 
-        if (psListLength(where->list)) {
-            psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        if (psListLength(whereComponent->list)) {
+            psString whereClause = psDBGenerateWhereConditionSQL(whereComponent, NULL);
             psStringAppend(&query, " AND %s", whereClause);
             psFree(whereClause);
@@ -582,4 +575,5 @@
 
     psFree(where);
+    psFree(whereComponent);
 
     if (!psDBCommit(config->dbh)) {
@@ -598,5 +592,5 @@
     PXOPT_COPY_S64(config->args, where, "-dist_id", "dist_id", "==");
     PXOPT_COPY_STR(config->args, where, "-stage", "stage", "==");
-    PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
+    pxAddLabelSearchArgs (config, where, "-label", "label", "==");
 
     PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
@@ -719,5 +713,5 @@
     psMetadata *where = psMetadataAlloc();
     PXOPT_COPY_S64(config->args, where, "-dist_id", "dist_id", "==");
-    PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
+    pxAddLabelSearchArgs (config, where, "-label", "label", "==");
 
     PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
@@ -863,5 +857,5 @@
     psMetadata *where = psMetadataAlloc();
     PXOPT_COPY_S64(config->args, where, "-dist_id", "dist_id", "==");
-    PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
+    pxAddLabelSearchArgs (config, where, "-label", "label", "==");
 
     PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
Index: branches/eam_branches/20090522/ippTools/src/disttoolConfig.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/disttoolConfig.c	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/disttoolConfig.c	(revision 24557)
@@ -98,5 +98,5 @@
     psMetadataAddS64(pendingcomponentArgs, PS_LIST_TAIL, "-dist_id", 0, "define dist_id", 0);
     psMetadataAddStr(pendingcomponentArgs, PS_LIST_TAIL, "-stage",    0, "limit results to runs for stage", NULL);
-    psMetadataAddStr(pendingcomponentArgs, PS_LIST_TAIL, "-label",    0, "limit results to label", NULL);
+    psMetadataAddStr(pendingcomponentArgs, PS_LIST_TAIL, "-label",    PS_META_DUPLICATE_OK, "limit results to label", NULL);
     psMetadataAddU64(pendingcomponentArgs, PS_LIST_TAIL, "-limit",  0,  "limit result set to N items", 0);
     psMetadataAddBool(pendingcomponentArgs, PS_LIST_TAIL, "-simple", 0, "use the simple output format", false);
@@ -121,5 +121,5 @@
     psMetadata *toadvanceArgs = psMetadataAlloc();
     psMetadataAddS64(toadvanceArgs, PS_LIST_TAIL, "-dist_id", 0, "define dist_id", 0);
-    psMetadataAddStr(toadvanceArgs, PS_LIST_TAIL, "-label",   0, "limit updates to label", NULL);
+    psMetadataAddStr(toadvanceArgs, PS_LIST_TAIL, "-label",   PS_META_DUPLICATE_OK, "limit updates to label", NULL);
     psMetadataAddU64(toadvanceArgs, PS_LIST_TAIL, "-limit",   0,  "limit result set to N items", 0);
     psMetadataAddBool(toadvanceArgs, PS_LIST_TAIL, "-simple", 0, "use the simple output format", false);
@@ -128,5 +128,5 @@
     psMetadata *pendingfilesetArgs = psMetadataAlloc();
     psMetadataAddS64(pendingfilesetArgs, PS_LIST_TAIL, "-dist_id", 0, "define dist_id", 0);
-    psMetadataAddStr(pendingfilesetArgs, PS_LIST_TAIL, "-label",   0, "limit results to label", NULL);
+    psMetadataAddStr(pendingfilesetArgs, PS_LIST_TAIL, "-label",   PS_META_DUPLICATE_OK, "limit results to label", NULL);
     psMetadataAddStr(pendingfilesetArgs, PS_LIST_TAIL, "-stage",   0, "limit results to runs for stage", NULL);
     psMetadataAddU64(pendingfilesetArgs, PS_LIST_TAIL, "-limit",   0,  "limit result set to N items", 0);
@@ -145,5 +145,5 @@
     psMetadataAddU64(pendingdestArgs, PS_LIST_TAIL, "-limit",   0,  "limit result set to N items", 0);
     psMetadataAddBool(pendingdestArgs, PS_LIST_TAIL, "-simple", 0, "use the simple output format", false);
-    psMetadataAddStr(pendingdestArgs, PS_LIST_TAIL, "-label",   0, "limit results to label", NULL);
+    psMetadataAddStr(pendingdestArgs, PS_LIST_TAIL, "-label",   PS_META_DUPLICATE_OK, "limit results to label", NULL);
 
     // -revertfileset
Index: branches/eam_branches/20090522/ippTools/src/faketool.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/faketool.c	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/faketool.c	(revision 24557)
@@ -235,8 +235,8 @@
         bool status;
         char *end_stage = psMetadataLookupStr(&status, md, "end_stage");
-	if (end_stage && strcasecmp(end_stage, "warp")) continue;
+        if (end_stage && strcasecmp(end_stage, "warp")) continue;
 
         char *raw_tess_id   = psMetadataLookupStr(&status, md, "tess_id");
-	if (raw_tess_id || tess_id) continue;
+        if (raw_tess_id || tess_id) continue;
 
         char *label  = psMetadataLookupStr(&status, md, "label");
@@ -244,5 +244,5 @@
 
         if (!status) {
-	    psError(PS_ERR_UNKNOWN, false, "cannot queue analysis to WARP without a defined tess id: label: %s, exp_id %" PRId64, label, exp_id);
+            psError(PS_ERR_UNKNOWN, false, "cannot queue analysis to WARP without a defined tess id: label: %s, exp_id %" PRId64, label, exp_id);
             psFree(output);
             return false;
@@ -455,6 +455,6 @@
 
     if (where && psListLength(where->list)) {
-        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-        psStringAppend(&query, " WHERE %s", whereClause);
+        psString whereClause = psDBGenerateWhereConditionSQL(where, "fakeRun");
+        psStringAppend(&query, " AND %s", whereClause);
         psFree(whereClause);
     }
@@ -1157,10 +1157,11 @@
         // pxwarpQueueByFakeID() can only be run after fakeRun.state has been set to stop
         if (!pxwarpQueueByFakeID(config,
-                    fakeRun->fake_id,
-                    fakeRun->workdir,
-                    fakeRun->label,
-                    fakeRun->dvodb,
-                    fakeRun->tess_id,
-                    fakeRun->end_stage
+                                 fakeRun->fake_id,
+                                 fakeRun->workdir,
+                                 fakeRun->label,
+                                 fakeRun->dvodb,
+                                 fakeRun->tess_id,
+                                 fakeRun->reduction,
+                                 fakeRun->end_stage
         )) {
             psError(PS_ERR_UNKNOWN, false, "failed to queue warpRun");
Index: branches/eam_branches/20090522/ippTools/src/magicdstool.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/magicdstool.c	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/magicdstool.c	(revision 24557)
@@ -38,4 +38,6 @@
 static bool revertdestreakedfileMode(pxConfig *config);
 static bool getskycellsMode(pxConfig *config);
+static bool toremoveMode(pxConfig *config);
+static bool torestoreMode(pxConfig *config);
 
 static bool setmagicDSRunState(pxConfig *config, psS64 magic_id, const char *state);
@@ -68,4 +70,6 @@
         MODECASE(MAGICDSTOOL_MODE_REVERTDESTREAKEDFILE,revertdestreakedfileMode);
         MODECASE(MAGICDSTOOL_MODE_GETSKYCELLS,         getskycellsMode);
+        MODECASE(MAGICDSTOOL_MODE_TOREMOVE,            toremoveMode);
+        MODECASE(MAGICDSTOOL_MODE_TORESTORE,           torestoreMode);
         default:
             psAbort("invalid option (this should not happen)");
@@ -501,11 +505,11 @@
     // chose the appropriate query based on the stage
     if (!strcmp(stage, "raw")) {
-        query = "UPDATE rawImfile SET magicked = 1 where exp_id = %" PRId64 " AND class_id = '%s'";
+        query = "UPDATE rawImfile SET magicked = %" PRId64 " where exp_id = %" PRId64 " AND class_id = '%s'";
     } else if (!strcmp(stage, "chip")) {
-        query = "UPDATE chipProcessedImfile SET magicked = 1 where chip_id = %" PRId64 " AND class_id = '%s'";
+        query = "UPDATE chipProcessedImfile SET magicked = %" PRId64 " where chip_id = %" PRId64 " AND class_id = '%s'";
     } else if (!strcmp(stage, "warp")) {
-        query = "UPDATE warpSkyfile SET magicked = 1 where warp_id = %" PRId64 " AND skycell_id = '%s'";
+        query = "UPDATE warpSkyfile SET magicked = %" PRId64 " where warp_id = %" PRId64 " AND skycell_id = '%s'";
     } else if (!strcmp(stage, "diff")) {
-        query = "UPDATE diffSkyfile SET magicked = 1 where diff_id = %" PRId64 " AND skycell_id = '%s'";
+        query = "UPDATE diffSkyfile SET magicked = %" PRId64 " where diff_id = %" PRId64 " AND skycell_id = '%s'";
     } else {
         psError(PS_ERR_UNKNOWN, true, "unexpected value for stage: %s found", stage);
@@ -513,5 +517,5 @@
         return false;
     }
-    if (!p_psDBRunQueryF(config->dbh, query, stage_id, component)) {
+    if (!p_psDBRunQueryF(config->dbh, query, magic_ds_id, stage_id, component)) {
         psError(PS_ERR_UNKNOWN, false, "database error");
         return false;
@@ -563,11 +567,11 @@
     // chose the appropriate query based on the stage
     if (!strcmp(stage, "raw")) {
-        query = "UPDATE rawExp SET magicked = 1 where exp_id = %" PRId64;
+        query = "UPDATE rawExp SET magicked = %" PRId64 " where exp_id = %" PRId64;
     } else if (!strcmp(stage, "chip")) {
-        query = "UPDATE chipRun SET magicked = 1 where chip_id = %" PRId64;
+        query = "UPDATE chipRun SET magicked = %" PRId64 " where chip_id = %" PRId64;
     } else if (!strcmp(stage, "warp")) {
-        query = "UPDATE warpRun SET magicked = 1 where warp_id = %" PRId64;
+        query = "UPDATE warpRun SET magicked = %" PRId64 " where warp_id = %" PRId64;
     } else if (!strcmp(stage, "diff")) {
-        query = "UPDATE diffRun SET magicked = 1 where diff_id = %" PRId64;
+        query = "UPDATE diffRun SET magicked = %" PRId64 " where diff_id = %" PRId64;
     } else {
         psError(PS_ERR_UNKNOWN, true, "unexpected value for stage: %s found", stage);
@@ -575,5 +579,5 @@
         return false;
     }
-    if (!p_psDBRunQueryF(config->dbh, query, stage_id)) {
+    if (!p_psDBRunQueryF(config->dbh, query, magic_ds_id, stage_id)) {
         psError(PS_ERR_UNKNOWN, false, "database error");
         return false;
@@ -625,5 +629,5 @@
     }
 
-    if (!magicDSFileInsert(config->dbh, magic_ds_id, component, backup_path_base, recovery_path_base, fault)) {
+    if (!magicDSFileInsert(config->dbh, magic_ds_id, component, backup_path_base, recovery_path_base, fault, "full")) {
             // rollback
         if (!psDBRollback(config->dbh)) {
@@ -889,2 +893,148 @@
 }
 
+static bool toremoveMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-magic_ds_id", "magic_ds_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-magic_id", "magic_id", "==");
+    pxAddLabelSearchArgs (config, where, "-label", "label", "==");
+
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+
+    // look for "inputs" that need to processed
+    psString query = pxDataGet("magicdstool_toremove.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " WHERE %s", whereClause);
+        psFree(whereClause);
+    }
+    psFree(where);
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psErrorCode err = psErrorCodeLast();
+        switch (err) {
+            case PS_ERR_DB_CLIENT:
+                psError(PXTOOLS_ERR_SYS, false, "database error");
+            case PS_ERR_DB_SERVER:
+                psError(PXTOOLS_ERR_PROG, false, "database error");
+            default:
+                psError(PXTOOLS_ERR_PROG, false, "unknown error");
+        }
+
+        return false;
+    }
+    if (!psArrayLength(output)) {
+        psTrace("magicdstool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    if (psArrayLength(output)) {
+        // negative simple so the default is true
+        if (!ippdbPrintMetadatas(stdout, output, "toremove", !simple)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to print array");
+            psFree(output);
+            return false;
+        }
+    }
+
+    psFree(output);
+
+    return true;
+}
+static bool torestoreMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-magic_ds_id", "magic_ds_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-magic_id", "magic_id", "==");
+    pxAddLabelSearchArgs (config, where, "-label", "label", "==");
+
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+
+    // look for "inputs" that need to processed
+    psString query = pxDataGet("magicdstool_torestore.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " WHERE %s", whereClause);
+        psFree(whereClause);
+    }
+    psFree(where);
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psErrorCode err = psErrorCodeLast();
+        switch (err) {
+            case PS_ERR_DB_CLIENT:
+                psError(PXTOOLS_ERR_SYS, false, "database error");
+            case PS_ERR_DB_SERVER:
+                psError(PXTOOLS_ERR_PROG, false, "database error");
+            default:
+                psError(PXTOOLS_ERR_PROG, false, "unknown error");
+        }
+
+        return false;
+    }
+    if (!psArrayLength(output)) {
+        psTrace("magicdstool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    if (psArrayLength(output)) {
+        // negative simple so the default is true
+        if (!ippdbPrintMetadatas(stdout, output, "torestore", !simple)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to print array");
+            psFree(output);
+            return false;
+        }
+    }
+
+    psFree(output);
+
+    return true;
+}
Index: branches/eam_branches/20090522/ippTools/src/magicdstool.h
===================================================================
--- branches/eam_branches/20090522/ippTools/src/magicdstool.h	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/magicdstool.h	(revision 24557)
@@ -32,4 +32,6 @@
     MAGICDSTOOL_MODE_REVERTDESTREAKEDFILE,
     MAGICDSTOOL_MODE_GETSKYCELLS,
+    MAGICDSTOOL_MODE_TOREMOVE,
+    MAGICDSTOOL_MODE_TORESTORE,
 } MAGICDStoolMode;
 
Index: branches/eam_branches/20090522/ippTools/src/magicdstoolConfig.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/magicdstoolConfig.c	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/magicdstoolConfig.c	(revision 24557)
@@ -114,4 +114,20 @@
     psMetadataAddBool(getskycellsArgs, PS_LIST_TAIL, "-simple", 0, "use the simple output format", false);
 
+    // -toremove
+    psMetadata *toremoveArgs = psMetadataAlloc();
+    psMetadataAddS64(toremoveArgs, PS_LIST_TAIL, "-magic_ds_id", 0, "search by magic Destreak ID", 0);
+    psMetadataAddS64(toremoveArgs, PS_LIST_TAIL, "-magic_id", 0, "search by magic ID", 0);
+    psMetadataAddStr(toremoveArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK, "define label", NULL);
+    psMetadataAddU64(toremoveArgs, PS_LIST_TAIL, "-limit", 0, "limit result set to N items", 0);
+    psMetadataAddBool(toremoveArgs, PS_LIST_TAIL, "-simple", 0, "use the simple output format", false);
+
+    // -torestore
+    psMetadata *torestoreArgs = psMetadataAlloc();
+    psMetadataAddS64(torestoreArgs, PS_LIST_TAIL, "-magic_ds_id", 0, "search by magic Destreak ID", 0);
+    psMetadataAddS64(torestoreArgs, PS_LIST_TAIL, "-magic_id", 0, "search by magic ID", 0);
+    psMetadataAddStr(torestoreArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK, "define label", NULL);
+    psMetadataAddU64(torestoreArgs, PS_LIST_TAIL, "-limit", 0, "limit result set to N items", 0);
+    psMetadataAddBool(torestoreArgs, PS_LIST_TAIL, "-simple", 0, "use the simple output format", false);
+
     psFree(now);
 
@@ -133,4 +149,8 @@
     PXOPT_ADD_MODE("-getskycells", "get skycell files ",
                     MAGICDSTOOL_MODE_GETSKYCELLS, getskycellsArgs);
+    PXOPT_ADD_MODE("-toremove", "backup images pending removal",
+                    MAGICDSTOOL_MODE_TOREMOVE, toremoveArgs);
+    PXOPT_ADD_MODE("-torestore", "images pending restore of exicsed streak pixels",
+                    MAGICDSTOOL_MODE_TORESTORE, torestoreArgs);
 
     if (!pxGetOptions(stderr, argc, argv, config, modes, argSets)) {
Index: branches/eam_branches/20090522/ippTools/src/magictool.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/magictool.c	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/magictool.c	(revision 24557)
@@ -47,9 +47,4 @@
 static bool revertmaskMode(pxConfig *config);
 static bool maskMode(pxConfig *config);
-static bool diffskyfileMode(pxConfig *config);
-static bool warpskyfileMode(pxConfig *config);
-static bool chipprocessedimfileMode(pxConfig *config);
-static bool rawimfileMode(pxConfig *config);
-
 
 static bool setmagicRunState(pxConfig *config, psS64 magic_id, const char *state);
@@ -90,8 +85,4 @@
         MODECASE(MAGICTOOL_MODE_REVERTMASK,          revertmaskMode);
         MODECASE(MAGICTOOL_MODE_MASK,                maskMode);
-        MODECASE(MAGICTOOL_MODE_DIFFSKYFILE,         diffskyfileMode);
-        MODECASE(MAGICTOOL_MODE_WARPSKYFILE,         warpskyfileMode);
-        MODECASE(MAGICTOOL_MODE_CHIPPROCESSEDIMFILE, chipprocessedimfileMode);
-        MODECASE(MAGICTOOL_MODE_RAWIMFILE,           rawimfileMode);
         default:
             psAbort("invalid option (this should not happen)");
@@ -1306,266 +1297,4 @@
 }
 
-
-static bool diffskyfileMode(pxConfig *config)
-{
-    PS_ASSERT_PTR_NON_NULL(config, false);
-
-    psMetadata *where = psMetadataAlloc();
-    PXOPT_COPY_S64(config->args, where, "-magic_id", "magicRun.magic_id", "==");
-    PXOPT_COPY_STR(config->args, where, "-class_id", "warpSkyCellMap.class_id", "==");
-    PXOPT_COPY_STR(config->args, where, "-skycell_id", "warpSkyCellMap.skycell_id", "==");
-
-    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
-
-    psString query = pxDataGet("magictool_diffskyfile.sql");
-    if (!query) {
-        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
-        return false;
-    }
-
-    if (psListLength(where->list)) {
-        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-        psStringAppend(&query, " AND %s", whereClause);
-        psFree(whereClause);
-    }
-    psFree(where);
-
-    if (!p_psDBRunQuery(config->dbh, query)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        psFree(query);
-        return false;
-    }
-    psFree(query);
-
-    psArray *output = p_psDBFetchResult(config->dbh);
-    if (!output) {
-        psErrorCode err = psErrorCodeLast();
-        switch (err) {
-            case PS_ERR_DB_CLIENT:
-                psError(PXTOOLS_ERR_SYS, false, "database error");
-            case PS_ERR_DB_SERVER:
-                psError(PXTOOLS_ERR_PROG, false, "database error");
-            default:
-                psError(PXTOOLS_ERR_PROG, false, "unknown error");
-        }
-
-        return false;
-    }
-    if (!psArrayLength(output)) {
-        psTrace("magictool", PS_LOG_INFO, "no rows found");
-        psFree(output);
-        return true;
-    }
-
-    if (psArrayLength(output)) {
-        // negative simple so the default is true
-        if (!ippdbPrintMetadatas(stdout, output, "magicDiffSkyfile", !simple)) {
-            psError(PS_ERR_UNKNOWN, false, "failed to print array");
-            psFree(output);
-            return false;
-        }
-    }
-
-    psFree(output);
-
-    return true;
-}
-
-
-static bool warpskyfileMode(pxConfig *config)
-{
-    PS_ASSERT_PTR_NON_NULL(config, false);
-
-    psMetadata *where = psMetadataAlloc();
-    PXOPT_COPY_S64(config->args, where, "-magic_id", "magicRun.magic_id", "==");
-    PXOPT_COPY_STR(config->args, where, "-skycell_id", "warpSkyfile.skycell_id", "==");
-
-    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
-
-    psString query = pxDataGet("magictool_warpskyfile.sql");
-    if (!query) {
-        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
-        return false;
-    }
-
-    if (psListLength(where->list)) {
-        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-        psStringAppend(&query, " AND %s", whereClause);
-        psFree(whereClause);
-    }
-    psFree(where);
-
-    if (!p_psDBRunQuery(config->dbh, query)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        psFree(query);
-        return false;
-    }
-    psFree(query);
-
-    psArray *output = p_psDBFetchResult(config->dbh);
-    if (!output) {
-        psErrorCode err = psErrorCodeLast();
-        switch (err) {
-            case PS_ERR_DB_CLIENT:
-                psError(PXTOOLS_ERR_SYS, false, "database error");
-            case PS_ERR_DB_SERVER:
-                psError(PXTOOLS_ERR_PROG, false, "database error");
-            default:
-                psError(PXTOOLS_ERR_PROG, false, "unknown error");
-        }
-
-        return false;
-    }
-    if (!psArrayLength(output)) {
-        psTrace("magictool", PS_LOG_INFO, "no rows found");
-        psFree(output);
-        return true;
-    }
-
-    if (psArrayLength(output)) {
-        // negative simple so the default is true
-        if (!ippdbPrintMetadatas(stdout, output, "magicWarpSkyfile", !simple)) {
-            psError(PS_ERR_UNKNOWN, false, "failed to print array");
-            psFree(output);
-            return false;
-        }
-    }
-
-    psFree(output);
-
-    return true;
-}
-
-
-static bool chipprocessedimfileMode(pxConfig *config)
-{
-    PS_ASSERT_PTR_NON_NULL(config, false);
-
-    psMetadata *where = psMetadataAlloc();
-    PXOPT_COPY_S64(config->args, where, "-magic_id", "magicRun.magic_id", "==");
-    PXOPT_COPY_STR(config->args, where, "-class_id", "warpSkyCellMap.class_id", "==");
-
-    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
-
-    psString query = pxDataGet("magictool_chipprocessedimfile.sql");
-    if (!query) {
-        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
-        return false;
-    }
-
-    if (psListLength(where->list)) {
-        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-        psStringAppend(&query, " AND %s", whereClause);
-        psFree(whereClause);
-    }
-    psFree(where);
-
-    if (!p_psDBRunQuery(config->dbh, query)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        psFree(query);
-        return false;
-    }
-    psFree(query);
-
-    psArray *output = p_psDBFetchResult(config->dbh);
-    if (!output) {
-        psErrorCode err = psErrorCodeLast();
-        switch (err) {
-            case PS_ERR_DB_CLIENT:
-                psError(PXTOOLS_ERR_SYS, false, "database error");
-            case PS_ERR_DB_SERVER:
-                psError(PXTOOLS_ERR_PROG, false, "database error");
-            default:
-                psError(PXTOOLS_ERR_PROG, false, "unknown error");
-        }
-
-        return false;
-    }
-    if (!psArrayLength(output)) {
-        psTrace("magictool", PS_LOG_INFO, "no rows found");
-        psFree(output);
-        return true;
-    }
-
-    if (psArrayLength(output)) {
-        // negative simple so the default is true
-        if (!ippdbPrintMetadatas(stdout, output, "magicChipProcessedImfile", !simple)) {
-            psError(PS_ERR_UNKNOWN, false, "failed to print array");
-            psFree(output);
-            return false;
-        }
-    }
-
-    psFree(output);
-
-    return true;
-}
-
-
-static bool rawimfileMode(pxConfig *config)
-{
-    PS_ASSERT_PTR_NON_NULL(config, false);
-
-    psMetadata *where = psMetadataAlloc();
-    PXOPT_COPY_S64(config->args, where, "-magic_id", "magicRun.magic_id", "==");
-    PXOPT_COPY_STR(config->args, where, "-class_id", "warpSkyCellMap.class_id", "==");
-
-    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
-
-    psString query = pxDataGet("magictool_rawimfile.sql");
-    if (!query) {
-        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
-        return false;
-    }
-
-    if (psListLength(where->list)) {
-        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-        psStringAppend(&query, " AND %s", whereClause);
-        psFree(whereClause);
-    }
-    psFree(where);
-
-    if (!p_psDBRunQuery(config->dbh, query)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        psFree(query);
-        return false;
-    }
-    psFree(query);
-
-    psArray *output = p_psDBFetchResult(config->dbh);
-    if (!output) {
-        psErrorCode err = psErrorCodeLast();
-        switch (err) {
-            case PS_ERR_DB_CLIENT:
-                psError(PXTOOLS_ERR_SYS, false, "database error");
-            case PS_ERR_DB_SERVER:
-                psError(PXTOOLS_ERR_PROG, false, "database error");
-            default:
-                psError(PXTOOLS_ERR_PROG, false, "unknown error");
-        }
-
-        return false;
-    }
-    if (!psArrayLength(output)) {
-        psTrace("magictool", PS_LOG_INFO, "no rows found");
-        psFree(output);
-        return true;
-    }
-
-    if (psArrayLength(output)) {
-        // negative simple so the default is true
-        if (!ippdbPrintMetadatas(stdout, output, "magicRawImfile", !simple)) {
-            psError(PS_ERR_UNKNOWN, false, "failed to print array");
-            psFree(output);
-            return false;
-        }
-    }
-
-    psFree(output);
-
-    return true;
-}
-
-
 static bool setmagicRunState(pxConfig *config, psS64 magic_id, const char *state)
 {
Index: branches/eam_branches/20090522/ippTools/src/magictoolConfig.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/magictoolConfig.c	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/magictoolConfig.c	(revision 24557)
@@ -160,4 +160,5 @@
     psMetadataAddBool(maskArgs, PS_LIST_TAIL, "-simple", 0, "use the simple output format", false);
 
+#ifdef notdef
     // -diffskyfile
     psMetadata *diffskyfileArgs = psMetadataAlloc();
@@ -184,4 +185,5 @@
     psMetadataAddStr(rawimfileArgs, PS_LIST_TAIL, "-class_id", 0, "define class identifier", NULL);
     psMetadataAddBool(rawimfileArgs, PS_LIST_TAIL, "-simple", 0, "use the simple output format", false);
+#endif // notdef
 
     psFree(now);
@@ -206,8 +208,10 @@
     PXOPT_ADD_MODE("-revertmask",          "", MAGICTOOL_MODE_REVERTMASK,          revertmaskArgs);
     PXOPT_ADD_MODE("-mask",                "", MAGICTOOL_MODE_MASK,                maskArgs);
+#ifdef notdef
     PXOPT_ADD_MODE("-diffskyfile",         "", MAGICTOOL_MODE_DIFFSKYFILE,         diffskyfileArgs);
     PXOPT_ADD_MODE("-warpskyfile",         "", MAGICTOOL_MODE_WARPSKYFILE,         warpskyfileArgs);
     PXOPT_ADD_MODE("-chipprocessedimfile", "", MAGICTOOL_MODE_CHIPPROCESSEDIMFILE, chipprocessedimfileArgs);
     PXOPT_ADD_MODE("-rawimfile",           "", MAGICTOOL_MODE_RAWIMFILE,           rawimfileArgs);
+#endif
 
     if (!pxGetOptions(stderr, argc, argv, config, modes, argSets)) {
Index: branches/eam_branches/20090522/ippTools/src/pubtool.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/pubtool.c	(revision 24557)
+++ branches/eam_branches/20090522/ippTools/src/pubtool.c	(revision 24557)
@@ -0,0 +1,336 @@
+/*
+ * pubtool.c
+ *
+ * Copyright (C) 2008
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "pxtools.h"
+#include "pxdata.h"
+#include "pubtool.h"
+
+static bool defineclientMode(pxConfig *config);
+static bool definerunMode(pxConfig *config);
+static bool pendingMode(pxConfig *config);
+static bool addMode(pxConfig *config);
+static bool revertMode(pxConfig *config);
+
+# define MODECASE(caseName, func) \
+    case caseName: \
+    if (!func(config)) { \
+        goto FAIL; \
+    } \
+    break;
+
+
+int main(int argc, char **argv)
+{
+    psLibInit(NULL);
+
+    pxConfig *config = pubtoolConfig(NULL, argc, argv);
+    if (!config) {
+        psError(PXTOOLS_ERR_CONFIG, false, "failed to configure");
+        goto FAIL;
+    }
+
+    switch (config->mode) {
+        MODECASE(PUBTOOL_MODE_DEFINECLIENT, defineclientMode);
+        MODECASE(PUBTOOL_MODE_DEFINERUN, definerunMode);
+        MODECASE(PUBTOOL_MODE_PENDING, pendingMode);
+        MODECASE(PUBTOOL_MODE_ADD, addMode);
+        MODECASE(PUBTOOL_MODE_REVERT, revertMode);
+      default:
+        psAbort("invalid option (this should not happen)");
+    }
+
+    psFree(config);
+    pmConfigDone();
+    psLibFinalize();
+
+    exit(EXIT_SUCCESS);
+
+FAIL:
+    psErrorStackPrint(stderr, "\n");
+    int exit_status = pxerrorGetExitStatus();
+
+    psFree(config);
+    pmConfigDone();
+    psLibFinalize();
+
+    exit(exit_status);
+}
+
+static bool defineclientMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    // required
+    PXOPT_LOOKUP_STR(product, config->args, "-product",  true, false);
+    PXOPT_LOOKUP_STR(stage, config->args, "-stage", true, false);
+    PXOPT_LOOKUP_STR(workdir, config->args, "-workdir",  true, false);
+
+    // optional
+    PXOPT_LOOKUP_STR(comment, config->args, "-comment",  false, false);
+
+    if (!publishClientInsert(config->dbh, 0, product, stage, workdir, comment)) {
+        psError(PS_ERR_UNKNOWN, false, "Database error");
+        return false;
+    }
+
+    return true;
+}
+
+static bool definerunMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc(); // WHERE conditions
+
+    // required
+
+    // optional
+    PXOPT_COPY_S64(config->args, where, "-client_id", "client_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
+
+    PXOPT_LOOKUP_STR(label, config->args, "-label", false, false);
+
+    psString query = pxDataGet("pubtool_definerun.sql"); // Query to run
+    if (!query) {
+        psError(PXTOOLS_ERR_DATA, false, "Failed to retreive SQL statement");
+        psFree(where);
+        return false;
+    }
+
+    if (!psDBTransaction(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "Database error");
+        psFree(where);
+        return false;
+    }
+
+    psString whereClause = psStringCopy(""); // Additional constraints to add to query
+    if (psListLength(where->list)) {
+        psString clause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&whereClause, "\n AND %s", clause);
+        psFree(clause);
+    }
+    psFree(where);
+
+    if (!p_psDBRunQueryF(config->dbh, query, whereClause, whereClause)) {
+        psError(PS_ERR_UNKNOWN, false, "Database error");
+        psFree(query);
+        psFree(whereClause);
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "Database error");
+        }
+        return false;
+    }
+    psFree(query);
+    psFree(whereClause);
+
+    psArray *output = p_psDBFetchResult(config->dbh); // Output of SELECT statement
+    if (!output) {
+        psError(PS_ERR_UNKNOWN, false, "Database error");
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "Database error");
+        }
+        return false;
+    }
+    if (!psArrayLength(output)) {
+        psTrace("pubtool", PS_LOG_INFO, "No rows found");
+        psFree(output);
+        return true;
+    }
+
+    for (int i = 0; i < output->n; i++) {
+        psMetadata *row = output->data[i]; // Row of interest
+        psS64 client = psMetadataLookupS64(NULL, row, "client_id"); // Client identifier
+        psS64 stage = psMetadataLookupS64(NULL, row, "stage_id");   // Stage identifier
+
+        if (!publishRunInsert(config->dbh, 0, client, stage, label, "new")) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to add fileset");
+            psFree(output);
+            if (!psDBRollback(config->dbh)) {
+                psError(PS_ERR_UNKNOWN, false, "Database error");
+            }
+            return false;
+        }
+    }
+    psFree(output);
+
+    if (!psDBCommit(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "Database error");
+        return false;
+    }
+
+    return true;
+}
+
+static bool pendingMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc(); // WHERE conditions
+
+    // required
+    PXOPT_COPY_STR(config->args, where, "-client_id", "publishClient.client_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-stage", "publishClient.stage", "==");
+    PXOPT_COPY_STR(config->args, where, "-comment", "publishClient.comment", "LIKE");
+    PXOPT_COPY_STR(config->args, where, "-label", "publishRun.label", "==");
+
+    // optional
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+
+    psString query = pxDataGet("pubtool_pending.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_DATA, false, "Failed to retreive SQL statement");
+        psFree(where);
+        return false;
+    }
+
+    psString whereClause = psStringCopy(""); // WHERE conditions to add
+    if (psListLength(where->list)) {
+        psString clause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&whereClause, "\nAND %s", clause);
+        psFree(clause);
+    }
+    psFree(where);
+
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQueryF(config->dbh, query, whereClause, whereClause)) {
+        psError(PS_ERR_UNKNOWN, false, "Database error");
+        psFree(whereClause);
+        psFree(query);
+        return false;
+    }
+    psFree(whereClause);
+    psFree(query);
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psError(PS_ERR_UNKNOWN, false, "Database error");
+        return false;
+    }
+    if (!psArrayLength(output)) {
+        psTrace("pubtool", PS_LOG_INFO, "No rows found");
+        psFree(output);
+        return true;
+    }
+    if (!ippdbPrintMetadatas(stdout, output, "publishRun", !simple)) {
+        psError(PS_ERR_UNKNOWN, false, "Failed to print array");
+        psFree(output);
+        return false;
+    }
+    psFree(output);
+
+    return true;
+}
+
+static bool addMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    // required
+    PXOPT_LOOKUP_S64(pub_id, config->args, "-pub_id", true, false);
+    PXOPT_LOOKUP_STR(path_base, config->args, "-path_base",  true, false);
+
+    // optional
+    PXOPT_LOOKUP_S32(fault, config->args, "-fault", false, false);
+
+    if (!psDBTransaction(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "Database error");
+        return false;
+    }
+
+    if (!publishDoneInsert(config->dbh, pub_id, path_base, fault)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to add file");
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "Database error");
+        }
+        return false;
+    }
+
+    if (fault == 0) {
+        if (!p_psDBRunQueryF(config->dbh,
+                             "UPDATE publishRun SET state = 'full' WHERE pub_id = %" PRId64,
+                             pub_id)) {
+            psError(PS_ERR_UNKNOWN, false, "Database error");
+            if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "Database error");
+            }
+            return false;
+        }
+    }
+
+    if (!psDBCommit(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "Database error");
+        return false;
+    }
+
+    return true;
+}
+
+
+
+
+static bool revertMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc(); // WHERE conditions
+    PXOPT_COPY_S64(config->args, where, "-pub_id", "publishRun.pub_id", "==");
+    PXOPT_COPY_S32(config->args, where, "-fault", "publishDone.fault", "==");
+    PXOPT_COPY_STR(config->args, where, "-client_id", "publishClient.client_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-comment", "publishClient.comment", "LIKE");
+    PXOPT_COPY_STR(config->args, where, "-label", "publishRun.label", "==");
+
+    psString query = pxDataGet("pubtool_revert.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_DATA, false, "Failed to retreive SQL statement");
+        psFree(where);
+        return false;
+    }
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    }
+    psFree(where);
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "Database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    return true;
+}
+
Index: branches/eam_branches/20090522/ippTools/src/pubtool.h
===================================================================
--- branches/eam_branches/20090522/ippTools/src/pubtool.h	(revision 24557)
+++ branches/eam_branches/20090522/ippTools/src/pubtool.h	(revision 24557)
@@ -0,0 +1,36 @@
+/*
+ * pubtool.h
+ *
+ * Copyright (C) 2008 IfA
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef PUBTOOL_H
+#define PUBTOOL_H 1
+
+#include "pxtools.h"
+
+typedef enum {
+    PUBTOOL_MODE_NONE      = 0x0,
+    PUBTOOL_MODE_DEFINECLIENT,
+    PUBTOOL_MODE_DEFINERUN,
+    PUBTOOL_MODE_PENDING,
+    PUBTOOL_MODE_ADD,
+    PUBTOOL_MODE_REVERT,
+} pubtoolMode;
+
+pxConfig *pubtoolConfig(pxConfig *config, int argc, char **argv);
+
+#endif // PUBTOOL_H
Index: branches/eam_branches/20090522/ippTools/src/pubtoolConfig.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/pubtoolConfig.c	(revision 24557)
+++ branches/eam_branches/20090522/ippTools/src/pubtoolConfig.c	(revision 24557)
@@ -0,0 +1,111 @@
+/*
+ * pubtoolConfig.c
+ *
+ * Copyright (C) 2008
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <psmodules.h>
+
+#include "pxtools.h"
+#include "pubtool.h"
+
+pxConfig *pubtoolConfig(pxConfig *config, int argc, char **argv)
+{
+    if (!config) {
+        config = pxConfigAlloc();
+    }
+
+    pmConfigReadParamsSet(false);
+
+    // setup site config
+    config->modules = pmConfigRead(&argc, argv, NULL);
+    if (!config->modules) {
+        psError(PS_ERR_UNKNOWN, false, "Can't find site configuration!");
+        psFree(config);
+        return NULL;
+    }
+
+    // -defineclient
+    psMetadata *defineclientArgs = psMetadataAlloc();
+    psMetadataAddStr(defineclientArgs, PS_LIST_TAIL, "-stage", 0, "define stage (required)", NULL);
+    psMetadataAddStr(defineclientArgs, PS_LIST_TAIL, "-product", 0, "define product (required)", NULL);
+    psMetadataAddStr(defineclientArgs, PS_LIST_TAIL, "-workdir", 0, "define workdir (required)", NULL);
+    psMetadataAddStr(defineclientArgs, PS_LIST_TAIL, "-comment", 0, "define comment", NULL);
+
+    // -definerun
+    psMetadata *definerunArgs = psMetadataAlloc();
+    psMetadataAddS64(definerunArgs, PS_LIST_TAIL, "-client_id", 0, "search by client_id", 0);
+    psMetadataAddStr(definerunArgs, PS_LIST_TAIL, "-label", 0, "set and search by label", NULL);
+
+    // -pending
+    psMetadata *pendingArgs = psMetadataAlloc();
+    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-client_id", 0, "search on client_id", NULL);
+    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-stage", 0, "search on source", NULL);
+    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-comment", 0, "search on comment (LIKE)", NULL);
+    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-label", 0, "search on label", NULL);
+    psMetadataAddBool(pendingArgs, PS_LIST_TAIL, "-simple",  0, "use simple output format?", false);
+    psMetadataAddU64(pendingArgs, PS_LIST_TAIL, "-limit",  0, "limit result set", 0);
+
+    // -add
+    psMetadata *addArgs = psMetadataAlloc();
+    psMetadataAddS64(addArgs, PS_LIST_TAIL, "-pub_id", 0, "define pub_id (required)", 0);
+    psMetadataAddStr(addArgs, PS_LIST_TAIL, "-path_base", 0, "define path_base (required)", NULL);
+    psMetadataAddS32(addArgs, PS_LIST_TAIL, "-fault", 0, "define fault code", 0);
+
+    // -revert
+    psMetadata *revertArgs = psMetadataAlloc();
+    psMetadataAddS64(revertArgs, PS_LIST_TAIL, "-pub_id", 0, "search on pub_id", 0);
+    psMetadataAddS32(revertArgs, PS_LIST_TAIL, "-fault", 0, "search on fault code", 0);
+    psMetadataAddStr(revertArgs, PS_LIST_TAIL, "-client_id", 0, "search on client_id", NULL);
+    psMetadataAddStr(revertArgs, PS_LIST_TAIL, "-comment", 0, "search on comment (LIKE)", NULL);
+    psMetadataAddStr(revertArgs, PS_LIST_TAIL, "-label", 0, "search on label", NULL);
+
+
+    psMetadata *argSets = psMetadataAlloc();
+    psMetadata *modes = psMetadataAlloc();
+
+    PXOPT_ADD_MODE("-defineclient", "", PUBTOOL_MODE_DEFINECLIENT, defineclientArgs);
+    PXOPT_ADD_MODE("-definerun", "", PUBTOOL_MODE_DEFINERUN, definerunArgs);
+    PXOPT_ADD_MODE("-pending", "", PUBTOOL_MODE_PENDING, pendingArgs);
+    PXOPT_ADD_MODE("-add", "", PUBTOOL_MODE_ADD, addArgs);
+    PXOPT_ADD_MODE("-revert", "", PUBTOOL_MODE_REVERT, revertArgs);
+
+    if (!pxGetOptions(stderr, argc, argv, config, modes, argSets)) {
+        psError(PS_ERR_UNKNOWN, true, "option parsing failed");
+        psFree(argSets);
+        psFree(modes);
+        psFree(config);
+        return NULL;
+    }
+
+    psFree(argSets);
+    psFree(modes);
+
+    // define database handle, if used
+    // do this last so we don't setup a connection before CLI options are validated
+    config->dbh = psMemIncrRefCounter(pmConfigDB(config->modules));
+    if (!config->dbh) {
+        psError(PS_ERR_UNKNOWN, false, "Can't configure database");
+        psFree(config);
+        return NULL;
+    }
+
+    return config;
+}
Index: branches/eam_branches/20090522/ippTools/src/pxchip.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/pxchip.c	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/pxchip.c	(revision 24557)
@@ -175,5 +175,5 @@
     psString query = psStringCopy("UPDATE chipRun JOIN rawExp USING(exp_id) SET state = '%s'");
 
-    if (where) {
+    if (where && psListLength(where->list) > 0) {
         psString whereClause = psDBGenerateWhereSQL(where, NULL);
         psStringAppend(&query, " %s", whereClause);
@@ -216,5 +216,5 @@
     psString query = psStringCopy("UPDATE chipRun JOIN rawExp USING(exp_id) SET label = '%s'");
 
-    if (where) {
+    if (where && psListLength(where->list) > 0) {
         psString whereClause = psDBGenerateWhereSQL(where, NULL);
         psStringAppend(&query, " %s", whereClause);
@@ -264,5 +264,5 @@
             dvodb,
             tess_id,
-            end_stage, 
+            end_stage,
             0           // magicked
             )
@@ -277,5 +277,5 @@
     psS64 chip_id =  psDBLastInsertID(config->dbh);
 
-    // Create rows in chipImfile table for each input exposure. 
+    // Create rows in chipImfile table for each input exposure.
     // This creates the chip_image_id values
     psString query = "INSERT INTO chipImfile "
@@ -295,5 +295,5 @@
         return 0;
     }
-    
+
     return chip_id;
 }
Index: branches/eam_branches/20090522/ippTools/src/pxwarp.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/pxwarp.c	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/pxwarp.c	(revision 24557)
@@ -126,10 +126,11 @@
 
 bool pxwarpQueueByFakeID(pxConfig *config,
-                    psS64 fake_id,
-                    char *workdir,
-                    char *label,
-                    char *dvodb,
-                    char *tess_id,
-                    char *end_stage)
+                         psS64 fake_id,
+                         const char *workdir,
+                         const char *label,
+                         const char *dvodb,
+                         const char *tess_id,
+                         const char *reduction,
+                         const char *end_stage)
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
@@ -146,4 +147,5 @@
         dvodb,
         tess_id,
+                       reduction,
         end_stage,
         NULL,      // registered
Index: branches/eam_branches/20090522/ippTools/src/pxwarp.h
===================================================================
--- branches/eam_branches/20090522/ippTools/src/pxwarp.h	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/pxwarp.h	(revision 24557)
@@ -31,10 +31,11 @@
 
 bool pxwarpQueueByFakeID(pxConfig *config,
-                    psS64 fake_id,
-                    char *workdir,
-                    char *label,
-                    char *dvodb,
-                    char *tess_id,
-                    char *end_stage);
+                         psS64 fake_id,
+                         const char *workdir,
+                         const char *label,
+                         const char *dvodb,
+                         const char *tess_id,
+                         const char *reduction,
+                         const char *end_stage);
 
 #endif // PXWARP_H
Index: branches/eam_branches/20090522/ippTools/src/warptool.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/warptool.c	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/warptool.c	(revision 24557)
@@ -38,4 +38,5 @@
 static bool tooverlapMode(pxConfig *config);
 static bool addoverlapMode(pxConfig *config);
+static bool revertoverlapMode(pxConfig *config);
 static bool scmapMode(pxConfig *config);
 static bool towarpedMode(pxConfig *config);
@@ -86,4 +87,5 @@
         MODECASE(WARPTOOL_MODE_TOOVERLAP,          tooverlapMode);
         MODECASE(WARPTOOL_MODE_ADDOVERLAP,         addoverlapMode);
+        MODECASE(WARPTOOL_MODE_REVERTOVERLAP,      revertoverlapMode);
         MODECASE(WARPTOOL_MODE_SCMAP,              scmapMode);
         MODECASE(WARPTOOL_MODE_TOWARPED,           towarpedMode);
@@ -137,4 +139,5 @@
     PXOPT_LOOKUP_STR(dvodb, config->args, "-dvodb", false, false);
     PXOPT_LOOKUP_STR(tess_id, config->args, "-tess_id", true, false); // required (no default TESS)
+    PXOPT_LOOKUP_STR(reduction, config->args, "-reduction", false, false); // required (no default TESS)
     PXOPT_LOOKUP_STR(end_stage, config->args, "-end_stage", false, false);
     PXOPT_LOOKUP_TIME(registered, config->args, "-registered", false, false);
@@ -157,7 +160,8 @@
             dvodb,
             tess_id,
+            reduction,
             end_stage,
             registered,
-            false       // magicked
+            0       // magicked
     );
     if (!warpRun) {
@@ -247,4 +251,5 @@
     PXOPT_LOOKUP_STR(dvodb, config->args, "-set_dvodb", false, false);
     PXOPT_LOOKUP_STR(tess_id, config->args, "-set_tess_id", false, false);
+    PXOPT_LOOKUP_STR(reduction, config->args, "-set_reduction", false, false);
     PXOPT_LOOKUP_STR(end_stage, config->args, "-set_end_stage", false, false);
 
@@ -308,13 +313,12 @@
         }
 
-	if (!tess_id  && !row->tess_id) {
-	    psError(PS_ERR_UNKNOWN, false, "cannot queue warp run without a defined tess id: label: %s, fake_id %" PRId64, row->label, row->fake_id);
+        if (!tess_id  && !row->tess_id) {
+            psError(PS_ERR_UNKNOWN, false, "cannot queue warp run without a defined tess id: label: %s, fake_id %" PRId64, row->label, row->fake_id);
             psFree(output);
             return false;
-	}
+        }
 
         psFree(row);
     }
-    psFree(output);
 
     // loop over our list of fakeRun rows
@@ -331,10 +335,11 @@
         // queue the exp
         if (!pxwarpQueueByFakeID(config,
-                    row->fake_id,
-                    workdir     ? workdir   : row->workdir,
-                    label       ? label     : row->label,
-                    dvodb       ? dvodb     : row->dvodb,
-                    tess_id     ? tess_id   : row->tess_id,
-                    end_stage   ? end_stage : row->end_stage))
+                                 row->fake_id,
+                                 workdir     ? workdir   : row->workdir,
+                                 label       ? label     : row->label,
+                                 dvodb       ? dvodb     : row->dvodb,
+                                 tess_id     ? tess_id   : row->tess_id,
+                                 reduction   ? reduction : row->reduction,
+                                 end_stage   ? end_stage : row->end_stage))
           {
             psError(PS_ERR_UNKNOWN, false, "failed to trying to queue fake_id: %" PRId64, row->fake_id);
@@ -651,7 +656,7 @@
         warpSkyCellMapInsert(config->dbh,
             warp_id,
-            NULL,   // skycell_id
-            NULL,   // tess_id
-            NULL,   // class_id
+            "faulted",   // skycell_id
+            "faulted",   // tess_id
+            "faulted",   // class_id
             fault    // fault
         );
@@ -666,4 +671,60 @@
     return true;
 }
+
+static bool revertoverlapMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-warp_id",    "warpSkyCellMap.warp_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-skycell_id", "warpSkyCellMap.skycell_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-tess_id",    "warpSkyCellMap.tess_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-label",      "warpRun.label", "==");
+    PXOPT_COPY_S16(config->args, where, "-fault",      "warpSkyCellMap.fault", "==");
+
+    if (!psListLength(where->list)
+        && !psMetadataLookupBool(NULL, config->args, "-all")) {
+        psFree(where);
+        psError(PXTOOLS_ERR_DATA, false, "search parameters are required");
+        return false;
+    }
+
+    int numDeleted;                     // Number deleted
+    {
+        psString query = pxDataGet("warptool_revertoverlap.sql");
+        if (!query) {
+            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+            if (!psDBRollback(config->dbh)) {
+                psError(PS_ERR_UNKNOWN, false, "database error");
+            }
+            return false;
+        }
+
+        if (psListLength(where->list)) {
+            psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+            psStringAppend(&query, " AND %s", whereClause);
+            psFree(whereClause);
+        }
+
+        if (!p_psDBRunQuery(config->dbh, query)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+            psFree(query);
+            if (!psDBRollback(config->dbh)) {
+                psError(PS_ERR_UNKNOWN, false, "database error");
+            }
+            return false;
+        }
+        psFree(query);
+
+        numDeleted = psDBAffectedRows(config->dbh);
+    }
+
+    psLogMsg("warptool", PS_LOG_INFO, "Deleted %d warpSkycellMap", numDeleted);
+
+    psFree(where);
+
+    return true;
+}
+
 
 
@@ -919,5 +980,5 @@
     PXOPT_LOOKUP_STR(hostname, config->args, "-hostname", false, false);
     PXOPT_LOOKUP_F32(good_frac, config->args, "-good_frac", false, false);
-    PXOPT_LOOKUP_BOOL(magicked, config->args, "-magicked", false);
+    PXOPT_LOOKUP_S64(magicked, config->args, "-magicked", false, false);
 
     // default values
@@ -1023,5 +1084,5 @@
             return false;
         }
-        psS32 magicked = psMetadataLookupS64(&status, row, "magicked");
+        psS64 magicked = psMetadataLookupS64(&status, row, "magicked");
         if (!status) {
             psError(PS_ERR_UNKNOWN, false, "failed to look up value for magicked");
@@ -1224,53 +1285,4 @@
     }
 
-
-    // Update state to 'new'
-    int numUpdated;                     // Number updated
-    {
-        // This query is no longer necessary because we do not set warpRun's to full statte
-        // if they have faulted skyfiles.
-        // We do have runs in the DB that follow the old convention so we leave this in for
-        // now
-        psString query = pxDataGet("warptool_revertwarped_update.sql");
-        if (!query) {
-            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
-            return false;
-        }
-
-        if (psListLength(where->list)) {
-            psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-            psStringAppend(&query, " AND %s", whereClause);
-            psFree(whereClause);
-        }
-
-        if (!p_psDBRunQuery(config->dbh, query)) {
-            psError(PS_ERR_UNKNOWN, false, "database error");
-            psFree(query);
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
-            return false;
-        }
-        psFree(query);
-
-        numUpdated = psDBAffectedRows(config->dbh);
-
-#ifdef notdef
-        // new warpRuns won't get changed (they're already new) so don't require an update
-        if (numUpdated < 1) {
-            psError(PS_ERR_UNKNOWN, false, "should have affected at least 1 row");
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
-            return false;
-        }
-#endif
-    }
-
-    psLogMsg("warptool", PS_LOG_INFO, "Updated %d warp runs", numUpdated);
-
     // Delete product
     int numDeleted;                     // Number deleted
@@ -1744,5 +1756,5 @@
 
     if (clean) {
-        bool success = true; 
+        bool success = true;
         if (!strcmp(tables[i].tableName, "warpRun")) {
             success = pxSetStateCleaned("warpRun", "state", output);
Index: branches/eam_branches/20090522/ippTools/src/warptool.h
===================================================================
--- branches/eam_branches/20090522/ippTools/src/warptool.h	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/warptool.h	(revision 24557)
@@ -34,4 +34,5 @@
     WARPTOOL_MODE_TOOVERLAP,
     WARPTOOL_MODE_ADDOVERLAP,
+    WARPTOOL_MODE_REVERTOVERLAP,
     WARPTOOL_MODE_SCMAP,
     WARPTOOL_MODE_TOWARPED,
Index: branches/eam_branches/20090522/ippTools/src/warptoolConfig.c
===================================================================
--- branches/eam_branches/20090522/ippTools/src/warptoolConfig.c	(revision 24238)
+++ branches/eam_branches/20090522/ippTools/src/warptoolConfig.c	(revision 24557)
@@ -98,4 +98,5 @@
     psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_dvodb",          0, "define DVO db", NULL);
     psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_tess_id",        0, "define tess ID", NULL);
+    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_reduction",      0, "define reduction class", NULL);
     psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_end_stage",      0, "define end stage", NULL);
     psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-all",               0, "allow everything to be queued without search terms", false);
@@ -111,5 +112,6 @@
     psMetadataAddStr(definerunArgs, PS_LIST_TAIL, "-label", 0,            "define label", NULL);
     psMetadataAddStr(definerunArgs, PS_LIST_TAIL, "-dvodb", 0,            "define dvodb", NULL);
-    psMetadataAddStr(definerunArgs, PS_LIST_TAIL, "-tess_id", 0,            "define tess_id", NULL);
+    psMetadataAddStr(definerunArgs, PS_LIST_TAIL, "-tess_id", 0,            "define tess_id (required)", NULL);
+    psMetadataAddStr(definerunArgs, PS_LIST_TAIL, "-reduction", 0,            "define reduction class", NULL);
     psMetadataAddStr(definerunArgs, PS_LIST_TAIL, "-end_stage", 0,            "define end stage", NULL);
     psMetadataAddTime(definerunArgs, PS_LIST_TAIL, "-registered",  0,            "time detrend run was registered", now);
@@ -156,4 +158,14 @@
     psMetadataAddS64(addoverlapArgs, PS_LIST_TAIL, "-warp_id",  0,            "set warp ID", 0);
     psMetadataAddS16(addoverlapArgs, PS_LIST_TAIL, "-fault",  0,            "set fault code", 0);
+
+    // -revertoverlap
+    psMetadata *revertoverlapArgs = psMetadataAlloc();
+    psMetadataAddS64(revertoverlapArgs, PS_LIST_TAIL, "-warp_id", 0,            "search by warptool ID", 0);
+    psMetadataAddStr(revertoverlapArgs, PS_LIST_TAIL, "-skycell_id",  0,            "search by skycell ID", NULL);
+    psMetadataAddStr(revertoverlapArgs, PS_LIST_TAIL, "-tess_id",  0,            "search by tessellation ID", NULL);
+    psMetadataAddStr(revertoverlapArgs, PS_LIST_TAIL, "-label",  0,            "search by warpRun label", NULL);
+    psMetadataAddS16(revertoverlapArgs, PS_LIST_TAIL, "-fault",  0,            "search by fault code", 0);
+    psMetadataAddBool(revertoverlapArgs, PS_LIST_TAIL, "-all",  0,            "allow everything to be queued without search terms", false);
+
 
     // -scmap
@@ -300,4 +312,5 @@
     PXOPT_ADD_MODE("-tooverlap",       "", WARPTOOL_MODE_TOOVERLAP,      tooverlapArgs);
     PXOPT_ADD_MODE("-addoverlap",      "", WARPTOOL_MODE_ADDOVERLAP,     addoverlapArgs);
+    PXOPT_ADD_MODE("-revertoverlap",   "", WARPTOOL_MODE_REVERTOVERLAP,  revertoverlapArgs);
     PXOPT_ADD_MODE("-scmap",           "", WARPTOOL_MODE_SCMAP,          scmapArgs);
     PXOPT_ADD_MODE("-towarped",        "", WARPTOOL_MODE_TOWARPED,       towarpedArgs);
