diff --git a/Makefile.am b/Makefile.am
index a1506bf3f3ca576f4141242e67d0de6f32e4a5c5..5355cca97335e6f1dc725598577eb7f42f87eb13 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -25,7 +25,24 @@ EXTRA_DIST = README_win32.txt README.txt INSTALL.txt ChangeLog.txt NEWS.txt \
     win32/libmmtools/libmmtools.vcproj  \
     win32/libautotools/libautotools.vcproj  \
     win32/posix-sample/posix-sample.vcproj \
-    win32/callback-sample/callback-sample.vcproj
+    win32/callback-sample/callback-sample.vcproj \
+    bindings/java/README.txt \
+    bindings/java/build.xml \
+    bindings/java/jni/dataModel_SleuthkitJNI.cpp \
+    bindings/java/jni/dataModel_SleuthkitJNI.h \
+    bindings/java/jni/tskAutoDbJNI.h \
+    bindings/java/src/org/sleuthkit/datamodel/Content.java \
+    bindings/java/src/org/sleuthkit/datamodel/Directory.java \
+    bindings/java/src/org/sleuthkit/datamodel/File.java \
+    bindings/java/src/org/sleuthkit/datamodel/FileSystem.java \
+    bindings/java/src/org/sleuthkit/datamodel/FsContent.java \
+    bindings/java/src/org/sleuthkit/datamodel/Image.java \
+    bindings/java/src/org/sleuthkit/datamodel/Sleuthkit.java \
+    bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java \
+    bindings/java/src/org/sleuthkit/datamodel/TskData.java \
+    bindings/java/src/org/sleuthkit/datamodel/TskException.java \
+    bindings/java/src/org/sleuthkit/datamodel/Volume.java \
+    bindings/java/src/org/sleuthkit/datamodel/VolumeSystem.java 
 
 CLEANFILES = tsk3/tsk_incs.h
 
diff --git a/NEWS.txt b/NEWS.txt
index e13b231abafd3c3369fcaf267cfdfc37ec4b6738..cb8ae83b1c52ff110beed81fddbc4cca25efc013 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -6,6 +6,7 @@ Numbers refer to SourceForge.net tracker IDs:
 New Features:
 - Added multithreaded support
 - Added C++ wrapper classes
+- Added JNI bindings / Java data model classes
 
 ---------------- VERSION 3.2.2 --------------
 Bug Fixes
diff --git a/bindings/java/README.txt b/bindings/java/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e3c8122290d3864bd047f414d34f50d6495ddf54
--- /dev/null
+++ b/bindings/java/README.txt
@@ -0,0 +1,22 @@
+To build the java bindings first download the sqlitejdbc .jar files http://www.xerial.org/maven/repository/artifact/org/xerial/sqlite-jdbc/ (newest version is at the BOTTOM)
+
+Put the .jar files in sleuthkit/bindings/java/lib
+
+use the Ant target build.xml in sleuthkit/bindings/java/  
+
+To set up Ant download it from: http://ant.apache.org/ then follow the directions in the Ant Manual (http://ant.apache.org/manual/index.html) for installation
+
+To build the .dll build the win32 visual studio project. You will need to have a version of JDK for the .dll to build. You will need to set the JDK_HOME environment variable If it is not already set. 
+
+To use these bindings you will need to move the .dll to the appropriate location to be found by your java compiler. This will be specific to your IDE or should be specified on the command line if using a command linem compiler.
+To build the java bindings first download the sqlitejdbc .jar files http://www.xerial.org/maven/repository/artifact/org/xerial/sqlite-jdbc/ (newest version is at the BOTTOM)
+
+Put the .jar files in sleuthkit/bindings/java/lib
+
+use the Ant target build.xml in sleuthkit/bindings/java/  
+
+To set up Ant download it from: http://ant.apache.org/ then follow the directions in the Ant Manual (http://ant.apache.org/manual/index.html) for installation
+
+To build the .dll build the win32 visual studio project. You will need to have a version of JDK for the .dll to build. You will need to set the JDK_HOME environment variable If it is not already set. 
+
+To use these bindings you will need to move the .dll to the appropriate location to be found by your java compiler. This will be specific to your IDE or should be specified on the command line if using a command linem compiler.
\ No newline at end of file
diff --git a/bindings/java/build.xml b/bindings/java/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..91313ac16357c2bdc64ed0ad90816149ee2bd1a5
--- /dev/null
+++ b/bindings/java/build.xml
@@ -0,0 +1,98 @@
+<project name="DataModel" default="dist" basedir=".">
+    <description>
+        Sleuthkit Java DataModel 
+    </description>
+  <!-- set global properties for this build -->
+  <property name="src" location="src/org/sleuthkit/datamodel"/>
+  <property name="build" location="build/"/>
+  <property name="dist"  location="dist"/>
+  <property name="lib" location="lib"/>
+  
+  <path id="libraries">
+    <fileset dir="${lib}">
+      <include name="*.jar"/>
+    </fileset>
+	<pathelement path="${build}"/>
+  </path>
+
+
+  <target name="init">
+    <mkdir dir="${build}"/>
+	<mkdir dir="${dist}"/>
+  </target>
+ 
+  <target name="compile" depends="init"
+        description="compile the source " >
+    <!-- Compile the java code from ${src} into ${build} -->
+    <javac srcdir="${src}" destdir="${build}" classpathref="libraries"/>
+  </target>
+
+  <target name="dist" depends="jni"
+        description="generate the distribution" >
+    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
+    <jar jarfile="${dist}/Tsk_DataModel.jar" basedir="${build}"/>
+  </target>
+  
+  <target name="jni" depends="compile" description="make the jni.h file">
+    <javah classpath = "${build}" outputFile="jni/dataModel_SleuthkitJNI.h" force="yes">
+	  <class name="org.sleuthkit.datamodel.SleuthkitJNI"/>
+	</javah>
+  </target>
+  
+
+  <target name="clean"
+        description="clean up" >
+    <!-- Delete the ${build} and ${dist} directory trees -->
+    <delete dir="${build}"/>
+    <delete dir="${dist}"/>
+  </target>
+</project>
+<project name="DataModel" default="dist" basedir=".">
+    <description>
+        Sleuthkit Java DataModel 
+    </description>
+  <!-- set global properties for this build -->
+  <property name="src" location="src/org/sleuthkit/datamodel"/>
+  <property name="build" location="build/"/>
+  <property name="dist"  location="dist"/>
+  <property name="lib" location="lib"/>
+  
+  <path id="libraries">
+    <fileset dir="${lib}">
+      <include name="*.jar"/>
+    </fileset>
+	<pathelement path="${build}"/>
+  </path>
+
+
+  <target name="init">
+    <mkdir dir="${build}"/>
+	<mkdir dir="${dist}"/>
+  </target>
+ 
+  <target name="compile" depends="init"
+        description="compile the source " >
+    <!-- Compile the java code from ${src} into ${build} -->
+    <javac srcdir="${src}" destdir="${build}" classpathref="libraries"/>
+  </target>
+
+  <target name="dist" depends="jni"
+        description="generate the distribution" >
+    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
+    <jar jarfile="${dist}/Tsk_DataModel.jar" basedir="${build}"/>
+  </target>
+  
+  <target name="jni" depends="compile" description="make the jni.h file">
+    <javah classpath = "${build}" outputFile="jni/dataModel_SleuthkitJNI.h" force="yes">
+	  <class name="org.sleuthkit.datamodel.SleuthkitJNI"/>
+	</javah>
+  </target>
+  
+
+  <target name="clean"
+        description="clean up" >
+    <!-- Delete the ${build} and ${dist} directory trees -->
+    <delete dir="${build}"/>
+    <delete dir="${dist}"/>
+  </target>
+</project>
\ No newline at end of file
diff --git a/bindings/java/jni/dataModel_SleuthkitJNI.cpp b/bindings/java/jni/dataModel_SleuthkitJNI.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b643b06c688250006e0c691d689bfcddcedcf527
--- /dev/null
+++ b/bindings/java/jni/dataModel_SleuthkitJNI.cpp
@@ -0,0 +1,1044 @@
+#include "jni.h"
+#include "dataModel_SleuthkitJNI.h"
+#include "tsk3/libtsk.h"
+#include "tsk3/tsk_tools_i.h"
+#include "tskAutoDbJNI.h"
+#include "tsk3/auto/tsk_auto_i.h"
+#include "tsk3/auto/tsk_auto.h"
+
+
+TskAutoDbJNI::TskAutoDbJNI(){
+    m_cancelled = false;
+    TskAutoDb::TskAutoDb();
+}
+
+
+TSK_RETVAL_ENUM TskAutoDbJNI::processFile(TSK_FS_FILE * fs_file,
+        const char *path){
+            if(m_cancelled)
+                return TSK_STOP;
+            else
+                return TskAutoDb::processFile(fs_file, path);
+    }
+void TskAutoDbJNI::cancelProcess(){
+    m_cancelled = true;
+}
+
+/* Throw and exception to java
+ * @param the java environment to send the exception to
+ */
+static void throwTskError(JNIEnv *env){
+
+    jclass exception;
+    exception = env->FindClass("org/sleuthkit/datamodel/TskException");
+
+    const char* msg = tsk_error_get();
+    env->ThrowNew(exception, msg);
+
+}
+
+/*
+ * Class:     datamodel_SleuthkitJNI
+ * Method:    loaddb
+ * Signature: (Ljava/lang/String;I)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_loaddbNat
+(JNIEnv *env, jclass obj, jobjectArray paths, jint num_imgs, jstring outDir){
+    TskAutoDb tskDb;
+    //change to true when autopsy needs the block table.
+    tskDb.createBlockMap(false);
+
+#ifdef TSK_WIN32
+    jboolean isCopy;
+    char *cOutDir8 = (char *)env->GetStringUTFChars(outDir, &isCopy);
+
+    if(cOutDir8 == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    // get pointers to each of the file names
+    char ** imagepaths8 = (char**) tsk_malloc(num_imgs * sizeof(char *));
+    if(imagepaths8 == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    for(int i =0; i < num_imgs; i++){
+        imagepaths8[i] = (char *)env->GetStringUTFChars((jstring)env->GetObjectArrayElement(paths, i), &isCopy);
+    }
+
+    if (tskDb.openImageUtf8(num_imgs, imagepaths8, TSK_IMG_TYPE_DETECT, 0, cOutDir8)) {
+        tsk_error_print(stderr);
+        throwTskError(env);
+        return 1;
+    }
+#else
+#error "Only Win32 is currently supported"
+#endif
+
+    if (tskDb.addFilesInImgToDB()) {
+        tsk_error_print(stderr);
+        throwTskError(env);
+        return 1;
+    }
+    for(int i = 0; i < num_imgs; i++){
+        env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(paths, i), imagepaths8[i]);
+    }
+    free(imagepaths8);
+    
+    env->ReleaseStringUTFChars(outDir, cOutDir8);
+    tskDb.closeImage();
+    return 0;
+}
+
+/*
+ * Class:     datamodel_SleuthkitJNI
+ * Method:    loaddb
+ * Signature: (Ljava/lang/String;I)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_startloaddbNat
+(JNIEnv *env, jclass obj, jstring timezone){
+    jboolean isCopy;
+    char envstr[32];
+    _snprintf(envstr, 32, ("TZ=%s"), (char *)env->GetStringUTFChars(timezone, &isCopy));
+    if (0 != _putenv(envstr)) { 
+        throwTskError(env); 
+        return 1; }
+
+    /* we should be checking this somehow */
+    TZSET();
+    TskAutoDbJNI *tskDb = new TskAutoDbJNI();
+    return (jlong)tskDb;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    runloaddbNat
+* Signature: (J)V
+*/
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_runloaddbNat
+(JNIEnv * env, jclass obj, jlong process, jobjectArray paths, jint num_imgs, jstring outDir){
+    jboolean isCopy;
+
+    
+    TskAutoDbJNI * tskDb = ((TskAutoDbJNI*)process);
+
+    //change to true when autopsy needs the block table.
+    tskDb->createBlockMap(false);
+#ifdef TSK_WIN32
+    char *cOutDir8 = (char *)env->GetStringUTFChars(outDir, &isCopy);
+
+    if(cOutDir8 == NULL){
+        throwTskError(env);
+        return;
+    }
+    // get pointers to each of the file names
+    char ** imagepaths8 = (char**) tsk_malloc(num_imgs * sizeof(char *));
+    if(imagepaths8 == NULL){
+        throwTskError(env);
+        return;
+    }
+    for(int i =0; i < num_imgs; i++){
+        imagepaths8[i] = (char *)env->GetStringUTFChars((jstring)env->GetObjectArrayElement(paths, i), &isCopy);
+    }
+#else
+#error "Only Win32 is currently supported
+#endif
+
+    if (tskDb->openImageUtf8((int)num_imgs, imagepaths8, TSK_IMG_TYPE_DETECT, 0, cOutDir8)) {
+        tskDb->closeImage();
+        throwTskError(env);
+    }
+
+    if (tskDb->addFilesInImgToDB()) {
+        tskDb->closeImage();
+        tsk_error_print(stderr);
+        throwTskError(env);
+        
+    }
+    for(int i = 0; i < num_imgs; i++){
+        env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(paths, i), imagepaths8[i]);
+    }
+    free(imagepaths8);
+    
+    env->ReleaseStringUTFChars(outDir, cOutDir8);
+    tskDb->closeImage();
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    runloaddbNat
+* Signature: (J)V
+*/
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_stoploaddbNat
+(JNIEnv * env, jclass obj, jlong process){
+    ((TskAutoDbJNI*)process)->cancelProcess();  
+}
+
+
+
+
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    openImage
+* Signature: (Ljava/lang/String;I)J
+*/
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openImageNat
+(JNIEnv *env, jclass obj, jobjectArray paths, jint num_imgs){
+    TSK_IMG_INFO * img_info;
+        jboolean isCopy;
+#ifdef TSK_WIN32
+    // get pointers to each of the file names
+    char ** imagepaths8 = (char**) tsk_malloc(num_imgs * sizeof(char *));
+    if(imagepaths8 == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    for(int i =0; i < num_imgs; i++){
+        imagepaths8[i] = (char *)env->GetStringUTFChars((jstring)env->GetObjectArrayElement(paths, i), &isCopy);
+    }
+
+#else
+#error Only Win32 is currently supported
+#endif
+    img_info = tsk_img_open_utf8((int)num_imgs, imagepaths8, TSK_IMG_TYPE_DETECT, 0);
+
+    for(int i = 0; i < num_imgs; i++){
+        env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(paths, i), imagepaths8[i]);
+    }
+    free(imagepaths8);
+    if(img_info == NULL){
+        throwTskError(env);
+    }
+    return (jlong)img_info;
+}
+
+/* 
+* Class:     datamodel_SleuthkitJNI
+* Method:    openVol
+* Signature: (J)J
+*/
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openVsNat
+(JNIEnv * env, jclass obj, jlong img_info, jlong vsOffset){ 
+    TSK_IMG_INFO * img = (TSK_IMG_INFO *) img_info;
+    TSK_VS_INFO * vsInfo;
+
+    vsInfo = tsk_vs_open(img, vsOffset, TSK_VS_TYPE_DETECT);
+    if(vsInfo == NULL){
+        throwTskError(env);
+    }
+    return (jlong)vsInfo;
+}
+
+/*
+ * Class:     datamodel_SleuthkitJNI
+ * Method:    openVol
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openVolNat
+(JNIEnv * env, jclass obj, jlong vs_info, jlong vol_id){
+    TSK_VS_INFO * vsInfo = (TSK_VS_INFO *) vs_info;
+    TSK_VS_PART_INFO * volInfo;
+    volInfo = (TSK_VS_PART_INFO *) tsk_vs_part_get(vsInfo, (TSK_PNUM_T) vol_id);
+    if(volInfo == NULL){
+        throwTskError(env);
+    }
+    return (jlong)volInfo;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    openFs
+* Signature: (J)J
+*/
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openFsNat
+(JNIEnv * env, jclass obj, jlong img_info, jlong fs_offset){
+    TSK_IMG_INFO * img = (TSK_IMG_INFO *) img_info;
+    TSK_FS_INFO * fsInfo;
+
+    fsInfo = tsk_fs_open_img(img, (TSK_OFF_T) fs_offset /** img->sector_size*/, TSK_FS_TYPE_DETECT);
+    if(fsInfo == NULL){
+        throwTskError(env);
+    }
+    return (jlong)fsInfo;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    openFile
+* Signature: (JJ)J
+*/
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openFileNat
+(JNIEnv * env, jclass obj, jlong fs_info, jlong file_id){
+    TSK_FS_INFO * fs = (TSK_FS_INFO *) fs_info;
+    TSK_FS_FILE * file;
+
+    file = tsk_fs_file_open_meta(fs, NULL, (TSK_INUM_T) file_id);
+    if(file == NULL){
+        throwTskError(env);
+    }
+    return (jlong)file;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    readImgNat
+* Signature: (JJ)[B
+*/
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readImgNat
+(JNIEnv * env, jclass obj, jlong img_info, jlong offset, jlong len){
+    char * buf = (char *) tsk_malloc((size_t)len);
+    if(buf == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    TSK_IMG_INFO * img = (TSK_IMG_INFO *) img_info;
+
+    ssize_t retval = tsk_img_read(img, (TSK_OFF_T) offset, buf, (size_t) len);
+
+    if (retval != -1){
+        jbyteArray return_array = env->NewByteArray(retval);
+
+        jbyte * jBytes = env->GetByteArrayElements(return_array, 0);
+
+        for(int i = 0; i<(retval); i++){
+            jBytes[i] = buf[i];
+        }
+
+        env->ReleaseByteArrayElements(return_array, jBytes, 0);
+        free(buf);
+        return return_array;
+    }
+    else{
+        throwTskError(env);
+    }
+    free(buf);
+    return NULL;
+}
+ 
+/*
+ * Class:     datamodel_SleuthkitJNI
+ * Method:    readVsNat
+ * Signature: (JJJ)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readVsNat
+(JNIEnv * env, jclass obj, jlong vs_info, jlong offset, jlong len){
+    char * buf = (char *) tsk_malloc((size_t) len);
+    if(buf == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    TSK_VS_INFO * vs = (TSK_VS_INFO *) vs_info;
+
+    ssize_t retval = tsk_vs_read_block(vs, (TSK_DADDR_T) offset, buf, (size_t) len);
+
+    if (retval != -1){
+        jbyteArray return_array = env->NewByteArray(retval);
+
+        jbyte * jBytes = env->GetByteArrayElements(return_array, 0);
+
+        for(int i = 0; i<(retval); i++){
+            jBytes[i] = buf[i];
+        }
+
+        env->ReleaseByteArrayElements(return_array, jBytes, 0);
+        free(buf);
+        return return_array;
+    }
+    else{
+        throwTskError(env);
+    }
+    free(buf);
+    return NULL;
+}
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    readVolNat
+* Signature: (JJJ)[B
+*/
+
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readVolNat
+(JNIEnv * env, jclass obj, jlong vol_info, jlong offset, jlong len){
+    char * buf = (char *) tsk_malloc((size_t) len);
+    if(buf == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    TSK_VS_PART_INFO * vs = (TSK_VS_PART_INFO *) vol_info;
+
+    ssize_t retval = tsk_vs_part_read(vs, (TSK_OFF_T) offset, buf, (size_t) len);
+
+    if (retval != -1){
+        jbyteArray return_array = env->NewByteArray(retval);
+
+        jbyte * jBytes = env->GetByteArrayElements(return_array, 0);
+
+        for(int i = 0; i<(retval); i++){
+            jBytes[i] = buf[i];
+        }
+
+        env->ReleaseByteArrayElements(return_array, jBytes, 0);
+        free(buf);
+        return return_array;
+    }
+    else{
+        throwTskError(env);
+    }
+    free(buf);
+    return NULL;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    readFsNat
+* Signature: (JJJ)[B
+*/
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFsNat
+(JNIEnv * env, jclass obj, jlong fs_info, jlong offset, jlong len){
+    char * buf = (char *) tsk_malloc((size_t) len);
+    if(buf == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    TSK_FS_INFO * fs = (TSK_FS_INFO *) fs_info;
+
+    ssize_t retval = tsk_fs_read(fs, (TSK_OFF_T) offset, buf, (size_t) len);
+
+    if (retval != -1){
+        jbyteArray return_array = env->NewByteArray(retval);
+
+        jbyte * jBytes = env->GetByteArrayElements(return_array, 0);
+
+        for(int i = 0; i<(retval); i++){
+            jBytes[i] = buf[i];
+        }
+
+        env->ReleaseByteArrayElements(return_array, jBytes, 0);
+        free(buf);
+        return return_array;
+    }
+    else{
+        throwTskError(env);
+    }
+    free(buf);
+    return NULL;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    readFileNat
+* Signature: (JJJ)[B
+*/
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFileNat
+(JNIEnv * env, jclass obj, jlong file_info, jlong offset, jlong len){
+    char * buf = (char *) tsk_malloc((size_t) len);
+    if(buf == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    TSK_FS_FILE * file = (TSK_FS_FILE *) file_info;
+
+    ssize_t retval = tsk_fs_file_read(file, (TSK_OFF_T) offset, buf, (size_t) len, TSK_FS_FILE_READ_FLAG_NONE);
+
+    if (retval != -1){
+        jbyteArray return_array = env->NewByteArray(retval);
+
+        jbyte * jBytes = env->GetByteArrayElements(return_array, 0);
+
+        for(int i = 0; i<(retval); i++){
+            jBytes[i] = buf[i];
+        }
+
+        env->ReleaseByteArrayElements(return_array, jBytes, 0);
+        free(buf);
+        return return_array;
+    }
+    else{
+        throwTskError(env);
+    }
+    free(buf);
+    return NULL;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    closeImgNat
+* Signature: ()V
+*/
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeImgNat
+(JNIEnv * env, jclass obj, jlong img_info){
+    tsk_img_close((TSK_IMG_INFO *) img_info);
+}
+
+/*
+ * Class:     datamodel_SleuthkitJNI
+ * Method:    closeVsNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeVsNat
+(JNIEnv *env, jclass obj, jlong vsInfo){
+    tsk_vs_close((TSK_VS_INFO *) vsInfo);
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    closeVolNat
+* Signature: (J)V
+*/
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeVolNat
+(JNIEnv * env, jclass obj, jlong vol_info){
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    closeFsNat
+* Signature: ()V
+*/
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFsNat
+(JNIEnv * env, jclass obj, jlong fs_info){
+    tsk_fs_close((TSK_FS_INFO *) fs_info);
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    closeFileNat
+* Signature: (J)V
+*/
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFileNat
+(JNIEnv * env, jclass obj, jlong file_info){
+    tsk_fs_file_close((TSK_FS_FILE *) file_info);
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    getVersionNat
+* Signature: ()J
+*/
+JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getVersionNat
+(JNIEnv * env, jclass obj){
+    const char * cversion = tsk_version_get_str();
+    jstring jversion = (*env).NewStringUTF(cversion);
+    return jversion; 
+}
+#include "jni.h"
+#include "dataModel_SleuthkitJNI.h"
+#include "tsk3/libtsk.h"
+#include "tsk3/tsk_tools_i.h"
+#include "tskAutoDbJNI.h"
+#include "tsk3/auto/tsk_auto_i.h"
+#include "tsk3/auto/tsk_auto.h"
+
+
+TskAutoDbJNI::TskAutoDbJNI(){
+    m_cancelled = false;
+    TskAutoDb::TskAutoDb();
+}
+
+
+TSK_RETVAL_ENUM TskAutoDbJNI::processFile(TSK_FS_FILE * fs_file,
+        const char *path){
+            if(m_cancelled)
+                return TSK_STOP;
+            else
+                return TskAutoDb::processFile(fs_file, path);
+    }
+void TskAutoDbJNI::cancelProcess(){
+    m_cancelled = true;
+}
+
+/* Throw and exception to java
+ * @param the java environment to send the exception to
+ */
+static void throwTskError(JNIEnv *env){
+
+    jclass exception;
+    exception = env->FindClass("org/sleuthkit/datamodel/TskException");
+
+    const char* msg = tsk_error_get();
+    env->ThrowNew(exception, msg);
+
+}
+
+/*
+ * Class:     datamodel_SleuthkitJNI
+ * Method:    loaddb
+ * Signature: (Ljava/lang/String;I)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_loaddbNat
+(JNIEnv *env, jclass obj, jobjectArray paths, jint num_imgs, jstring outDir){
+    TskAutoDb tskDb;
+    //change to true when autopsy needs the block table.
+    tskDb.createBlockMap(false);
+
+#ifdef TSK_WIN32
+    jboolean isCopy;
+    char *cOutDir8 = (char *)env->GetStringUTFChars(outDir, &isCopy);
+
+    if(cOutDir8 == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    // get pointers to each of the file names
+    char ** imagepaths8 = (char**) tsk_malloc(num_imgs * sizeof(char *));
+    if(imagepaths8 == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    for(int i =0; i < num_imgs; i++){
+        imagepaths8[i] = (char *)env->GetStringUTFChars((jstring)env->GetObjectArrayElement(paths, i), &isCopy);
+    }
+
+    if (tskDb.openImageUtf8(num_imgs, imagepaths8, TSK_IMG_TYPE_DETECT, 0, cOutDir8)) {
+        tsk_error_print(stderr);
+        throwTskError(env);
+        return 1;
+    }
+#else
+#error "Only Win32 is currently supported"
+#endif
+
+    if (tskDb.addFilesInImgToDB()) {
+        tsk_error_print(stderr);
+        throwTskError(env);
+        return 1;
+    }
+    for(int i = 0; i < num_imgs; i++){
+        env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(paths, i), imagepaths8[i]);
+    }
+    free(imagepaths8);
+    
+    env->ReleaseStringUTFChars(outDir, cOutDir8);
+    tskDb.closeImage();
+    return 0;
+}
+
+/*
+ * Class:     datamodel_SleuthkitJNI
+ * Method:    loaddb
+ * Signature: (Ljava/lang/String;I)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_startloaddbNat
+(JNIEnv *env, jclass obj, jstring timezone){
+    jboolean isCopy;
+    char envstr[32];
+    _snprintf(envstr, 32, ("TZ=%s"), (char *)env->GetStringUTFChars(timezone, &isCopy));
+    if (0 != _putenv(envstr)) { 
+        throwTskError(env); 
+        return 1; }
+
+    /* we should be checking this somehow */
+    TZSET();
+    TskAutoDbJNI *tskDb = new TskAutoDbJNI();
+    return (jlong)tskDb;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    runloaddbNat
+* Signature: (J)V
+*/
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_runloaddbNat
+(JNIEnv * env, jclass obj, jlong process, jobjectArray paths, jint num_imgs, jstring outDir){
+    jboolean isCopy;
+
+    
+    TskAutoDbJNI * tskDb = ((TskAutoDbJNI*)process);
+
+    //change to true when autopsy needs the block table.
+    tskDb->createBlockMap(false);
+#ifdef TSK_WIN32
+    char *cOutDir8 = (char *)env->GetStringUTFChars(outDir, &isCopy);
+
+    if(cOutDir8 == NULL){
+        throwTskError(env);
+        return;
+    }
+    // get pointers to each of the file names
+    char ** imagepaths8 = (char**) tsk_malloc(num_imgs * sizeof(char *));
+    if(imagepaths8 == NULL){
+        throwTskError(env);
+        return;
+    }
+    for(int i =0; i < num_imgs; i++){
+        imagepaths8[i] = (char *)env->GetStringUTFChars((jstring)env->GetObjectArrayElement(paths, i), &isCopy);
+    }
+#else
+#error "Only Win32 is currently supported
+#endif
+
+    if (tskDb->openImageUtf8(num_imgs, imagepaths8, TSK_IMG_TYPE_DETECT, 0, cOutDir8)) {
+        tskDb->closeImage();
+        throwTskError(env);
+    }
+
+    if (tskDb->addFilesInImgToDB()) {
+        tskDb->closeImage();
+        tsk_error_print(stderr);
+        throwTskError(env);
+        
+    }
+    for(int i = 0; i < num_imgs; i++){
+        env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(paths, i), imagepaths8[i]);
+    }
+    free(imagepaths8);
+    
+    env->ReleaseStringUTFChars(outDir, cOutDir8);
+    tskDb->closeImage();
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    runloaddbNat
+* Signature: (J)V
+*/
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_stoploaddbNat
+(JNIEnv * env, jclass obj, jlong process){
+    ((TskAutoDbJNI*)process)->cancelProcess();  
+}
+
+
+
+
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    openImage
+* Signature: (Ljava/lang/String;I)J
+*/
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openImageNat
+(JNIEnv *env, jclass obj, jobjectArray paths, jint num_imgs){
+    TSK_IMG_INFO * img_info;
+        jboolean isCopy;
+#ifdef TSK_WIN32
+    // get pointers to each of the file names
+    char ** imagepaths8 = (char**) tsk_malloc(num_imgs * sizeof(char *));
+    if(imagepaths8 == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    for(int i =0; i < num_imgs; i++){
+        imagepaths8[i] = (char *)env->GetStringUTFChars((jstring)env->GetObjectArrayElement(paths, i), &isCopy);
+    }
+
+#else
+#error Only Win32 is currently supported
+#endif
+    img_info = tsk_img_open_utf8((int)num_imgs, imagepaths8, TSK_IMG_TYPE_DETECT, 0);
+
+    for(int i = 0; i < num_imgs; i++){
+        env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(paths, i), imagepaths8[i]);
+    }
+    free(imagepaths8);
+    if(img_info == NULL){
+        throwTskError(env);
+    }
+    return (jlong)img_info;
+}
+
+/* 
+* Class:     datamodel_SleuthkitJNI
+* Method:    openVol
+* Signature: (J)J
+*/
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openVsNat
+(JNIEnv * env, jclass obj, jlong img_info, jlong vsOffset){ 
+    TSK_IMG_INFO * img = (TSK_IMG_INFO *) img_info;
+    TSK_VS_INFO * vsInfo;
+
+    vsInfo = tsk_vs_open(img, vsOffset, TSK_VS_TYPE_DETECT);
+    if(vsInfo == NULL){
+        throwTskError(env);
+    }
+    return (jlong)vsInfo;
+}
+
+/*
+ * Class:     datamodel_SleuthkitJNI
+ * Method:    openVol
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openVolNat
+(JNIEnv * env, jclass obj, jlong vs_info, jlong vol_id){
+    TSK_VS_INFO * vsInfo = (TSK_VS_INFO *) vs_info;
+    TSK_VS_PART_INFO * volInfo;
+    volInfo = (TSK_VS_PART_INFO *) tsk_vs_part_get(vsInfo, (TSK_PNUM_T) vol_id);
+    if(volInfo == NULL){
+        throwTskError(env);
+    }
+    return (jlong)volInfo;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    openFs
+* Signature: (J)J
+*/
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openFsNat
+(JNIEnv * env, jclass obj, jlong img_info, jlong fs_offset){
+    TSK_IMG_INFO * img = (TSK_IMG_INFO *) img_info;
+    TSK_FS_INFO * fsInfo;
+
+    fsInfo = tsk_fs_open_img(img, (TSK_OFF_T) fs_offset /** img->sector_size*/, TSK_FS_TYPE_DETECT);
+    if(fsInfo == NULL){
+        throwTskError(env);
+    }
+    return (jlong)fsInfo;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    openFile
+* Signature: (JJ)J
+*/
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openFileNat
+(JNIEnv * env, jclass obj, jlong fs_info, jlong file_id){
+    TSK_FS_INFO * fs = (TSK_FS_INFO *) fs_info;
+    TSK_FS_FILE * file;
+
+    file = tsk_fs_file_open_meta(fs, NULL, (TSK_INUM_T) file_id);
+    if(file == NULL){
+        throwTskError(env);
+    }
+    return (jlong)file;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    readImgNat
+* Signature: (JJ)[B
+*/
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readImgNat
+(JNIEnv * env, jclass obj, jlong img_info, jlong offset, jlong len){
+    char * buf = (char *) tsk_malloc((size_t)len);
+    if(buf == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    TSK_IMG_INFO * img = (TSK_IMG_INFO *) img_info;
+
+    ssize_t retval = tsk_img_read(img, (TSK_OFF_T) offset, buf, (size_t) len);
+
+    if (retval != -1){
+        jbyteArray return_array = env->NewByteArray(retval);
+
+        jbyte * jBytes = env->GetByteArrayElements(return_array, 0);
+
+        for(int i = 0; i<(retval); i++){
+            jBytes[i] = buf[i];
+        }
+
+        env->ReleaseByteArrayElements(return_array, jBytes, 0);
+        free(buf);
+        return return_array;
+    }
+    else{
+        throwTskError(env);
+    }
+    free(buf);
+    return NULL;
+}
+ 
+/*
+ * Class:     datamodel_SleuthkitJNI
+ * Method:    readVsNat
+ * Signature: (JJJ)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readVsNat
+(JNIEnv * env, jclass obj, jlong vs_info, jlong offset, jlong len){
+    char * buf = (char *) tsk_malloc((size_t) len);
+    if(buf == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    TSK_VS_INFO * vs = (TSK_VS_INFO *) vs_info;
+
+    ssize_t retval = tsk_vs_read_block(vs, (TSK_DADDR_T) offset, buf, (size_t) len);
+
+    if (retval != -1){
+        jbyteArray return_array = env->NewByteArray(retval);
+
+        jbyte * jBytes = env->GetByteArrayElements(return_array, 0);
+
+        for(int i = 0; i<(retval); i++){
+            jBytes[i] = buf[i];
+        }
+
+        env->ReleaseByteArrayElements(return_array, jBytes, 0);
+        free(buf);
+        return return_array;
+    }
+    else{
+        throwTskError(env);
+    }
+    free(buf);
+    return NULL;
+}
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    readVolNat
+* Signature: (JJJ)[B
+*/
+
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readVolNat
+(JNIEnv * env, jclass obj, jlong vol_info, jlong offset, jlong len){
+    char * buf = (char *) tsk_malloc((size_t) len);
+    if(buf == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    TSK_VS_PART_INFO * vs = (TSK_VS_PART_INFO *) vol_info;
+
+    ssize_t retval = tsk_vs_part_read(vs, (TSK_OFF_T) offset, buf, (size_t) len);
+
+    if (retval != -1){
+        jbyteArray return_array = env->NewByteArray(retval);
+
+        jbyte * jBytes = env->GetByteArrayElements(return_array, 0);
+
+        for(int i = 0; i<(retval); i++){
+            jBytes[i] = buf[i];
+        }
+
+        env->ReleaseByteArrayElements(return_array, jBytes, 0);
+        free(buf);
+        return return_array;
+    }
+    else{
+        throwTskError(env);
+    }
+    free(buf);
+    return NULL;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    readFsNat
+* Signature: (JJJ)[B
+*/
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFsNat
+(JNIEnv * env, jclass obj, jlong fs_info, jlong offset, jlong len){
+    char * buf = (char *) tsk_malloc((size_t) len);
+    if(buf == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    TSK_FS_INFO * fs = (TSK_FS_INFO *) fs_info;
+
+    ssize_t retval = tsk_fs_read(fs, (TSK_OFF_T) offset, buf, (size_t) len);
+
+    if (retval != -1){
+        jbyteArray return_array = env->NewByteArray(retval);
+
+        jbyte * jBytes = env->GetByteArrayElements(return_array, 0);
+
+        for(int i = 0; i<(retval); i++){
+            jBytes[i] = buf[i];
+        }
+
+        env->ReleaseByteArrayElements(return_array, jBytes, 0);
+        free(buf);
+        return return_array;
+    }
+    else{
+        throwTskError(env);
+    }
+    free(buf);
+    return NULL;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    readFileNat
+* Signature: (JJJ)[B
+*/
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFileNat
+(JNIEnv * env, jclass obj, jlong file_info, jlong offset, jlong len){
+    char * buf = (char *) tsk_malloc((size_t) len);
+    if(buf == NULL){
+        throwTskError(env);
+        return NULL;
+    }
+    TSK_FS_FILE * file = (TSK_FS_FILE *) file_info;
+
+    ssize_t retval = tsk_fs_file_read(file, (TSK_OFF_T) offset, buf, (size_t) len, TSK_FS_FILE_READ_FLAG_NONE);
+
+    if (retval != -1){
+        jbyteArray return_array = env->NewByteArray(retval);
+
+        jbyte * jBytes = env->GetByteArrayElements(return_array, 0);
+
+        for(int i = 0; i<(retval); i++){
+            jBytes[i] = buf[i];
+        }
+
+        env->ReleaseByteArrayElements(return_array, jBytes, 0);
+        free(buf);
+        return return_array;
+    }
+    else{
+        throwTskError(env);
+    }
+    free(buf);
+    return NULL;
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    closeImgNat
+* Signature: ()V
+*/
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeImgNat
+(JNIEnv * env, jclass obj, jlong img_info){
+    tsk_img_close((TSK_IMG_INFO *) img_info);
+}
+
+/*
+ * Class:     datamodel_SleuthkitJNI
+ * Method:    closeVsNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeVsNat
+(JNIEnv *env, jclass obj, jlong vsInfo){
+    tsk_vs_close((TSK_VS_INFO *) vsInfo);
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    closeVolNat
+* Signature: (J)V
+*/
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeVolNat
+(JNIEnv * env, jclass obj, jlong vol_info){
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    closeFsNat
+* Signature: ()V
+*/
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFsNat
+(JNIEnv * env, jclass obj, jlong fs_info){
+    tsk_fs_close((TSK_FS_INFO *) fs_info);
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    closeFileNat
+* Signature: (J)V
+*/
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFileNat
+(JNIEnv * env, jclass obj, jlong file_info){
+    tsk_fs_file_close((TSK_FS_FILE *) file_info);
+}
+
+/*
+* Class:     datamodel_SleuthkitJNI
+* Method:    getVersionNat
+* Signature: ()J
+*/
+JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getVersionNat
+(JNIEnv * env, jclass obj){
+    const char * cversion = tsk_version_get_str();
+    jstring jversion = (*env).NewStringUTF(cversion);
+    return jversion; 
+}
\ No newline at end of file
diff --git a/bindings/java/jni/dataModel_SleuthkitJNI.h b/bindings/java/jni/dataModel_SleuthkitJNI.h
new file mode 100644
index 0000000000000000000000000000000000000000..aa7650857ff79962077dfffa68325ea6f4e6522f
--- /dev/null
+++ b/bindings/java/jni/dataModel_SleuthkitJNI.h
@@ -0,0 +1,346 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_sleuthkit_datamodel_SleuthkitJNI */
+
+#ifndef _Included_org_sleuthkit_datamodel_SleuthkitJNI
+#define _Included_org_sleuthkit_datamodel_SleuthkitJNI
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    getVersionNat
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getVersionNat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    loaddbNat
+ * Signature: ([Ljava/lang/String;ILjava/lang/String;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_loaddbNat
+  (JNIEnv *, jclass, jobjectArray, jint, jstring);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    startloaddbNat
+ * Signature: (Ljava/lang/String;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_startloaddbNat
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    runloaddbNat
+ * Signature: (J[Ljava/lang/String;ILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_runloaddbNat
+  (JNIEnv *, jclass, jlong, jobjectArray, jint, jstring);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    stoploaddbNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_stoploaddbNat
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    openImageNat
+ * Signature: ([Ljava/lang/String;I)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openImageNat
+  (JNIEnv *, jclass, jobjectArray, jint);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    openVsNat
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openVsNat
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    openVolNat
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openVolNat
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    openFsNat
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openFsNat
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    openFileNat
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openFileNat
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    readImgNat
+ * Signature: (JJJ)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readImgNat
+  (JNIEnv *, jclass, jlong, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    readVsNat
+ * Signature: (JJJ)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readVsNat
+  (JNIEnv *, jclass, jlong, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    readVolNat
+ * Signature: (JJJ)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readVolNat
+  (JNIEnv *, jclass, jlong, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    readFsNat
+ * Signature: (JJJ)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFsNat
+  (JNIEnv *, jclass, jlong, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    readFileNat
+ * Signature: (JJJ)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFileNat
+  (JNIEnv *, jclass, jlong, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    closeImgNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeImgNat
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    closeVsNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeVsNat
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    closeVolNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeVolNat
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    closeFsNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFsNat
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    closeFileNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFileNat
+  (JNIEnv *, jclass, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_sleuthkit_datamodel_SleuthkitJNI */
+
+#ifndef _Included_org_sleuthkit_datamodel_SleuthkitJNI
+#define _Included_org_sleuthkit_datamodel_SleuthkitJNI
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    getVersionNat
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getVersionNat
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    loaddbNat
+ * Signature: ([Ljava/lang/String;ILjava/lang/String;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_loaddbNat
+  (JNIEnv *, jclass, jobjectArray, jint, jstring);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    startloaddbNat
+ * Signature: (Ljava/lang/String;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_startloaddbNat
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    runloaddbNat
+ * Signature: (J[Ljava/lang/String;ILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_runloaddbNat
+  (JNIEnv *, jclass, jlong, jobjectArray, jint, jstring);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    stoploaddbNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_stoploaddbNat
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    openImageNat
+ * Signature: ([Ljava/lang/String;I)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openImageNat
+  (JNIEnv *, jclass, jobjectArray, jint);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    openVsNat
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openVsNat
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    openVolNat
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openVolNat
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    openFsNat
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openFsNat
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    openFileNat
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openFileNat
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    readImgNat
+ * Signature: (JJJ)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readImgNat
+  (JNIEnv *, jclass, jlong, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    readVsNat
+ * Signature: (JJJ)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readVsNat
+  (JNIEnv *, jclass, jlong, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    readVolNat
+ * Signature: (JJJ)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readVolNat
+  (JNIEnv *, jclass, jlong, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    readFsNat
+ * Signature: (JJJ)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFsNat
+  (JNIEnv *, jclass, jlong, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    readFileNat
+ * Signature: (JJJ)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFileNat
+  (JNIEnv *, jclass, jlong, jlong, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    closeImgNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeImgNat
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    closeVsNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeVsNat
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    closeVolNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeVolNat
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    closeFsNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFsNat
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    closeFileNat
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFileNat
+  (JNIEnv *, jclass, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/bindings/java/jni/tskAutoDbJNI.h b/bindings/java/jni/tskAutoDbJNI.h
new file mode 100644
index 0000000000000000000000000000000000000000..796725b92ba16327aed9e78c404a0248e1f3e67f
--- /dev/null
+++ b/bindings/java/jni/tskAutoDbJNI.h
@@ -0,0 +1,16 @@
+class TskAutoDbJNI:public TskAutoDb {
+  public:
+      bool m_cancelled;
+      TskAutoDbJNI();
+      virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE * fs_file,
+        const char *path);
+      void cancelProcess();
+};
+class TskAutoDbJNI:public TskAutoDb {
+  public:
+      bool m_cancelled;
+      TskAutoDbJNI();
+      virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE * fs_file,
+        const char *path);
+      void cancelProcess();
+};
\ No newline at end of file
diff --git a/bindings/java/src/org/sleuthkit/datamodel/Content.java b/bindings/java/src/org/sleuthkit/datamodel/Content.java
new file mode 100644
index 0000000000000000000000000000000000000000..2da2374f5af58063f475d23bf538e91bb53608c8
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/Content.java
@@ -0,0 +1,22 @@
+package org.sleuthkit.datamodel;
+
+/**
+ * Interface for all content from the sleuthkit.
+ * @author alawrence
+ */
+public interface Content {
+
+    /**
+     * read data from the content in the sleuthkit
+     * @param offset offset to start reading from
+     * @param len amount of data to read (in bytes)
+     * @return a character array of data (in bytes)
+     */
+    public byte[] read(long offset, long len) throws TskException;
+
+    /**
+     * get the size of the content
+     * @return size of the content
+     */
+    public long getSize();
+}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/Directory.java b/bindings/java/src/org/sleuthkit/datamodel/Directory.java
new file mode 100644
index 0000000000000000000000000000000000000000..f39114d0218c0aec8a6dab196f773844d9dc78be
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/Directory.java
@@ -0,0 +1,205 @@
+package org.sleuthkit.datamodel;
+
+import java.sql.SQLException;
+import java.util.*;
+
+/**
+ *
+ * @author alawrence
+ */
+public class Directory extends FsContent{
+	
+    /**
+     * Contructor: most inputs are from the database
+     * @param db java database structure
+     * @param fs_id
+     * @param file_id
+     * @param attr_type
+     * @param attr_id
+     * @param name
+     * @param par_file_id
+     * @param dir_type
+     * @param meta_type
+     * @param dir_flags
+     * @param meta_flags
+     * @param size
+     * @param ctime
+     * @param crtime
+     * @param atime
+     * @param mtime
+     * @param mode
+     * @param uid
+     * @param gid
+     */
+    protected Directory(Sleuthkit db, long fs_id, long file_id, long attr_type, long attr_id, String name, long par_file_id,
+			long dir_type, long meta_type, long dir_flags, long meta_flags, long size, 
+			long ctime, long crtime, long atime, long mtime, long mode, long uid, long gid) throws SQLException{
+		this.db = db;
+		this.fs_id = fs_id;
+		this.file_id = file_id;
+		this.attr_type = attr_type;
+		this.attr_id = attr_id;
+                this.name = name;
+		this.par_file_id = par_file_id;
+		this.dir_type = dir_type;
+		this.meta_type = meta_type;
+		this.dir_flags = dir_flags;
+		this.meta_flags = meta_flags;
+		this.size = size;
+		this.ctime = ctime;
+		this.crtime = crtime;
+		this.atime = atime;
+		this.mtime = mtime;
+		this.mode = mode;
+		this.uid = uid;
+		this.gid = gid;
+		childIds = db.getChildIds(file_id, fs_id);
+		childNames = db.getChildNames(file_id, fs_id);
+
+                /**
+                 * If name is empty, it means we adding the root metadata. In
+                 * this case, we add this to the child as well. We will change
+                 * the name to "." on "getFile(fs_id, file_id, name)" method.
+                 */
+                if(name.equals("") && !childIds.contains(file_id)){
+                    childIds.add(file_id);
+                    childNames.add(name);
+                }
+	}
+	
+	private ArrayList<Long> childIds; //could use set or other structure
+	private ArrayList<String> childNames;
+	
+        /**
+         * is this a directory?
+         * @return true, it is a directory
+         */
+    @Override
+        public boolean isDir(){
+		return true;
+	}
+
+        /**
+         * gets all child files and directories of this directory
+         * @return an arraylist of the children
+         */
+        public ArrayList<FsContent> getFiles() throws SQLException{
+		ArrayList<FsContent> content = new ArrayList<FsContent>();
+		for(int i = 0; i < childIds.size(); i++){
+			FsContent file = db.getFile(fs_id, childIds.get(i), childNames.get(i));
+			if (file != null /*&&!file.getName().equals(".")&&!file.getName().equals("..") */){
+				file.setParent(parentFileSystem);
+				content.add(file);
+			}
+		}
+			return content;
+	}
+}
+package org.sleuthkit.datamodel;
+
+import java.sql.SQLException;
+import java.util.*;
+
+/**
+ *
+ * @author alawrence
+ */
+public class Directory extends FsContent{
+	
+    /**
+     * Contructor: most inputs are from the database
+     * @param db java database structure
+     * @param fs_id
+     * @param file_id
+     * @param attr_type
+     * @param attr_id
+     * @param name
+     * @param par_file_id
+     * @param dir_type
+     * @param meta_type
+     * @param dir_flags
+     * @param meta_flags
+     * @param size
+     * @param ctime
+     * @param crtime
+     * @param atime
+     * @param mtime
+     * @param mode
+     * @param uid
+     * @param gid
+     */
+    protected Directory(Sleuthkit db, long fs_id, long file_id, long attr_type, long attr_id, String name, long par_file_id,
+			long dir_type, long meta_type, long dir_flags, long meta_flags, long size, 
+			long ctime, long crtime, long atime, long mtime, long mode, long uid, long gid) throws SQLException{
+		this.db = db;
+		this.fs_id = fs_id;
+		this.file_id = file_id;
+		this.attr_type = attr_type;
+		this.attr_id = attr_id;
+                this.name = name;
+		this.par_file_id = par_file_id;
+		this.dir_type = dir_type;
+		this.meta_type = meta_type;
+		this.dir_flags = dir_flags;
+		this.meta_flags = meta_flags;
+		this.size = size;
+		this.ctime = ctime;
+		this.crtime = crtime;
+		this.atime = atime;
+		this.mtime = mtime;
+		this.mode = mode;
+		this.uid = uid;
+		this.gid = gid;
+		childIds = db.getChildIds(file_id, fs_id);
+		childNames = db.getChildNames(file_id, fs_id);
+
+                /**
+                 * If name is empty, it means we adding the root metadata. In
+                 * this case, we add this to the child as well. We will change
+                 * the name to "." on "getFile(fs_id, file_id, name)" method.
+                 */
+                if(name.equals("") && !childIds.contains(file_id)){
+                    childIds.add(file_id);
+                    childNames.add(name);
+                }
+	}
+	
+	private ArrayList<Long> childIds; //could use set or other structure
+	private ArrayList<String> childNames;
+	
+        /**
+         * is this a directory?
+         * @return true, it is a directory
+         */
+    @Override
+        public boolean isDir(){
+		return true;
+	}
+
+        /**
+         * gets all child files and directories of this directory
+         * @return an arraylist of the children
+         */
+        public ArrayList<FsContent> getFiles() throws SQLException{
+		ArrayList<FsContent> content = new ArrayList<FsContent>();
+		//if(childIds != null){
+			for(int i = 0; i < childIds.size(); i++){
+				FsContent file = db.getFile(fs_id, childIds.get(i), childNames.get(i));
+				if (file != null /*&&!file.getName().equals(".")&&!file.getName().equals("..") */){
+					file.setParent(parentFileSystem);
+					content.add(file);
+				}
+				
+			}
+			return content;
+		//}
+		//else return content;
+	}
+
+
+	/*public long getSize() {
+		// directory size
+		return 0;
+	}*/
+
+}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/File.java b/bindings/java/src/org/sleuthkit/datamodel/File.java
new file mode 100644
index 0000000000000000000000000000000000000000..21bfb852fdf2a9bade6f42646811bf12cfe13529
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/File.java
@@ -0,0 +1,67 @@
+package org.sleuthkit.datamodel;
+
+
+/**
+ *
+ * @author alawrence
+ */
+public class File extends FsContent{
+	
+	//constructor used for getfile from tskDb
+    /**
+     * Constructor most fields are from the database
+     * @param db java database class
+     * @param fs_id
+     * @param file_id
+     * @param attr_type
+     * @param attr_id
+     * @param name
+     * @param par_file_id
+     * @param dir_type
+     * @param meta_type
+     * @param dir_flags
+     * @param meta_flags
+     * @param size
+     * @param ctime
+     * @param crtime
+     * @param atime
+     * @param mtime
+     * @param mode
+     * @param uid
+     * @param gid
+     */
+    protected File(Sleuthkit db, long fs_id, long file_id, long attr_type, long attr_id, String name, long par_file_id,
+			long dir_type, long meta_type, long dir_flags, long meta_flags, long size, 
+			long ctime, long crtime, long atime, long mtime, long mode, long uid, long gid){
+		this.db = db;
+		this.fs_id = fs_id;
+		this.file_id = file_id;
+		this.attr_type = attr_type;
+		this.attr_id = attr_id;
+		this.name = name;
+		this.par_file_id = par_file_id;
+		this.dir_type = dir_type;
+		this.meta_type = meta_type;
+		this.dir_flags = dir_flags;
+		this.meta_flags = meta_flags;
+		this.size = size;
+		this.ctime = ctime;
+		this.crtime = crtime;
+		this.atime = atime;
+		this.mtime = mtime;
+		this.mode = mode;
+		this.uid = uid;
+		this.gid = gid;
+	}
+	
+        /**
+         * is this a file?
+         * @return true, it is a file
+         */
+        public boolean isFile(){
+		return true;
+	}
+	
+	
+}
+
diff --git a/bindings/java/src/org/sleuthkit/datamodel/FileSystem.java b/bindings/java/src/org/sleuthkit/datamodel/FileSystem.java
new file mode 100644
index 0000000000000000000000000000000000000000..d455191f1281252d21808c51c4560af218c48d7f
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/FileSystem.java
@@ -0,0 +1,215 @@
+package org.sleuthkit.datamodel;
+import java.sql.SQLException;
+import java.util.*;
+
+/**
+ *
+ * @author alawrence
+ */
+public class FileSystem implements Content{
+	
+	long fs_id, img_offset, vol_id, fs_type, block_size, block_count, root_inum,
+		first_inum, last_inum;
+	private Sleuthkit db;
+	private Volume parentVolume;
+	private long filesystemHandle = 0;
+	
+        /**
+         * Constructor most inputs are from the database
+         * @param db java database class
+         * @param fs_id
+         * @param img_offset
+         * @param vol_id
+         * @param fs_type
+         * @param block_size
+         * @param block_count
+         * @param root_inum
+         * @param first_inum
+         * @param last_inum
+         */
+        protected FileSystem(Sleuthkit db, long fs_id, long img_offset, long vol_id, long fs_type,
+			long block_size, long block_count, long root_inum, long first_inum, 
+			long last_inum){
+		this.db = db;
+		this.fs_id = fs_id; 
+		this.img_offset = img_offset; 
+		this.vol_id = vol_id; 
+		this.fs_type = fs_type;
+		this.block_size = block_size;
+		this.block_count = block_count;
+		this.root_inum = root_inum;
+		this.first_inum = first_inum;
+		this.last_inum = last_inum;
+	}
+	
+        /**
+         * set the parent class, will be called by the parent
+         * @param parent parent volume
+         */
+        protected void setParent(Volume parent){
+		parentVolume = parent;
+	}
+	
+	
+        /**
+         * get the root directory if one exists
+         * @return a directory object if the root is listed in the db otherwise null
+         */
+        public FsContent getRootDir() throws SQLException{
+		//get the root directory. good for starting a file browser 
+		FsContent dir = db.getFile(fs_id, root_inum);
+		if (dir != null){
+			dir.setParent(this);
+		}
+		return dir;
+	}
+	
+        /**
+         * gets a list of files and directories in the root of this file system
+         * @return an arraylist of files and directories in the root directory
+         */
+        public ArrayList<FsContent> getRootFiles() throws SQLException{
+		//getfiles in root directory
+		ArrayList<Long> childIds = db.getChildIds(root_inum, fs_id);
+		ArrayList<FsContent> content = new ArrayList<FsContent>();
+		
+		for(Long id : childIds){
+			FsContent newContent = db.getFile(fs_id, id);
+			if(!newContent.getName().equals(".")&&!newContent.getName().equals("..")){
+                            newContent.setParent(this);
+                            content.add(newContent);
+                        }
+		}
+		return content;
+	}
+	
+        /**
+         * gets a directory with the given inum
+         * @param INUM directory's id
+         * @return a directory or null if it doesn't exist
+         */
+        public FsContent getDirectory(long INUM) throws SQLException{
+		//get the directory at the given inum, will need to use commandline tools
+		//if file id is the same as inum then can use database
+		FsContent dir = db.getFile(fs_id, INUM);
+		if(dir != null){
+			dir.setParent(this);
+		}
+		return dir;
+	}
+
+        /**
+         * read data from the filesystem
+         * @param offset offset in bytes from the start of the filesystem
+         * @param len how many bytes to read
+         * @return the bytes
+         * @throws TskException
+         */
+	public byte[] read(long offset, long len) throws TskException{
+		// read from the file system
+		if(filesystemHandle == 0){
+			filesystemHandle = SleuthkitJNI.openFs(this.getParent().getParent().getParent().getImageHandle(), img_offset);
+		}
+		return SleuthkitJNI.readFs(filesystemHandle, offset, len);
+	}
+
+        /**
+         * get the parent volume
+         * @return volume object
+         */
+        public Volume getParent(){
+		return parentVolume;
+	}
+
+        /**
+         * get the size of the filesystem
+         * @return size of the filesystem
+         */
+	public long getSize() {
+		// size of the file system
+		return block_size * block_count;
+	}
+	
+        /**
+         * lazily loads the filesystem pointer ie: won't be loaded until this is called
+         * @return a filesystem pointer from the sleuthkit
+         */
+        public long getFileSystemHandle() throws TskException{
+		if (filesystemHandle == 0){
+			filesystemHandle = SleuthkitJNI.openFs(this.getParent().getParent().getParent().getImageHandle(), img_offset);
+		}
+		return this.filesystemHandle;
+	}
+	
+	//methods get exact data from database. could be manipulated to get more
+	//meaningful data.
+        /**
+         * get the file system id
+         * @return fs id
+         */
+        public long getFs_id() {
+		return fs_id;
+	}	
+        /**
+         * get the byte offset of this filesystem in the image
+         * @return offset
+         */
+        public long getImg_offset() {
+		return img_offset;
+	}	 	
+        /**
+         * get the volume id
+         * @return id
+         */
+        public long getVol_id() {
+		return vol_id;
+	}	 	
+        /**
+         * get the file system type
+         * @return enum number from sleuthkit database
+         */
+        public long getFs_type() {
+		return fs_type;
+	}	 	
+        /**
+         * get the block size
+         * @return block size
+         */
+        public long getBlock_size() {
+		return block_size;
+	}	 	
+        /**
+         * get the number of blocks
+         * @return block count
+         */
+        public long getBlock_count() {
+		return block_count;
+	}	 	
+        /**
+         * get the inum of the root directory
+         * @return
+         */
+        public long getRoot_inum() {
+		return root_inum;
+	}	
+        /**
+         * get the first inum in this file system
+         * @return first inum
+         */
+        public long getFirst_inum() {
+		return first_inum;
+	}	 	
+        /**
+         * get the last inum
+         * @return last inum
+         */
+        public long getLast_inum() {
+		return last_inum;
+	}	
+	
+	public void finalize(){
+		if(filesystemHandle != 0){
+			SleuthkitJNI.closeFs(filesystemHandle);
+		}
+	}
+}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/FsContent.java b/bindings/java/src/org/sleuthkit/datamodel/FsContent.java
new file mode 100644
index 0000000000000000000000000000000000000000..a44d07b2337f528fb639b4f9606570b6c6100b39
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/FsContent.java
@@ -0,0 +1,1196 @@
+package org.sleuthkit.datamodel;
+
+/**
+ * generalized class for files and directories
+ * @author alawrence
+ */
+public class FsContent implements Content{
+
+    /*
+     * database fields
+     */
+    protected long attr_type, attr_id, par_file_id, dirtype, meta_type, dir_type, dir_flags,
+    meta_flags, size, ctime, crtime, atime, mtime, uid, gid, fs_id, mode,
+    file_id;
+    /**
+     * name from the database
+     */
+    protected String name;
+    /**
+     * parent file system
+     */
+    protected FileSystem parentFileSystem;
+    /**
+     * file Handle
+     */
+    protected long fileHandle = 0;
+    /**
+     * database object
+     */
+    protected Sleuthkit db;
+
+    /**
+     * sets the parent, called by parent on creation
+     * @param parent parent file system object
+     */
+    protected void setParent(FileSystem parent){
+        parentFileSystem = parent;
+    }
+
+    @Override
+    public byte[] read(long offset, long len) throws TskException{
+        if (fileHandle == 0){
+                fileHandle = SleuthkitJNI.openFile(parentFileSystem.getFileSystemHandle(), file_id);
+        }
+        return SleuthkitJNI.readFile(fileHandle, offset, len);
+    }
+
+    //methods get exact data from database. could be manipulated to get more
+    //meaningful data.
+    /**
+     * is this a file?
+     * @return false unless overridden by a subclass (specifically the file subclass)
+     */
+    public boolean isFile(){
+        return false;
+    }
+    /**
+     * is this a directory?
+     * @return false unless overridden by a subclass (specifically the directory subclass)
+     */
+    public boolean isDir(){
+        return false;
+    }
+
+    /**
+     * get the parent file system
+     * @return the file system object of the parent
+     */
+    public FileSystem getParent(){
+        return parentFileSystem;
+    }
+
+    /**
+     * get the sleuthkit database object
+     * @return the sleuthkit object
+     */
+    public Sleuthkit getSleuthkit(){
+        return db;
+    }
+
+    /**
+     * get the name
+     * @return name
+     */
+    public String getName(){
+        return name;
+    }
+
+    /**
+     * get the attribute type
+     * @return attribute type
+     */
+    public long getAttr_type(){
+        return attr_type;
+    }
+    
+    /**
+     * get the attribute id
+     * @return attribute id
+     */
+    public long getAttr_id(){
+        return attr_id;
+    }
+
+    /**
+     * get the file id
+     * @return file id
+     */
+    public long getPar_file_id(){
+        return par_file_id;
+    }
+
+    /**
+     * get the directory type
+     * @return directory type
+     */
+    public long getDirtype(){
+        return dirtype;
+    }
+
+    /**
+     * get the meta data type
+     * @return meta data type
+     */
+    public long getMeta_type(){
+        return meta_type;
+    }
+    /**
+     * get the meta data type as String
+     * @return meta data type as String
+     */
+    public String getMetaTypeAsString(){
+        return FsContent.metaTypeToString(meta_type);
+    }
+
+    /**
+     * get the directory type
+     * @return directory type
+     */
+    public long getDir_type(){
+        return dir_type;
+    }
+    /**
+     * get the directory type as String
+     * @return directory type as String
+     */
+    public String getDirTypeAsString(){
+        return FsContent.dirTypeToString(dir_type);
+    }
+
+    /**
+     * get the directory flags
+     * @return directory flags
+     */
+    public long getDir_flags(){
+        return dir_flags;
+    }
+    /**
+     * get the directory flags as String
+     * @return directory flags as String
+     */
+    public String getDirFlagsAsString(){
+        return FsContent.dirFlagToString(dir_flags);
+    }
+
+    /**
+     * get the meta data flags
+     * @return meta data flags
+     */
+    public long getMeta_flags(){
+        return meta_flags;
+    }
+    /**
+     * get the meta data flags as String
+     * @return meta data flags as String
+     */
+    public String getMetaFlagsAsString(){
+        return FsContent.metaFlagToString(meta_flags);
+    }
+
+    /**
+     * get the size of the content
+     * @return size of the content
+     */
+    @Override
+    public long getSize(){
+        return size;
+    }
+    /**
+     * get the change time
+     * @return change time
+     */
+    public long getCtime(){
+        return ctime;
+    }
+    /**
+     * get the change time as Date
+     * @return change time as Date
+     */
+    public String getCtimeAsDate(){
+        return FsContent.epochToTime(ctime);
+    }
+
+    /**
+     * get the creation time
+     * @return creation time
+     */
+    public long getCrtime(){
+        return crtime;
+    }
+    /**
+     * get the creation time as Date
+     * @return creation time as Date
+     */
+    public String getCrtimeAsDate(){
+        return FsContent.epochToTime(crtime);
+    }
+
+    /**
+     * get the access time
+     * @return access time
+     */
+    public long getAtime(){
+        return atime;
+    }
+    /**
+     * get the access time as Date
+     * @return access time as Date
+     */
+    public String getAtimeAsDate(){
+        return FsContent.epochToTime(atime);
+    }
+
+    /**
+     * get the modified time
+     * @return modified time
+     */
+    public long getMtime(){
+        return mtime;
+    }
+    /**
+     * get the modified time as Date
+     * @return modified time as Date
+     */
+    public String getMtimeAsDate(){
+        return FsContent.epochToTime(mtime);
+    }
+    
+    /**
+     * get the user id
+     * @return user id
+     */
+    public long getUid(){
+        return uid;
+    }
+    /**
+     * get the group id
+     * @return group id
+     */
+    public long getGid(){
+        return gid;
+    }
+    /**
+     * get the file system id
+     * @return file system id
+     */
+    public long getFs_id(){
+        return fs_id;
+    }
+    /**
+     * get the mode
+     * @return mode
+     */
+    public long getMode(){
+        return mode;
+    }
+    /**
+     * get the mode as String
+     * @return mode as String
+     */
+    public String getModeAsString(){
+        return FsContent.modeToString(mode, meta_type);
+    }
+    
+    /**
+     * get the file id
+     * @return file id
+     */
+    public long getFile_id(){
+        return file_id;
+    }
+
+    public void finalize(){
+        if(fileHandle != 0){
+                SleuthkitJNI.closeFile(fileHandle);
+        }
+    }
+
+    /*
+     * -------------------------------------------------------------------------
+     * All the methods below are used to convert / map the data
+     * -------------------------------------------------------------------------
+     */
+
+    // return the epoch into string in ISO 8601 dateTime format
+    public static String epochToTime(long epoch){
+        String time = "0000-00-00 00:00:00";
+        if(epoch != 0){
+            // Note: new java.util.Date(long date) -> date represent the specific number of milliseconds since the standard base time known.
+            // Therefore we need to times the date / epoch with 1000.
+            time = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date(epoch*1000));
+        }
+        return time;
+    }
+
+    // return the date in the ISO 8601 dateTime format into epoch
+    public static long timeToEpoch(String time){
+        long epoch = 0;
+        try{
+            epoch = new java.text.SimpleDateFormat ("yyyy-MM-dd HH:mm:ss").parse(time).getTime() / 1000;
+        }
+        catch(Exception e){}
+
+        return epoch;
+    }
+
+    // --- Here are all the methods for Directory Type conversion / mapping ---
+    public static String dirTypeToValue(long dirType){
+
+        String result = "";
+
+        for (TskData.TSK_FS_NAME_TYPE_ENUM type : TskData.TSK_FS_NAME_TYPE_ENUM.values()){
+            if(type.getDirType() == dirType){
+                result = type.toString();
+            }
+        }
+        return result;
+    }
+
+    public static long valueToDirType(String dirType){
+
+        long result = 0;
+
+        for (TskData.TSK_FS_NAME_TYPE_ENUM type : TskData.TSK_FS_NAME_TYPE_ENUM.values()){
+            if(type.toString().equals(dirType)){
+                result = type.getDirType();
+            }
+        }
+        return result;
+    }
+
+    public static String dirTypeToString(long dirType){
+        return TskData.tsk_fs_name_type_str[(int)dirType];
+    }
+
+
+    // -------- Here all the methods for Meta Type conversion / mapping --------
+    public static String metaTypeToValue(long metaType){
+        
+        String result = "";
+
+        for (TskData.TSK_FS_META_TYPE_ENUM type : TskData.TSK_FS_META_TYPE_ENUM.values()){
+            if(type.getMetaType() == metaType){
+                result = type.toString();
+            }
+        }
+        return result;
+    }
+
+    public static long valueToMetaType(String metaType){
+
+        long result = 0;
+
+        for (TskData.TSK_FS_META_TYPE_ENUM type : TskData.TSK_FS_META_TYPE_ENUM.values()){
+            if(type.toString().equals(metaType)){
+                result = type.getMetaType();
+            }
+        }
+        return result;
+    }
+
+    public static String metaTypeToString(long metaType){
+        return TskData.tsk_fs_meta_type_str[(int)metaType];
+    }
+
+    // ----- Here all the methods for Directory Flags conversion / mapping -----
+    public static String dirFlagToValue(long dirFlag){
+
+        String result = "";
+
+        for (TskData.TSK_FS_NAME_FLAG_ENUM flag : TskData.TSK_FS_NAME_FLAG_ENUM.values()){
+            if(flag.getDirFlag() == dirFlag){
+                result = flag.toString();
+            }
+        }
+        return result;
+    }
+
+    public static long valueToDirFlag(String dirFlag){
+
+        long result = 0;
+
+        for (TskData.TSK_FS_NAME_FLAG_ENUM flag : TskData.TSK_FS_NAME_FLAG_ENUM.values()){
+            if(flag.toString().equals(dirFlag)){
+                result = flag.getDirFlag();
+            }
+        }
+        return result;
+    }
+
+    public static String dirFlagToString(long dirFlag){
+        
+        String result = "";
+
+        long allocFlag = TskData.TSK_FS_NAME_FLAG_ENUM.TSK_FS_NAME_FLAG_ALLOC.getDirFlag();
+        long unallocFlag = TskData.TSK_FS_NAME_FLAG_ENUM.TSK_FS_NAME_FLAG_UNALLOC.getDirFlag();
+
+        if((dirFlag & allocFlag) == allocFlag){
+            result = "Allocated";
+        }
+        if((dirFlag & unallocFlag) == unallocFlag){
+            result = "Unallocated";
+        }
+
+        return result;
+    }
+
+    // ----- Here all the methods for Meta Flags conversion / mapping -----
+    public static String metaFlagToValue(long metaFlag){
+
+        String result = "";
+
+        for (TskData.TSK_FS_META_FLAG_ENUM flag : TskData.TSK_FS_META_FLAG_ENUM.values()){
+            if(flag.getMetaFlag() == metaFlag){
+                result = flag.toString();
+            }
+        }
+        return result;
+    }
+
+    public static long valueToMetaFlag(String metaFlag){
+
+        long result = 0;
+
+        for (TskData.TSK_FS_META_FLAG_ENUM flag : TskData.TSK_FS_META_FLAG_ENUM.values()){
+            if(flag.toString().equals(metaFlag)){
+                result = flag.getMetaFlag();
+            }
+        }
+        return result;
+    }
+
+    public static String metaFlagToString(long metaFlag){
+
+        String result = "";
+
+        long allocFlag = TskData.TSK_FS_META_FLAG_ENUM.TSK_FS_META_FLAG_ALLOC.getMetaFlag();
+        long unallocFlag = TskData.TSK_FS_META_FLAG_ENUM.TSK_FS_META_FLAG_UNALLOC.getMetaFlag();
+
+        // some variables that might be needed in the future
+        long usedFlag = TskData.TSK_FS_META_FLAG_ENUM.TSK_FS_META_FLAG_USED.getMetaFlag();
+        long unusedFlag = TskData.TSK_FS_META_FLAG_ENUM.TSK_FS_META_FLAG_UNUSED.getMetaFlag();
+        long compFlag = TskData.TSK_FS_META_FLAG_ENUM.TSK_FS_META_FLAG_COMP.getMetaFlag();
+        long orphanFlag = TskData.TSK_FS_META_FLAG_ENUM.TSK_FS_META_FLAG_ORPHAN.getMetaFlag();
+
+        if((metaFlag & allocFlag) == allocFlag){
+            result = "Allocated";
+        }
+        if((metaFlag & unallocFlag) == unallocFlag){
+            result = "Unallocated";
+        }
+        // ... add more code here if needed
+
+        return result;
+    }
+
+    // ----- Here is the method to convert Mode to String -----
+    public static String modeToString(long mode, long metaType){
+        
+        String result = "";
+
+        long metaTypeMax = TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_STR_MAX.getMetaType();
+
+        long isuid = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_ISUID.getMode(); 
+        long isgid = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_ISGID.getMode();
+        long isvtx = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_ISVTX.getMode();
+
+        long irusr = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IRUSR.getMode();
+        long iwusr = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IWUSR.getMode();
+        long ixusr = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IXUSR.getMode();
+
+        long irgrp = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IRGRP.getMode();
+        long iwgrp = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IWGRP.getMode();
+        long ixgrp= TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IXGRP.getMode();
+
+        long iroth = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IROTH.getMode();
+        long iwoth = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IWOTH.getMode();
+        long ixoth = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IXOTH.getMode();
+
+        // first character = the Meta Type
+        if(metaType < metaTypeMax){
+            result += FsContent.metaTypeToString(metaType);
+        }
+        else{result += "-";}
+
+        // second and third characters = user permissions
+        if((mode & irusr) == irusr){
+            result += "r";
+        }
+        else{result += "-";}
+        if((mode & iwusr) == iwusr){
+            result += "w";
+        }
+        else{result += "-";}
+
+        // fourth character = set uid
+        if((mode & isuid) == isuid){
+            if((mode & ixusr) == ixusr){
+                result += "s";
+            }
+            else{
+                result += "S";
+            }
+        }
+        else{
+            if((mode & ixusr) == ixusr){
+                result += "x";
+            }
+            else{
+                result += "-";
+            }
+        }
+
+        // fifth and sixth characters = group permissions
+        if((mode & irgrp) == irgrp){
+            result += "r";
+        }
+        else{result += "-";}
+        if((mode & iwgrp) == iwgrp){
+            result += "w";
+        }
+        else{result += "-";}
+
+        // seventh character = set gid
+        if((mode & isgid) == isgid){
+            if((mode & ixgrp) == ixgrp){
+                result += "s";
+            }
+            else{
+                result += "S";
+            }
+        }
+        else{
+            if((mode & ixgrp) == ixgrp){
+                result += "x";
+            }
+            else{
+                result += "-";
+            }
+        }
+
+        // eighth and ninth character = other permissions
+        if((mode & iroth) == iroth){
+            result += "r";
+        }
+        else{result += "-";}
+        if((mode & iwoth) == iwoth){
+            result += "w";
+        }
+        else{result += "-";}
+
+        // tenth character = sticky bit
+        if((mode & isvtx) == isvtx){
+            if((mode & ixoth) == ixoth){
+                result += "t";
+            }
+            else{
+                result += "T";
+            }
+        }
+        else{
+            if((mode & ixoth) == ixoth){
+                result += "x";
+            }
+            else{
+                result += "-";
+            }
+        }
+
+        // check the result
+        if(result.length() != 10){
+            // throw error here
+            result = "ERROR";
+        }
+        return result;
+    }
+
+}
+package org.sleuthkit.datamodel;
+
+/**
+ * generalized class for files and directories
+ * @author alawrence
+ */
+public class FsContent implements Content{
+
+    /*
+     * database fields
+     */
+    protected long attr_type, attr_id, par_file_id, dirtype, meta_type, dir_type, dir_flags,
+    meta_flags, size, ctime, crtime, atime, mtime, uid, gid, fs_id, mode,
+    file_id;
+    /**
+     * name from the database
+     */
+    protected String name;
+    /**
+     * parent file system
+     */
+    protected FileSystem parentFileSystem;
+    /**
+     * file Handle
+     */
+    protected long fileHandle = 0;
+    /**
+     * database object
+     */
+    protected Sleuthkit db;
+
+    /**
+     * sets the parent, called by parent on creation
+     * @param parent parent file system object
+     */
+    protected void setParent(FileSystem parent){
+        parentFileSystem = parent;
+    }
+
+    @Override
+    public byte[] read(long offset, long len) throws TskException{
+        if (fileHandle == 0){
+                fileHandle = SleuthkitJNI.openFile(parentFileSystem.getFileSystemHandle(), file_id);
+        }
+        return SleuthkitJNI.readFile(fileHandle, offset, len);
+    }
+
+    //methods get exact data from database. could be manipulated to get more
+    //meaningful data.
+    /**
+     * is this a file?
+     * @return false unless overridden by a subclass (specifically the file subclass)
+     */
+    public boolean isFile(){
+        return false;
+    }
+    /**
+     * is this a directory?
+     * @return false unless overridden by a subclass (specifically the directory subclass)
+     */
+    public boolean isDir(){
+        return false;
+    }
+
+    /**
+     * get the parent file system
+     * @return the file system object of the parent
+     */
+    public FileSystem getParent(){
+        return parentFileSystem;
+    }
+
+    /**
+     * get the sleuthkit database object
+     * @return the sleuthkit object
+     */
+    public Sleuthkit getSleuthkit(){
+        return db;
+    }
+
+    /**
+     * get the name
+     * @return name
+     */
+    public String getName(){
+        return name;
+    }
+
+    /**
+     * get the attribute type
+     * @return attribute type
+     */
+    public long getAttr_type(){
+        return attr_type;
+    }
+    
+    /**
+     * get the attribute id
+     * @return attribute id
+     */
+    public long getAttr_id(){
+        return attr_id;
+    }
+
+    /**
+     * get the file id
+     * @return file id
+     */
+    public long getPar_file_id(){
+        return par_file_id;
+    }
+
+    /**
+     * get the directory type
+     * @return directory type
+     */
+    public long getDirtype(){
+        return dirtype;
+    }
+
+    /**
+     * get the meta data type
+     * @return meta data type
+     */
+    public long getMeta_type(){
+        return meta_type;
+    }
+    /**
+     * get the meta data type as String
+     * @return meta data type as String
+     */
+    public String getMetaTypeAsString(){
+        return FsContent.metaTypeToString(meta_type);
+    }
+
+    /**
+     * get the directory type
+     * @return directory type
+     */
+    public long getDir_type(){
+        return dir_type;
+    }
+    /**
+     * get the directory type as String
+     * @return directory type as String
+     */
+    public String getDirTypeAsString(){
+        return FsContent.dirTypeToString(dir_type);
+    }
+
+    /**
+     * get the directory flags
+     * @return directory flags
+     */
+    public long getDir_flags(){
+        return dir_flags;
+    }
+    /**
+     * get the directory flags as String
+     * @return directory flags as String
+     */
+    public String getDirFlagsAsString(){
+        return FsContent.dirFlagToString(dir_flags);
+    }
+
+    /**
+     * get the meta data flags
+     * @return meta data flags
+     */
+    public long getMeta_flags(){
+        return meta_flags;
+    }
+    /**
+     * get the meta data flags as String
+     * @return meta data flags as String
+     */
+    public String getMetaFlagsAsString(){
+        return FsContent.metaFlagToString(meta_flags);
+    }
+
+    /**
+     * get the size of the content
+     * @return size of the content
+     */
+    @Override
+    public long getSize(){
+        return size;
+    }
+    /**
+     * get the change time
+     * @return change time
+     */
+    public long getCtime(){
+        return ctime;
+    }
+    /**
+     * get the change time as Date
+     * @return change time as Date
+     */
+    public String getCtimeAsDate(){
+        return FsContent.epochToTime(ctime);
+    }
+
+    /**
+     * get the creation time
+     * @return creation time
+     */
+    public long getCrtime(){
+        return crtime;
+    }
+    /**
+     * get the creation time as Date
+     * @return creation time as Date
+     */
+    public String getCrtimeAsDate(){
+        return FsContent.epochToTime(crtime);
+    }
+
+    /**
+     * get the access time
+     * @return access time
+     */
+    public long getAtime(){
+        return atime;
+    }
+    /**
+     * get the access time as Date
+     * @return access time as Date
+     */
+    public String getAtimeAsDate(){
+        return FsContent.epochToTime(atime);
+    }
+
+    /**
+     * get the modified time
+     * @return modified time
+     */
+    public long getMtime(){
+        return mtime;
+    }
+    /**
+     * get the modified time as Date
+     * @return modified time as Date
+     */
+    public String getMtimeAsDate(){
+        return FsContent.epochToTime(mtime);
+    }
+    
+    /**
+     * get the user id
+     * @return user id
+     */
+    public long getUid(){
+        return uid;
+    }
+    /**
+     * get the group id
+     * @return group id
+     */
+    public long getGid(){
+        return gid;
+    }
+    /**
+     * get the file system id
+     * @return file system id
+     */
+    public long getFs_id(){
+        return fs_id;
+    }
+    /**
+     * get the mode
+     * @return mode
+     */
+    public long getMode(){
+        return mode;
+    }
+    /**
+     * get the mode as String
+     * @return mode as String
+     */
+    public String getModeAsString(){
+        return FsContent.modeToString(mode, meta_type);
+    }
+    
+    /**
+     * get the file id
+     * @return file id
+     */
+    public long getFile_id(){
+        return file_id;
+    }
+
+    public void finalize(){
+        if(fileHandle != 0){
+                SleuthkitJNI.closeFile(fileHandle);
+        }
+    }
+
+    /*
+     * -------------------------------------------------------------------------
+     * All the methods below are used to convert / map the data
+     * -------------------------------------------------------------------------
+     */
+
+    // return the epoch into string in ISO 8601 dateTime format
+    public static String epochToTime(long epoch){
+        String time = "0000-00-00 00:00:00";
+        if(epoch != 0){
+            // Note: new java.util.Date(long date) -> date represent the specific number of milliseconds since the standard base time known.
+            // Therefore we need to times the date / epoch with 1000.
+            time = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date(epoch*1000));
+        }
+        return time;
+    }
+
+    // return the date in the ISO 8601 dateTime format into epoch
+    public static long timeToEpoch(String time){
+        long epoch = 0;
+        try{
+            epoch = new java.text.SimpleDateFormat ("yyyy-MM-dd HH:mm:ss").parse(time).getTime() / 1000;
+        }
+        catch(Exception e){}
+
+        return epoch;
+    }
+
+    // --- Here are all the methods for Directory Type conversion / mapping ---
+    public static String dirTypeToValue(long dirType){
+
+        String result = "";
+
+        for (TskData.TSK_FS_NAME_TYPE_ENUM type : TskData.TSK_FS_NAME_TYPE_ENUM.values()){
+            if(type.getDirType() == dirType){
+                result = type.toString();
+            }
+        }
+        return result;
+    }
+
+    public static long valueToDirType(String dirType){
+
+        long result = 0;
+
+        for (TskData.TSK_FS_NAME_TYPE_ENUM type : TskData.TSK_FS_NAME_TYPE_ENUM.values()){
+            if(type.toString().equals(dirType)){
+                result = type.getDirType();
+            }
+        }
+        return result;
+    }
+
+    public static String dirTypeToString(long dirType){
+        return TskData.tsk_fs_name_type_str[(int)dirType];
+    }
+
+
+    // -------- Here all the methods for Meta Type conversion / mapping --------
+    public static String metaTypeToValue(long metaType){
+        
+        String result = "";
+
+        for (TskData.TSK_FS_META_TYPE_ENUM type : TskData.TSK_FS_META_TYPE_ENUM.values()){
+            if(type.getMetaType() == metaType){
+                result = type.toString();
+            }
+        }
+        return result;
+    }
+
+    public static long valueToMetaType(String metaType){
+
+        long result = 0;
+
+        for (TskData.TSK_FS_META_TYPE_ENUM type : TskData.TSK_FS_META_TYPE_ENUM.values()){
+            if(type.toString().equals(metaType)){
+                result = type.getMetaType();
+            }
+        }
+        return result;
+    }
+
+    public static String metaTypeToString(long metaType){
+        return TskData.tsk_fs_meta_type_str[(int)metaType];
+    }
+
+    // ----- Here all the methods for Directory Flags conversion / mapping -----
+    public static String dirFlagToValue(long dirFlag){
+
+        String result = "";
+
+        for (TskData.TSK_FS_NAME_FLAG_ENUM flag : TskData.TSK_FS_NAME_FLAG_ENUM.values()){
+            if(flag.getDirFlag() == dirFlag){
+                result = flag.toString();
+            }
+        }
+        return result;
+    }
+
+    public static long valueToDirFlag(String dirFlag){
+
+        long result = 0;
+
+        for (TskData.TSK_FS_NAME_FLAG_ENUM flag : TskData.TSK_FS_NAME_FLAG_ENUM.values()){
+            if(flag.toString().equals(dirFlag)){
+                result = flag.getDirFlag();
+            }
+        }
+        return result;
+    }
+
+    public static String dirFlagToString(long dirFlag){
+        
+        String result = "";
+
+        long allocFlag = TskData.TSK_FS_NAME_FLAG_ENUM.TSK_FS_NAME_FLAG_ALLOC.getDirFlag();
+        long unallocFlag = TskData.TSK_FS_NAME_FLAG_ENUM.TSK_FS_NAME_FLAG_UNALLOC.getDirFlag();
+
+        if((dirFlag & allocFlag) == allocFlag){
+            result = "Allocated";
+        }
+        if((dirFlag & unallocFlag) == unallocFlag){
+            result = "Unallocated";
+        }
+
+        return result;
+    }
+
+    // ----- Here all the methods for Meta Flags conversion / mapping -----
+    public static String metaFlagToValue(long metaFlag){
+
+        String result = "";
+
+        for (TskData.TSK_FS_META_FLAG_ENUM flag : TskData.TSK_FS_META_FLAG_ENUM.values()){
+            if(flag.getMetaFlag() == metaFlag){
+                result = flag.toString();
+            }
+        }
+        return result;
+    }
+
+    public static long valueToMetaFlag(String metaFlag){
+
+        long result = 0;
+
+        for (TskData.TSK_FS_META_FLAG_ENUM flag : TskData.TSK_FS_META_FLAG_ENUM.values()){
+            if(flag.toString().equals(metaFlag)){
+                result = flag.getMetaFlag();
+            }
+        }
+        return result;
+    }
+
+    public static String metaFlagToString(long metaFlag){
+
+        String result = "";
+
+        long allocFlag = TskData.TSK_FS_META_FLAG_ENUM.TSK_FS_META_FLAG_ALLOC.getMetaFlag();
+        long unallocFlag = TskData.TSK_FS_META_FLAG_ENUM.TSK_FS_META_FLAG_UNALLOC.getMetaFlag();
+
+        // some variables that might be needed in the future
+        long usedFlag = TskData.TSK_FS_META_FLAG_ENUM.TSK_FS_META_FLAG_USED.getMetaFlag();
+        long unusedFlag = TskData.TSK_FS_META_FLAG_ENUM.TSK_FS_META_FLAG_UNUSED.getMetaFlag();
+        long compFlag = TskData.TSK_FS_META_FLAG_ENUM.TSK_FS_META_FLAG_COMP.getMetaFlag();
+        long orphanFlag = TskData.TSK_FS_META_FLAG_ENUM.TSK_FS_META_FLAG_ORPHAN.getMetaFlag();
+
+        if((metaFlag & allocFlag) == allocFlag){
+            result = "Allocated";
+        }
+        if((metaFlag & unallocFlag) == unallocFlag){
+            result = "Unallocated";
+        }
+        // ... add more code here if needed
+
+        return result;
+    }
+
+    // ----- Here is the method to convert Mode to String -----
+    public static String modeToString(long mode, long metaType){
+        
+        String result = "";
+
+        long metaTypeMax = TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_STR_MAX.getMetaType();
+
+        long isuid = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_ISUID.getMode(); 
+        long isgid = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_ISGID.getMode();
+        long isvtx = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_ISVTX.getMode();
+
+        long irusr = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IRUSR.getMode();
+        long iwusr = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IWUSR.getMode();
+        long ixusr = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IXUSR.getMode();
+
+        long irgrp = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IRGRP.getMode();
+        long iwgrp = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IWGRP.getMode();
+        long ixgrp= TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IXGRP.getMode();
+
+        long iroth = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IROTH.getMode();
+        long iwoth = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IWOTH.getMode();
+        long ixoth = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IXOTH.getMode();
+
+        // first character = the Meta Type
+        if(metaType < metaTypeMax){
+            result += FsContent.metaTypeToString(metaType);
+        }
+        else{result += "-";}
+
+        // second and third characters = user permissions
+        if((mode & irusr) == irusr){
+            result += "r";
+        }
+        else{result += "-";}
+        if((mode & iwusr) == iwusr){
+            result += "w";
+        }
+        else{result += "-";}
+
+        // fourth character = set uid
+        if((mode & isuid) == isuid){
+            if((mode & ixusr) == ixusr){
+                result += "s";
+            }
+            else{
+                result += "S";
+            }
+        }
+        else{
+            if((mode & ixusr) == ixusr){
+                result += "x";
+            }
+            else{
+                result += "-";
+            }
+        }
+
+        // fifth and sixth characters = group permissions
+        if((mode & irgrp) == irgrp){
+            result += "r";
+        }
+        else{result += "-";}
+        if((mode & iwgrp) == iwgrp){
+            result += "w";
+        }
+        else{result += "-";}
+
+        // seventh character = set gid
+        if((mode & isgid) == isgid){
+            if((mode & ixgrp) == ixgrp){
+                result += "s";
+            }
+            else{
+                result += "S";
+            }
+        }
+        else{
+            if((mode & ixgrp) == ixgrp){
+                result += "x";
+            }
+            else{
+                result += "-";
+            }
+        }
+
+        // eighth and ninth character = other permissions
+        if((mode & iroth) == iroth){
+            result += "r";
+        }
+        else{result += "-";}
+        if((mode & iwoth) == iwoth){
+            result += "w";
+        }
+        else{result += "-";}
+
+        // tenth character = sticky bit
+        if((mode & isvtx) == isvtx){
+            if((mode & ixoth) == ixoth){
+                result += "t";
+            }
+            else{
+                result += "T";
+            }
+        }
+        else{
+            if((mode & ixoth) == ixoth){
+                result += "x";
+            }
+            else{
+                result += "-";
+            }
+        }
+
+        // check the result
+        if(result.length() != 10){
+            // throw error here
+            result = "ERROR";
+        }
+        return result;
+    }
+
+}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/Image.java b/bindings/java/src/org/sleuthkit/datamodel/Image.java
new file mode 100644
index 0000000000000000000000000000000000000000..61da7bea747f1f18c563e3346b1f6623406d7b87
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/Image.java
@@ -0,0 +1,205 @@
+package org.sleuthkit.datamodel;
+
+import java.sql.SQLException;
+
+/**
+ * Image class
+ * @author alawrence
+ */
+public class Image implements Content {
+    //data about image
+
+    private long type, ssize;
+    private String name;
+    private String[] paths;
+    private Sleuthkit db;
+    private long imageHandle = 0;
+
+    /**
+     * constructor most inputs are from the database
+     * @param db database object
+     * @param type
+     * @param ssize
+     * @param name
+     * @param path
+     */
+    protected Image(Sleuthkit db, long type, long ssize, String name, String[] paths) throws TskException {
+        this.db = db;
+        this.type = type;
+        this.ssize = ssize;
+        this.name = name;
+        this.paths = paths;
+        this.imageHandle = SleuthkitJNI.openImage(paths);
+    }
+
+    /**
+     * sets a new image path (NOT CURRENTLY IMPLEMENTED)
+     * @param newPath new image path
+     */
+    public void setPath(String newPath) {
+        //check if path is valid/leads to an image
+    }
+
+    /**
+     * get the volume system at the given byte offset
+     * @param offset bytes (should be 0 in most cases)
+     * @return volume system object
+     */
+    public VolumeSystem getVolumeSystem(long offset) throws SQLException {
+        VolumeSystem vs = db.getVolumeSystem(offset);
+        if (vs != null) {
+            vs.setParent(this);
+        }
+        return vs;
+    }
+
+    /**
+     * get the handle to the sleuthkit image info object
+     * @return the object pointer
+     */
+    public long getImageHandle() {
+        return imageHandle;
+    }
+
+    /**
+     * read from the image
+     * @param offset in bytes
+     * @param len in bytes
+     * @return the byte data
+     * @throws TskException
+     */
+    @Override
+    public byte[] read(long offset, long len) throws TskException {
+        // read from the image
+        return SleuthkitJNI.readImg(imageHandle, offset, len);
+    }
+
+    /**
+     * get the image size
+     * @return image size
+     */
+    @Override
+    public long getSize() {
+        return 0;
+    }
+
+    //methods get exact data from database. could be manipulated to get more
+    //meaningful data.
+    /**
+     * get the type
+     * @return type
+     */
+    public long getType() {
+        return type;
+    }
+
+    /**
+     * get the sector size
+     * @return sector size
+     */
+    public long getSsize() {
+        return ssize;
+    }
+
+    /**
+     * get the name
+     * @return name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * get the path
+     * @return path
+     */
+    public String[] getPaths() {
+        return paths;
+    }
+
+    /**
+     * get the sleuthkit database object
+     * @return the sleuthkit object
+     */
+    public Sleuthkit getSleuthkit(){
+        return db;
+    }
+
+    // ----- Here all the methods for Image Type conversion / mapping -----
+
+    public static String imageTypeToValue(long imageType){
+
+        String result = "";
+
+        for (TskData.TSK_IMG_TYPE_ENUM imgType : TskData.TSK_IMG_TYPE_ENUM.values()){
+            if(imgType.getImageType() == imageType){
+                result = imgType.toString();
+            }
+        }
+        return result;
+    }
+
+    public static long valueToImageType(String imageType){
+
+        long result = 0;
+
+        for (TskData.TSK_IMG_TYPE_ENUM imgType : TskData.TSK_IMG_TYPE_ENUM.values()){
+            if(imgType.toString().equals(imageType)){
+                result = imgType.getImageType();
+            }
+        }
+        return result;
+    }
+
+    public static String imageTypeToString(long imageType){
+
+        String result = "";
+
+        long detect = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_DETECT.getImageType();
+        long raw = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_RAW_SING.getImageType();
+        long split = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_RAW_SPLIT.getImageType();
+        long aff = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_AFF_AFF.getImageType();
+        long afd = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_AFF_AFD.getImageType();
+        long afm = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_AFF_AFM.getImageType();
+        long afflib = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_AFF_ANY.getImageType();
+        long ewf = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_EWF_EWF.getImageType();
+        long unsupported = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_UNSUPP.getImageType();
+
+        if(imageType == detect){
+            result = "Auto Detection";
+        }
+        if(imageType == raw){
+            result = "Single raw file (dd)";
+        }
+        if(imageType == split){
+            result = "Split raw files";
+        }
+        if(imageType == aff){
+            result = "Advanced Forensic Format";
+        }
+        if(imageType == afd){
+            result = "AFF Multiple File";
+        }
+        if(imageType == afm){
+            result = "AFF with external metadata";
+        }
+        if(imageType == afflib){
+            result = "All AFFLIB image formats (including beta ones)";
+        }
+        if(imageType == ewf){
+            result = "Expert Witness format (encase)";
+        }
+        if(imageType == unsupported){
+            result = "Unsupported Image Type";
+        }
+
+        return result;
+    }
+
+    /**
+     * Closes the connection to the sleuthkit.
+     */
+    public void closeConnection(){
+        db.closeConnection();
+    }
+}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/Sleuthkit.java b/bindings/java/src/org/sleuthkit/datamodel/Sleuthkit.java
new file mode 100644
index 0000000000000000000000000000000000000000..b4fb35d417b75799217ca0e079b8c15194fcc982
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/Sleuthkit.java
@@ -0,0 +1,1002 @@
+package org.sleuthkit.datamodel;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.*;
+import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_TYPE_ENUM;
+
+/**
+ * database connection object. makes use of the sqlite jdbc libraries
+ * @author alawrence
+ */
+public class Sleuthkit {
+	private String dbPath;
+        private String imageDirectory;
+	private Connection con;
+
+        /**
+         * constructor
+         * @param path path to the database
+         * @throws SQLException
+         * @throws ClassNotFoundException
+         */
+        public Sleuthkit(String dbPath) throws SQLException, ClassNotFoundException{
+	        Class.forName("org.sqlite.JDBC");
+		this.dbPath = dbPath;
+                int i = dbPath.length()-1;
+                while(dbPath.charAt(i) != '\\' && dbPath.charAt(i) != '/'){
+                    i--;
+                }
+                imageDirectory = dbPath.substring(0, i);
+		con = DriverManager.getConnection("jdbc:sqlite:" + dbPath);
+                con.setReadOnly(true);
+	}
+
+        public Sleuthkit(String dbPath, String imageDirectory) throws SQLException, ClassNotFoundException{
+                Class.forName("org.sqlite.JDBC");
+                this.dbPath = dbPath;
+                this.imageDirectory = imageDirectory;
+                con = DriverManager.getConnection("jdbc:sqlite:" + dbPath);
+        }
+
+        public static void makeDb(String[] paths, String outDir) throws TskException{
+            SleuthkitJNI.makeDb(paths, outDir);
+        }
+
+        /**
+         * fill a new filesystem content object with data from the database. will
+         * also check the database field to determine if it is a file or directory
+         * @param fs_id file system id
+         * @param file_id file id
+         * @return a new FsContent object
+         */
+        public FsContent getFile(long fs_id, long file_id) throws SQLException{
+		Statement statement;
+			statement = con.createStatement();
+
+			ResultSet rs = statement.executeQuery("select * from tsk_fs_files " +
+					"where file_id = " + file_id +" and fs_id = " + fs_id);
+			if(!rs.next()){
+                                rs.close();
+                                statement.close();
+			        return null;
+			}
+			else
+				if (rs.getLong("dir_type") == TSK_FS_NAME_TYPE_ENUM.TSK_FS_NAME_TYPE_DIR.getDirType()){
+					Directory dir = new Directory(this, rs.getLong("fs_id"), rs.getLong("file_id"), rs.getLong("attr_type"),
+							rs.getLong("attr_id"), rs.getString("name"), rs.getLong("par_file_id"), rs.getLong("dir_type"),
+							rs.getLong("meta_type"), rs.getLong("dir_flags"), rs.getLong("meta_flags"), rs.getLong("size"),
+							rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
+							rs.getLong("mode"), rs.getLong("uid"), rs.getLong("gid"));
+                                        rs.close();
+                                        statement.close();
+                                        return dir;
+				}
+				else{
+					File file = new File(this, rs.getLong("fs_id"), rs.getLong("file_id"), rs.getLong("attr_type"),
+							rs.getLong("attr_id"), rs.getString("name"), rs.getLong("par_file_id"), rs.getLong("dir_type"),
+							rs.getLong("meta_type"), rs.getLong("dir_flags"), rs.getLong("meta_flags"), rs.getLong("size"),
+							rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
+							rs.getLong("mode"), rs.getLong("uid"), rs.getLong("gid"));
+                                        rs.close();
+                                        statement.close();
+                                        return file;
+				}
+	}
+
+        /**
+         * fill a new filesystem content object with data from the database. will
+         * also check the database field to determine if it is a file or directory
+         * @param fs_id file system id
+         * @param file_id file id
+         * @param name file name (used to differentiate between directories by name
+         * and . and .. directories
+         * @return a new FsContent object
+         */
+        public FsContent getFile(long fs_id, long file_id, String name) throws SQLException{
+            Statement statement;
+            statement = con.createStatement();
+
+            ResultSet rs = statement.executeQuery("select * from tsk_fs_files " +
+                            "where file_id = " + file_id +" and fs_id = " + fs_id + " and name = \"" + name + "\"");
+            if(!rs.next()){
+                    rs.close();
+                    statement.close();
+                    return null;
+            }
+            else{
+                String tempName = "";
+
+                // if name is empty, it's the root metadata so need to change the name to "."
+                if(name.equals("")){
+                    tempName = ".";
+                }
+                else{
+                    tempName = rs.getString("name");
+                }
+
+                if (rs.getLong("dir_type") == TSK_FS_NAME_TYPE_ENUM.TSK_FS_NAME_TYPE_DIR.getDirType()){
+                        Directory dir = new Directory(this, rs.getLong("fs_id"), rs.getLong("file_id"), rs.getLong("attr_type"),
+                                        rs.getLong("attr_id"), tempName, rs.getLong("par_file_id"), rs.getLong("dir_type"),
+                                        rs.getLong("meta_type"), rs.getLong("dir_flags"), rs.getLong("meta_flags"), rs.getLong("size"),
+                                        rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
+                                        rs.getLong("mode"), rs.getLong("uid"), rs.getLong("gid"));
+                        rs.close();
+                        statement.close();
+                        return dir;
+                }
+                else{
+                        File file = new File(this, rs.getLong("fs_id"), rs.getLong("file_id"), rs.getLong("attr_type"),
+                                        rs.getLong("attr_id"), rs.getString("name"), rs.getLong("par_file_id"), rs.getLong("dir_type"),
+                                        rs.getLong("meta_type"), rs.getLong("dir_flags"), rs.getLong("meta_flags"), rs.getLong("size"),
+                                        rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
+                                        rs.getLong("mode"), rs.getLong("uid"), rs.getLong("gid"));
+                        rs.close();
+                        statement.close();
+                        return file;
+                }
+            }
+	}
+
+        /**
+         * get the name and parent of the file/directory with the given id
+         * @param fs_id filesystem id
+         * @param file_id file id
+         * @return array of length 2 with the name and parent id
+         * @throws SQLException
+         */
+        public String[] getFsContentNameAndParent(long fs_id, long file_id) throws SQLException{
+            Statement statement;
+            statement = con.createStatement();
+
+            ResultSet rs = statement.executeQuery("select name, par_file_id from tsk_fs_files " +
+                            "where file_id = " + file_id +" and fs_id = " + fs_id);
+            if(!rs.next()){
+                String[] result = {"", "0"};
+                return result;
+            }
+            else{
+                String[] result = {rs.getString("name"), Long.toString(rs.getLong("par_file_id"))};
+                return result;
+            }
+        }
+
+        /**
+         * fills a new file system object with data from the database
+         * @param vol_id the volume to get the filesystem from
+         * @return a new file system object
+         */
+        public FileSystem getFileSystem(long vol_id) throws SQLException{
+		Statement statement;
+			statement = con.createStatement();
+
+			ResultSet rs = statement.executeQuery("select * from tsk_fs_info " +
+					"where vol_id = " + vol_id);
+			if(!rs.next()){
+                                rs.close();
+                                statement.close();
+				return null;
+			}
+			else{
+				FileSystem fs = new FileSystem(this, rs.getLong("fs_id"), rs.getLong("img_offset"), rs.getLong("vol_id"),
+						rs.getLong("fs_type"), rs.getLong("block_size"), rs.getLong("block_count"),
+                                                rs.getLong("root_inum"), rs.getLong("first_inum"), rs.getLong("last_inum"));
+                                rs.close();
+                                statement.close();
+                                return fs;
+            }
+	}
+
+        /**
+         * Gets a new file system object with data from the database
+         * @param fs_id  the FileSystem ID to get the filesystem from
+         * @return fs    a new file system object
+         */
+        public FileSystem getFileSystemFromID(long fs_id) throws SQLException{
+            Statement statement = con.createStatement();
+            ResultSet rs = statement.executeQuery("select * from tsk_fs_info " +
+                                    "where fs_id = " + fs_id);
+            if(!rs.next()){
+                rs.close();
+                statement.close();
+                return null;
+            }
+            else{
+                FileSystem fs = new FileSystem(this, rs.getLong("fs_id"), rs.getLong("img_offset"), rs.getLong("vol_id"),
+                                    rs.getLong("fs_type"), rs.getLong("block_size"), rs.getLong("block_count"),
+                                    rs.getLong("root_inum"), rs.getLong("first_inum"), rs.getLong("last_inum"));
+                return fs;
+            }
+	}
+
+        /**
+         * fills a new volume object from the database
+         * @param vol_id volume id
+         * @return new volume object
+         */
+        public Volume getVolume(long vol_id) throws SQLException{
+            //get volume info from the database
+            Statement statement;
+            statement = con.createStatement();
+
+            ResultSet rs = statement.executeQuery("select * from tsk_vs_parts " +
+                            "where vol_id = " + vol_id);
+            if(!rs.next()){
+                rs.close();
+                statement.close();
+                return null;
+            }
+            else{
+                Volume vol = new Volume(this, rs.getLong("vol_id"), rs.getLong("start"), rs.getLong("length"),
+                                rs.getLong("flags"), rs.getString("desc"));
+                rs.close();
+                statement.close();
+                return vol;
+            }
+	}
+
+        /**
+         * fills a new volume system object from the database
+         * @param offset offset to the volume system
+         * @return a new volume system object
+         */
+        public VolumeSystem getVolumeSystem(long offset) throws SQLException{
+            Statement statement;
+            ArrayList<Long> vol_ids = new ArrayList<Long>();
+            statement = con.createStatement();
+
+            ResultSet rs = statement.executeQuery("select * from tsk_vs_info " +
+                            "where img_offset = " + offset);
+            if(!rs.next()){
+                rs.close();
+                statement.close();
+                return null;
+            }
+            else{
+                long type = rs.getLong("vs_type");
+                long imgOffset = rs.getLong("img_offset");
+                long blockSize = rs.getLong("block_size");
+                rs = statement.executeQuery("select vol_id from tsk_vs_parts");
+                if(!rs.next()){
+                        rs.close();
+                        statement.close();
+                        return null;
+                }
+                else{
+                        do{
+                                vol_ids.add(new Long(rs.getLong("vol_id")));
+                        }while(rs.next());
+                }
+                VolumeSystem vs = new VolumeSystem(this, type, imgOffset, blockSize,
+                                vol_ids);
+                rs.close();
+                statement.close();
+                return vs;
+            }
+	}
+
+        /**
+         * get the name of this volume (based on the volume id)
+         * @param fs_id file system
+         * @return string with the name
+         * @throws SQLException
+         */
+        public String getVolName(long fs_id) throws SQLException{
+            Statement statement;
+            ArrayList<Long> vol_ids = new ArrayList<Long>();
+            statement = con.createStatement();
+
+            ResultSet rs = statement.executeQuery("select vol_id from tsk_fs_info " +
+                            "where fs_id = " + fs_id);
+            if(!rs.next()){
+                return null;
+            }
+            else{
+                return "vol" + rs.getLong("vol_id");
+            }
+        }
+
+        /**
+         * fills a new image object with data from the database
+         * @param imagePath path to the image
+         * @return a new image object
+         */
+        public Image getImage() throws TskException, SQLException{
+		//get image info from the database
+		Statement statement;
+		long type, ssize;
+		String name;
+                ArrayList<String> names = new ArrayList<String>();
+			statement = con.createStatement();
+
+			ResultSet rs = statement.executeQuery("select * from tsk_image_info");
+			if(!rs.next()){
+                                rs.close();
+                                statement.close();
+				return null;
+			}
+			else{
+				type = rs.getLong("type");
+				ssize = rs.getLong("ssize");
+			}
+			rs = statement.executeQuery("select * from tsk_image_names");
+			if(!rs.next()){
+                                rs.close();
+                                statement.close();
+				return null;
+			}
+			else{
+                            name = rs.getString("name");
+                            do{
+				names.add(imageDirectory + "\\" + rs.getString("name"));
+                            }while(rs.next());
+				
+			}
+
+			Image img = new Image(this, type, ssize, name, names.toArray(new String[names.size()]));
+                        rs.close();
+                        statement.close();
+                        return img;
+	}
+
+        /**
+         * searches the database for files whose parent is the given file
+         * @param dir_id directory id
+         * @param fs_id file system to search
+         * @return an arraylist of file ids
+         */
+        public ArrayList<Long> getChildIds(long dir_id, long fs_id) throws SQLException{
+			Statement statement = con.createStatement();
+			ArrayList<Long> childIds = new ArrayList<Long>();
+			ResultSet rs = statement.executeQuery("SELECT file_id FROM tsk_fs_files " +
+				"WHERE fs_id = " + fs_id + " AND par_file_id = " + dir_id);
+			if(!rs.next()){
+                                rs.close();
+                                statement.close();
+				return childIds;
+			}
+			else{
+                            do{
+                                    childIds.add(rs.getLong("file_id"));
+                            }while(rs.next());
+			}
+                        rs.close();
+                        statement.close();
+			return childIds;
+	}
+
+
+        /**
+         * get the names of the child files and directories. important for differentiating
+         * between directories and . and .. directories
+         * @param dir_id directory id
+         * @param fs_id file system to search
+         * @return an arraylist of names
+         */
+        public ArrayList<String> getChildNames(long dir_id, long fs_id) throws SQLException {
+			Statement statement = con.createStatement();
+			ArrayList<String> childIds = new ArrayList<String>();
+			ResultSet rs = statement.executeQuery("SELECT name FROM tsk_fs_files " +
+				"WHERE fs_id = " + fs_id + " AND par_file_id = " + dir_id);
+			if(!rs.next()){
+                                rs.close();
+                                statement.close();
+				return childIds;
+			}
+			else{
+                            do{
+                                    childIds.add(rs.getString("name"));
+                            }while(rs.next());
+			}
+                        rs.close();
+                        statement.close();
+			return childIds;
+	}
+        
+        /**
+         * fill a new filesystem content object with data from the database. will
+         * also check the database field to determine if it is a file or directory
+         * @param fs_id file system id
+         * @param file_id file id
+         * @param name file name (used to differentiate between directories by name
+         * and . and .. directories
+         * @return a new FsContent object
+         */
+        public ArrayList<FsContent> resultSetToObjects(ResultSet rs, Image img) throws SQLException{
+            ArrayList<FsContent> result = new ArrayList<FsContent>();
+            FileSystem fs;
+
+            if(!rs.next()){
+                    return result;
+            }
+            else{
+                Hashtable map = new Hashtable();
+
+                do{
+                    Long fsid = rs.getLong("fs_id");
+                    if(map.containsKey(fsid)){
+                        fs = (FileSystem)map.get(fsid);
+                    }
+                    else{
+                    // Set all the parents for the FsContent
+                    fs = this.getFileSystemFromID(fsid);
+                    Volume vol = this.getVolume(fs.getVol_id());
+                    VolumeSystem vs = this.getVolumeSystem(0); // usually the offset is 0, change it when needed
+                    vs.setParent(img);
+                    vol.setParent(vs);
+                    fs.setParent(vol);
+                    map.put(fsid, fs);
+                    }
+
+                    if (rs.getLong("dir_type") == TSK_FS_NAME_TYPE_ENUM.TSK_FS_NAME_TYPE_DIR.getDirType()){
+                        Directory temp =  new Directory(this, rs.getLong("fs_id"), rs.getLong("file_id"), rs.getLong("attr_type"),
+                                                rs.getLong("attr_id"), rs.getString("name"), rs.getLong("par_file_id"), rs.getLong("dir_type"),
+                                                rs.getLong("meta_type"), rs.getLong("dir_flags"), rs.getLong("meta_flags"), rs.getLong("size"),
+                                                rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
+                                                rs.getLong("mode"), rs.getLong("uid"), rs.getLong("gid"));
+                        temp.setParent(fs);
+                        result.add(temp);
+                    }
+                    else{
+                        File temp =  new File(this, rs.getLong("fs_id"), rs.getLong("file_id"), rs.getLong("attr_type"),
+                                                rs.getLong("attr_id"), rs.getString("name"), rs.getLong("par_file_id"), rs.getLong("dir_type"),
+                                                rs.getLong("meta_type"), rs.getLong("dir_flags"), rs.getLong("meta_flags"), rs.getLong("size"),
+                                                rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
+                                                rs.getLong("mode"), rs.getLong("uid"), rs.getLong("gid"));
+                        temp.setParent(fs);
+                        result.add(temp);
+                    }
+                }
+                while(rs.next());
+            }
+            return result;
+	}
+
+        /**
+         * Returns the ResultSet from the given query.
+         *
+         * @param query  the given string query to run
+         * @return rs    the resultSet
+         * @throws SQLException
+         */
+        public ResultSet runQuery(String query) throws SQLException{
+            Statement statement;
+            statement = con.createStatement();
+
+            ResultSet rs = statement.executeQuery(query);
+            return rs;
+	}
+
+	public void finalize(){
+		try
+	      {
+	        if(con != null)
+	          con.close();
+	      }
+	      catch(SQLException e)
+	      {
+	        // connection close failed.
+	        System.err.println(e);
+	      }
+	}
+
+        /**
+         * Closes the connection of this class.
+         */
+        public void closeConnection(){
+		try
+	      {
+	        if(con != null)
+	          con.close();
+	      }
+	      catch(SQLException e)
+	      {
+	        // connection close failed.
+	        System.err.println(e);
+	      }
+	}
+}
+package org.sleuthkit.datamodel;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.*;
+import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_TYPE_ENUM;
+
+/**
+ * database connection object. makes use of the sqlite jdbc libraries
+ * @author alawrence
+ */
+public class Sleuthkit {
+	private String dbPath;
+        private String imageDirectory;
+	private Connection con;
+
+        /**
+         * constructor
+         * @param path path to the database
+         * @throws SQLException
+         * @throws ClassNotFoundException
+         */
+        public Sleuthkit(String dbPath) throws SQLException, ClassNotFoundException{
+	        Class.forName("org.sqlite.JDBC");
+		this.dbPath = dbPath;
+                int i = dbPath.length()-1;
+                while(dbPath.charAt(i) != '\\' && dbPath.charAt(i) != '/'){
+                    i--;
+                }
+                imageDirectory = dbPath.substring(0, i);
+		con = DriverManager.getConnection("jdbc:sqlite:" + dbPath);
+                con.setReadOnly(true);
+	}
+
+        public Sleuthkit(String dbPath, String imageDirectory) throws SQLException, ClassNotFoundException{
+                Class.forName("org.sqlite.JDBC");
+                this.dbPath = dbPath;
+                this.imageDirectory = imageDirectory;
+                con = DriverManager.getConnection("jdbc:sqlite:" + dbPath);
+        }
+
+        public static void makeDb(String[] paths, String outDir) throws TskException{
+            SleuthkitJNI.makeDb(paths, outDir);
+        }
+
+        /**
+         * fill a new filesystem content object with data from the database. will
+         * also check the database field to determine if it is a file or directory
+         * @param fs_id file system id
+         * @param file_id file id
+         * @return a new FsContent object
+         */
+        public FsContent getFile(long fs_id, long file_id) throws SQLException{
+		Statement statement;
+			statement = con.createStatement();
+
+			ResultSet rs = statement.executeQuery("select * from tsk_fs_files " +
+					"where file_id = " + file_id +" and fs_id = " + fs_id);
+			if(!rs.next()){
+                                rs.close();
+                                statement.close();
+			        return null;
+			}
+			else
+				if (rs.getLong("dir_type") == TSK_FS_NAME_TYPE_ENUM.TSK_FS_NAME_TYPE_DIR.getDirType()){
+					Directory dir = new Directory(this, rs.getLong("fs_id"), rs.getLong("file_id"), rs.getLong("attr_type"),
+							rs.getLong("attr_id"), rs.getString("name"), rs.getLong("par_file_id"), rs.getLong("dir_type"),
+							rs.getLong("meta_type"), rs.getLong("dir_flags"), rs.getLong("meta_flags"), rs.getLong("size"),
+							rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
+							rs.getLong("mode"), rs.getLong("uid"), rs.getLong("gid"));
+                                        rs.close();
+                                        statement.close();
+                                        return dir;
+				}
+				else{
+					File file = new File(this, rs.getLong("fs_id"), rs.getLong("file_id"), rs.getLong("attr_type"),
+							rs.getLong("attr_id"), rs.getString("name"), rs.getLong("par_file_id"), rs.getLong("dir_type"),
+							rs.getLong("meta_type"), rs.getLong("dir_flags"), rs.getLong("meta_flags"), rs.getLong("size"),
+							rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
+							rs.getLong("mode"), rs.getLong("uid"), rs.getLong("gid"));
+                                        rs.close();
+                                        statement.close();
+                                        return file;
+				}
+	}
+
+        /**
+         * fill a new filesystem content object with data from the database. will
+         * also check the database field to determine if it is a file or directory
+         * @param fs_id file system id
+         * @param file_id file id
+         * @param name file name (used to differentiate between directories by name
+         * and . and .. directories
+         * @return a new FsContent object
+         */
+        public FsContent getFile(long fs_id, long file_id, String name) throws SQLException{
+            Statement statement;
+            statement = con.createStatement();
+
+            ResultSet rs = statement.executeQuery("select * from tsk_fs_files " +
+                            "where file_id = " + file_id +" and fs_id = " + fs_id + " and name = \"" + name + "\"");
+            if(!rs.next()){
+                    rs.close();
+                    statement.close();
+                    return null;
+            }
+            else{
+                String tempName = "";
+
+                // if name is empty, it's the root metadata so need to change the name to "."
+                if(name.equals("")){
+                    tempName = ".";
+                }
+                else{
+                    tempName = rs.getString("name");
+                }
+
+                if (rs.getLong("dir_type") == TSK_FS_NAME_TYPE_ENUM.TSK_FS_NAME_TYPE_DIR.getDirType()){
+                        Directory dir = new Directory(this, rs.getLong("fs_id"), rs.getLong("file_id"), rs.getLong("attr_type"),
+                                        rs.getLong("attr_id"), tempName, rs.getLong("par_file_id"), rs.getLong("dir_type"),
+                                        rs.getLong("meta_type"), rs.getLong("dir_flags"), rs.getLong("meta_flags"), rs.getLong("size"),
+                                        rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
+                                        rs.getLong("mode"), rs.getLong("uid"), rs.getLong("gid"));
+                        rs.close();
+                        statement.close();
+                        return dir;
+                }
+                else{
+                        File file = new File(this, rs.getLong("fs_id"), rs.getLong("file_id"), rs.getLong("attr_type"),
+                                        rs.getLong("attr_id"), rs.getString("name"), rs.getLong("par_file_id"), rs.getLong("dir_type"),
+                                        rs.getLong("meta_type"), rs.getLong("dir_flags"), rs.getLong("meta_flags"), rs.getLong("size"),
+                                        rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
+                                        rs.getLong("mode"), rs.getLong("uid"), rs.getLong("gid"));
+                        rs.close();
+                        statement.close();
+                        return file;
+                }
+            }
+	}
+
+        /**
+         * get the name and parent of the file/directory with the given id
+         * @param fs_id filesystem id
+         * @param file_id file id
+         * @return array of length 2 with the name and parent id
+         * @throws SQLException
+         */
+        public String[] getFsContentNameAndParent(long fs_id, long file_id) throws SQLException{
+            Statement statement;
+            statement = con.createStatement();
+
+            ResultSet rs = statement.executeQuery("select name, par_file_id from tsk_fs_files " +
+                            "where file_id = " + file_id +" and fs_id = " + fs_id);
+            if(!rs.next()){
+                String[] result = {"", "0"};
+                return result;
+            }
+            else{
+                String[] result = {rs.getString("name"), Long.toString(rs.getLong("par_file_id"))};
+                return result;
+            }
+        }
+
+        /**
+         * fills a new file system object with data from the database
+         * @param vol_id the volume to get the filesystem from
+         * @return a new file system object
+         */
+        public FileSystem getFileSystem(long vol_id) throws SQLException{
+		Statement statement;
+			statement = con.createStatement();
+
+			ResultSet rs = statement.executeQuery("select * from tsk_fs_info " +
+					"where vol_id = " + vol_id);
+			if(!rs.next()){
+                                rs.close();
+                                statement.close();
+				return null;
+			}
+			else{
+				FileSystem fs = new FileSystem(this, rs.getLong("fs_id"), rs.getLong("img_offset"), rs.getLong("vol_id"),
+						rs.getLong("fs_type"), rs.getLong("block_size"), rs.getLong("block_count"),
+                                                rs.getLong("root_inum"), rs.getLong("first_inum"), rs.getLong("last_inum"));
+                                rs.close();
+                                statement.close();
+                                return fs;
+            }
+	}
+
+        /**
+         * Gets a new file system object with data from the database
+         * @param fs_id  the FileSystem ID to get the filesystem from
+         * @return fs    a new file system object
+         */
+        public FileSystem getFileSystemFromID(long fs_id) throws SQLException{
+            Statement statement = con.createStatement();
+            ResultSet rs = statement.executeQuery("select * from tsk_fs_info " +
+                                    "where fs_id = " + fs_id);
+            if(!rs.next()){
+                rs.close();
+                statement.close();
+                return null;
+            }
+            else{
+                FileSystem fs = new FileSystem(this, rs.getLong("fs_id"), rs.getLong("img_offset"), rs.getLong("vol_id"),
+                                    rs.getLong("fs_type"), rs.getLong("block_size"), rs.getLong("block_count"),
+                                    rs.getLong("root_inum"), rs.getLong("first_inum"), rs.getLong("last_inum"));
+                return fs;
+            }
+	}
+
+        /**
+         * fills a new volume object from the database
+         * @param vol_id volume id
+         * @return new volume object
+         */
+        public Volume getVolume(long vol_id) throws SQLException{
+            //get volume info from the database
+            Statement statement;
+            statement = con.createStatement();
+
+            ResultSet rs = statement.executeQuery("select * from tsk_vs_parts " +
+                            "where vol_id = " + vol_id);
+            if(!rs.next()){
+                rs.close();
+                statement.close();
+                return null;
+            }
+            else{
+                Volume vol = new Volume(this, rs.getLong("vol_id"), rs.getLong("start"), rs.getLong("length"),
+                                rs.getLong("flags"), rs.getString("desc"));
+                rs.close();
+                statement.close();
+                return vol;
+            }
+	}
+
+        /**
+         * fills a new volume system object from the database
+         * @param offset offset to the volume system
+         * @return a new volume system object
+         */
+        public VolumeSystem getVolumeSystem(long offset) throws SQLException{
+            Statement statement;
+            ArrayList<Long> vol_ids = new ArrayList<Long>();
+            statement = con.createStatement();
+
+            ResultSet rs = statement.executeQuery("select * from tsk_vs_info " +
+                            "where img_offset = " + offset);
+            if(!rs.next()){
+                rs.close();
+                statement.close();
+                return null;
+            }
+            else{
+                long type = rs.getLong("vs_type");
+                long imgOffset = rs.getLong("img_offset");
+                long blockSize = rs.getLong("block_size");
+                rs = statement.executeQuery("select vol_id from tsk_vs_parts");
+                if(!rs.next()){
+                        rs.close();
+                        statement.close();
+                        return null;
+                }
+                else{
+                        do{
+                                vol_ids.add(new Long(rs.getLong("vol_id")));
+                        }while(rs.next());
+                }
+                VolumeSystem vs = new VolumeSystem(this, type, imgOffset, blockSize,
+                                vol_ids);
+                rs.close();
+                statement.close();
+                return vs;
+            }
+	}
+
+        /**
+         * get the name of this volume (based on the volume id)
+         * @param fs_id file system
+         * @return string with the name
+         * @throws SQLException
+         */
+        public String getVolName(long fs_id) throws SQLException{
+            Statement statement;
+            ArrayList<Long> vol_ids = new ArrayList<Long>();
+            statement = con.createStatement();
+
+            ResultSet rs = statement.executeQuery("select vol_id from tsk_fs_info " +
+                            "where fs_id = " + fs_id);
+            if(!rs.next()){
+                return null;
+            }
+            else{
+                return "vol" + rs.getLong("vol_id");
+            }
+        }
+
+        /**
+         * fills a new image object with data from the database
+         * @param imagePath path to the image
+         * @return a new image object
+         */
+        public Image getImage() throws TskException, SQLException{
+		//get image info from the database
+		Statement statement;
+		long type, ssize;
+		String name;
+                ArrayList<String> names = new ArrayList<String>();
+			statement = con.createStatement();
+
+			ResultSet rs = statement.executeQuery("select * from tsk_image_info");
+			if(!rs.next()){
+                                rs.close();
+                                statement.close();
+				return null;
+			}
+			else{
+				type = rs.getLong("type");
+				ssize = rs.getLong("ssize");
+			}
+			rs = statement.executeQuery("select * from tsk_image_names");
+			if(!rs.next()){
+                                rs.close();
+                                statement.close();
+				return null;
+			}
+			else{
+                            name = rs.getString("name");
+                            do{
+				names.add(imageDirectory + "\\" + rs.getString("name"));
+                            }while(rs.next());
+				
+			}
+
+			Image img = new Image(this, type, ssize, name, names.toArray(new String[names.size()]));
+                        rs.close();
+                        statement.close();
+                        return img;
+	}
+
+        /**
+         * searches the database for files whose parent is the given file
+         * @param dir_id directory id
+         * @param fs_id file system to search
+         * @return an arraylist of file ids
+         */
+        public ArrayList<Long> getChildIds(long dir_id, long fs_id) throws SQLException{
+			Statement statement = con.createStatement();
+			ArrayList<Long> childIds = new ArrayList<Long>();
+			ResultSet rs = statement.executeQuery("SELECT file_id FROM tsk_fs_files " +
+				"WHERE fs_id = " + fs_id + " AND par_file_id = " + dir_id);
+			if(!rs.next()){
+                                rs.close();
+                                statement.close();
+				return childIds;
+			}
+			else{
+                            do{
+                                    childIds.add(rs.getLong("file_id"));
+                            }while(rs.next());
+			}
+                        rs.close();
+                        statement.close();
+			return childIds;
+	}
+
+
+        /**
+         * get the names of the child files and directories. important for differentiating
+         * between directories and . and .. directories
+         * @param dir_id directory id
+         * @param fs_id file system to search
+         * @return an arraylist of names
+         */
+        public ArrayList<String> getChildNames(long dir_id, long fs_id) throws SQLException {
+			Statement statement = con.createStatement();
+			ArrayList<String> childIds = new ArrayList<String>();
+			ResultSet rs = statement.executeQuery("SELECT name FROM tsk_fs_files " +
+				"WHERE fs_id = " + fs_id + " AND par_file_id = " + dir_id);
+			if(!rs.next()){
+                                rs.close();
+                                statement.close();
+				return childIds;
+			}
+			else{
+                            do{
+                                    childIds.add(rs.getString("name"));
+                            }while(rs.next());
+			}
+                        rs.close();
+                        statement.close();
+			return childIds;
+	}
+        
+        /**
+         * fill a new filesystem content object with data from the database. will
+         * also check the database field to determine if it is a file or directory
+         * @param fs_id file system id
+         * @param file_id file id
+         * @param name file name (used to differentiate between directories by name
+         * and . and .. directories
+         * @return a new FsContent object
+         */
+        public ArrayList<FsContent> resultSetToObjects(ResultSet rs, Image img) throws SQLException{
+            ArrayList<FsContent> result = new ArrayList<FsContent>();
+            FileSystem fs;
+
+            if(!rs.next()){
+                    return result;
+            }
+            else{
+                Hashtable map = new Hashtable();
+
+                do{
+                    Long fsid = rs.getLong("fs_id");
+                    if(map.containsKey(fsid)){
+                        fs = (FileSystem)map.get(fsid);
+                    }
+                    else{
+                    // Set all the parents for the FsContent
+                    fs = this.getFileSystemFromID(fsid);
+                    Volume vol = this.getVolume(fs.getVol_id());
+                    VolumeSystem vs = this.getVolumeSystem(0); // usually the offset is 0, change it when needed
+                    vs.setParent(img);
+                    vol.setParent(vs);
+                    fs.setParent(vol);
+                    map.put(fsid, fs);
+                    }
+
+                    if (rs.getLong("dir_type") == TSK_FS_NAME_TYPE_ENUM.TSK_FS_NAME_TYPE_DIR.getDirType()){
+                        Directory temp =  new Directory(this, rs.getLong("fs_id"), rs.getLong("file_id"), rs.getLong("attr_type"),
+                                                rs.getLong("attr_id"), rs.getString("name"), rs.getLong("par_file_id"), rs.getLong("dir_type"),
+                                                rs.getLong("meta_type"), rs.getLong("dir_flags"), rs.getLong("meta_flags"), rs.getLong("size"),
+                                                rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
+                                                rs.getLong("mode"), rs.getLong("uid"), rs.getLong("gid"));
+                        temp.setParent(fs);
+                        result.add(temp);
+                    }
+                    else{
+                        File temp =  new File(this, rs.getLong("fs_id"), rs.getLong("file_id"), rs.getLong("attr_type"),
+                                                rs.getLong("attr_id"), rs.getString("name"), rs.getLong("par_file_id"), rs.getLong("dir_type"),
+                                                rs.getLong("meta_type"), rs.getLong("dir_flags"), rs.getLong("meta_flags"), rs.getLong("size"),
+                                                rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
+                                                rs.getLong("mode"), rs.getLong("uid"), rs.getLong("gid"));
+                        temp.setParent(fs);
+                        result.add(temp);
+                    }
+                }
+                while(rs.next());
+            }
+            return result;
+	}
+
+        /**
+         * Returns the ResultSet from the given query.
+         *
+         * @param query  the given string query to run
+         * @return rs    the resultSet
+         * @throws SQLException
+         */
+        public ResultSet runQuery(String query) throws SQLException{
+            Statement statement;
+            statement = con.createStatement();
+
+            ResultSet rs = statement.executeQuery(query);
+            return rs;
+	}
+
+	public void finalize(){
+		try
+	      {
+	        if(con != null)
+	          con.close();
+	      }
+	      catch(SQLException e)
+	      {
+	        // connection close failed.
+	        System.err.println(e);
+	      }
+	}
+
+        /**
+         * Closes the connection of this class.
+         */
+        public void closeConnection(){
+		try
+	      {
+	        if(con != null)
+	          con.close();
+	      }
+	      catch(SQLException e)
+	      {
+	        // connection close failed.
+	        System.err.println(e);
+	      }
+	}
+}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
new file mode 100644
index 0000000000000000000000000000000000000000..283b3161808baaaaab64d702d7403713d32ff1ce
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
@@ -0,0 +1,472 @@
+package org.sleuthkit.datamodel;
+
+/**
+ * Class links to sleuthkit c/c++ libraries to read data from image files
+ * @author alawrence
+ */
+public class SleuthkitJNI {
+	//Native methods
+        private static native String getVersionNat();
+        //loaddb
+        private static native long loaddbNat(String[] imgPath, int splits, String outDir) throws TskException;
+	private static native long startloaddbNat(String timezone) throws TskException;
+        private static native void runloaddbNat(long process, String[] imgPath, int splits, String outDir) throws TskException;;
+        private static native void stoploaddbNat(long process) throws TskException;;
+        //open functions
+	private static native long openImageNat(String[] imgPath, int splits) throws TskException;
+	private static native long openVsNat(long imgHandle, long vsOffset) throws TskException;
+	private static native long openVolNat(long vsHandle, long volId) throws TskException;
+	private static native long openFsNat(long imgHandle, long fsId) throws TskException;
+	private static native long openFileNat(long fsHandle, long fileId) throws TskException;
+	
+	//read functions
+	private static native byte[] readImgNat(long imgHandle, long offset, long len) throws TskException;
+	private static native byte[] readVsNat(long vsHandle, long offset, long len) throws TskException;
+	private static native byte[] readVolNat(long volHandle, long offset, long len) throws TskException;
+	private static native byte[] readFsNat(long fsHandle, long offset, long len) throws TskException;
+	private static native byte[] readFileNat(long fileHandle, long offset, long len) throws TskException;
+	
+	//close functions
+	private static native void closeImgNat(long imgHandle);
+	private static native void closeVsNat(long vsHandle);
+	private static native void closeVolNat(long volHandle);
+	private static native void closeFsNat(long fsHandle);
+	private static native void closeFileNat(long fileHandle);
+	
+	static {
+            System.loadLibrary("zlib1");
+            System.loadLibrary("libewf");
+            System.loadLibrary("tsk_jni");
+	}
+
+
+	public SleuthkitJNI(){}
+
+        /**
+         * get the sleuthkit version string
+         * @return the version string
+         */
+        public static String getVersion(){
+            return getVersionNat();
+        }
+
+        /**
+         * open the image and return the image info pointer
+         * @param imageDirs the paths to the images
+         * @return the image info pointer
+         * @throws TskException
+         */
+        public static long openImage(String[] imageDirs) throws TskException{
+            return openImageNat(imageDirs, imageDirs.length);
+        }
+
+        /**
+         * create the sqlite database for the given image
+         * @param imgPaths paths to the image splits
+         * @param outDir the directory to write the database to
+         * @throws TskException
+         */
+        public static void makeDb(String[] imgPaths, String outDir) throws TskException{
+                loaddbNat(imgPaths, imgPaths.length, outDir);
+        }
+
+        /**
+         * create a process pointer for loaddb (this process can be started and stopped)
+         * @param timezone timezone of the image
+         * @return a pointer to a process
+         * @throws TskException
+         */
+        public static long makeLoaddbProcess(String timezone) throws TskException{
+            return startloaddbNat(timezone);
+        }
+
+        /**
+         * start the given loaddb process
+         * @param process pointer to an open process
+         * @param imgPaths paths to the image to make the database from
+         * @param outDir directory to write the database to
+         * @throws TskException
+         */
+        public static void runLoaddbProcess(long process, String[] imgPaths, String outDir) throws TskException{
+            runloaddbNat(process, imgPaths, imgPaths.length, outDir);
+        }
+
+        /**
+         * cancels the given loaddb process
+         * @param process pointer to a running process
+         * @throws TskException
+         */
+        public static void stopLoaddbProcess(long process) throws TskException{
+            stoploaddbNat(process);
+        }
+        /**
+         * Get volume system Handle
+         * @param vsOffset byte offset in the image to the volume system (usually 0)
+         * @return pointer to a vsHandle structure in the sleuthkit
+         */
+        public static long openVs(long imgHandle, long vsOffset) throws TskException{
+            return openVsNat(imgHandle, vsOffset);
+	}
+	
+	//get pointers
+        /**
+         * Get volume Handle
+         * @param vsHandle pointer to the volume system structure in the sleuthkit
+         * @param volId id of the volume
+         * @return pointer to a volHandle structure in the sleuthkit
+         */
+        public static long openVsPart(long vsHandle, long volId) throws TskException{
+            //returned long is ptr to vs Handle object in tsk
+            return openVolNat(vsHandle, volId);
+	}
+	
+        /**
+         * get file system Handle
+         * @param fsOffset byte offset to the file system
+         * @return pointer to a fsHandle structure in the sleuthkit
+         */
+        public static long openFs(long imgHandle, long fsOffset) throws TskException{
+		return openFsNat(imgHandle, fsOffset);
+	}
+	
+        /**
+         * get file Handle
+         * @param fsHandle fsHandle pointer in the sleuthkit
+         * @param fileId id of the file
+         * @return pointer to a file structure in the sleuthkit
+         */
+        public static long openFile(long fsHandle, long fileId) throws TskException{
+		return openFileNat(fsHandle, fileId);
+	}
+	
+	//do reads
+        /**
+         * reads data from an image
+         * @param offset byte offset in the image to start at
+         * @param len amount of data to read
+         * @return an array of characters (bytes of data)
+         */
+        public static byte[] readImg(long imgHandle, long offset, long len) throws TskException{
+		//returned byte[] is the data buffer
+		return readImgNat(imgHandle, offset, len);
+	}
+        /**
+         * reads data from an volume system
+         * @param vsHandle pointer to a volume system structure in the sleuthkit
+         * @param offset sector offset in the image to start at
+         * @param len amount of data to read
+         * @return an array of characters (bytes of data)
+         */
+        public static byte[] readVs(long vsHandle, long offset, long len) throws TskException{
+		return readVsNat(vsHandle, offset, len);
+	}
+        /**
+         * reads data from an volume
+         * @param volHandle pointer to a volume structure in the sleuthkit
+         * @param offset byte offset in the image to start at
+         * @param len amount of data to read
+         * @return an array of characters (bytes of data)
+         */
+        public static byte[] readVsPart(long volHandle, long offset, long len) throws TskException{
+		//returned byte[] is the data buffer
+		return readVolNat(volHandle, offset, len);
+	}
+        /**
+         * reads data from an file system
+         * @param fsHandle pointer to a file system structure in the sleuthkit
+         * @param offset byte offset in the image to start at
+         * @param len amount of data to read
+         * @return an array of characters (bytes of data)
+         */
+        public static byte[] readFs(long fsHandle, long offset, long len) throws TskException{
+		//returned byte[] is the data buffer
+		return readFsNat(fsHandle, offset, len);
+	}
+        /**
+         * reads data from an file
+         * @param fileHandle pointer to a file structure in the sleuthkit
+         * @param offset byte offset in the image to start at
+         * @param len amount of data to read
+         * @return an array of characters (bytes of data)
+         */
+        public static byte[] readFile(long fileHandle, long offset, long len) throws TskException{
+		//returned byte[] is the data buffer
+		return readFileNat(fileHandle, offset, len);
+	}
+	
+	//free pointers
+        /**
+         * frees the imgHandle pointer
+         */
+        public static void closeImg(long imgHandle){
+		closeImgNat(imgHandle);
+	}
+        /**
+         * frees the vsHandle pointer
+         * @param vsHandle pointer to volume system structure in sleuthkit
+         */
+        public static void closeVs(long vsHandle){
+		closeVsNat(vsHandle);
+	}
+        /**
+         * frees the volHandle pointer
+         * @param volHandle pointer to volume structure in sleuthkit
+         */
+        public static void closeVsPart(long volHandle){
+		closeVolNat(volHandle);
+	}
+        /**
+         * frees the fsHandle pointer
+         * @param fsHandle pointer to file system structure in sleuthkit
+         */
+        public static void closeFs(long fsHandle){
+		closeFsNat(fsHandle);
+	}
+        /**
+         * frees the fileHandle pointer
+         * @param fileHandle pointer to file structure in sleuthkit
+         */
+        public static void closeFile(long fileHandle){
+		closeFileNat(fileHandle);
+	}
+}
+package org.sleuthkit.datamodel;
+
+/**
+ * Class links to sleuthkit c/c++ libraries to read data from image files
+ * @author alawrence
+ */
+public class SleuthkitJNI {
+	//Native methods
+        private static native String getVersionNat();
+        //loaddb
+        private static native long loaddbNat(String[] imgPath, int splits, String outDir) throws TskException;
+	private static native long startloaddbNat(String timezone) throws TskException;
+        private static native void runloaddbNat(long process, String[] imgPath, int splits, String outDir) throws TskException;;
+        private static native void stoploaddbNat(long process) throws TskException;;
+        //open functions
+	private static native long openImageNat(String[] imgPath, int splits) throws TskException;
+	private static native long openVsNat(long imgHandle, long vsOffset) throws TskException;
+	private static native long openVolNat(long vsHandle, long volId) throws TskException;
+	private static native long openFsNat(long imgHandle, long fsId) throws TskException;
+	private static native long openFileNat(long fsHandle, long fileId) throws TskException;
+	
+	//read functions
+	private static native byte[] readImgNat(long imgHandle, long offset, long len) throws TskException;
+	private static native byte[] readVsNat(long vsHandle, long offset, long len) throws TskException;
+	private static native byte[] readVolNat(long volHandle, long offset, long len) throws TskException;
+	private static native byte[] readFsNat(long fsHandle, long offset, long len) throws TskException;
+	private static native byte[] readFileNat(long fileHandle, long offset, long len) throws TskException;
+	
+	//close functions
+	private static native void closeImgNat(long imgHandle);
+	private static native void closeVsNat(long vsHandle);
+	private static native void closeVolNat(long volHandle);
+	private static native void closeFsNat(long fsHandle);
+	private static native void closeFileNat(long fileHandle);
+	
+	static {
+            System.loadLibrary("zlib1");
+            System.loadLibrary("libewf");
+            System.loadLibrary("tsk_jni");
+	}
+
+
+        /**
+         * Constructor
+         * @param imageDir path to the image file to be analyzed
+         */
+        /*protected AutopsyJNI(String[] imageDirs) throws TskException{
+                imgHandle = openImageNat(imageDirs, imageDirs.length);
+	}*/
+
+	public SleuthkitJNI(){}
+
+        /**
+         * get the sleuthkit version string
+         * @return the version string
+         */
+        public static String getVersion(){
+            return getVersionNat();
+        }
+
+        /**
+         * open the image and return the image info pointer
+         * @param imageDirs the paths to the images
+         * @return the image info pointer
+         * @throws TskException
+         */
+        public static long openImage(String[] imageDirs) throws TskException{
+            return openImageNat(imageDirs, imageDirs.length);
+        }
+
+        /**
+         * create the sqlite database for the given image
+         * @param imgPaths paths to the image splits
+         * @param outDir the directory to write the database to
+         * @throws TskException
+         */
+        public static void makeDb(String[] imgPaths, String outDir) throws TskException{
+                loaddbNat(imgPaths, imgPaths.length, outDir);
+        }
+
+        /**
+         * create a process pointer for loaddb (this process can be started and stopped)
+         * @param timezone timezone of the image
+         * @return a pointer to a process
+         * @throws TskException
+         */
+        public static long makeLoaddbProcess(String timezone) throws TskException{
+            return startloaddbNat(timezone);
+        }
+
+        /**
+         * start the given loaddb process
+         * @param process pointer to an open process
+         * @param imgPaths paths to the image to make the database from
+         * @param outDir directory to write the database to
+         * @throws TskException
+         */
+        public static void runLoaddbProcess(long process, String[] imgPaths, String outDir) throws TskException{
+            runloaddbNat(process, imgPaths, imgPaths.length, outDir);
+        }
+
+        /**
+         * cancels the given loaddb process
+         * @param process pointer to a running process
+         * @throws TskException
+         */
+        public static void stopLoaddbProcess(long process) throws TskException{
+            stoploaddbNat(process);
+        }
+        /**
+         * Get volume system Handle
+         * @param vsOffset byte offset in the image to the volume system (usually 0)
+         * @return pointer to a vsHandle structure in the sleuthkit
+         */
+        public static long openVs(long imgHandle, long vsOffset) throws TskException{
+            return openVsNat(imgHandle, vsOffset);
+	}
+	
+	//get pointers
+        /**
+         * Get volume Handle
+         * @param vsHandle pointer to the volume system structure in the sleuthkit
+         * @param volId id of the volume
+         * @return pointer to a volHandle structure in the sleuthkit
+         */
+        public static long openVsPart(long vsHandle, long volId) throws TskException{
+            //returned long is ptr to vs Handle object in tsk
+            return openVolNat(vsHandle, volId);
+	}
+	
+        /**
+         * get file system Handle
+         * @param fsOffset byte offset to the file system
+         * @return pointer to a fsHandle structure in the sleuthkit
+         */
+        public static long openFs(long imgHandle, long fsOffset) throws TskException{
+		return openFsNat(imgHandle, fsOffset);
+	}
+	
+        /**
+         * get file Handle
+         * @param fsHandle fsHandle pointer in the sleuthkit
+         * @param fileId id of the file
+         * @return pointer to a file structure in the sleuthkit
+         */
+        public static long openFile(long fsHandle, long fileId) throws TskException{
+		return openFileNat(fsHandle, fileId);
+	}
+	
+	//do reads
+        /**
+         * reads data from an image
+         * @param offset byte offset in the image to start at
+         * @param len amount of data to read
+         * @return an array of characters (bytes of data)
+         */
+        public static byte[] readImg(long imgHandle, long offset, long len) throws TskException{
+		//returned byte[] is the data buffer
+		return readImgNat(imgHandle, offset, len);
+	}
+        /**
+         * reads data from an volume system
+         * @param vsHandle pointer to a volume system structure in the sleuthkit
+         * @param offset sector offset in the image to start at
+         * @param len amount of data to read
+         * @return an array of characters (bytes of data)
+         */
+        public static byte[] readVs(long vsHandle, long offset, long len) throws TskException{
+		return readVsNat(vsHandle, offset, len);
+	}
+        /**
+         * reads data from an volume
+         * @param volHandle pointer to a volume structure in the sleuthkit
+         * @param offset byte offset in the image to start at
+         * @param len amount of data to read
+         * @return an array of characters (bytes of data)
+         */
+        public static byte[] readVsPart(long volHandle, long offset, long len) throws TskException{
+		//returned byte[] is the data buffer
+		return readVolNat(volHandle, offset, len);
+	}
+        /**
+         * reads data from an file system
+         * @param fsHandle pointer to a file system structure in the sleuthkit
+         * @param offset byte offset in the image to start at
+         * @param len amount of data to read
+         * @return an array of characters (bytes of data)
+         */
+        public static byte[] readFs(long fsHandle, long offset, long len) throws TskException{
+		//returned byte[] is the data buffer
+		return readFsNat(fsHandle, offset, len);
+	}
+        /**
+         * reads data from an file
+         * @param fileHandle pointer to a file structure in the sleuthkit
+         * @param offset byte offset in the image to start at
+         * @param len amount of data to read
+         * @return an array of characters (bytes of data)
+         */
+        public static byte[] readFile(long fileHandle, long offset, long len) throws TskException{
+		//returned byte[] is the data buffer
+		return readFileNat(fileHandle, offset, len);
+	}
+	
+	//free pointers
+        /**
+         * frees the imgHandle pointer
+         */
+        public static void closeImg(long imgHandle){
+		closeImgNat(imgHandle);
+	}
+        /**
+         * frees the vsHandle pointer
+         * @param vsHandle pointer to volume system structure in sleuthkit
+         */
+        public static void closeVs(long vsHandle){
+		closeVsNat(vsHandle);
+	}
+        /**
+         * frees the volHandle pointer
+         * @param volHandle pointer to volume structure in sleuthkit
+         */
+        public static void closeVsPart(long volHandle){
+		closeVolNat(volHandle);
+	}
+        /**
+         * frees the fsHandle pointer
+         * @param fsHandle pointer to file system structure in sleuthkit
+         */
+        public static void closeFs(long fsHandle){
+		closeFsNat(fsHandle);
+	}
+        /**
+         * frees the fileHandle pointer
+         * @param fileHandle pointer to file structure in sleuthkit
+         */
+        public static void closeFile(long fileHandle){
+		closeFileNat(fileHandle);
+	}
+}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/TskData.java b/bindings/java/src/org/sleuthkit/datamodel/TskData.java
new file mode 100644
index 0000000000000000000000000000000000000000..d6f62689a05e5d1e5cec9f23789af05a6bd1831e
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/TskData.java
@@ -0,0 +1,362 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.sleuthkit.datamodel;
+
+/**
+ * The class that stores the "ENUM" for the data conversion.
+ *
+ * @author jantonius
+ */
+public class TskData {
+
+    // Enum and Arrya for Directory Type
+    public enum TSK_FS_NAME_TYPE_ENUM {
+        TSK_FS_NAME_TYPE_UNDEF(0),     ///< Unknown type
+        TSK_FS_NAME_TYPE_FIFO(1),      ///< Named pipe
+        TSK_FS_NAME_TYPE_CHR(2),       ///< Character device
+        TSK_FS_NAME_TYPE_DIR(3),       ///< Directory
+        TSK_FS_NAME_TYPE_BLK(4),       ///< Block device
+        TSK_FS_NAME_TYPE_REG(5),       ///< Regular file
+        TSK_FS_NAME_TYPE_LNK(6),       ///< Symbolic link
+        TSK_FS_NAME_TYPE_SOCK(7),      ///< Socket
+        TSK_FS_NAME_TYPE_SHAD(8),      ///< Shadow inode (solaris)
+        TSK_FS_NAME_TYPE_WHT(9),       ///< Whiteout (openbsd)
+        TSK_FS_NAME_TYPE_VIRT(10),     ///< Special (TSK added "Virtual" files)
+        TSK_FS_NAME_TYPE_STR_MAX(11);  ///< Number of types that have a short string name
+
+        private long dir_type;
+
+        private TSK_FS_NAME_TYPE_ENUM(long type){
+            dir_type = type;
+        }
+
+        public long getDirType(){
+            return dir_type;
+        }
+    }
+
+    public static String[] tsk_fs_name_type_str = { "-", "p", "c", "d", "b", "r", "l", "s", "h", "w", "v"};
+
+
+    // Enum and Array for Meta Type
+    public enum TSK_FS_META_TYPE_ENUM {
+        TSK_FS_META_TYPE_UNDEF(0),
+        TSK_FS_META_TYPE_REG(1),        ///< Regular file
+        TSK_FS_META_TYPE_DIR(2),        ///< Directory file
+        TSK_FS_META_TYPE_FIFO(3),       ///< Named pipe (fifo)
+        TSK_FS_META_TYPE_CHR(4),        ///< Character device
+        TSK_FS_META_TYPE_BLK(5),        ///< Block device
+        TSK_FS_META_TYPE_LNK(6),        ///< Symbolic link
+        TSK_FS_META_TYPE_SHAD(7),       ///< SOLARIS ONLY
+        TSK_FS_META_TYPE_SOCK(8),       ///< UNIX domain socket
+        TSK_FS_META_TYPE_WHT(9),        ///< Whiteout
+        TSK_FS_META_TYPE_VIRT(10),      ///< "Virtual File" created by TSK for file system areas
+        TSK_FS_META_TYPE_STR_MAX(11);   ///< Number of file types in shortname array
+
+        private long meta_type;
+
+        private TSK_FS_META_TYPE_ENUM(long type){
+            meta_type = type;
+        }
+
+        public long getMetaType(){
+            return meta_type;
+        }
+    }
+
+    public static String[] tsk_fs_meta_type_str = { "-", "r", "d", "p", "c", "b", "l", "s", "h", "w", "v"};
+
+    // Enum for Directory Flags
+    public enum TSK_FS_NAME_FLAG_ENUM {
+        TSK_FS_NAME_FLAG_ALLOC(1),      ///< Name is in an allocated state
+        TSK_FS_NAME_FLAG_UNALLOC(2);    ///< Name is in an unallocated state
+
+        private long dir_flag;
+
+        private TSK_FS_NAME_FLAG_ENUM(long flag){
+            dir_flag = flag;
+        }
+
+        public long getDirFlag(){
+            return dir_flag;
+        }
+    }
+
+    
+    // Enum for Meta Flags
+    public enum TSK_FS_META_FLAG_ENUM {
+        TSK_FS_META_FLAG_ALLOC(1),      ///< Metadata structure is currently in an allocated state
+        TSK_FS_META_FLAG_UNALLOC(2),    ///< Metadata structure is currently in an unallocated state
+        TSK_FS_META_FLAG_USED(4),       ///< Metadata structure has been allocated at least once
+        TSK_FS_META_FLAG_UNUSED(8),     ///< Metadata structure has never been allocated.
+        TSK_FS_META_FLAG_COMP(16),      ///< The file contents are compressed.
+        TSK_FS_META_FLAG_ORPHAN(32);    ///< Return only metadata structures that have no file name pointing to the (inode_walk flag only)
+
+        private long meta_flag;
+
+        private TSK_FS_META_FLAG_ENUM(long flag){
+            meta_flag = flag;
+        }
+
+        public long getMetaFlag(){
+            return meta_flag;
+        }
+    }
+
+    // Enum for Volume System Flags
+    public enum TSK_VS_PART_FLAG_ENUM{
+        TSK_VS_PART_FLAG_ALLOC(1),      ///< Sectors are allocated to a volume in the volume system
+        TSK_VS_PART_FLAG_UNALLOC(2),    ///< Sectors are not allocated to a volume
+        TSK_VS_PART_FLAG_META(4),       ///< Sectors contain volume system metadata and could also be ALLOC or UNALLOC
+        TSK_VS_PART_FLAG_ALL(7);        ///< Show all sectors in the walk.
+
+        private long vs_flag;
+
+        private TSK_VS_PART_FLAG_ENUM(long flag){
+            vs_flag = flag;
+        }
+
+        public long getVsFlag(){
+            return vs_flag;
+        }
+    } 
+
+    // Enum for Mode
+    public enum TSK_FS_META_MODE_ENUM {
+        /* The following describe the file permissions */
+        TSK_FS_META_MODE_ISUID(0004000),       ///< set user id on execution
+        TSK_FS_META_MODE_ISGID(0002000),       ///< set group id on execution
+        TSK_FS_META_MODE_ISVTX(0001000),       ///< sticky bit
+
+        TSK_FS_META_MODE_IRUSR(0000400),       ///< R for owner
+        TSK_FS_META_MODE_IWUSR(0000200),       ///< W for owner
+        TSK_FS_META_MODE_IXUSR(0000100),       ///< X for owner
+
+        TSK_FS_META_MODE_IRGRP(0000040),       ///< R for group
+        TSK_FS_META_MODE_IWGRP(0000020),       ///< W for group
+        TSK_FS_META_MODE_IXGRP(0000010),       ///< X for group
+
+        TSK_FS_META_MODE_IROTH(0000004),       ///< R for other
+        TSK_FS_META_MODE_IWOTH(0000002),       ///< W for other
+        TSK_FS_META_MODE_IXOTH(0000001);       ///< X for other
+
+        private long mode;
+
+        private TSK_FS_META_MODE_ENUM(long mode){
+            this.mode = mode;
+        }
+
+        public long getMode(){
+            return mode;
+        }
+    };
+
+    // Enum for Image Type
+    public enum TSK_IMG_TYPE_ENUM {
+        /* The following describe the image type */
+        TSK_IMG_TYPE_DETECT(0),       // Auto Detection
+        TSK_IMG_TYPE_RAW_SING(1),     // Single raw file (dd)
+        TSK_IMG_TYPE_RAW_SPLIT(2),    // Split raw files
+        TSK_IMG_TYPE_AFF_AFF(4),      // Advanced Forensic Format
+        TSK_IMG_TYPE_AFF_AFD(8),      // AFF Multiple File
+        TSK_IMG_TYPE_AFF_AFM(16),     // AFF with external metadata
+        TSK_IMG_TYPE_AFF_ANY(32),     // All AFFLIB image formats (including beta ones)
+        TSK_IMG_TYPE_EWF_EWF(64),     // Expert Witness format (encase)
+        TSK_IMG_TYPE_UNSUPP(65535);   // Unsupported Image Type
+
+        private long imgType;
+
+        private TSK_IMG_TYPE_ENUM (long type){
+            this.imgType = type;
+        }
+
+        public long getImageType(){
+            return imgType;
+        }
+    };
+
+}
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.sleuthkit.datamodel;
+
+/**
+ * The class that stores the "ENUM" for the data conversion.
+ *
+ * @author jantonius
+ */
+public class TskData {
+
+    // Enum and Arrya for Directory Type
+    public enum TSK_FS_NAME_TYPE_ENUM {
+        TSK_FS_NAME_TYPE_UNDEF(0),     ///< Unknown type
+        TSK_FS_NAME_TYPE_FIFO(1),      ///< Named pipe
+        TSK_FS_NAME_TYPE_CHR(2),       ///< Character device
+        TSK_FS_NAME_TYPE_DIR(3),       ///< Directory
+        TSK_FS_NAME_TYPE_BLK(4),       ///< Block device
+        TSK_FS_NAME_TYPE_REG(5),       ///< Regular file
+        TSK_FS_NAME_TYPE_LNK(6),       ///< Symbolic link
+        TSK_FS_NAME_TYPE_SOCK(7),      ///< Socket
+        TSK_FS_NAME_TYPE_SHAD(8),      ///< Shadow inode (solaris)
+        TSK_FS_NAME_TYPE_WHT(9),       ///< Whiteout (openbsd)
+        TSK_FS_NAME_TYPE_VIRT(10),     ///< Special (TSK added "Virtual" files)
+        TSK_FS_NAME_TYPE_STR_MAX(11);  ///< Number of types that have a short string name
+
+        private long dir_type;
+
+        private TSK_FS_NAME_TYPE_ENUM(long type){
+            dir_type = type;
+        }
+
+        public long getDirType(){
+            return dir_type;
+        }
+    }
+
+    public static String[] tsk_fs_name_type_str = { "-", "p", "c", "d", "b", "r", "l", "s", "h", "w", "v"};
+
+
+    // Enum and Array for Meta Type
+    public enum TSK_FS_META_TYPE_ENUM {
+        TSK_FS_META_TYPE_UNDEF(0),
+        TSK_FS_META_TYPE_REG(1),        ///< Regular file
+        TSK_FS_META_TYPE_DIR(2),        ///< Directory file
+        TSK_FS_META_TYPE_FIFO(3),       ///< Named pipe (fifo)
+        TSK_FS_META_TYPE_CHR(4),        ///< Character device
+        TSK_FS_META_TYPE_BLK(5),        ///< Block device
+        TSK_FS_META_TYPE_LNK(6),        ///< Symbolic link
+        TSK_FS_META_TYPE_SHAD(7),       ///< SOLARIS ONLY
+        TSK_FS_META_TYPE_SOCK(8),       ///< UNIX domain socket
+        TSK_FS_META_TYPE_WHT(9),        ///< Whiteout
+        TSK_FS_META_TYPE_VIRT(10),      ///< "Virtual File" created by TSK for file system areas
+        TSK_FS_META_TYPE_STR_MAX(11);   ///< Number of file types in shortname array
+
+        private long meta_type;
+
+        private TSK_FS_META_TYPE_ENUM(long type){
+            meta_type = type;
+        }
+
+        public long getMetaType(){
+            return meta_type;
+        }
+    }
+
+    public static String[] tsk_fs_meta_type_str = { "-", "r", "d", "p", "c", "b", "l", "s", "h", "w", "v"};
+
+    // Enum for Directory Flags
+    public enum TSK_FS_NAME_FLAG_ENUM {
+        TSK_FS_NAME_FLAG_ALLOC(1),      ///< Name is in an allocated state
+        TSK_FS_NAME_FLAG_UNALLOC(2);    ///< Name is in an unallocated state
+
+        private long dir_flag;
+
+        private TSK_FS_NAME_FLAG_ENUM(long flag){
+            dir_flag = flag;
+        }
+
+        public long getDirFlag(){
+            return dir_flag;
+        }
+    }
+
+    
+    // Enum for Meta Flags
+    public enum TSK_FS_META_FLAG_ENUM {
+        TSK_FS_META_FLAG_ALLOC(1),      ///< Metadata structure is currently in an allocated state
+        TSK_FS_META_FLAG_UNALLOC(2),    ///< Metadata structure is currently in an unallocated state
+        TSK_FS_META_FLAG_USED(4),       ///< Metadata structure has been allocated at least once
+        TSK_FS_META_FLAG_UNUSED(8),     ///< Metadata structure has never been allocated.
+        TSK_FS_META_FLAG_COMP(16),      ///< The file contents are compressed.
+        TSK_FS_META_FLAG_ORPHAN(32);    ///< Return only metadata structures that have no file name pointing to the (inode_walk flag only)
+
+        private long meta_flag;
+
+        private TSK_FS_META_FLAG_ENUM(long flag){
+            meta_flag = flag;
+        }
+
+        public long getMetaFlag(){
+            return meta_flag;
+        }
+    }
+
+    // Enum for Volume System Flags
+    public enum TSK_VS_PART_FLAG_ENUM{
+        TSK_VS_PART_FLAG_ALLOC(1),      ///< Sectors are allocated to a volume in the volume system
+        TSK_VS_PART_FLAG_UNALLOC(2),    ///< Sectors are not allocated to a volume
+        TSK_VS_PART_FLAG_META(4),       ///< Sectors contain volume system metadata and could also be ALLOC or UNALLOC
+        TSK_VS_PART_FLAG_ALL(7);        ///< Show all sectors in the walk.
+
+        private long vs_flag;
+
+        private TSK_VS_PART_FLAG_ENUM(long flag){
+            vs_flag = flag;
+        }
+
+        public long getVsFlag(){
+            return vs_flag;
+        }
+    } 
+
+    // Enum for Mode
+    public enum TSK_FS_META_MODE_ENUM {
+        /* The following describe the file permissions */
+        TSK_FS_META_MODE_ISUID(0004000),       ///< set user id on execution
+        TSK_FS_META_MODE_ISGID(0002000),       ///< set group id on execution
+        TSK_FS_META_MODE_ISVTX(0001000),       ///< sticky bit
+
+        TSK_FS_META_MODE_IRUSR(0000400),       ///< R for owner
+        TSK_FS_META_MODE_IWUSR(0000200),       ///< W for owner
+        TSK_FS_META_MODE_IXUSR(0000100),       ///< X for owner
+
+        TSK_FS_META_MODE_IRGRP(0000040),       ///< R for group
+        TSK_FS_META_MODE_IWGRP(0000020),       ///< W for group
+        TSK_FS_META_MODE_IXGRP(0000010),       ///< X for group
+
+        TSK_FS_META_MODE_IROTH(0000004),       ///< R for other
+        TSK_FS_META_MODE_IWOTH(0000002),       ///< W for other
+        TSK_FS_META_MODE_IXOTH(0000001);       ///< X for other
+
+        private long mode;
+
+        private TSK_FS_META_MODE_ENUM(long mode){
+            this.mode = mode;
+        }
+
+        public long getMode(){
+            return mode;
+        }
+    };
+
+    // Enum for Image Type
+    public enum TSK_IMG_TYPE_ENUM {
+        /* The following describe the image type */
+        TSK_IMG_TYPE_DETECT(0),       // Auto Detection
+        TSK_IMG_TYPE_RAW_SING(1),     // Single raw file (dd)
+        TSK_IMG_TYPE_RAW_SPLIT(2),    // Split raw files
+        TSK_IMG_TYPE_AFF_AFF(4),      // Advanced Forensic Format
+        TSK_IMG_TYPE_AFF_AFD(8),      // AFF Multiple File
+        TSK_IMG_TYPE_AFF_AFM(16),     // AFF with external metadata
+        TSK_IMG_TYPE_AFF_ANY(32),     // All AFFLIB image formats (including beta ones)
+        TSK_IMG_TYPE_EWF_EWF(64),     // Expert Witness format (encase)
+        TSK_IMG_TYPE_UNSUPP(65535);   // Unsupported Image Type
+
+        private long imgType;
+
+        private TSK_IMG_TYPE_ENUM (long type){
+            this.imgType = type;
+        }
+
+        public long getImageType(){
+            return imgType;
+        }
+    };
+
+}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/TskException.java b/bindings/java/src/org/sleuthkit/datamodel/TskException.java
new file mode 100644
index 0000000000000000000000000000000000000000..18c7eccb69a97e37e96e67b251e53cc5a53b96ed
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/TskException.java
@@ -0,0 +1,35 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.sleuthkit.datamodel;
+
+/**
+ *
+ * @author alawrence
+ */
+public class TskException extends Exception{
+    public TskException(String msg){
+        super(msg);
+    }
+
+}
+
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.sleuthkit.datamodel;
+
+/**
+ *
+ * @author alawrence
+ */
+public class TskException extends Exception{
+    public TskException(String msg){
+        super(msg);
+    }
+
+}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/Volume.java b/bindings/java/src/org/sleuthkit/datamodel/Volume.java
new file mode 100644
index 0000000000000000000000000000000000000000..806fd7619c38426333c019f2ea54c2d376afb933
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/Volume.java
@@ -0,0 +1,198 @@
+package org.sleuthkit.datamodel;
+
+import java.sql.SQLException;
+
+/**
+ * Volume class
+ * @author alawrence
+ */
+public class Volume implements Content{
+    // @@@ We should mark these as private and comment somewhere what the units are (bytes, sectors, etc.)
+    long vol_id, start, length, flags;
+    String desc;
+    private Sleuthkit db;
+    private VolumeSystem parentVs;
+    private long volumeHandle = 0;
+
+    /**
+     * Constructor most inputs are from the database
+     * @param db database object
+     * @param vol_id
+     * @param start
+     * @param length
+     * @param flags
+     * @param desc
+     */
+    protected Volume(Sleuthkit db, long vol_id, long start, long length, long flags, String descr){
+        this.db = db;
+        this.vol_id = vol_id;
+        this.start = start;
+        this.length = length;
+        this.flags = flags;
+        if(!descr.equals("")){
+            this.desc = descr;
+        }
+        else{
+            this.desc = "Unknown";
+        }
+
+    }
+
+    /**
+     * set the parent volume system. called by the parent on creation
+     * @param parent parent volume system
+     */
+    protected void setParent(VolumeSystem parent){
+        parentVs = parent;
+    }
+
+    /**
+     * get the file system in this volume
+     * @return file system
+     */
+    public FileSystem getFileSystem() throws SQLException{
+        //get the file system corresponding to this volume if any
+        FileSystem fs = db.getFileSystem(vol_id);
+        if (fs != null){
+                fs.setParent(this);
+        }
+        return fs;
+    }
+
+    /**
+     * read from this volume
+     * @param offset in bytes
+     * @param len in bytes
+     * @return the byte data
+     * @throws TskException
+     */
+    @Override
+    public byte[] read(long offset, long len) throws TskException {
+        // read from the volume
+        if(volumeHandle == 0){
+                volumeHandle = SleuthkitJNI.openVsPart(parentVs.getVolumeSystemHandle(), vol_id);
+        }
+        return SleuthkitJNI.readVsPart(volumeHandle, offset, len);
+    }
+
+    @Override
+    public long getSize() {
+        // size of the volume
+        return length;
+    }
+
+    /**
+     * get the parent volume system
+     * @return parent volume system object
+     */
+    public VolumeSystem getParent(){
+        return parentVs;
+    }
+
+    /**
+     * get the sleuthkit database object
+     * @return the sleuthkit object
+     */
+    public Sleuthkit getSleuthkit(){
+        return db;
+    }
+
+    //methods get exact data from database. could be manipulated to get more
+    //meaningful data.
+    /**
+     * get the volume id
+     * @return volume id
+     */
+    public long getVol_id() {
+        return vol_id;
+    }
+    /**
+     * get the starting byte offset
+     * @return starting byte offset
+     */
+    public long getStart() {
+        return start;
+    }
+    /**
+     * get the length
+     * @return length
+     */
+    public long getLength() {
+        return length;
+    }
+    /**
+     * get the flags
+     * @return flags
+     */
+    public long getFlags() {
+        return flags;
+    }
+            /**
+     * get the flags as String
+     * @return flags as String
+     */
+    public String getFlagsAsString() {
+        return Volume.vsFlagToString(flags);
+    }
+
+    /**
+     * get the description
+     * @return description
+     */
+    public String getDescription(){
+        return desc;
+    }
+
+    public void finalize(){
+        if(volumeHandle != 0){
+                SleuthkitJNI.closeVsPart(volumeHandle);
+        }
+    }
+
+    // ----- Here all the methods for vs flags conversion / mapping -----
+    public static String vsFlagToValue(long vsFlag){
+
+        String result = "";
+
+        for (TskData.TSK_VS_PART_FLAG_ENUM flag : TskData.TSK_VS_PART_FLAG_ENUM.values()){
+            if(flag.getVsFlag() == vsFlag){
+                result = flag.toString();
+            }
+        }
+        return result;
+    }
+
+    public static long valueToVsFlag(String vsFlag){
+
+        long result = 0;
+
+        for (TskData.TSK_VS_PART_FLAG_ENUM flag : TskData.TSK_VS_PART_FLAG_ENUM.values()){
+            if(flag.toString().equals(vsFlag)){
+                result = flag.getVsFlag();
+            }
+        }
+        return result;
+    }
+
+    public static String vsFlagToString(long vsFlag){
+
+        String result = "";
+
+        long allocFlag = TskData.TSK_VS_PART_FLAG_ENUM.TSK_VS_PART_FLAG_ALLOC.getVsFlag();
+        long unallocFlag = TskData.TSK_VS_PART_FLAG_ENUM.TSK_VS_PART_FLAG_UNALLOC.getVsFlag();
+
+        // some variables that might be needed in the future
+        long metaFlag = TskData.TSK_VS_PART_FLAG_ENUM.TSK_VS_PART_FLAG_META.getVsFlag();
+        long allFlag = TskData.TSK_VS_PART_FLAG_ENUM.TSK_VS_PART_FLAG_ALL.getVsFlag();
+
+        if((vsFlag & allocFlag) == allocFlag){
+            result = "Allocated";
+        }
+        if((vsFlag & unallocFlag) == unallocFlag){
+            result = "Unallocated";
+        }
+        // ... add more code here if needed
+
+        return result;
+    }
+}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/VolumeSystem.java b/bindings/java/src/org/sleuthkit/datamodel/VolumeSystem.java
new file mode 100644
index 0000000000000000000000000000000000000000..3ab7ed52193450a32716e0ee8c06882b624227f8
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/VolumeSystem.java
@@ -0,0 +1,252 @@
+package org.sleuthkit.datamodel;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+
+/**
+ * Volume System Object
+ * @author alawrence
+ */
+public class VolumeSystem implements Content{
+	private Sleuthkit db;
+	private long volumeSystemHandle = 0;
+	private long type, imgOffset, blockSize;
+	private Image parent;
+	private ArrayList<Long> vol_ids;
+	
+        /**
+         * Constructor most inputs are from the database
+         * @param db database object
+         * @param type
+         * @param imgOffset
+         * @param blockSize
+         * @param vol_ids
+         */
+        protected VolumeSystem(Sleuthkit db, long type, long imgOffset, long blockSize, ArrayList<Long> vol_ids){
+		this.db = db;
+		this.type = type;
+		this.imgOffset = imgOffset;
+		this.blockSize = blockSize;
+		this.vol_ids = vol_ids;
+	}
+	
+        /**
+         * set the parent image called by parent on creation
+         * @param parent parent image
+         */
+        protected void setParent(Image parent){
+		this.parent = parent;
+	}
+        //byte offset
+	public byte[] read(long offset, long len) throws TskException{
+		if(volumeSystemHandle == 0){
+			volumeSystemHandle = SleuthkitJNI.openVs(this.getParent().getImageHandle(), imgOffset);
+		}
+		return SleuthkitJNI.readVs(volumeSystemHandle, offset, len);
+	}
+        /**
+         * get the sleuthkit database object
+         * @return the sleuthkit object
+         */
+        public Sleuthkit getSleuthkit(){
+            return db;
+        }
+
+        /**
+         * get the volume in the volume system with the given id
+         * @param id volume id
+         * @return volume
+         */
+        public Volume getVolume(long id) throws SQLException{
+		//get given volume.
+		Volume vol = db.getVolume(id);
+		if (vol != null){
+			vol.setParent(this);
+		}
+		return vol;
+	}
+	
+        /**
+         * get the parent image
+         * @return parent image
+         */
+        public Image getParent(){
+		return parent;
+	}
+        /**
+         * get the size of the volume system
+         * @return the size of the volume system
+         */
+	public long getSize() {
+		return 0;
+	}
+        /**
+         * get the type
+         * @return type
+         */
+        public long getType(){
+		return type;
+	}
+        /**
+         * get the byte offset
+         * @return byte offset
+         */
+        public long getOffset(){
+		return imgOffset;
+	}
+        /**
+         * get the block size
+         * @return block size
+         */
+        public long getBlockSize(){
+		return blockSize;
+	}
+        /**
+         * get the volume system Handle pointer
+         * @return volume system Handle pointer
+         */
+        protected long getVolumeSystemHandle() throws TskException{
+		if (volumeSystemHandle == 0){
+			volumeSystemHandle = SleuthkitJNI.openVs(this.getParent().getImageHandle(), imgOffset);
+		}
+			
+		return volumeSystemHandle;
+	}
+        /**
+         * get the child volume ids
+         * @return child volume ids
+         */
+        public ArrayList<Long> getVolIds(){
+		return vol_ids;
+	}
+	
+	public void finalize(){
+		SleuthkitJNI.closeVs(volumeSystemHandle);
+	}
+}
+package org.sleuthkit.datamodel;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+
+/**
+ * Volume System Object
+ * @author alawrence
+ */
+public class VolumeSystem implements Content{
+	private Sleuthkit db;
+	private long volumeSystemHandle = 0;
+	private long type, imgOffset, blockSize;
+	private Image parent;
+	private ArrayList<Long> vol_ids;
+	
+        /**
+         * Constructor most inputs are from the database
+         * @param db database object
+         * @param type
+         * @param imgOffset
+         * @param blockSize
+         * @param vol_ids
+         */
+        protected VolumeSystem(Sleuthkit db, long type, long imgOffset, long blockSize, ArrayList<Long> vol_ids){
+		this.db = db;
+		this.type = type;
+		this.imgOffset = imgOffset;
+		this.blockSize = blockSize;
+		this.vol_ids = vol_ids;
+	}
+	
+        /**
+         * set the parent image called by parent on creation
+         * @param parent parent image
+         */
+        protected void setParent(Image parent){
+		this.parent = parent;
+	}
+        //byte offset
+	public byte[] read(long offset, long len) throws TskException{
+		if(volumeSystemHandle == 0){
+			volumeSystemHandle = SleuthkitJNI.openVs(this.getParent().getImageHandle(), imgOffset);
+		}
+		return SleuthkitJNI.readVs(volumeSystemHandle, offset, len);
+	}
+        /**
+         * get the sleuthkit database object
+         * @return the sleuthkit object
+         */
+        public Sleuthkit getSleuthkit(){
+            return db;
+        }
+
+        /**
+         * get the volume in the volume system with the given id
+         * @param id volume id
+         * @return volume
+         */
+        public Volume getVolume(long id) throws SQLException{
+		//get given volume.
+		Volume vol = db.getVolume(id);
+		if (vol != null){
+			vol.setParent(this);
+		}
+		return vol;
+	}
+	
+        /**
+         * get the parent image
+         * @return parent image
+         */
+        public Image getParent(){
+		return parent;
+	}
+        /**
+         * get the size of the volume system
+         * @return the size of the volume system
+         */
+	public long getSize() {
+		return 0;
+	}
+        /**
+         * get the type
+         * @return type
+         */
+        public long getType(){
+		return type;
+	}
+        /**
+         * get the byte offset
+         * @return byte offset
+         */
+        public long getOffset(){
+		return imgOffset;
+	}
+        /**
+         * get the block size
+         * @return block size
+         */
+        public long getBlockSize(){
+		return blockSize;
+	}
+        /**
+         * get the volume system Handle pointer
+         * @return volume system Handle pointer
+         */
+        protected long getVolumeSystemHandle() throws TskException{
+		if (volumeSystemHandle == 0){
+			volumeSystemHandle = SleuthkitJNI.openVs(this.getParent().getImageHandle(), imgOffset);
+		}
+			
+		return volumeSystemHandle;
+	}
+        /**
+         * get the child volume ids
+         * @return child volume ids
+         */
+        public ArrayList<Long> getVolIds(){
+		return vol_ids;
+	}
+	
+	public void finalize(){
+		SleuthkitJNI.closeVs(volumeSystemHandle);
+	}
+}
diff --git a/tsk3/auto/auto.cpp b/tsk3/auto/auto.cpp
index 20da94f83c6b2dd94e03e4aa93053d48b3d2a1f9..a4ab430cf24e7f074960666cd053e693cb44c878 100644
--- a/tsk3/auto/auto.cpp
+++ b/tsk3/auto/auto.cpp
@@ -60,6 +60,33 @@ uint8_t
         return 1;
 }
 
+/**
+ * Opens the disk image to be analyzed.  This must be called before any
+ * of the findFilesInXXX() methods. Always uses the utf8 tsk_img_open
+ * even in windows.
+ *
+ * @param a_numImg The number of images to open (will be > 1 for split images).
+ * @param a_images The path to the image files (the number of files must
+ * be equal to num_img and they must be in a sorted order)
+ * @param a_imgType The disk image type (can be autodetection)
+ * @param a_sSize Size of device sector in bytes (or 0 for default)
+ * @returns 1 on error, 0 on success
+ */
+uint8_t
+    TskAuto::openImageUtf8(int a_numImg, const char *const a_images[],
+    TSK_IMG_TYPE_ENUM a_imgType, unsigned int a_sSize)
+{
+    if (m_img_info)
+        closeImage();
+
+    m_internalOpen = true;
+    m_img_info = tsk_img_open_utf8(a_numImg, a_images, a_imgType, a_sSize);
+    if (m_img_info)
+        return 0;
+    else
+        return 1;
+}
+
 /**
  * Uses the already opened image for future analysis. This must be called before any
  * of the findFilesInXXX() methods. Note that the TSK_IMG_INFO will not
@@ -67,12 +94,11 @@ uint8_t
  * @param a_img_info Handle to an already opened disk image.
  * @returns 1 on error and 0 on success
  */
-uint8_t
-TskAuto::openImage(TSK_IMG_INFO *a_img_info)
+uint8_t TskAuto::openImage(TSK_IMG_INFO * a_img_info)
 {
     if (m_img_info)
         closeImage();
-    
+
     m_internalOpen = false;
     m_img_info = a_img_info;
     return 0;
@@ -126,7 +152,8 @@ void
  * that is found.
  * @return 1 on error, 0 on success
  */
-uint8_t TskAuto::findFilesInImg()
+uint8_t
+TskAuto::findFilesInImg()
 {
     if (!m_img_info) {
         tsk_error_reset();
@@ -186,7 +213,8 @@ TSK_WALK_RET_ENUM
  * @param a_vtype Volume system type to analyze
  * @return 1 on error, 0 on success
  */
-uint8_t TskAuto::findFilesInVs(TSK_OFF_T a_start, TSK_VS_TYPE_ENUM a_vtype)
+uint8_t
+TskAuto::findFilesInVs(TSK_OFF_T a_start, TSK_VS_TYPE_ENUM a_vtype)
 {
     if (!m_img_info) {
         tsk_error_reset();
@@ -195,12 +223,9 @@ uint8_t TskAuto::findFilesInVs(TSK_OFF_T a_start, TSK_VS_TYPE_ENUM a_vtype)
         return 1;
     }
 
-    TSK_VS_INFO *
-        vs_info;
+    TSK_VS_INFO *vs_info;
     // USE mm_walk to get the volumes
-    if ((vs_info =
-            tsk_vs_open(m_img_info, a_start,
-                a_vtype)) == NULL) {
+    if ((vs_info = tsk_vs_open(m_img_info, a_start, a_vtype)) == NULL) {
         if (tsk_verbose)
             fprintf(stderr,
                 "Error determining volume system -- trying file systems\n");
@@ -217,7 +242,7 @@ uint8_t TskAuto::findFilesInVs(TSK_OFF_T a_start, TSK_VS_TYPE_ENUM a_vtype)
             return TSK_STOP;
         else if (retval == TSK_FILTER_SKIP)
             return TSK_OK;
-        
+
         /* Walk the allocated volumes (skip metadata and unallocated volumes) */
         if (tsk_vs_part_walk(vs_info, 0, vs_info->part_count - 1,
                 m_volFilterFlags, vsWalkCb, this)) {
@@ -236,7 +261,8 @@ uint8_t TskAuto::findFilesInVs(TSK_OFF_T a_start, TSK_VS_TYPE_ENUM a_vtype)
  * @param a_start Byte offset to start analyzing from.
  * @return 1 on error, 0 on success
  */
-uint8_t TskAuto::findFilesInVs(TSK_OFF_T a_start)
+uint8_t
+TskAuto::findFilesInVs(TSK_OFF_T a_start)
 {
     return findFilesInVs(a_start, TSK_VS_TYPE_DETECT);
 }
@@ -250,20 +276,19 @@ uint8_t TskAuto::findFilesInVs(TSK_OFF_T a_start)
  * @param a_ftype File system type.
  * @returns values that allow the caller to differentiate stop from ok.  
  */
-TSK_RETVAL_ENUM TskAuto::findFilesInFsRet(TSK_OFF_T a_start, TSK_FS_TYPE_ENUM a_ftype)
+TSK_RETVAL_ENUM
+TskAuto::findFilesInFsRet(TSK_OFF_T a_start, TSK_FS_TYPE_ENUM a_ftype)
 {
     if (!m_img_info) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_NOTOPEN);
-        tsk_error_set_errstr( "findFilesInFsRet\n");
+        tsk_error_set_errstr("findFilesInFsRet\n");
         return TSK_ERR;
     }
 
-    TSK_FS_INFO *
-        fs_info;
+    TSK_FS_INFO *fs_info;
     /* Try it as a file system */
-    if ((fs_info =
-            tsk_fs_open_img(m_img_info, a_start, a_ftype)) == NULL) {
+    if ((fs_info = tsk_fs_open_img(m_img_info, a_start, a_ftype)) == NULL) {
         tsk_error_print(stderr);
 
         /* We could do some carving on the volume data at this point */
@@ -271,8 +296,7 @@ TSK_RETVAL_ENUM TskAuto::findFilesInFsRet(TSK_OFF_T a_start, TSK_FS_TYPE_ENUM a_
         return TSK_ERR;
     }
 
-    TSK_RETVAL_ENUM
-        retval = findFilesInFsInt(fs_info, fs_info->root_inum);
+    TSK_RETVAL_ENUM retval = findFilesInFsInt(fs_info, fs_info->root_inum);
     tsk_fs_close(fs_info);
     return retval;
 }
@@ -286,7 +310,8 @@ TSK_RETVAL_ENUM TskAuto::findFilesInFsRet(TSK_OFF_T a_start, TSK_FS_TYPE_ENUM a_
  *
  * @returns 1 on error and 0 on success
  */
-uint8_t TskAuto::findFilesInFs(TSK_OFF_T a_start)
+uint8_t
+TskAuto::findFilesInFs(TSK_OFF_T a_start)
 {
     if (findFilesInFsRet(a_start, TSK_FS_TYPE_DETECT) == TSK_ERR)
         return 1;
@@ -305,7 +330,8 @@ uint8_t TskAuto::findFilesInFs(TSK_OFF_T a_start)
  *
  * @returns 1 on error and 0 on success
  */
-uint8_t TskAuto::findFilesInFs(TSK_OFF_T a_start, TSK_FS_TYPE_ENUM a_ftype)
+uint8_t
+TskAuto::findFilesInFs(TSK_OFF_T a_start, TSK_FS_TYPE_ENUM a_ftype)
 {
     if (findFilesInFsRet(a_start, a_ftype) == TSK_ERR)
         return 1;
@@ -325,29 +351,27 @@ uint8_t TskAuto::findFilesInFs(TSK_OFF_T a_start, TSK_FS_TYPE_ENUM a_ftype)
  *
  * @returns 1 on error and 0 on success
  */
-uint8_t TskAuto::findFilesInFs(TSK_OFF_T a_start, TSK_FS_TYPE_ENUM a_ftype, TSK_INUM_T a_inum)
+uint8_t
+TskAuto::findFilesInFs(TSK_OFF_T a_start, TSK_FS_TYPE_ENUM a_ftype,
+    TSK_INUM_T a_inum)
 {
     if (!m_img_info) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_NOTOPEN);
-        tsk_error_set_errstr( "findFilesInFs\n");
+        tsk_error_set_errstr("findFilesInFs\n");
         return 1;
     }
 
-    TSK_FS_INFO *
-        fs_info;
+    TSK_FS_INFO *fs_info;
     /* Try it as a file system */
-    if ((fs_info =
-            tsk_fs_open_img(m_img_info, a_start,
-                a_ftype)) == NULL) {
+    if ((fs_info = tsk_fs_open_img(m_img_info, a_start, a_ftype)) == NULL) {
         tsk_error_print(stderr);
 
         /* We could do some carving on the volume data at this point */
 
         return 1;
     }
-    TSK_RETVAL_ENUM
-        retval = findFilesInFsInt(fs_info, a_inum);
+    TSK_RETVAL_ENUM retval = findFilesInFsInt(fs_info, a_inum);
     tsk_fs_close(fs_info);
     if (retval == TSK_ERR)
         return 1;
@@ -367,7 +391,8 @@ uint8_t TskAuto::findFilesInFs(TSK_OFF_T a_start, TSK_FS_TYPE_ENUM a_ftype, TSK_
  *
  * @returns 1 on error and 0 on success
  */
-uint8_t TskAuto::findFilesInFs(TSK_OFF_T a_start, TSK_INUM_T a_inum)
+uint8_t
+TskAuto::findFilesInFs(TSK_OFF_T a_start, TSK_INUM_T a_inum)
 {
     return TskAuto::findFilesInFs(a_start, TSK_FS_TYPE_DETECT, a_inum);
 }
@@ -385,11 +410,11 @@ TSK_WALK_RET_ENUM
     if (tsk->m_tag != TSK_AUTO_TAG)
         return TSK_WALK_STOP;
     TSK_RETVAL_ENUM retval = tsk->processFile(a_fs_file, a_path);
-    if (retval != TSK_OK){
-            if(retval == TSK_STOP)
-                return TSK_WALK_STOP;
-            else
-                return TSK_WALK_ERROR;
+    if (retval != TSK_OK) {
+        if (retval == TSK_STOP)
+            return TSK_WALK_STOP;
+        else
+            return TSK_WALK_ERROR;
     }
     else
         return TSK_WALK_CONT;
@@ -431,13 +456,14 @@ TSK_RETVAL_ENUM
  * @returns 1 if the file system processing should stop and not process more files.
  */
 TSK_RETVAL_ENUM
-TskAuto::processAttributes(TSK_FS_FILE * fs_file, const char *path)
+    TskAuto::processAttributes(TSK_FS_FILE * fs_file, const char *path)
 {
     int
      count = tsk_fs_file_attr_getsize(fs_file), i;
     for (i = 0; i < count; i++) {
-        TSK_RETVAL_ENUM retval = processAttribute(fs_file, tsk_fs_file_attr_get_idx(fs_file, i),
-                path);
+        TSK_RETVAL_ENUM retval =
+            processAttribute(fs_file, tsk_fs_file_attr_get_idx(fs_file, i),
+            path);
         if (retval != TSK_OK)
             return retval;
     }
@@ -467,7 +493,8 @@ uint8_t
  *
  * @returns 1 if the file is an FAT System file, 0 if not.
  */
-uint8_t TskAuto::isFATSystemFiles(TSK_FS_FILE * a_fs_file)
+uint8_t
+TskAuto::isFATSystemFiles(TSK_FS_FILE * a_fs_file)
 {
     if ((a_fs_file) && (a_fs_file->fs_info)
         && (TSK_FS_TYPE_ISFAT(a_fs_file->fs_info->ftype))
@@ -487,7 +514,8 @@ uint8_t TskAuto::isFATSystemFiles(TSK_FS_FILE * a_fs_file)
  *
  * @returns 1 if the file is a dot directory, 0 if not.
  */
-uint8_t TskAuto::isDotDir(TSK_FS_FILE * a_fs_file, const char *a_path)
+uint8_t
+TskAuto::isDotDir(TSK_FS_FILE * a_fs_file, const char *a_path)
 {
     if ((!a_fs_file) || (!a_fs_file->name)
         || ((a_fs_file->name->flags & TSK_FS_NAME_TYPE_DIR) == 0))
@@ -509,7 +537,8 @@ uint8_t TskAuto::isDotDir(TSK_FS_FILE * a_fs_file, const char *a_path)
  *
  * @returns 1 if the file is a directory, 0 if not.
  */
-uint8_t TskAuto::isDir(TSK_FS_FILE * a_fs_file)
+uint8_t
+TskAuto::isDir(TSK_FS_FILE * a_fs_file)
 {
     if ((a_fs_file) && (a_fs_file->name)
         && (a_fs_file->name->type == TSK_FS_NAME_TYPE_DIR))
@@ -523,7 +552,8 @@ uint8_t TskAuto::isDir(TSK_FS_FILE * a_fs_file)
  *
  * @returns 1 if the file is a file, 0 if not.
  */
-uint8_t TskAuto::isFile(TSK_FS_FILE * a_fs_file)
+uint8_t
+TskAuto::isFile(TSK_FS_FILE * a_fs_file)
 {
     if ((a_fs_file) && (a_fs_file->name)
         && (a_fs_file->name->type == TSK_FS_NAME_TYPE_REG))
@@ -554,7 +584,8 @@ uint8_t
  *
  * @returns 1 if the attribute is non-resident, 0 if not.
  */
-uint8_t TskAuto::isNonResident(const TSK_FS_ATTR * a_fs_attr)
+uint8_t
+TskAuto::isNonResident(const TSK_FS_ATTR * a_fs_attr)
 {
     if ((a_fs_attr) && (a_fs_attr->flags & TSK_FS_ATTR_NONRES))
         return 1;
diff --git a/tsk3/auto/auto_db.cpp b/tsk3/auto/auto_db.cpp
index 50b983fdd5a2c55dcb403060767c976edc8aba20..1797bf0a7612751727d1acb1de2cde119004bee5 100644
--- a/tsk3/auto/auto_db.cpp
+++ b/tsk3/auto/auto_db.cpp
@@ -50,15 +50,33 @@ void
  * @return Resturns 1 on error
  */
 uint8_t
-TskAutoDb::openImage(int a_num, const TSK_TCHAR * const a_images[],
-                     TSK_IMG_TYPE_ENUM a_type, unsigned int a_ssize)
+    TskAutoDb::openImage(int a_num, const TSK_TCHAR * const a_images[],
+    TSK_IMG_TYPE_ENUM a_type, unsigned int a_ssize)
+{
+    return openImage(a_num, a_images, a_type, a_ssize, NULL);
+}
+
+/**
+ * Open the image to be analyzed.  Creates the database in the same
+ * directory as the image (with .db appended to the name). Uses the
+ * utf8 functions even in windows.
+ * @param a_num Number of images
+ * @param a_images Images to open
+ * @param a_type Image file format
+ * @param a_ssize Sector size in bytes
+ * @return Resturns 1 on error
+ */
+uint8_t
+    TskAutoDb::openImageUtf8(int a_num, const char *const a_images[],
+    TSK_IMG_TYPE_ENUM a_type, unsigned int a_ssize)
 {
-    return openImage(a_num, a_images, a_type, a_ssize, NULL);    
+    return openImageUtf8(a_num, a_images, a_type, a_ssize, NULL);
 }
 
 /**
  * Open the image to be analyzed.  Creates the database in the specified
- * directory (with .db appended to the name).
+ * directory (with .db appended to the name). Always uses utf8 functions
+ * even in windows.
  * @param a_num Number of images
  * @param a_images Images to open
  * @param a_type Image file format
@@ -67,11 +85,10 @@ TskAutoDb::openImage(int a_num, const TSK_TCHAR * const a_images[],
  * @return Resturns 1 on error
  */
 uint8_t
-    TskAutoDb::openImage(int a_num, const TSK_TCHAR * const a_images[],
-    TSK_IMG_TYPE_ENUM a_type, unsigned int a_ssize, TSK_TCHAR * a_output_dir)
+    TskAutoDb::openImageUtf8(int a_num, const char *const a_images[],
+    TSK_IMG_TYPE_ENUM a_type, unsigned int a_ssize, char *a_output_dir)
 {
-    TSK_TCHAR dbFile[1024];
-    char foo[1024];
+    char dbFile[1024];
 
     if (m_db) {
         sqlite3_close(m_db);
@@ -80,116 +97,192 @@ uint8_t
     m_curFsId = 0;
     m_curVsId = 0;
 
-    uint8_t retval = TskAuto::openImage(a_num, a_images, a_type, a_ssize);
+    uint8_t retval =
+        TskAuto::openImageUtf8(a_num, a_images, a_type, a_ssize);
     // open the DB
     if (retval != 0) {
         return retval;
     }
 
-    // make name of database
-#ifdef TSK_WIN32
-    if (a_output_dir != NULL){
-        wcsncpy(dbFile, a_output_dir, 1024);
-        
-        if(dbFile[wcslen(dbFile) - 1] != '/' && dbFile[wcslen(dbFile) - 1] != '\\')
-            wcsncat(dbFile, L"\\", 1024-wcslen(dbFile));
-        
-        // get the image name w/out the path
+    if (a_output_dir != NULL) {
+        strncpy(dbFile, a_output_dir, 1024);
+#ifdef WIN32
+        if (dbFile[strlen(dbFile) - 1] != '\\')
+            strncat(dbFile, "\\", 1024 - strlen(dbFile));
+#else
+        if (dbFile[strlen(dbFile) - 1] != '/')
+            strncat(dbFile, "/", 1024 - strlen(dbFile));
+#endif
+        // get the image name
         size_t j;
-        for (j = wcslen(a_images[0]) - 1; j > 0; j--) {
+        for (j = strlen(a_images[0]) - 1; j > 0; j--) {
             if ((a_images[0][j] == '/') || (a_images[0][j] == '\\')) {
                 j++;
                 break;
             }
         }
-        
-        wcsncat(dbFile, &a_images[0][j], 1024-wcslen(dbFile));
-        wcsncat(dbFile, L".db", 1024-wcslen(dbFile));
+
+        strncat(dbFile, &a_images[0][j], 1024 - strlen(dbFile));
+        strncat(dbFile, ".db", 1024 - strlen(dbFile));
     }
-    else{
-        wcsncpy(dbFile, a_images[0], 1024);
-        wcsncat(dbFile, L".db", 1024-wcslen(dbFile));
+    else {
+        snprintf(dbFile, 1024, "%s.db", a_images[0]);
     }
 
-    struct STAT_STR stat_buf;
-    if (TSTAT(dbFile, &stat_buf) == 0) {
+    struct stat stat_buf;
+    if (stat(dbFile, &stat_buf) == 0) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr( 
-                "Database %S already exists.  Must be deleted first.", dbFile);
+        tsk_error_set_errstr
+            ("Database %s already exists.  Must be deleted first.",
+            dbFile);
         return 1;
     }
-    
-    if (sqlite3_open16(dbFile, &m_db)) {
+
+    if (sqlite3_open(dbFile, &m_db)) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr( 
-            "Can't open database: %s\n", sqlite3_errmsg(m_db));
+        tsk_error_set_errstr("Can't open database: %s\n",
+            sqlite3_errmsg(m_db));
         sqlite3_close(m_db);
         return 1;
     }
-#else
-    if (a_output_dir != NULL){
-        strncpy(dbFile, a_output_dir, 1024);
-        
-        if(dbFile[strlen(dbFile) - 1] != '/')
-            strncat(dbFile, "/", 1024-strlen(dbFile));
-        
-        // get the image name
+
+    if (initDatabase((char **) a_images, a_num)) {
+        return 1;
+    }
+    return 0;
+}
+
+/**
+ * Open the image to be analyzed.  Creates the database in the specified
+ * directory (with .db appended to the name).
+ * @param a_num Number of images
+ * @param a_images Images to open
+ * @param a_type Image file format
+ * @param a_ssize Sector size in bytes
+ * @param a_output_dir Output directory to place database into or NULL to place it in the same directory as the image. 
+ * @return Resturns 1 on error
+ */
+uint8_t
+    TskAutoDb::openImage(int a_num, const TSK_TCHAR * const a_images[],
+    TSK_IMG_TYPE_ENUM a_type, unsigned int a_ssize,
+    TSK_TCHAR * a_output_dir)
+{
+    // make name of database
+#ifdef TSK_WIN32
+    TSK_TCHAR dbFile[1024];
+
+    if (m_db) {
+        sqlite3_close(m_db);
+        m_db = NULL;
+    }
+    m_curFsId = 0;
+    m_curVsId = 0;
+
+    uint8_t retval = TskAuto::openImage(a_num, a_images, a_type, a_ssize);
+    // open the DB
+    if (retval != 0) {
+        return retval;
+    }
+    if (a_output_dir != NULL) {
+        wcsncpy(dbFile, a_output_dir, 1024);
+
+        if (dbFile[wcslen(dbFile) - 1] != '/'
+            && dbFile[wcslen(dbFile) - 1] != '\\')
+            wcsncat(dbFile, L"\\", 1024 - wcslen(dbFile));
+
+        // get the image name w/out the path
         size_t j;
-        for (j = strlen(a_images[0]) - 1; j > 0; j--) {
+        for (j = wcslen(a_images[0]) - 1; j > 0; j--) {
             if ((a_images[0][j] == '/') || (a_images[0][j] == '\\')) {
                 j++;
                 break;
             }
-        }        
-        
-        strncat(dbFile, &a_images[0][j], 1024-strlen(dbFile));
-        strncat(dbFile, ".db", 1024-strlen(dbFile));
+        }
+
+        wcsncat(dbFile, &a_images[0][j], 1024 - wcslen(dbFile));
+        wcsncat(dbFile, L".db", 1024 - wcslen(dbFile));
     }
     else {
-        snprintf(dbFile, 1024, "%s.db", a_images[0]);
+        wcsncpy(dbFile, a_images[0], 1024);
+        wcsncat(dbFile, L".db", 1024 - wcslen(dbFile));
     }
 
     struct STAT_STR stat_buf;
     if (TSTAT(dbFile, &stat_buf) == 0) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr( 
-                "Database %s already exists.  Must be deleted first.", dbFile);
+        tsk_error_set_errstr
+            ("Database %S already exists.  Must be deleted first.",
+            dbFile);
         return 1;
     }
-    
-    if (sqlite3_open(dbFile, &m_db)) {
+
+    if (sqlite3_open16(dbFile, &m_db)) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr( 
-            "Can't open database: %s\n", sqlite3_errmsg(m_db));
+        tsk_error_set_errstr("Can't open database: %s\n",
+            sqlite3_errmsg(m_db));
         sqlite3_close(m_db);
         return 1;
     }
+    char **img_ptrs = (char **) tsk_malloc(sizeof(char **));
+    for (int i = 0; i < a_num; i++) {
+        char img2[1024];
+        UTF8 *ptr8;
+        UTF16 *ptr16;
 
-#endif
+        ptr8 = (UTF8 *) img2;
+        ptr16 = (UTF16 *) a_images[i];
+
+        retval =
+            tsk_UTF16toUTF8_lclorder((const UTF16 **) &ptr16, (UTF16 *)
+            & ptr16[TSTRLEN(a_images[i]) + 1], &ptr8,
+            (UTF8 *) ((uintptr_t) ptr8 + 1024), TSKlenientConversion);
+        if (retval != TSKconversionOK) {
+            tsk_error_reset();
+            tsk_error_set_errno(TSK_ERR_AUTO_UNICODE);
+            tsk_error_set_errstr("Error converting image to UTF-8\n");
+            return 1;
+        }
+        img_ptrs[i] = img2;
+    }
+    if (initDatabase(img_ptrs, a_num)) {
+        return 1;
+    }
 
+    return 0;
+#else
+    return openImageUtf8(a_num, a_images, a_type, a_ssize, a_output_dir);
+#endif
+}
 
-    char *errmsg;
+uint8_t TskAutoDb::initDatabase(char **img_ptrs, int a_num)
+{
+    char
+        foo[1024];
+    char *
+        errmsg;
     // disable synchronous for loading the DB since we have no crash recovery anyway...
     if (sqlite3_exec(m_db,
-                     "PRAGMA synchronous =  OFF;", NULL, NULL, &errmsg) != SQLITE_OK) {
+            "PRAGMA synchronous =  OFF;", NULL, NULL,
+            &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-                 "Error setting PRAGMA synchronous: %s\n", errmsg);
+        tsk_error_set_errstr("Error setting PRAGMA synchronous: %s\n",
+            errmsg);
         sqlite3_free(errmsg);
         return 1;
     }
     // We don't care about the return values of inserts etc.
     if (sqlite3_exec(m_db,
-                     "PRAGMA count_changes = false;", NULL, NULL, &errmsg) != SQLITE_OK) {
+            "PRAGMA count_changes = false;", NULL, NULL,
+            &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-                 "Error setting PRAGMA count changes: %s\n", errmsg);
+        tsk_error_set_errstr("Error setting PRAGMA count changes: %s\n",
+            errmsg);
         sqlite3_free(errmsg);
         return 1;
     }
@@ -199,8 +292,8 @@ uint8_t
             NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error creating tsk_db_info table: %s\n", errmsg);
+        tsk_error_set_errstr("Error creating tsk_db_info table: %s\n",
+            errmsg);
         sqlite3_free(errmsg);
         return 1;
     }
@@ -211,8 +304,8 @@ uint8_t
     if (sqlite3_exec(m_db, foo, NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error adding data to tsk_db_info table: %s\n", errmsg);
+        tsk_error_set_errstr
+            ("Error adding data to tsk_db_info table: %s\n", errmsg);
         sqlite3_free(errmsg);
         return 1;
     }
@@ -222,8 +315,8 @@ uint8_t
             NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error creating tsk_image_info table: %s\n", errmsg);
+        tsk_error_set_errstr("Error creating tsk_image_info table: %s\n",
+            errmsg);
         sqlite3_free(errmsg);
         return 1;
     }
@@ -234,8 +327,8 @@ uint8_t
     if (sqlite3_exec(m_db, foo, NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error adding data to tsk_image_info table: %s\n", errmsg);
+        tsk_error_set_errstr
+            ("Error adding data to tsk_image_info table: %s\n", errmsg);
         sqlite3_free(errmsg);
         return 1;
     }
@@ -245,39 +338,18 @@ uint8_t
             NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error creating tsk_image_names table: %s\n", errmsg);
+        tsk_error_set_errstr("Error creating tsk_image_names table: %s\n",
+            errmsg);
         sqlite3_free(errmsg);
         return 1;
     }
 
     for (int i = 0; i < a_num; i++) {
-        int a;
-        char *img_ptr = NULL;
-#ifdef TSK_WIN32
-        char img2[1024];
-        UTF8 *ptr8;
-        UTF16 *ptr16;
-
-        ptr8 = (UTF8 *) img2;
-        ptr16 = (UTF16 *) a_images[i];
-
-        retval =
-            tsk_UTF16toUTF8_lclorder((const UTF16 **) &ptr16, (UTF16 *)
-            & ptr16[TSTRLEN(a_images[i]) + 1], &ptr8,
-            (UTF8 *) ((uintptr_t) ptr8 + 1024), TSKlenientConversion);
-        if (retval != TSKconversionOK) {
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_AUTO_UNICODE);
-            tsk_error_set_errstr(
-                "Error converting image to UTF-8\n");
-            return 1;
-        }
-        img_ptr = img2;
-#else
-        img_ptr = (char *) a_images[i];
-#endif
-
+        int
+            a;
+        char *
+            img_ptr = NULL;
+        img_ptr = img_ptrs[i];
         // get only the file name (ignore the directory name)
         for (a = strlen(img_ptr) - 1; a > 0; a--) {
             if ((img_ptr[a] == '/') || (img_ptr[a] == '\\')) {
@@ -291,8 +363,8 @@ uint8_t
         if (sqlite3_exec(m_db, foo, NULL, NULL, &errmsg) != SQLITE_OK) {
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_AUTO_DB);
-            tsk_error_set_errstr(
-                "Error adding data to tsk_image_names table: %s\n",
+            tsk_error_set_errstr
+                ("Error adding data to tsk_image_names table: %s\n",
                 errmsg);
             sqlite3_free(errmsg);
             return 1;
@@ -304,8 +376,8 @@ uint8_t
             NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error creating tsk_vs_info table: %s\n", errmsg);
+        tsk_error_set_errstr("Error creating tsk_vs_info table: %s\n",
+            errmsg);
         sqlite3_free(errmsg);
         return 1;
     }
@@ -315,8 +387,8 @@ uint8_t
             NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error creating tsk_vol_info table: %s\n", errmsg);
+        tsk_error_set_errstr("Error creating tsk_vol_info table: %s\n",
+            errmsg);
         sqlite3_free(errmsg);
         return 1;
     }
@@ -326,8 +398,8 @@ uint8_t
             NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error creating tsk_fs_info table: %s\n", errmsg);
+        tsk_error_set_errstr("Error creating tsk_fs_info table: %s\n",
+            errmsg);
         sqlite3_free(errmsg);
         return 1;
     }
@@ -337,8 +409,8 @@ uint8_t
             NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error creating tsk_fs_files table: %s\n", errmsg);
+        tsk_error_set_errstr("Error creating tsk_fs_files table: %s\n",
+            errmsg);
         sqlite3_free(errmsg);
         return 1;
     }
@@ -349,8 +421,8 @@ uint8_t
                 NULL, NULL, &errmsg) != SQLITE_OK) {
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_AUTO_DB);
-            tsk_error_set_errstr(
-                "Error creating tsk_fs_blocks table: %s\n", errmsg);
+            tsk_error_set_errstr
+                ("Error creating tsk_fs_blocks table: %s\n", errmsg);
             sqlite3_free(errmsg);
             return 1;
         }
@@ -370,17 +442,17 @@ void
 }
 
 
-uint8_t
-TskAutoDb::createParentDirIndex()
+uint8_t TskAutoDb::createParentDirIndex()
 {
-    char *errmsg;
+    char *
+        errmsg;
     if (sqlite3_exec(m_db,
             "CREATE INDEX parentDir ON tsk_fs_files(par_file_id, fs_id);",
             NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error creating tsk_fs_files index on par_file_id: %s\n",
+        tsk_error_set_errstr
+            ("Error creating tsk_fs_files index on par_file_id: %s\n",
             errmsg);
         sqlite3_free(errmsg);
         return 1;
@@ -393,20 +465,20 @@ TskAutoDb::createParentDirIndex()
  * Analyzes the open image and adds image info to a database.
  * @returns 1 on error
  */
-uint8_t TskAutoDb::addFilesInImgToDB()
+uint8_t
+TskAutoDb::addFilesInImgToDB()
 {
     if (m_db == NULL) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "addFilesInImgToDB: m_db not open\n");
+        tsk_error_set_errstr("addFilesInImgToDB: m_db not open\n");
         return 1;
     }
 
-    setVolFilterFlags((TSK_VS_PART_FLAG_ENUM)(TSK_VS_PART_FLAG_ALLOC | TSK_VS_PART_FLAG_UNALLOC));
+    setVolFilterFlags((TSK_VS_PART_FLAG_ENUM) (TSK_VS_PART_FLAG_ALLOC |
+            TSK_VS_PART_FLAG_UNALLOC));
 
-    uint8_t
-        retval = findFilesInImg();
+    uint8_t retval = findFilesInImg();
     if (retval)
         return retval;
 
@@ -417,33 +489,36 @@ uint8_t TskAutoDb::addFilesInImgToDB()
     return 0;
 }
 
-TSK_FILTER_ENUM TskAutoDb::filterVs(const TSK_VS_INFO * vs_info) {
+TSK_FILTER_ENUM
+TskAutoDb::filterVs(const TSK_VS_INFO * vs_info)
+{
     char statement[1024];
     char *errmsg;
 
     m_vsFound = true;
     snprintf(statement, 1024,
         "INSERT INTO tsk_vs_info (vs_type, img_offset, block_size) VALUES (%d,%"
-        PRIuOFF ",%d)", vs_info->vstype, vs_info->offset, vs_info->block_size);
+        PRIuOFF ",%d)", vs_info->vstype, vs_info->offset,
+        vs_info->block_size);
 
     if (sqlite3_exec(m_db, statement, NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error adding data to tsk_vs_info table: %s\n", errmsg);
+        tsk_error_set_errstr
+            ("Error adding data to tsk_vs_info table: %s\n", errmsg);
         sqlite3_free(errmsg);
         return TSK_FILTER_STOP;
     }
-    
+
     return TSK_FILTER_CONT;
 }
 
-TSK_FILTER_ENUM
-TskAutoDb::filterVol(const TSK_VS_PART_INFO * vs_part)
+TSK_FILTER_ENUM TskAutoDb::filterVol(const TSK_VS_PART_INFO * vs_part)
 {
     char
      foo[1024];
-    char *errmsg;
+    char *
+        errmsg;
 
     m_volFound = true;
     snprintf(foo, 1024,
@@ -454,8 +529,8 @@ TskAutoDb::filterVol(const TSK_VS_PART_INFO * vs_part)
     if (sqlite3_exec(m_db, foo, NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error adding data to tsk_vol_info table: %s\n", errmsg);
+        tsk_error_set_errstr
+            ("Error adding data to tsk_vol_info table: %s\n", errmsg);
         sqlite3_free(errmsg);
         return TSK_FILTER_STOP;
     }
@@ -466,13 +541,14 @@ TskAutoDb::filterVol(const TSK_VS_PART_INFO * vs_part)
 }
 
 
-TSK_FILTER_ENUM
-TskAutoDb::filterFs(TSK_FS_INFO * fs_info)
+TSK_FILTER_ENUM TskAutoDb::filterFs(TSK_FS_INFO * fs_info)
 {
     char
      foo[1024];
-    char *errmsg;
-    TSK_FS_FILE *file_root;
+    char *
+        errmsg;
+    TSK_FS_FILE *
+        file_root;
 
     m_curFsId++;
 
@@ -480,7 +556,7 @@ TskAutoDb::filterFs(TSK_FS_INFO * fs_info)
      * we only do this so that we can have a dummy volume in vs_part so that
      * programs that use this can assume that there will be at least one 
      * volume. */
-    if(!m_vsFound){
+    if (!m_vsFound) {
         m_vsFound = true;
         snprintf(foo, 1024,
             "INSERT INTO tsk_vs_info (vs_type, img_offset, block_size) VALUES (%d,%"
@@ -489,26 +565,27 @@ TskAutoDb::filterFs(TSK_FS_INFO * fs_info)
         if (sqlite3_exec(m_db, foo, NULL, NULL, &errmsg) != SQLITE_OK) {
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_AUTO_DB);
-            tsk_error_set_errstr(
-                "Error adding data to tsk_vs_info table: %s\n", errmsg);
+            tsk_error_set_errstr
+                ("Error adding data to tsk_vs_info table: %s\n", errmsg);
             sqlite3_free(errmsg);
             return TSK_FILTER_STOP;
         }
     }
 
-    if(!m_volFound){
+    if (!m_volFound) {
         m_volFound = true;
         snprintf(foo, 1024,
             "INSERT INTO tsk_vs_parts (vol_id, start, length, desc, flags) VALUES (%d,%"
             PRIuOFF ",%" PRIuOFF ",'%s',%d)", 0,
-            fs_info->offset, fs_info->block_count * fs_info->block_size, "", TSK_VS_PART_FLAG_ALLOC);
+            fs_info->offset, fs_info->block_count * fs_info->block_size,
+            "", TSK_VS_PART_FLAG_ALLOC);
 
         m_curVsId = 0;
         if (sqlite3_exec(m_db, foo, NULL, NULL, &errmsg) != SQLITE_OK) {
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_AUTO_DB);
-            tsk_error_set_errstr(
-                "Error adding data to tsk_vs_parts table: %s\n", errmsg);
+            tsk_error_set_errstr
+                ("Error adding data to tsk_vs_parts table: %s\n", errmsg);
             sqlite3_free(errmsg);
             return TSK_FILTER_STOP;
         }
@@ -525,8 +602,8 @@ TskAutoDb::filterFs(TSK_FS_INFO * fs_info)
     if (sqlite3_exec(m_db, foo, NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error adding data to tsk_fs_info table: %s\n", errmsg);
+        tsk_error_set_errstr
+            ("Error adding data to tsk_fs_info table: %s\n", errmsg);
         sqlite3_free(errmsg);
         return TSK_FILTER_STOP;
     }
@@ -644,15 +721,15 @@ TSK_RETVAL_ENUM
         "INSERT INTO tsk_fs_files (fs_id, file_id, attr_type, attr_id, name, par_file_id, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid) VALUES (%d,%"
         PRIuINUM ",%d,%d,'%s',%" PRIuINUM ",%d,%d,%d,%d,%" PRIuOFF
         ",%d,%d,%d,%d,%d,%d,%d)", m_curFsId, fs_file->name->meta_addr,
-        type, idx, name, fs_file->name->par_addr, fs_file->name->type, meta_type,
-        fs_file->name->flags, meta_flags, size, crtime, ctime, atime,
-        mtime, meta_mode, gid, uid);
+        type, idx, name, fs_file->name->par_addr, fs_file->name->type,
+        meta_type, fs_file->name->flags, meta_flags, size, crtime, ctime,
+        atime, mtime, meta_mode, gid, uid);
 
     if (sqlite3_exec(m_db, foo, NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error adding data to tsk_fs_files table: %s\n", errmsg);
+        tsk_error_set_errstr
+            ("Error adding data to tsk_fs_files table: %s\n", errmsg);
         sqlite3_free(errmsg);
         free(name);
         return TSK_ERR;
@@ -673,8 +750,8 @@ TSK_RETVAL_ENUM
     if (sqlite3_exec(m_db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error using BEGIN for insert transaction: %s\n", errmsg);
+        tsk_error_set_errstr
+            ("Error using BEGIN for insert transaction: %s\n", errmsg);
         sqlite3_free(errmsg);
         return TSK_ERR;
     }
@@ -689,8 +766,8 @@ TSK_RETVAL_ENUM
     if (sqlite3_exec(m_db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr(
-            "Error using COMMIT for insert transaction: %s\n", errmsg);
+        tsk_error_set_errstr
+            ("Error using COMMIT for insert transaction: %s\n", errmsg);
         sqlite3_free(errmsg);
         return TSK_ERR;
     }
@@ -710,7 +787,8 @@ TSK_RETVAL_ENUM
     }
 
     // add the block map, if requested and the file is non-resident
-    if ((m_blkMapFlag) && (isNonResident(fs_attr)) && (isDotDir(fs_file, path) == 0)) {
+    if ((m_blkMapFlag) && (isNonResident(fs_attr))
+        && (isDotDir(fs_file, path) == 0)) {
         TSK_FS_ATTR_RUN *run;
         for (run = fs_attr->nrd.run; run != NULL; run = run->next) {
             char foo[1024];
@@ -721,16 +799,17 @@ TSK_RETVAL_ENUM
                 continue;
 
             snprintf(foo, 1024,
-                     "INSERT INTO tsk_fs_blocks (fs_id, blk_start, blk_len, file_id, attr_type, attr_id) VALUES (%d,%"
-                     PRIuDADDR ",%"PRIuDADDR ",%" PRIuINUM ",%d,%d)", m_curFsId, run->addr, run->len,
-                     fs_file->meta->addr, fs_attr->type, fs_attr->id);
+                "INSERT INTO tsk_fs_blocks (fs_id, blk_start, blk_len, file_id, attr_type, attr_id) VALUES (%d,%"
+                PRIuDADDR ",%" PRIuDADDR ",%" PRIuINUM ",%d,%d)",
+                m_curFsId, run->addr, run->len, fs_file->meta->addr,
+                fs_attr->type, fs_attr->id);
 
-            if (sqlite3_exec(m_db, foo, NULL, NULL,
-                             &errmsg) != SQLITE_OK) {
+            if (sqlite3_exec(m_db, foo, NULL, NULL, &errmsg) != SQLITE_OK) {
                 tsk_error_reset();
                 tsk_error_set_errno(TSK_ERR_AUTO_DB);
-                tsk_error_set_errstr(
-                         "Error adding data to tsk_fs_info table: %s\n", errmsg);
+                tsk_error_set_errstr
+                    ("Error adding data to tsk_fs_info table: %s\n",
+                    errmsg);
                 sqlite3_free(errmsg);
                 return TSK_ERR;
             }
diff --git a/tsk3/auto/tsk_auto.h b/tsk3/auto/tsk_auto.h
index 1d0aaa7b1647a2a72fb9b92d02f746572e233c48..437ac00d8d46ba3b2f5dea95673f5af67d455d83 100644
--- a/tsk3/auto/tsk_auto.h
+++ b/tsk3/auto/tsk_auto.h
@@ -61,6 +61,8 @@ class TskAuto {
 
     virtual uint8_t openImage(int, const TSK_TCHAR * const images[],
         TSK_IMG_TYPE_ENUM, unsigned int a_ssize);
+    virtual uint8_t openImageUtf8(int, const char *const images[],
+        TSK_IMG_TYPE_ENUM, unsigned int a_ssize);
     virtual uint8_t openImage(TSK_IMG_INFO *);
     virtual void closeImage();
 
@@ -70,8 +72,10 @@ class TskAuto {
     uint8_t findFilesInFs(TSK_OFF_T start);
     uint8_t findFilesInFs(TSK_OFF_T start, TSK_FS_TYPE_ENUM ftype);
     uint8_t findFilesInFs(TSK_OFF_T start, TSK_INUM_T inum);
-    uint8_t findFilesInFs(TSK_OFF_T start, TSK_FS_TYPE_ENUM ftype, TSK_INUM_T inum);
-    TSK_RETVAL_ENUM findFilesInFsRet(TSK_OFF_T start, TSK_FS_TYPE_ENUM a_ftype);
+    uint8_t findFilesInFs(TSK_OFF_T start, TSK_FS_TYPE_ENUM ftype,
+        TSK_INUM_T inum);
+    TSK_RETVAL_ENUM findFilesInFsRet(TSK_OFF_T start,
+        TSK_FS_TYPE_ENUM a_ftype);
 
     void setFileFilterFlags(TSK_FS_DIR_WALK_FLAG_ENUM);
     void setVolFilterFlags(TSK_VS_PART_FLAG_ENUM);
@@ -86,7 +90,7 @@ class TskAuto {
     virtual TSK_FILTER_ENUM filterVs(const TSK_VS_INFO * vs_info) {
         return TSK_FILTER_CONT;
     };
-    
+
     /**
      * TskAuto calls this method before it processes each volume that is found in a 
      * volume system. You can use this to learn about each volume before it is processed
@@ -139,7 +143,7 @@ class TskAuto {
 
   protected:
     TSK_IMG_INFO * m_img_info;
-    bool m_internalOpen; ///< True if m_img_info was opened in TskAuto and false if passed in
+    bool m_internalOpen;        ///< True if m_img_info was opened in TskAuto and false if passed in
     uint8_t isNtfsSystemFiles(TSK_FS_FILE * fs_file, const char *path);
     uint8_t isFATSystemFiles(TSK_FS_FILE * fs_file);
     uint8_t isDotDir(TSK_FS_FILE * fs_file, const char *path);
@@ -183,8 +187,12 @@ class TskAutoDb:public TskAuto {
     virtual ~ TskAutoDb();
     virtual uint8_t openImage(int, const TSK_TCHAR * const images[],
         TSK_IMG_TYPE_ENUM, unsigned int a_ssize);
+    virtual uint8_t openImageUtf8(int, const char *const images[],
+        TSK_IMG_TYPE_ENUM, unsigned int a_ssize);
     uint8_t openImage(int, const TSK_TCHAR * const images[],
         TSK_IMG_TYPE_ENUM, unsigned int a_ssize, TSK_TCHAR * output_dir);
+    uint8_t openImageUtf8(int, const char *const images[],
+        TSK_IMG_TYPE_ENUM, unsigned int a_ssize, char *output_dir);
     virtual void closeImage();
 
     uint8_t addFilesInImgToDB();
@@ -203,6 +211,7 @@ class TskAutoDb:public TskAuto {
     bool m_vsFound;
     bool m_volFound;
 
+    uint8_t initDatabase(char **, int);
     TSK_RETVAL_ENUM insertFileData(TSK_FS_FILE * fs_file,
         const TSK_FS_ATTR *, const char *path);
     virtual TSK_RETVAL_ENUM processAttribute(TSK_FS_FILE *,