Index: trunk/ippTools/src/chiptool.c
===================================================================
--- trunk/ippTools/src/chiptool.c	(revision 32520)
+++ trunk/ippTools/src/chiptool.c	(revision 32573)
@@ -43,4 +43,5 @@
 static bool revertprocessedimfileMode(pxConfig *config);
 static bool updateprocessedimfileMode(pxConfig *config);
+static bool dropprocessedimfileMode(pxConfig *config);
 static bool advanceexpMode(pxConfig *config);
 static bool blockMode(pxConfig *config);
@@ -88,4 +89,5 @@
         MODECASE(CHIPTOOL_MODE_REVERTPROCESSEDIMFILE,   revertprocessedimfileMode);
         MODECASE(CHIPTOOL_MODE_UPDATEPROCESSEDIMFILE,   updateprocessedimfileMode);
+        MODECASE(CHIPTOOL_MODE_DROPPROCESSEDIMFILE,     dropprocessedimfileMode);
         MODECASE(CHIPTOOL_MODE_ADVANCEEXP,              advanceexpMode);
         MODECASE(CHIPTOOL_MODE_BLOCK,                   blockMode);
@@ -962,5 +964,5 @@
     PXOPT_COPY_S64(config->args, where, "-chip_id", "chip_id", "==");
     PXOPT_COPY_STR(config->args, where, "-class_id", "class_id", "==");
-    PXOPT_LOOKUP_STR(state, config->args, "-set_state", false, NULL);
+    PXOPT_LOOKUP_STR(state, config->args, "-set_state", true, false);
     if (psListLength(where->list) == 0) {
         psError(PS_ERR_UNKNOWN, true, "search parameters are required");
@@ -986,4 +988,74 @@
 
 
+    return true;
+}
+
+// "drop" previously processed components as though the original processing
+// had poor quality. Sets quality, data_state, clears fault and magicked
+// Deletes corresponding magicDSFile (if one exists)
+static bool dropprocessedimfileMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-chip_id", "chipProcessedImfile.chip_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-class_id", "chipProcessedImfile.class_id", "==");
+    PXOPT_LOOKUP_S64(chip_id, config->args, "-chip_id", true, false);
+    PXOPT_LOOKUP_S16(quality, config->args, "-set_quality", true, false);
+
+    if (!quality) {
+        psError(PXTOOLS_ERR_CONFIG, true, "non-zero quality value is required");
+        return false;
+    }
+
+    if (psListLength(where->list) == 0) {
+        psError(PXTOOLS_ERR_CONFIG, true, "-chip_id is required");
+        return false;
+    }
+
+    psString query = pxDataGet("chiptool_dropprocessedimfile_update.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+    psString delete_query = pxDataGet("chiptool_dropprocessedimfile_delete.sql");
+    if (!delete_query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringAppend(&query, " WHERE %s", whereClause);
+    psFree(where);
+
+    if (!psDBTransaction(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+    if (!p_psDBRunQueryF(config->dbh, query, quality)) {
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error on rollback");
+        }
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    psStringAppend(&delete_query, " AND %s", whereClause);
+    psFree(whereClause);
+    if (!p_psDBRunQuery(config->dbh, delete_query)) {
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error on rollback");
+        }
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(delete_query);
+        return false;
+    }
+    psFree(delete_query);
+
+    if (!psDBCommit(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
     return true;
 }
