diff --git a/bindings/java/jni/dataModel_SleuthkitJNI.cpp b/bindings/java/jni/dataModel_SleuthkitJNI.cpp
index b69469ac088ebb74029be1f2189a2380e003e833..d856587341cc8e51478cf3a043ca6ef1114ab20f 100644
--- a/bindings/java/jni/dataModel_SleuthkitJNI.cpp
+++ b/bindings/java/jni/dataModel_SleuthkitJNI.cpp
@@ -1003,7 +1003,6 @@ JNIEXPORT void JNICALL
         return;
     }
 
-
     // move the strings into the C++ world
 
     // get pointers to each of the file names
@@ -1080,6 +1079,95 @@ JNIEXPORT void JNICALL
     // if process completes successfully, must call revertAddImgNat or commitAddImgNat to free the TskAutoDb
 }
 
+/*
+ * Create a database for the given image using a pre-created process which can be cancelled.
+ * MUST call commitAddImg or revertAddImg afterwards once runAddImg returns.  If there is an 
+ * error, you do not need to call revert or commit and the 'process' handle will be deleted.
+ * @return the 0 for success 1 for failure
+ * @param env pointer to java environment this was called from
+ * @param obj the java object this was called from
+ * @param process the add-image process created by initAddImgNat
+ * @param dataSrcId An identifier for the data source that is unique across multiple cases (e.g., a UUID)
+ * @param imgPath The full path to the image
+ * @param timezone the timezone the image is from
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_runAddImgNat(JNIEnv * env, jclass obj, jlong process, jstring dataSrcId, jstring imgPath, jstring timeZone) {
+
+    // Validate arguments.
+    TskAutoDb *tskAuto = ((TskAutoDb *) process);
+    if (!tskAuto || tskAuto->m_tag != TSK_AUTO_TAG) {
+        setThrowTskCoreError(env, "runAddImgNat: Invalid process argument");
+        return;
+    }
+    if (env->GetStringLength(dataSrcId) <= 0) {    
+        setThrowTskCoreError(env, "runAddImgNat: Invalid data source id argument");
+        return;
+    }
+    if (env->GetStringLength(imgPath) <= 0) {    
+        setThrowTskCoreError(env, "runAddImgNat: Invalid image path argument");
+        return;
+    }
+
+    // Convert the string arguments into native strings.
+    jboolean isCopy;
+    const char *data_src_id = (const char *) env->GetStringUTFChars(dataSrcId, &isCopy);
+    if (NULL == data_src_id) {
+        setThrowTskCoreError(env, "runAddImgNat: Can't convert data source id string");
+        return;
+    }
+    char **image_paths = (char **) tsk_malloc(1 * sizeof(char *));
+    if (NULL == image_paths) {
+        setThrowTskCoreError(env, "runAddImgNat: Can't malloc array for image path string");
+        env->ReleaseStringUTFChars(dataSrcId, (const char *) data_src_id);
+        return;
+    }
+    image_paths[0] = (char *) env->GetStringUTFChars(imgPath, &isCopy);    
+
+    // Set the time zone.
+    if (env->GetStringLength(timeZone) > 0) {
+        const char *time_zone = env->GetStringUTFChars(timeZone, &isCopy);
+        tskAuto->setTz(string(time_zone));
+        env->ReleaseStringUTFChars(timeZone, time_zone);
+    }
+
+    // Add the image.
+    uint8_t ret = 0;
+    if ( (ret = tskAuto->startAddImage(1, image_paths, TSK_IMG_TYPE_DETECT, 0)) != 0) {
+        stringstream msgss;
+        msgss << "runAddImgNat: Errors occured while ingesting image " << std::endl;
+        vector<TskAuto::error_record> errors = tskAuto->getErrorList();
+        for (size_t i = 0; i < errors.size(); i++) {
+            msgss << (i+1) << ". ";
+            msgss << (TskAuto::errorRecordToString(errors[i]));
+            msgss << " " << std::endl;
+        }
+        if (ret == 1) {
+            //fatal error
+            setThrowTskCoreError(env, msgss.str().c_str());
+        }
+        else if (ret == 2) {
+			if(tskAuto->isDbOpen()) {
+				// if we can still talk to the database, it's a non-fatal error
+				setThrowTskDataError(env, msgss.str().c_str());
+			}
+			else {
+				// we cannot talk to the database, fatal error
+				setThrowTskCoreError(env, msgss.str().c_str());
+			}
+        }
+    }
+
+    // @@@ SHOULD WE CLOSE HERE before we commit / revert etc.
+    //close image first before freeing the image paths
+    tskAuto->closeImage();
+
+    // cleanup
+    env->ReleaseStringUTFChars(imgPath, (const char *) image_paths[0]);
+    free(image_paths);
+    env->ReleaseStringUTFChars(dataSrcId, (const char *) data_src_id);
+
+    // if process completes successfully, must call revertAddImgNat or commitAddImgNat to free the TskAutoDb
+}
 
 
 /*
diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
index 4090fa42191f162d375f503cc9696d429c259472..5b88b6a67b43c925f3fc0f6d1eb69c7a89ecb264 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
@@ -40,7 +40,7 @@
  * application
  */
 public class SleuthkitJNI {
-	
+
 	// Lock used to synchronize image and file system cache
 	private static final Object cacheLock = new Object();
 
@@ -60,6 +60,7 @@ public class SleuthkitJNI {
 
 	private static native void closeCaseDbNat(long db) throws TskCoreException;
 
+	//hash-lookup database   
 	private static native int hashDbOpenNat(String hashDbPath) throws TskCoreException;
 
 	private static native int hashDbNewNat(String hashDbPath) throws TskCoreException;
@@ -86,7 +87,6 @@ public class SleuthkitJNI {
 
 	private static native void hashDbClose(int dbHandle) throws TskCoreException;
 
-	//hash-lookup database functions   
 	private static native void hashDbCreateIndexNat(int dbHandle) throws TskCoreException;
 
 	private static native boolean hashDbIndexExistsNat(int dbHandle) throws TskCoreException;
@@ -97,11 +97,13 @@ public class SleuthkitJNI {
 
 	private static native HashHitInfo hashDbLookupVerbose(String hash, int dbHandle) throws TskCoreException;
 
-	//load image
+	//add image
 	private static native long initAddImgNat(long db, String timezone, boolean addUnallocSpace, boolean noFatFsOrphans) throws TskCoreException;
 
 	private static native void runAddImgNat(long process, String[] imgPath, int splits, String timezone) throws TskCoreException, TskDataException; // if runAddImg finishes without being stopped, revertAddImg or commitAddImg MUST be called
 
+	private static native void runAddImgNat(long process, String dataSourceId, String imgPath, String timezone) throws TskCoreException, TskDataException; // if runAddImg finishes without being stopped, revertAddImg or commitAddImg MUST be called
+
 	private static native void stopAddImgNat(long process) throws TskCoreException;
 
 	private static native void revertAddImgNat(long process) throws TskCoreException;
@@ -213,8 +215,8 @@ void free() throws TskCoreException {
 		 * Start the process of adding a disk image to the case
 		 *
 		 * @param timezone Timezone that image was from
-		 * @param addUnallocSpace true to create virtual files for unallocated space
-		 * the image
+		 * @param addUnallocSpace true to create virtual files for unallocated
+		 * space the image
 		 * @param noFatFsOrphans true if to skip processing of orphans on FAT
 		 * filesystems
 		 *
@@ -268,6 +270,33 @@ public void run(String[] imgPath) throws TskCoreException, TskDataException {
 				runAddImgNat(autoDbPointer, imgPath, imgPath.length, timezone);
 			}
 
+			/**
+			 * Start the process of adding an image to the case database. MUST
+			 * call either commit() or revert() after calling run().
+			 *
+			 * @param dataSourceId An identifier for the data source that is
+			 * unique across multiple cases (e.g., a UUID).
+			 * @param imgPath Full path to the image file.
+			 * @throws TskCoreException exception thrown if critical error
+			 * occurs within TSK
+			 * @throws TskDataException exception thrown if non-critical error
+			 * occurs within TSK (should be OK to continue)
+			 */
+			public void run(String dataSourceId, String imagePath) throws TskCoreException, TskDataException {
+				if (autoDbPointer != 0) {
+					throw new TskCoreException("AddImgProcess:run: AutoDB pointer is already set");
+				}
+
+				synchronized (this) {
+					autoDbPointer = initAddImgNat(caseDbPointer, timezoneLongToShort(timezone), addUnallocSpace, noFatFsOrphans);
+				}
+				if (autoDbPointer == 0) {
+					//additional check in case initAddImgNat didn't throw exception
+					throw new TskCoreException("AddImgProcess::run: AutoDB pointer is NULL after initAddImgNat");
+				}
+				runAddImgNat(autoDbPointer, dataSourceId, imagePath, timezone);
+			}
+
 			/**
 			 * Call while run() is executing in another thread to prematurely
 			 * halt the process. Must call revert() in the other thread once the