Index: /trunk/ippTools/src/dettool.c
===================================================================
--- /trunk/ippTools/src/dettool.c	(revision 7292)
+++ /trunk/ippTools/src/dettool.c	(revision 7293)
@@ -99,26 +99,46 @@
 static bool defineMode(pxConfig *config)
 {
+    bool status     = false;
     psString str    = NULL;
-    bool status     = false;
 
     PS_ASSERT_PTR_NON_NULL(config, false);
 
+    // start a transaction so we don't end up with orphaned det_ids
     if (!psDBTransaction(config->dbh)) {
         psError(PS_ERR_UNKNOWN, false, "database error");
-        
+        return false;
     }
 
     // what type of detRun is this?
     // XXX make this flag required
-    str = psMetadataLookupStr(&status, config->args, "-det_type");
-    
-    // XXX the value being inserted is junk as we can't yet have an 'empty
-    // table'
-    detRunInsert(config->dbh, str);
+    psString det_type = psMetadataLookupStr(&status, config->args, "-det_type");
+    detRunInsert(config->dbh, det_type);
     long det_id = psDBLastInsertID(config->dbh);
     
-    // XXX this needs to fixed to support multipe exp_ids
+    // we have to support multipe exp_ids
+    psMetadataItem *item = psMetadataLookup(config->args, "-exp_id");
     psMetadata *where = psMetadataAlloc();
-    if ((str = psMetadataLookupStr(&status, config->args, "-exp_id"))) {
+
+    // was more then one exp_id specified?
+    if (item->type == PS_DATA_METADATA_MULTI) {
+        // yes
+        psListIterator *iter = psListIteratorAlloc(item->data.list, 0, false);
+        psMetadataItem *mItem = NULL;
+        while ((mItem = psListGetAndIncrement(iter))) {
+            psString exp_id = mItem->data.V;
+            if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id",
+                        PS_META_DUPLICATE_OK, "==", exp_id)) {
+                psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+                // rollback
+                if (!psDBRollback(config->dbh)) {
+                    psError(PS_ERR_UNKNOWN, false, "database error");
+                }
+                psFree(iter);
+                psFree(where);
+                return false;
+            }
+        }
+    } else if ((str = psMetadataLookupStr(&status, config->args, "-exp_id"))) {
+        // no
         if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==", str)) {
             psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
@@ -137,4 +157,5 @@
     }
 
+    // check that the specified exp_ids actually exist
     psArray *rawExps = rawDetrendExpSelectRowObjects(config->dbh, where, 0);
     psFree(where);
@@ -148,16 +169,47 @@
     }
 
-    detInputExpRow *detInputExp = rawDetrenTodetInputExpRow(
-        rawExps->data[0],
-        det_id
-    );
-
-    if (!detInputExpInsertObject(config->dbh, detInputExp)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        // rollback
-        if (!psDBRollback(config->dbh)) {
+    if (item->type == PS_DATA_METADATA_MULTI) {
+        // we should have one rawExp row be exp_id specified
+        if (psListLength(item->data.list) != psArrayLength(rawExps)) {
+            // rollback
+            if (!psDBRollback(config->dbh)) {
+                psError(PS_ERR_UNKNOWN, false, "database error");
+            }
+            psAbort(config->argv[0],
+        "an -exp_id matched more then one rawExp (this should not happen");
+
+        }
+    } else {
+        // we should have matched only one exp_id
+        if (psArrayLength(rawExps) != 1) {
+            // rollback
+            if (!psDBRollback(config->dbh)) {
+                psError(PS_ERR_UNKNOWN, false, "database error");
+            }
+            psAbort(config->argv[0],
+        "an -exp_id matched more then one rawExp (this should not happen");
+        }
+    }
+
+    // create new detInputExp row(s) from the rawExp row(s)
+    psArray *inputExps = psArrayAlloc(psArrayLength(rawExps));
+    for (long i = 0; i < psArrayLength(rawExps); i++) {
+        detInputExpRow *inputExp = rawDetrenTodetInputExpRow(
+            rawExps->data[i],
+            det_id
+        );
+        psArrayAdd(inputExps, 0, inputExp);
+        psFree(inputExp);
+    }
+
+    for (long i = 0; i < psArrayLength(inputExps); i++) {
+        if (!detInputExpInsertObject(config->dbh, inputExps->data[i])) {
             psError(PS_ERR_UNKNOWN, false, "database error");
-        }
-        return false;
+            // rollback
+            if (!psDBRollback(config->dbh)) {
+                psError(PS_ERR_UNKNOWN, false, "database error");
+            }
+            return false;
+        }
     }
 
Index: /trunk/ippTools/src/dettoolConfig.c
===================================================================
--- /trunk/ippTools/src/dettoolConfig.c	(revision 7292)
+++ /trunk/ippTools/src/dettoolConfig.c	(revision 7293)
@@ -23,5 +23,5 @@
     // -define 
     psMetadata *defineArgs = psMetadataAlloc();
-    psMetadataAddStr(defineArgs, PS_LIST_TAIL, "-exp_id",  0,
+    psMetadataAddStr(defineArgs, PS_LIST_TAIL, "-exp_id",  PS_META_DUPLICATE_OK,
         "include this exposure (XXX more then one)", NULL);
     psMetadataAddStr(defineArgs, PS_LIST_TAIL, "-det_type",  0,
@@ -313,4 +313,8 @@
     }
 
+    // save argv/argc
+    config->argv = argv;
+    config->argc = argc;
+
     return config;
 }
Index: /trunk/ippTools/src/pxtools.h
===================================================================
--- /trunk/ippTools/src/pxtools.h	(revision 7292)
+++ /trunk/ippTools/src/pxtools.h	(revision 7293)
@@ -49,4 +49,6 @@
     psMetadata *args;
     psMetadata *where;
+    int argc;
+    char **argv;
 } pxConfig;
 
