diff --git a/bindings/java/jni/auto_db_java.cpp b/bindings/java/jni/auto_db_java.cpp
index c3833d86c776830b5bf30142a7f58fafc116b655..969d87ba117d3a9b4959ad27feb27c116d42b62f 100644
--- a/bindings/java/jni/auto_db_java.cpp
+++ b/bindings/java/jni/auto_db_java.cpp
@@ -115,11 +115,6 @@ TskAutoDbJava::initializeJni(JNIEnv * jniEnv, jobject jobj) {
         return TSK_ERR;
     }
 
-    m_getParentIdMethodID = m_jniEnv->GetMethodID(m_callbackClass, "findParentObjId", "(JJLjava/lang/String;Ljava/lang/String;)J");
-    if (m_getParentIdMethodID == NULL) {
-        return TSK_ERR;
-    }
-
     m_addUnallocParentMethodID = m_jniEnv->GetMethodID(m_callbackClass, "addUnallocFsBlockFilesParent", "(JLjava/lang/String;)J");
     if (m_addUnallocParentMethodID == NULL) {
         return TSK_ERR;
@@ -464,56 +459,10 @@ void extractExtension(char *name, char *extension) {
     }
 }
 
-/**
-* Store info about a directory in a complex map structure as a cache for the
-* files who are a child of this directory and want to know its object id.
-*
-* @param fsObjId fs id of this directory
-* @param fs_file File for the directory to store
-* @param path Full path (parent and this file) of the directory
-* @param objId object id of the directory
-*/
-void TskAutoDbJava::storeObjId(const int64_t& fsObjId, const TSK_FS_FILE* fs_file, const char* path, const int64_t& objId)
-{
-    // skip the . and .. entries
-    if ((fs_file->name) && (fs_file->name->name) && (TSK_FS_ISDOT(fs_file->name->name)))
-    {
-        return;
-    }
-
-    uint32_t seq;
-    uint32_t path_hash = hash((const unsigned char *)path);
-
-    /* NTFS uses sequence, otherwise we hash the path. We do this to map to the
-    * correct parent folder if there are two from the root dir that eventually point to
-    * the same folder (one deleted and one allocated) or two hard links. */
-    if (TSK_FS_TYPE_ISNTFS(fs_file->fs_info->ftype)) {
-        /* Use the sequence stored in meta (which could be one larger than the name value
-        * if the directory is deleted. We do this because the par_seq gets added to the
-        * name structure when it is added to the directory based on teh value stored in
-        * meta. */
-        seq = fs_file->meta->seq;
-    }
-    else {
-        seq = path_hash;
-    }
-
-    map<TSK_INUM_T, map<uint32_t, map<uint32_t, int64_t> > >& fsMap = m_parentDirIdCache[fsObjId];
-    if (fsMap.count(fs_file->name->meta_addr) == 0) {
-        fsMap[fs_file->name->meta_addr][seq][path_hash] = objId;
-    }
-    else {
-        map<uint32_t, map<uint32_t, int64_t> >& fileMap = fsMap[fs_file->name->meta_addr];
-        if (fileMap.count(seq) == 0) {
-            fileMap[seq][path_hash] = objId;
-        }
-    }
-}
-
-
 /**
 * Adds a file and its associated slack file to database.
-* Does not learn object ID for new files.
+* Does not learn object ID for new files, and files may 
+* not be added to the database immediately.
 *
 * @param fs_file
 * @param fs_attr
@@ -878,161 +827,6 @@ TskAutoDbJava::addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t& objI
     return TSK_OK;
 }
 
-/**
-* Return a hash of the passed in string. We use this
-* for full paths.
-* From: http://www.cse.yorku.ca/~oz/hash.html
-*/
-uint32_t 
-TskAutoDbJava::hash(const unsigned char* str)
-{
-    uint32_t hash = 5381;
-    int c;
-
-    while ((c = *str++)) {
-        // skip slashes -> normalizes leading/ending/double slashes
-        if (c == '/')
-            continue;
-        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
-    }
-
-    return hash;
-}
-
-/*
-* Utility method to break up path into parent folder and folder/file name.
-* @param path Path of folder that we want to analyze
-* @param ret_parent_path pointer to parent path (begins and ends with '/')
-* @param ret_name pointer to final folder/file name
-* @returns 0 on success, 1 on error
-*/
-bool 
-TskAutoDbJava::getParentPathAndName(const char *path, const char **ret_parent_path, const char **ret_name) {
-    // Need to break up 'path' in to the parent folder to match in 'parent_path' and the folder 
-    // name to match with the 'name' column in tsk_files table
-
-    // reset all arrays
-    parent_name[0] = '\0';
-    parent_path[0] = '\0';
-
-    size_t path_len = strlen(path);
-    if (path_len >= MAX_PATH_LENGTH_JAVA_DB_LOOKUP) {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_AUTO_DB);
-        tsk_error_set_errstr("TskDb::getParentPathAndName: Path is too long. Length = %zd, Max length = %d", path_len, MAX_PATH_LENGTH_JAVA_DB_LOOKUP);
-        // assign return values to pointers
-        *ret_parent_path = "";
-        *ret_name = "";
-        return 1;
-    }
-
-    // check if empty path or just "/" were passed in
-    if (path_len == 0 || (strcmp(path, "/") == 0)) {
-        *ret_name = "";
-        *ret_parent_path = "/";
-        return 0;
-    }
-
-
-    // step 1, copy everything into parent_path and clean it up
-    // add leading slash if its not in input.  
-    if (path[0] != '/') {
-        sprintf(parent_path, "%s", "/");
-    }
-
-    strncat(parent_path, path, MAX_PATH_LENGTH_JAVA_DB_LOOKUP);
-
-    // remove trailing slash
-    if (parent_path[strlen(parent_path) - 1] == '/') {
-        parent_path[strlen(parent_path) - 1] = '\0';
-    }
-
-    // replace all non-UTF8 characters
-    tsk_cleanupUTF8(parent_path, '^');
-
-    // Step 2, move the final folder/file to parent_file
-
-    // Find the last '/' 
-    char *chptr = strrchr(parent_path, '/');
-    if (chptr) {
-        // character found in the string
-        size_t position = chptr - parent_path;
-
-        sprintf(parent_name, "%s", chptr + 1);  // copy everything after slash into parent_name
-        *ret_name = parent_name;
-
-        parent_path[position + 1] = '\0';   // add terminating null after last "/"
-        *ret_parent_path = parent_path;
-    }
-    else {
-        // "/" character not found. the entire path is parent file name. parent path is "/"
-        *ret_name = parent_path;
-        *ret_parent_path = "/";
-    }
-    return 0;
-}
-
-/**
-* Find parent object id of TSK_FS_FILE. Use local cache map, if not found, fall back to SQL
-* @param fs_file file to find parent obj id for
-* @param parentPath Path of parent folder that we want to match
-* @param fsObjId fs id of this file
-* @returns parent obj id ( > 0), -1 on error
-*/
-int64_t 
-TskAutoDbJava::findParObjId(const TSK_FS_FILE* fs_file, const char* parentPath, const int64_t& fsObjId)
-{
-    uint32_t seq;
-    uint32_t path_hash = hash((const unsigned char *)parentPath);
-
-    /* NTFS uses sequence, otherwise we hash the path. We do this to map to the
-    * correct parent folder if there are two from the root dir that eventually point to
-    * the same folder (one deleted and one allocated) or two hard links. */
-    if (TSK_FS_TYPE_ISNTFS(fs_file->fs_info->ftype))
-    {
-        seq = fs_file->name->par_seq;
-    }
-    else
-    {
-        seq = path_hash;
-    }
-
-    //get from cache by parent meta addr, if available
-    map<TSK_INUM_T, map<uint32_t, map<uint32_t, int64_t> > >& fsMap = m_parentDirIdCache[fsObjId];
-    if (fsMap.count(fs_file->name->par_addr) > 0)
-    {
-        map<uint32_t, map<uint32_t, int64_t> >& fileMap = fsMap[fs_file->name->par_addr];
-        if (fileMap.count(seq) > 0) {
-            map<uint32_t, int64_t>& pathMap = fileMap[seq];
-            if (pathMap.count(path_hash) > 0) {
-                return pathMap[path_hash];
-            }
-        }
-    }
-
-    // Need to break up 'path' in to the parent folder to match in 'parent_path' and the folder 
-    // name to match with the 'name' column in tsk_files table
-    const char *parent_name = "";
-    const char *parent_path = "";
-    if (getParentPathAndName(parentPath, &parent_path, &parent_name)) {
-        return -1;
-    }
-
-    jstring jpath = m_jniEnv->NewStringUTF(parent_path);
-    jstring jname = m_jniEnv->NewStringUTF(parent_name);
-
-    // Look up in the database
-    jlong objIdj = m_jniEnv->CallLongMethod(m_javaDbObj, m_getParentIdMethodID,
-        fs_file->name->par_addr, fsObjId, jpath, jname);
-    int64_t objId = (int64_t)objIdj;
-
-    if (objId < 0) {
-        return -1;
-    }
-
-    return objId;
-}
-
 /**
 * Adds a new volume that will hold the unallocated blocks for the pool.
 *
diff --git a/bindings/java/jni/auto_db_java.h b/bindings/java/jni/auto_db_java.h
index 9ff046ce11a5611761f525413faee10812f21ff5..e6c5e68dd7217d784695749cf53c24df090db75d 100644
--- a/bindings/java/jni/auto_db_java.h
+++ b/bindings/java/jni/auto_db_java.h
@@ -143,16 +143,6 @@ class TskAutoDbJava :public TskAuto {
     std::map<int64_t, int64_t> m_poolOffsetToParentId;
     std::map<int64_t, int64_t> m_poolOffsetToVsId;
 
-    // Used to look up object IDs for files
-    #define MAX_PATH_LENGTH_JAVA_DB_LOOKUP 2048
-    char parent_name[MAX_PATH_LENGTH_JAVA_DB_LOOKUP];
-    char parent_path[MAX_PATH_LENGTH_JAVA_DB_LOOKUP + 2]; // +2 is for leading slash and trailing slash
-    map<int64_t, map<TSK_INUM_T, map<uint32_t, map<uint32_t, int64_t> > > > m_parentDirIdCache; //maps a file system ID to a map, which maps a directory file system meta address to a map, which maps a sequence ID to a map, which maps a hash of a path to its object ID in the database
-    int64_t findParObjId(const TSK_FS_FILE* fs_file, const char* parentPath, const int64_t& fsObjId);
-    bool getParentPathAndName(const char *path, const char **ret_parent_path, const char **ret_name);
-    void storeObjId(const int64_t& fsObjId, const TSK_FS_FILE* fs_file, const char* path, const int64_t& objId);
-    uint32_t hash(const unsigned char* str);
-
     // JNI data
     JNIEnv * m_jniEnv = NULL;
     jclass m_callbackClass = NULL;
@@ -164,7 +154,6 @@ class TskAutoDbJava :public TskAuto {
     jmethodID m_addPoolMethodID = NULL;
     jmethodID m_addFileSystemMethodID = NULL;
     jmethodID m_addFileMethodID = NULL;
-    jmethodID m_getParentIdMethodID = NULL;
     jmethodID m_addUnallocParentMethodID = NULL;
     jmethodID m_addLayoutFileMethodID = NULL;
     jmethodID m_addLayoutFileRangeMethodID = NULL;
diff --git a/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java b/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java
index 09285a40502f6b9f1c9042a0c675245159ede3f6..4f2e97246b222d0ad80f7406b7d36cd5e9a9264a 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java
@@ -359,8 +359,7 @@ private long addBatchedFilesToDb() {
 						} else {
 							// The parent wasn't found in the cache so do a database query
 							java.io.File parentAsFile = new java.io.File(parentPath);
-							computedParentObjId = findParentObjId(fileInfo.parMetaAddr, fileInfo.fsObjId, parentAsFile.getPath(), parentAsFile.getName());
-							// TODO - error checking. findParentObjId might throw exception if not needed from native code TODO
+							computedParentObjId = caseDb.findParentObjIdJNI(fileInfo.parMetaAddr, fileInfo.fsObjId, parentAsFile.getPath(), parentAsFile.getName(), trans);
 						}
 					}
 
@@ -509,28 +508,6 @@ private long addBatchedLayoutRangesToDb() {
 		}
 	}
     
-    /**
-     * Look up the parent of a file based on metadata address and name/path.
-     * Intended to be called from the native code during the add image process.
-	 * // TODO is this still needed from native code?????
-	 * // TODO note that transaction should be open
-     * 
-     * @param metaAddr
-     * @param fsObjId
-     * @param path
-     * @param name
-     * 
-     * @return The object ID of the parent or -1 if not found
-     */
-    long findParentObjId(long metaAddr, long fsObjId, String path, String name) {
-        try {
-            return caseDb.findParentObjIdJNI(metaAddr, fsObjId, path, name, trans);
-        } catch (TskCoreException ex) {
-            logger.log(Level.WARNING, "Error looking up parent with meta addr: " + metaAddr + " and name " + name, ex);
-            return -1;
-        }
-    }
-    
     /**
      * Add a virtual directory to hold unallocated file system blocks.
      * Intended to be called from the native code during the add image process.
@@ -547,9 +524,9 @@ long addUnallocFsBlockFilesParent(long fsObjId, String name) {
                 return -1;
             }
 			beginTransaction();
-            long objId = caseDb.addVirtualDirectoryJNI(fsIdToRootDir.get(fsObjId), name, trans);
+            VirtualDirectory dir = caseDb.addVirtualDirectory(fsIdToRootDir.get(fsObjId), name, trans);
 			commitTransaction();
-			return objId;
+			return dir.getId();
         } catch (TskCoreException ex) {
             logger.log(Level.SEVERE, "Error creating virtual directory " + name + " under file system ID " + fsObjId, ex);
 			revertTransaction();
diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
index bd102bf42a5a61accdeeddf4d2efb054352778c5..e835158cba185e1d6dcc1984b37edd0a84bd86b9 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
@@ -11106,10 +11106,10 @@ long findParentObjIdJNI(long metaAddr, long fsObjId, String path, String name, C
 			if (resultSet.next()) {
 				return resultSet.getLong("obj_id");
 			} else {
-				throw new TskCoreException(String.format("Error looking up parent meta addr %d", metaAddr));
+				throw new TskCoreException(String.format("Error looking up parent - meta addr: %d, path: %s, name: %s", metaAddr, path, name));
 			}
 		} catch (SQLException ex) {
-			throw new TskCoreException(String.format("Error looking up parent meta addr %d", metaAddr), ex);
+			throw new TskCoreException(String.format("Error looking up parent - meta addr: %d, path: %s, name: %s", metaAddr, path, name), ex);
 		} finally {
 			closeResultSet(resultSet);
 		}
@@ -11317,121 +11317,6 @@ void addLayoutFileRangeJNI(long objId, long byteStart, long byteLen,
 			releaseSingleUserCaseWriteLock();
 		}
 	}
-	
-	/**
-	 * Adds a virtual directory to the database and returns a VirtualDirectory
-	 * object representing it.
-	 * For use with the JNI callbacks associated with the add image process.
-	 *
-	 * @param parentId      the ID of the parent, or 0 if NULL
-	 * @param directoryName the name of the virtual directory to create
-	 * @param transaction   the transaction in the scope of which the operation
-	 *                      is to be performed, managed by the caller
-	 *
-	 * @return The object ID of the new virtual directory
-	 * 
-	 * @throws TskCoreException
-	 */
-	long addVirtualDirectoryJNI(long parentId, String directoryName, CaseDbTransaction transaction) throws TskCoreException {
-		acquireSingleUserCaseWriteLock();
-		ResultSet resultSet = null;
-		try {
-			// Get the parent path.
-			CaseDbConnection connection = transaction.getConnection();
-
-			String parentPath;
-			Content parent = this.getAbstractFileById(parentId, connection);
-			if (parent instanceof AbstractFile) {
-				if (isRootDirectory((AbstractFile) parent, transaction)) {
-					parentPath = "/";
-				} else {
-					parentPath = ((AbstractFile) parent).getParentPath() + parent.getName() + "/"; //NON-NLS
-				}
-			} else {
-				// The parent was either null or not an abstract file
-				parentPath = "/";
-			}
-
-			// Insert a row for the virtual directory into the tsk_objects table.
-			long newObjId = addObject(parentId, TskData.ObjectType.ABSTRACTFILE.getObjectType(), connection);
-
-			// Insert a row for the virtual directory into the tsk_files table.
-			// INSERT INTO tsk_files (obj_id, fs_obj_id, name, type, has_path, dir_type, meta_type,
-			// dir_flags, meta_flags, size, ctime, crtime, atime, mtime, md5, known, mime_type, parent_path, data_source_obj_id,extension)
-			// VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)
-			PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE);
-			statement.clearParameters();
-			statement.setLong(1, newObjId);
-
-			// If the parent is part of a file system, grab its file system ID
-			if (0 != parentId) {
-				long parentFs = this.getFileSystemId(parentId, connection);
-				if (parentFs != -1) {
-					statement.setLong(2, parentFs);
-				} else {
-					statement.setNull(2, java.sql.Types.BIGINT);
-				}
-			} else {
-				statement.setNull(2, java.sql.Types.BIGINT);
-			}
-
-			// name
-			statement.setString(3, directoryName);
-
-			//type
-			statement.setShort(4, TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType());
-			statement.setShort(5, (short) 1);
-
-			//flags
-			final TSK_FS_NAME_TYPE_ENUM dirType = TSK_FS_NAME_TYPE_ENUM.DIR;
-			statement.setShort(6, dirType.getValue());
-			final TSK_FS_META_TYPE_ENUM metaType = TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR;
-			statement.setShort(7, metaType.getValue());
-
-			//allocated
-			final TSK_FS_NAME_FLAG_ENUM dirFlag = TSK_FS_NAME_FLAG_ENUM.ALLOC;
-			statement.setShort(8, dirFlag.getValue());
-			final short metaFlags = (short) (TSK_FS_META_FLAG_ENUM.ALLOC.getValue()
-					| TSK_FS_META_FLAG_ENUM.USED.getValue());
-			statement.setShort(9, metaFlags);
-
-			//size
-			statement.setLong(10, 0);
-
-			//  nulls for params 11-14
-			statement.setNull(11, java.sql.Types.BIGINT);
-			statement.setNull(12, java.sql.Types.BIGINT);
-			statement.setNull(13, java.sql.Types.BIGINT);
-			statement.setNull(14, java.sql.Types.BIGINT);
-
-			statement.setNull(15, java.sql.Types.VARCHAR); // MD5
-			statement.setByte(16, FileKnown.UNKNOWN.getFileKnownValue()); // Known
-			statement.setNull(17, java.sql.Types.VARCHAR); // MIME type	
-
-			// parent path
-			statement.setString(18, parentPath);
-
-			// data source object id (same as object id if this is a data source)
-			long dataSourceObjectId;
-			if (0 == parentId) {
-				dataSourceObjectId = newObjId;
-			} else {
-				dataSourceObjectId = getDataSourceObjectId(connection, parentId);
-			}
-			statement.setLong(19, dataSourceObjectId);
-
-			//extension, since this is not really file we just set it to null
-			statement.setString(20, null);
-			connection.executeUpdate(statement);
-			
-			return newObjId;
-		} catch (SQLException e) {
-			throw new TskCoreException("Error creating virtual directory '" + directoryName + "'", e);
-		} finally {
-			closeResultSet(resultSet);
-			releaseSingleUserCaseWriteLock();
-		}
-	}	
 
 	/**
 	 * Stores a pair of object ID and its type
diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
index 1ecd0cf20dd1c70f6d714824e76f037b51e571fa..4fe44e69095ea9e9a78621ed570f2a5b3417896d 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
@@ -531,11 +531,7 @@ public void run(String deviceId, String[] imageFilePaths, int sectorSize) throws
 						}
 					}
 					if (imageHandle != 0) {
-						long startTime = System.currentTimeMillis();
 						runAddImgNat(tskAutoDbPointer, deviceId, imageHandle, timeZone, imageWriterPath);
-						long endTime = System.currentTimeMillis();
-						long elapsed = endTime - startTime;
-						System.out.println("\n### runAddImgNat time: " + elapsed + " ms\n");
 					}
 				} finally {
 					releaseTSKReadLock();