diff --git a/bindings/java/jni/dataModel_SleuthkitJNI.cpp b/bindings/java/jni/dataModel_SleuthkitJNI.cpp
index 35e18a139731694850f96c94e31baa90dbfd8dd2..7b1d4d4cb69c1cc2d0fbecc1d3a7767e36515f80 100644
--- a/bindings/java/jni/dataModel_SleuthkitJNI.cpp
+++ b/bindings/java/jni/dataModel_SleuthkitJNI.cpp
@@ -1604,6 +1604,48 @@ Java_org_sleuthkit_datamodel_SleuthkitJNI_readFileNat(JNIEnv * env,
 }
 
 
+/**
+ * Runs istat on a given file and saves the output to a temp file.
+ *
+ * @returns -1 on error (and throws exception)
+ */
+JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_saveFileMetaDataTextNat
+  (JNIEnv *env, jclass obj, jlong a_file_handle, jstring a_tmp_path)
+{
+    const TSK_JNI_FILEHANDLE *file_handle = castFsFile(env, a_file_handle);
+    if (file_handle == 0) {
+        //exception already set
+        return -1;
+    }
+    
+    // check the pointers
+    if (file_handle->fs_file == NULL || file_handle->fs_file->fs_info == NULL || file_handle->fs_file->meta == NULL) {
+        setThrowTskCoreError(env, "NULL pointers for istat file.");
+        return -1;
+    }
+    TSK_FS_INFO *fs_info = file_handle->fs_file->fs_info;   
+
+    // open a file to write the details to
+    jboolean isCopy;
+    char *str8 = (char *) env->GetStringUTFChars(a_tmp_path, &isCopy);
+    FILE *hFile = fopen(str8, "w");
+    if (hFile == NULL) {
+        env->ReleaseStringUTFChars(a_tmp_path, str8);
+        setThrowTskCoreError(env, "Couldn't open istat temp file for writing.");
+        return -1;
+    }
+    env->ReleaseStringUTFChars(a_tmp_path, str8);
+    
+    if (fs_info->istat(fs_info, hFile, file_handle->fs_file->meta->addr, 0, 0) != 0) {
+        fclose(hFile);
+        setThrowTskCoreError(env);
+        return -1;
+    }
+
+    fclose(hFile);
+    return 0;
+}
+
 /*
  * Close the given image
  * @param env pointer to java environment this was called from
diff --git a/bindings/java/jni/dataModel_SleuthkitJNI.h b/bindings/java/jni/dataModel_SleuthkitJNI.h
index 03c3ad83187c2fa344793da19da644a4646a9ece..3daa672b8c11c4e0e66c670e30ac067ad51dccff 100644
--- a/bindings/java/jni/dataModel_SleuthkitJNI.h
+++ b/bindings/java/jni/dataModel_SleuthkitJNI.h
@@ -1,3 +1,4 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
 #include <jni.h>
 /* Header for class org_sleuthkit_datamodel_SleuthkitJNI */
 
@@ -61,84 +62,80 @@ JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbOpenNat
  * Method:    hashDbNewNat
  * Signature: (Ljava/lang/String;)I
  */
-JNIEXPORT jint JNICALL
-    Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbNewNat(JNIEnv * env,
-    jclass obj, jstring pathJ);
-
-JNIEXPORT jint JNICALL
-Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbBeginTransactionNat(
-    JNIEnv *env, jclass obj, jint dbHandle);
+JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbNewNat
+  (JNIEnv *, jclass, jstring);
 
-JNIEXPORT jint JNICALL
-Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCommitTransactionNat(
-    JNIEnv *env, jclass obj, jint dbHandle);
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    hashDbBeginTransactionNat
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbBeginTransactionNat
+  (JNIEnv *, jclass, jint);
 
-JNIEXPORT jint JNICALL
-Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbRollbackTransactionNat(
-    JNIEnv *env, jclass obj, jint dbHandle);
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    hashDbCommitTransactionNat
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCommitTransactionNat
+  (JNIEnv *, jclass, jint);
 
 /*
  * Class:     org_sleuthkit_datamodel_SleuthkitJNI
- * Method:    hashDbAddRecordNat
- * Signature: 
+ * Method:    hashDbRollbackTransactionNat
+ * Signature: (I)I
  */
-JNIEXPORT jint JNICALL
-    Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbAddEntryNat(JNIEnv * env,
-    jclass obj, jstring filenameJ, jstring hashMd5J, jstring hashSha1J, jstring hashSha256J, 
-    jstring commentJ, jint dbHandle);
+JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbRollbackTransactionNat
+  (JNIEnv *, jclass, jint);
 
 /*
  * Class:     org_sleuthkit_datamodel_SleuthkitJNI
- * Method:    hashDbIsUpdateableNat
- * Signature: 
+ * Method:    hashDbAddEntryNat
+ * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)I
  */
-JNIEXPORT jboolean JNICALL
-    Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsUpdateableNat(JNIEnv * env,
-    jclass obj, jint dbHandle);
+JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbAddEntryNat
+  (JNIEnv *, jclass, jstring, jstring, jstring, jstring, jstring, jint);
 
 /*
  * Class:     org_sleuthkit_datamodel_SleuthkitJNI
- * Method:    hashDbIsIdxOnlyNat
- * Signature: 
+ * Method:    hashDbIsUpdateableNat
+ * Signature: (I)Z
  */
-JNIEXPORT jboolean JNICALL
-    Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsIdxOnlyNat(JNIEnv * env,
-    jclass obj, jint dbHandle);
+JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsUpdateableNat
+  (JNIEnv *, jclass, jint);
 
 /*
  * Class:     org_sleuthkit_datamodel_SleuthkitJNI
  * Method:    hashDbIsReindexableNat
- * Signature: 
+ * Signature: (I)Z
  */
-JNIEXPORT jboolean JNICALL
-    Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsReindexableNat(JNIEnv * env,
-    jclass obj, jint dbHandle);
+JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsReindexableNat
+  (JNIEnv *, jclass, jint);
 
 /*
  * Class:     org_sleuthkit_datamodel_SleuthkitJNI
  * Method:    hashDbPathNat
- * Signature: 
+ * Signature: (I)Ljava/lang/String;
  */
-JNIEXPORT jstring JNICALL
-    Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbPathNat(JNIEnv * env,
-    jclass obj, jint dbHandle);
+JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbPathNat
+  (JNIEnv *, jclass, jint);
 
 /*
  * Class:     org_sleuthkit_datamodel_SleuthkitJNI
  * Method:    hashDbIndexPathNat
- * Signature: 
+ * Signature: (I)Ljava/lang/String;
  */
-JNIEXPORT jstring JNICALL
-    Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIndexPathNat(JNIEnv * env,
-    jclass obj, jint dbHandle);
+JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIndexPathNat
+  (JNIEnv *, jclass, jint);
 
 /*
  * Class:     org_sleuthkit_datamodel_SleuthkitJNI
- * Method:    hashDbGetName
- * Signature: 
+ * Method:    hashDbGetDisplayName
+ * Signature: (I)Ljava/lang/String;
  */
 JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbGetDisplayName
-  (JNIEnv *, jclass, jint dbHandle);
+  (JNIEnv *, jclass, jint);
 
 /*
  * Class:     org_sleuthkit_datamodel_SleuthkitJNI
@@ -151,23 +148,47 @@ JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCloseAll
 /*
  * Class:     org_sleuthkit_datamodel_SleuthkitJNI
  * Method:    hashDbClose
- * Signature: 
+ * Signature: (I)V
  */
 JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbClose
-  (JNIEnv *, jclass, jint dbHandle);
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    hashDbCreateIndexNat
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCreateIndexNat
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    hashDbIndexExistsNat
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIndexExistsNat
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    hashDbIsIdxOnlyNat
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsIdxOnlyNat
+  (JNIEnv *, jclass, jint);
 
 /*
  * Class:     org_sleuthkit_datamodel_SleuthkitJNI
  * Method:    hashDbLookup
- * Signature: (Ljava/lang/String;I)B
+ * Signature: (Ljava/lang/String;I)Z
  */
 JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbLookup
   (JNIEnv *, jclass, jstring, jint);
 
 /*
  * Class:     org_sleuthkit_datamodel_SleuthkitJNI
- * Method:    hashDbLookup
- * Signature: (Ljava/lang/String;I)Lorg/sleuthkit/datamodel/HashInfo
+ * Method:    hashDbLookupVerbose
+ * Signature: (Ljava/lang/String;I)Lorg/sleuthkit/datamodel/HashHitInfo;
  */
 JNIEXPORT jobject JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbLookupVerbose
   (JNIEnv *, jclass, jstring, jint);
@@ -292,6 +313,14 @@ JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFsNat
 JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFileNat
   (JNIEnv *, jclass, jlong, jbyteArray, jlong, jlong);
 
+/*
+ * Class:     org_sleuthkit_datamodel_SleuthkitJNI
+ * Method:    saveFileMetaDataTextNat
+ * Signature: (JLjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_saveFileMetaDataTextNat
+  (JNIEnv *, jclass, jlong, jstring);
+
 /*
  * Class:     org_sleuthkit_datamodel_SleuthkitJNI
  * Method:    closeImgNat
@@ -324,22 +353,6 @@ JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFsNat
 JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFileNat
   (JNIEnv *, jclass, jlong);
 
-/*
- * Class:     org_sleuthkit_datamodel_SleuthkitJNI
- * Method:    hashDbCreateIndexNat
- * Signature: 
- */
-JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCreateIndexNat
-  (JNIEnv *, jclass, jint);
-
-/*
- * Class:     org_sleuthkit_datamodel_SleuthkitJNI
- * Method:    hashDbIndexExistsNat
- * Signature: 
- */
-JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIndexExistsNat
-  (JNIEnv *, jclass, jint);
-
 /*
  * Class:     org_sleuthkit_datamodel_SleuthkitJNI
  * Method:    findDeviceSizeNat
@@ -360,3 +373,25 @@ JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getCurDirNat
 }
 #endif
 #endif
+/* Header for class org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle */
+
+#ifndef _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle
+#define _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle_AddImageProcess */
+
+#ifndef _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle_AddImageProcess
+#define _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle_AddImageProcess
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/bindings/java/src/org/sleuthkit/datamodel/FsContent.java b/bindings/java/src/org/sleuthkit/datamodel/FsContent.java
index 4a987335a11ec5bea935611a15a663e80493882e..d8f7ac8e2108a541f93a004cb271d5d0496a5f70 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/FsContent.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/FsContent.java
@@ -18,10 +18,10 @@
  */
 package org.sleuthkit.datamodel;
 
+import java.util.List;
+import java.util.ResourceBundle;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import java.util.ResourceBundle;
-
 import org.sleuthkit.datamodel.TskData.FileKnown;
 import org.sleuthkit.datamodel.TskData.TSK_FS_ATTR_TYPE_ENUM;
 import org.sleuthkit.datamodel.TskData.TSK_FS_META_TYPE_ENUM;
@@ -45,6 +45,8 @@ public abstract class FsContent extends AbstractFile {
 	///read-write database tsk_files fields
 	private final SleuthkitCase tskCase;
 	
+	private List<String> metaDataText = null;
+	
 	/**
 	 * parent file system
 	 */
@@ -124,6 +126,21 @@ public FileSystem getFileSystem() throws TskCoreException {
 		}
 		return parentFileSystem;
 	}
+	
+	/**
+	 * Open JNI file handle if it is not open already
+	 * 
+	 * @throws TskCoreException 
+	 */
+	private void loadFileHandle() throws TskCoreException {
+		if (fileHandle == 0) {
+			synchronized (this) {
+				if (fileHandle == 0) {
+					fileHandle = SleuthkitJNI.openFile(getFileSystem().getFileSystemHandle(), metaAddr, attrType, attrId);
+				}
+			}
+		}
+	}
 
 	@Override
     @SuppressWarnings("deprecation")
@@ -133,13 +150,7 @@ protected int readInt(byte[] buf, long offset, long len) throws TskCoreException
 				//special case for 0-size file
 				return 0;
 			}
-			if (fileHandle == 0) {
-				synchronized (this) {
-					if (fileHandle == 0) {
-						fileHandle = SleuthkitJNI.openFile(getFileSystem().getFileSystemHandle(), metaAddr, attrType, attrId);
-					}
-				}
-			}
+			loadFileHandle();
 			return SleuthkitJNI.readFile(fileHandle, buf, offset, len);
 		}
 		catch (TskCoreException ex) {
@@ -198,6 +209,24 @@ public synchronized String getUniquePath() throws TskCoreException {
 		}
 		return uniquePath;
 	}
+	
+	/**
+	 * Return a text-based description of the file's metadata.
+	 * This is the same content as the TSK istat tool produces.
+	 * Is different information for each type of file system.
+	 * 
+	 * @return List of text, one string per line.
+	 * @throws TskCoreException 
+	 */
+	public List<String> getMetaDataText() throws TskCoreException {
+		if (metaDataText != null) {
+			return metaDataText;
+		}
+		
+		loadFileHandle();
+		metaDataText = SleuthkitJNI.getFileMetaDataText(fileHandle);
+		return metaDataText;
+	}
 
 	@Override
 	public void close() {
diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
index 91acb6e8c57afefb4f07a1d1c1cbdfb50de7cbea..30c95a212224c3947d7c64aec3b56e43de44cc95 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
@@ -18,11 +18,15 @@
  */
 package org.sleuthkit.datamodel;
 
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.GregorianCalendar;
-import java.util.List;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.TimeZone;
 import org.sleuthkit.datamodel.TskData.TSK_FS_ATTR_TYPE_ENUM;
@@ -121,6 +125,8 @@ public class SleuthkitJNI {
 
 	private static native int readFileNat(long fileHandle, byte[] readBuffer, long offset, long len) throws TskCoreException;
 
+	private static native int saveFileMetaDataTextNat(long fileHandle, String fileName) throws TskCoreException;
+	
 	//close functions
 	private static native void closeImgNat(long imgHandle);
 
@@ -523,6 +529,39 @@ public static int readFs(long fsHandle, byte[] readBuffer, long offset, long len
 	public static int readFile(long fileHandle, byte[] readBuffer, long offset, long len) throws TskCoreException {
 		return readFileNat(fileHandle, readBuffer, offset, len);
 	}
+	
+	
+	/**
+	 * Get human readable (some what) details about a file. This is the same as the 'istat' TSK tool
+	 * @param fileHandle pointer to file structure in the sleuthkit
+	 * @return text
+	 * @throws TskCoreException if errors occurred
+	 */
+	public static List<String> getFileMetaDataText(long fileHandle) throws TskCoreException {
+		try {
+			java.io.File tmp = java.io.File.createTempFile("tsk", ".txt");
+			
+			saveFileMetaDataTextNat(fileHandle, tmp.getAbsolutePath());
+			
+			FileReader fr = new FileReader(tmp.getAbsolutePath());
+			BufferedReader textReader = new BufferedReader(fr);
+			
+			List<String> lines = new ArrayList<String>();
+			while (true) {
+				String line = textReader.readLine();
+				if (line == null) {
+					break;
+				}
+				lines.add(line);
+			}
+		
+			tmp.delete();
+			return lines;
+		} catch (IOException ex) {
+			throw new TskCoreException("Error reading istat output: " + ex.getLocalizedMessage());
+		}
+	}
+	
 
 	//free pointers
 	/**