Index: /trunk/ippTools/src/dettool.c
===================================================================
--- /trunk/ippTools/src/dettool.c	(revision 8526)
+++ /trunk/ippTools/src/dettool.c	(revision 8527)
@@ -3689,6 +3689,18 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
+    // det_id is required
+    // XXX this isn't strictly nessicary but not having the det_id complicates
+    // incrementing the iteration number
+    bool status = false;
+    psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");
+        return false;
+    }
+    if (!det_id) {
+        psError(PS_ERR_UNKNOWN, true, "-det_id is required");
+        return false;
+    }
     // either -rerun or -stop must be specified
-    bool status = false;
     bool again = psMetadataLookupBool(&status, config->args, "-again");
     if (!status) {
@@ -3707,4 +3719,133 @@
     if (again && stop) {
         psError(PS_ERR_UNKNOWN, true, "either -again or -stop must be specified");
+        return false;
+    }
+
+    // XXX stop deson't actually do anything at this point
+    if (stop) {
+        return true;
+    }
+
+    // else
+    // -again
+  
+    // select detRun.position
+    // select detRun.iteration
+    // select detInputExp.exp_id
+    // select detResidExp.accept
+    // by:
+    // find the current iteration bassed on det_id
+    // find all exp_ids in the current det_id/iteration from detInputExp
+    // find all exp_ids in the current det_id/iteration from detResidExp
+    // compare the counts of exp_ids
+
+    psString query = psStringCopy(
+        "SELECT DISTINCT"
+        "   detRun.position AS det_id,"
+        "   detRun.iteration,"
+        "   detInputExp.exp_id,"
+        "   detResidExp.accept"
+        " FROM detRun"
+        " LEFT JOIN detInputExp"
+        "   ON detRun.position = detInputExp.det_id"
+        "   AND detRun.iteration = detInputExp.iteration"
+        " LEFT JOIN detResidExp"
+        "   ON detRun.position = detResidExp.det_id"
+        "   AND detRun.iteration = detResidExp.iteration"
+        "   AND detInputExp.exp_id = detResidExp.exp_id"
+        " WHERE"
+        "   detInputExp.exp_id IS NOT NULL"
+        "   AND detResidExp.accept IS NOT NULL"
+        " GROUP BY"
+        "   detRun.position,"
+        "   detRun.iteration,"
+        "   detInputExp.exp_id"
+        " HAVING"
+        "   COUNT(detResidExp.exp_id) = COUNT(detInputExp.exp_id)"
+        ); 
+
+    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) {
+        // XXX check psError here
+        psError(PS_ERR_UNKNOWN, false, "no completed detrun iterations found");
+        return false;
+    }
+
+    // start a transaction so we don't end up with an incremented iteration
+    // count but no detInputExps
+    if (!psDBTransaction(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(output);
+        return false;
+    }
+
+    // up the detRuns iteration count for for the single det_id we are
+    // operating on
+    // XXX this will have to changed in order to support multiple det_ids with
+    // a single invocation of this functions
+    psS32 newIteration = incrementIteration(config, det_id);
+    if (!newIteration) {
+        // rollback
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+        }
+        psFree(output);
+        return false;
+    }
+
+    for (long i = 0; i < psArrayLength(output); i++) {
+        psMetadata *row = output->data[i];
+        psString exp_id = psMetadataLookupStr(&status, row, "exp_id");
+        if (!status) {
+            // rollback
+            if (!psDBRollback(config->dbh)) {
+                psError(PS_ERR_UNKNOWN, false, "database error");
+            }
+            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for exp_id");
+            psFree(output);
+            return false;
+        }
+        bool accept = psMetadataLookupBool(&status, row, "accept");
+        if (!status) {
+            // rollback
+            if (!psDBRollback(config->dbh)) {
+                psError(PS_ERR_UNKNOWN, false, "database error");
+            }
+            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for accept");
+            psFree(output);
+            return false;
+        }
+        
+        // detResidExp.include is used to set detInputExp.include
+        if (!detInputExpInsert(
+                    config->dbh,
+                    (psS32)atol(det_id),
+                    newIteration,
+                    exp_id,
+                    accept
+                )
+        ) {
+            // rollback
+            if (!psDBRollback(config->dbh)) {
+                psError(PS_ERR_UNKNOWN, false, "database error");
+            }
+            psError(PS_ERR_UNKNOWN, false, "database error");
+            psFree(output);
+            return false;
+        }
+    }
+
+    psFree(output);
+
+    // point of no return for det_id creation
+    if (!psDBCommit(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
         return false;
     }
