diff --git a/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java b/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java
index f6bc4bf65d09d57e1868307ca9da639d39bc049d..5adb2b2fd0b12c31151e41787c0faecb0e3094fd 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/CaseDatabaseFactory.java
@@ -25,9 +25,9 @@
 import java.sql.Statement;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import org.sleuthkit.datamodel.databaseutils.DatabaseQueryHelper;
-import org.sleuthkit.datamodel.databaseutils.PostgreSQLQueryHelper;
-import org.sleuthkit.datamodel.databaseutils.SQLiteQueryHelper;
+import java.util.Properties;
+import org.sleuthkit.datamodel.SQLHelper.PostgreSQLHelper;
+import org.sleuthkit.datamodel.SQLHelper.SQLiteHelper;
 
 /**
  *
@@ -35,7 +35,7 @@
 class CaseDatabaseFactory {
 	private static final Logger logger = Logger.getLogger(CaseDatabaseFactory.class.getName());
 	
-	private final DatabaseQueryHelper dbQueryHelper;
+	private final SQLHelper dbQueryHelper;
 	private final DbCreationHelper dbCreationHelper;
 		
 	/**
@@ -44,7 +44,7 @@ class CaseDatabaseFactory {
 	 * @param dbPath Full path to the database
 	 */
 	CaseDatabaseFactory(String dbPath) {		
-		this.dbQueryHelper = new SQLiteQueryHelper();
+		this.dbQueryHelper = new SQLiteHelper();
 		this.dbCreationHelper = new SQLiteDbCreationHelper(dbPath);
 	}
 	
@@ -57,11 +57,10 @@ class CaseDatabaseFactory {
 	 *                    database server. Use getDatabaseName to get the
 	 *                    created name.
 	 * @param info        The information to connect to the database.
-	 * @param caseDirPath The case directory path.
 	 */
-	CaseDatabaseFactory(String caseName, CaseDbConnectionInfo info, String caseDirPath) {
-		this.dbQueryHelper = new PostgreSQLQueryHelper();
-		this.dbCreationHelper = new PostgreSQLDbCreationHelper(caseName, info, caseDirPath);
+	CaseDatabaseFactory(String caseName, CaseDbConnectionInfo info) {
+		this.dbQueryHelper = new PostgreSQLHelper();
+		this.dbCreationHelper = new PostgreSQLDbCreationHelper(caseName, info);
 	}
 	
 	/**
@@ -71,7 +70,6 @@ class CaseDatabaseFactory {
 	 * @throws TskCoreException 
 	 */
 	void createCaseDatabase() throws TskCoreException {
-		
 		createDatabase();
 		initializeSchema();
 	}
@@ -108,8 +106,7 @@ private void initializeSchema() throws TskCoreException {
 			dbCreationHelper.performPostTableInitialization(conn);
 		
 			// Add indexes
-			createIndexes(conn);
-		
+			addIndexes(conn);
 		} finally {
 			try {
 				conn.close();
@@ -127,18 +124,8 @@ private void initializeSchema() throws TskCoreException {
 	 * @throws TskCoreException 
 	 */
 	private void addDbInfo(Connection conn) throws TskCoreException {
-		
-		/* Version of code in number form.
-		 * Upper byte is A, next is B, and next byte is C in version A.B.C.
-		 * Lowest byte is 0xff, except in beta releases, in which case it
-		 * increments from 1.  
-		 * For example, 3.1.2 would be stored as 0x030102FF.
-		 */
 		CaseDbSchemaVersionNumber version = SleuthkitCase.CURRENT_DB_SCHEMA_VERSION;
-		long tskVersionNum = version.getMajor() << 24
-								| version.getMinor() << 16
-								| version.getPatch() << 8
-								| 0xff;
+		long tskVersionNum = 0; // This is the current version of TSK (not the DB schema version)
 		
 		try (Statement stmt = conn.createStatement()) {
 			stmt.execute("CREATE TABLE tsk_db_info (schema_ver INTEGER, tsk_ver INTEGER, schema_minor_ver INTEGER)");
@@ -176,22 +163,28 @@ private void addTables(Connection conn) throws TskCoreException {
 					+ "sequence INTEGER NOT NULL, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
             
 			stmt.execute("CREATE TABLE tsk_vs_info (obj_id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, vs_type INTEGER NOT NULL, "
-					+ "img_offset " + dbQueryHelper.getBigIntType() + " NOT NULL, block_size BIGINT NOT NULL, "
+					+ "img_offset " + dbQueryHelper.getBigIntType() + " NOT NULL, block_size " + dbQueryHelper.getBigIntType() + " NOT NULL, "
 					+ "FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
             
 			stmt.execute("CREATE TABLE data_source_info (obj_id " + dbQueryHelper.getBigIntType() + " PRIMARY KEY, device_id TEXT NOT NULL, "
 					+ "time_zone TEXT NOT NULL, acquisition_details TEXT, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
             
 			stmt.execute("CREATE TABLE tsk_fs_info (obj_id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, "
-					+ "img_offset " + dbQueryHelper.getBigIntType() + " NOT NULL, fs_type INTEGER NOT NULL, block_size BIGINT NOT NULL, "
-					+ "block_count BIGINT NOT NULL, root_inum BIGINT NOT NULL, first_inum BIGINT NOT NULL, last_inum BIGINT NOT NULL, "
+					+ "img_offset " + dbQueryHelper.getBigIntType() + " NOT NULL, fs_type INTEGER NOT NULL, "
+					+ "block_size " + dbQueryHelper.getBigIntType() + " NOT NULL, "
+					+ "block_count " + dbQueryHelper.getBigIntType() + " NOT NULL, root_inum " + dbQueryHelper.getBigIntType() + " NOT NULL, "
+					+ "first_inum " + dbQueryHelper.getBigIntType() + " NOT NULL, last_inum " + dbQueryHelper.getBigIntType() + " NOT NULL, "
 					+ "display_name TEXT, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
             
 			stmt.execute("CREATE TABLE tsk_files (obj_id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, "
-					+ "fs_obj_id " + dbQueryHelper.getBigIntType() + ", data_source_obj_id BIGINT NOT NULL, attr_type INTEGER, attr_id INTEGER, " 
-					+ "name TEXT NOT NULL, meta_addr BIGINT, meta_seq BIGINT, type INTEGER, has_layout INTEGER, has_path INTEGER, "
-					+ "dir_type INTEGER, meta_type INTEGER, dir_flags INTEGER, meta_flags INTEGER, size BIGINT, ctime BIGINT, "
-					+ "crtime BIGINT, atime BIGINT, mtime BIGINT, mode INTEGER, uid INTEGER, gid INTEGER, md5 TEXT, known INTEGER, "
+					+ "fs_obj_id " + dbQueryHelper.getBigIntType() + ", data_source_obj_id " + dbQueryHelper.getBigIntType() + " NOT NULL, "
+					+ "attr_type INTEGER, attr_id INTEGER, " 
+					+ "name TEXT NOT NULL, meta_addr " + dbQueryHelper.getBigIntType() + ", meta_seq " + dbQueryHelper.getBigIntType() + ", "
+					+ "type INTEGER, has_layout INTEGER, has_path INTEGER, "
+					+ "dir_type INTEGER, meta_type INTEGER, dir_flags INTEGER, meta_flags INTEGER, size " + dbQueryHelper.getBigIntType() + ", "
+					+ "ctime " + dbQueryHelper.getBigIntType() + ", "
+					+ "crtime " + dbQueryHelper.getBigIntType() + ", atime " + dbQueryHelper.getBigIntType() + ", "
+					+ "mtime " + dbQueryHelper.getBigIntType() + ", mode INTEGER, uid INTEGER, gid INTEGER, md5 TEXT, known INTEGER, "
 					+ "parent_path TEXT, mime_type TEXT, extension TEXT, "
 					+ "FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
 					+ "FOREIGN KEY(fs_obj_id) REFERENCES tsk_fs_info(obj_id) ON DELETE CASCADE, "
@@ -200,7 +193,7 @@ private void addTables(Connection conn) throws TskCoreException {
 			stmt.execute("CREATE TABLE file_encoding_types (encoding_type INTEGER PRIMARY KEY, name TEXT NOT NULL)");
             
 			stmt.execute("CREATE TABLE tsk_files_path (obj_id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, path TEXT NOT NULL, "
-					+ "encoding_type INTEGER, FOREIGN KEY(encoding_type) references file_encoding_types(encoding_type), "
+					+ "encoding_type INTEGER NOT NULL, FOREIGN KEY(encoding_type) references file_encoding_types(encoding_type), "
 					+ "FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
             
 			stmt.execute("CREATE TABLE tsk_files_derived (obj_id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, "
@@ -240,7 +233,8 @@ private void addTables(Connection conn) throws TskCoreException {
 			* http://www.postgresql.org/docs/9.4/static/libpq-example.html
 			*/
 			stmt.execute("CREATE TABLE blackboard_attributes (artifact_id " + dbQueryHelper.getBigIntType() + " NOT NULL, "
-					+ "artifact_type_id BIGINT NOT NULL, source TEXT, context TEXT, attribute_type_id BIGINT NOT NULL, "
+					+ "artifact_type_id " + dbQueryHelper.getBigIntType() + " NOT NULL, "
+					+ "source TEXT, context TEXT, attribute_type_id " + dbQueryHelper.getBigIntType() + " NOT NULL, "
 					+ "value_type INTEGER NOT NULL, value_byte " + dbQueryHelper.getBlobType() + ", "
 					+ "value_text TEXT, value_int32 INTEGER, value_int64 " + dbQueryHelper.getBigIntType() + ", value_double NUMERIC(20, 10), "
 					+ "FOREIGN KEY(artifact_id) REFERENCES blackboard_artifacts(artifact_id) ON DELETE CASCADE, "
@@ -248,7 +242,8 @@ private void addTables(Connection conn) throws TskCoreException {
 					+ "FOREIGN KEY(attribute_type_id) REFERENCES blackboard_attribute_types(attribute_type_id))");
             
 			stmt.execute("CREATE TABLE tsk_vs_parts (obj_id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, "
-					+ "addr " + dbQueryHelper.getBigIntType() + " NOT NULL, start BIGINT NOT NULL, length BIGINT NOT NULL, "
+					+ "addr " + dbQueryHelper.getBigIntType() + " NOT NULL, start " + dbQueryHelper.getBigIntType() + " NOT NULL, "
+					+ "length " + dbQueryHelper.getBigIntType() + " NOT NULL, "
 					+ dbQueryHelper.getVSDescColName() + " TEXT, "
 					+ "flags INTEGER NOT NULL, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE);");
             
@@ -265,7 +260,8 @@ private void addTables(Connection conn) throws TskCoreException {
             
 			stmt.execute("CREATE TABLE ingest_jobs (ingest_job_id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, "
 					+ "obj_id " + dbQueryHelper.getBigIntType() + " NOT NULL, host_name TEXT NOT NULL, "
-					+ "start_date_time BIGINT NOT NULL, end_date_time BIGINT NOT NULL, status_id INTEGER NOT NULL, "
+					+ "start_date_time " + dbQueryHelper.getBigIntType() + " NOT NULL, "
+					+ "end_date_time " + dbQueryHelper.getBigIntType() + " NOT NULL, status_id INTEGER NOT NULL, "
 					+ "settings_dir TEXT, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
 					+ "FOREIGN KEY(status_id) REFERENCES ingest_job_status_types(type_id) ON DELETE CASCADE);");
             
@@ -286,10 +282,11 @@ private void addTables(Connection conn) throws TskCoreException {
 					+ "UNIQUE(account_type_id, account_unique_identifier), "
 					+ "FOREIGN KEY(account_type_id) REFERENCES account_types(account_type_id))");
             
-			stmt.execute("CREATE TABLE account_relationships  (relationship_id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, "
+			stmt.execute("CREATE TABLE account_relationships (relationship_id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, "
 					+ "account1_id INTEGER NOT NULL, account2_id INTEGER NOT NULL, "
 					+ "relationship_source_obj_id " + dbQueryHelper.getBigIntType() + " NOT NULL, "
-					+ "date_time BIGINT, relationship_type INTEGER NOT NULL, data_source_obj_id BIGINT NOT NULL, "
+					+ "date_time " + dbQueryHelper.getBigIntType() + ", relationship_type INTEGER NOT NULL, "
+					+ "data_source_obj_id " + dbQueryHelper.getBigIntType() + " NOT NULL, "
 					+ "UNIQUE(account1_id, account2_id, relationship_source_obj_id), "
 					+ "FOREIGN KEY(account1_id) REFERENCES accounts(account_id), "
 					+ "FOREIGN KEY(account2_id) REFERENCES accounts(account_id), "
@@ -301,15 +298,14 @@ private void addTables(Connection conn) throws TskCoreException {
 					+ " display_name TEXT UNIQUE NOT NULL , "
 					+ " super_type_id INTEGER REFERENCES tsk_event_types(event_type_id) )");
              
-			stmt.execute(
-					"INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(0, 'Event Types', null);"
-					+ "INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(1, 'File System', 0);"
-					+ "INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(2, 'Web Activity', 0);"
-					+ "INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(3, 'Misc Types', 0);"
-					+ "INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(4, 'Modified', 1);"
-					+ "INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(5, 'Accessed', 1);"
-					+ "INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(6, 'Created', 1);"
-					+ "INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(7, 'Changed', 1);");
+			stmt.execute("INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(0, 'Event Types', null)");
+			stmt.execute("INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(1, 'File System', 0)");
+			stmt.execute("INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(2, 'Web Activity', 0)");
+			stmt.execute("INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(3, 'Misc Types', 0)");
+			stmt.execute("INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(4, 'Modified', 1)");
+			stmt.execute("INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(5, 'Accessed', 1)");
+			stmt.execute("INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(6, 'Created', 1)");
+			stmt.execute("INSERT INTO tsk_event_types(event_type_id, display_name, super_type_id) VALUES(7, 'Changed', 1)");
 			/*
 			* Regarding the timeline event tables schema, note that several columns
 			* in the tsk_event_descriptions table seem, at first glance, to be
@@ -350,22 +346,23 @@ private void addTables(Connection conn) throws TskCoreException {
 					+ "login_name TEXT NOT NULL, display_name TEXT, UNIQUE(login_name))");
             
 			stmt.execute("CREATE TABLE content_tags (tag_id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, "
-					+ "obj_id " + dbQueryHelper.getBigIntType() + " NOT NULL, tag_name_id BIGINT NOT NULL, "
-							+ "comment TEXT NOT NULL, begin_byte_offset BIGINT NOT NULL, end_byte_offset BIGINT NOT NULL, "
-							+ "examiner_id BIGINT, "
-							+ "FOREIGN KEY(examiner_id) REFERENCES tsk_examiners(examiner_id), "
-							+ "FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
-							+ "FOREIGN KEY(tag_name_id) REFERENCES tag_names(tag_name_id))");
+					+ "obj_id " + dbQueryHelper.getBigIntType() + " NOT NULL, tag_name_id " + dbQueryHelper.getBigIntType() + " NOT NULL, "
+					+ "comment TEXT NOT NULL, begin_byte_offset " + dbQueryHelper.getBigIntType() + " NOT NULL, "
+					+ "end_byte_offset " + dbQueryHelper.getBigIntType() + " NOT NULL, "
+					+ "examiner_id " + dbQueryHelper.getBigIntType() + ", "
+					+ "FOREIGN KEY(examiner_id) REFERENCES tsk_examiners(examiner_id), "
+					+ "FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
+					+ "FOREIGN KEY(tag_name_id) REFERENCES tag_names(tag_name_id))");
             
 			stmt.execute("CREATE TABLE blackboard_artifact_tags (tag_id " + dbQueryHelper.getPrimaryKey() + " PRIMARY KEY, "
-					+ "artifact_id " + dbQueryHelper.getBigIntType() + " NOT NULL, tag_name_id BIGINT NOT NULL, "
-					+ "comment TEXT NOT NULL,  examiner_id BIGINT, "
+					+ "artifact_id " + dbQueryHelper.getBigIntType() + " NOT NULL, tag_name_id " + dbQueryHelper.getBigIntType() + " NOT NULL, "
+					+ "comment TEXT NOT NULL,  examiner_id " + dbQueryHelper.getBigIntType() + ", "
 					+ "FOREIGN KEY(examiner_id) REFERENCES tsk_examiners(examiner_id), "
 					+ "FOREIGN KEY(artifact_id) REFERENCES blackboard_artifacts(artifact_id) ON DELETE CASCADE, "
 							+ "FOREIGN KEY(tag_name_id) REFERENCES tag_names(tag_name_id))");
             
 			stmt.execute("CREATE TABLE tsk_file_layout (obj_id " + dbQueryHelper.getBigIntType() + " NOT NULL, "
-					+ "byte_start BIGINT NOT NULL, byte_len BIGINT NOT NULL, "
+					+ "byte_start " + dbQueryHelper.getBigIntType() + " NOT NULL, byte_len " + dbQueryHelper.getBigIntType() + " NOT NULL, "
 					+ "sequence INTEGER NOT NULL, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE);");
 
 		} catch (SQLException ex) {
@@ -380,7 +377,38 @@ private void addTables(Connection conn) throws TskCoreException {
 	 * @throws TskCoreException 
 	 */
 	private void addIndexes(Connection conn) throws TskCoreException {
-	
+		try (Statement stmt = conn.createStatement()) {
+			// tsk_objects index
+			stmt.execute("CREATE INDEX parObjId ON tsk_objects(par_obj_id)");
+			
+			// file layout index
+			stmt.execute("CREATE INDEX layout_objID ON tsk_file_layout(obj_id)");
+			
+			// blackboard indexes
+			stmt.execute("CREATE INDEX artifact_objID ON blackboard_artifacts(obj_id)");
+			stmt.execute("CREATE INDEX artifact_artifact_objID ON blackboard_artifacts(artifact_obj_id)");
+			stmt.execute("CREATE INDEX artifact_typeID ON blackboard_artifacts(artifact_type_id)");
+			stmt.execute("CREATE INDEX attrsArtifactID ON blackboard_attributes(artifact_id)");
+			
+			//file type indexes
+			stmt.execute("CREATE INDEX mime_type ON tsk_files(dir_type,mime_type,type)"); //mime type
+			stmt.execute("CREATE INDEX file_extension ON tsk_files(extension)");  //file extenssion
+			stmt.execute("CREATE INDEX relationships_account1 ON account_relationships(account1_id)");
+			stmt.execute("CREATE INDEX relationships_account2 ON account_relationships(account2_id)");
+			stmt.execute("CREATE INDEX relationships_relationship_source_obj_id ON account_relationships(relationship_source_obj_id)");
+			stmt.execute("CREATE INDEX relationships_date_time ON account_relationships(date_time)");
+			stmt.execute("CREATE INDEX relationships_relationship_type ON account_relationships(relationship_type)");
+			stmt.execute("CREATE INDEX relationships_data_source_obj_id ON account_relationships(data_source_obj_id)");
+			
+			//tsk_events indices
+			stmt.execute("CREATE INDEX events_data_source_obj_id ON tsk_event_descriptions(data_source_obj_id)");
+			stmt.execute("CREATE INDEX events_content_obj_id ON tsk_event_descriptions(content_obj_id)");
+			stmt.execute("CREATE INDEX events_artifact_id ON tsk_event_descriptions(artifact_id)");
+			stmt.execute("CREATE INDEX events_sub_type_time ON tsk_events(event_type_id,  time)");
+			stmt.execute("CREATE INDEX events_time ON tsk_events(time)");
+		} catch (SQLException ex) {
+			throw new TskCoreException("Error initializing db_info tables", ex);
+		}
 	}
 	
 	private abstract class DbCreationHelper {
@@ -393,23 +421,21 @@ private abstract class DbCreationHelper {
 		abstract void createDatabase() throws TskCoreException;
 		
 		/**
-		 * Get an connection to the database
+		 * Get an connection to the case database
 		 * 
 		 * @return the connection
 		 */
 		abstract Connection getConnection();
 		
 		/**
-		 * Do initialization before creating the tables.
+		 * Do any needed initialization before creating the tables.
 		 * This is where SQLite pragmas are set up.
 		 * 
 		 * @param conn The database connection
 		 * 
 		 * @throws TskCoreException 
 		 */
-		void performPreInitialization(Connection conn) throws TskCoreException {
-			// By default do nothing
-		}
+		abstract void performPreInitialization(Connection conn) throws TskCoreException;
 		
 		/**
 		 * Do any additional steps after the tables are created.
@@ -417,30 +443,94 @@ void performPreInitialization(Connection conn) throws TskCoreException {
 		 * @param conn The database connection
 		 * @throws TskCoreException 
 		 */
-		void performPostTableInitialization(Connection conn) throws TskCoreException {
-			// By default do nothing
-		}
+		abstract void performPostTableInitialization(Connection conn) throws TskCoreException;
 	}
 	
 	private class PostgreSQLDbCreationHelper extends DbCreationHelper {
 		
-		PostgreSQLDbCreationHelper(String caseName, CaseDbConnectionInfo info, String caseDirPath) {
-			
+		private final static String JDBC_BASE_URI = "jdbc:postgresql://"; // NON-NLS
+		private final static String JDBC_DRIVER = "org.postgresql.Driver"; // NON-NLS
+		
+		final private String caseName;
+		final private CaseDbConnectionInfo info;
+		
+		PostgreSQLDbCreationHelper(String caseName, CaseDbConnectionInfo info) {
+			this.caseName = caseName;
+			this.info = info;
 		}
 		
 		@Override
-		void createDatabase() {}
+		void createDatabase() throws TskCoreException{
+			Connection conn = getPostgresConnection();
+			if (conn == null) {
+				throw new TskCoreException("Error connecting to the PostgreSQL server");
+			}
+		
+			try(Statement stmt = conn.createStatement()) {
+				stmt.execute("CREATE DATABASE \"" + caseName + "\" WITH ENCODING='UTF8'");		
+			} catch (SQLException ex) {
+				throw new TskCoreException("Error creating PostgreSQL case " + caseName, ex);
+			} finally {
+				try {
+					conn.close();
+				} catch (SQLException ex) {
+					logger.log(Level.SEVERE, "Error closing connection.", ex);
+				}
+			}
+		}
 		
 		@Override
-		Connection getConnection() { return null; }
+		Connection getConnection() {
+			return getConnection(caseName);
+		}		
+		
+		/**
+		 * Connects to the "postgres" database for creating new databases.
+		 * 
+		 * @return the connection to the "postgres" database
+		 */
+		Connection getPostgresConnection() {
+			return getConnection("postgres");
+		}
+		
+		Connection getConnection(String databaseName) {
+			
+			StringBuilder url = new StringBuilder();
+			url.append(JDBC_BASE_URI)
+				.append(info.getHost())
+				.append("/") // NON-NLS
+				.append(databaseName);
+			
+			Connection conn;
+			try {
+				Properties props = new Properties();
+				props.setProperty("user", info.getUserName());
+				props.setProperty("password", info.getPassword());
+
+				Class.forName(JDBC_DRIVER);
+				conn = DriverManager.getConnection(url.toString(), props);
+			} catch (ClassNotFoundException | SQLException ex) {
+				// TODO: Determine why a connection failure (ConnectionException) re-throws
+				// the SQLException and does not print this log message?
+				logger.log(Level.SEVERE, "Failed to acquire ephemeral connection to postgresql."); // NON-NLS
+				conn = null;
+			}
+			return conn;
+		}	
+		
+		@Override
+		void performPreInitialization(Connection conn) throws TskCoreException {
+			// Nothing to do here for PostgreSQL
+		}
 		
 		@Override
 		void performPostTableInitialization(Connection conn) throws TskCoreException {
-			
-			// TODO TODO
-			//stmt.execute("ALTER SEQUENCE blackboard_artifacts_artifact_id_seq minvalue -9223372036854775808 restart with -9223372036854775808");
+			try (Statement stmt = conn.createStatement()) {
+				stmt.execute("ALTER SEQUENCE blackboard_artifacts_artifact_id_seq minvalue -9223372036854775808 restart with -9223372036854775808");
+			} catch (SQLException ex) {
+				throw new TskCoreException("Error setting pragmas", ex);
+			}
 		}
-
 	}
 	
 	private class SQLiteDbCreationHelper extends DbCreationHelper {
@@ -517,5 +607,10 @@ void performPreInitialization(Connection conn) throws TskCoreException {
 				}
 			*/
 		}	
+
+		@Override
+		void performPostTableInitialization(Connection conn) throws TskCoreException {
+			// Nothing to do here for SQLite
+		}
 	}
 }
diff --git a/bindings/java/src/org/sleuthkit/datamodel/databaseutils/DatabaseQueryHelper.java b/bindings/java/src/org/sleuthkit/datamodel/SQLHelper.java
similarity index 54%
rename from bindings/java/src/org/sleuthkit/datamodel/databaseutils/DatabaseQueryHelper.java
rename to bindings/java/src/org/sleuthkit/datamodel/SQLHelper.java
index 91247144d9cd401b1400ed11f7f70cbe82421a6f..47c0b5066ae27963a1dceb8612c5cad56bc3da21 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/databaseutils/DatabaseQueryHelper.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/SQLHelper.java
@@ -16,12 +16,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.sleuthkit.datamodel.databaseutils;
+package org.sleuthkit.datamodel;
 
 /**
  * Interface for classes to help create queries for SQLite or PostgreSQL
  */
-public interface DatabaseQueryHelper {
+interface SQLHelper {
 	
 	// Get the type for the primary key
 	String getPrimaryKey();
@@ -32,6 +32,54 @@ public interface DatabaseQueryHelper {
 	// Get the type for blob-type data
 	String getBlobType();
 	
-	// Get the description column name for the tsk_vs_parts table
+	// Get the description column name for the tsk_vs_parts table.
+	// This varies between SQLite and PostgreSQL.
 	String getVSDescColName();
-}
+
+
+	class PostgreSQLHelper implements SQLHelper {
+
+		@Override
+		public String getPrimaryKey() {
+			return "BIGSERIAL";
+		}
+
+		@Override
+		public String getBigIntType() {
+			return "BIGINT";
+		}
+
+		@Override
+		public String getBlobType() {
+			return "BYTEA";
+		}
+
+		@Override
+		public String getVSDescColName() {
+			return "descr";
+		}
+	}
+	
+	class SQLiteHelper implements SQLHelper {
+
+		@Override
+		public String getPrimaryKey() {
+			return "INTEGER";
+		}
+
+		@Override
+		public String getBigIntType() {
+			return "INTEGER";
+		}
+
+		@Override
+		public String getBlobType() {
+			return "BLOB";
+		}
+
+		@Override
+		public String getVSDescColName() {
+			return "desc";
+		}
+	}
+}
\ No newline at end of file
diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
index 1cb42fbe2214daf9e3130441ada97cc68ae7cae0..b598a6d56863d5006b96db13fec28eb7ce7cf945 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
@@ -80,9 +80,6 @@
 import org.sleuthkit.datamodel.TskData.TSK_FS_META_TYPE_ENUM;
 import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_FLAG_ENUM;
 import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_TYPE_ENUM;
-import org.sleuthkit.datamodel.databaseutils.DatabaseQueryHelper;
-import org.sleuthkit.datamodel.databaseutils.PostgreSQLQueryHelper;
-import org.sleuthkit.datamodel.databaseutils.SQLiteQueryHelper;
 
 import org.sqlite.SQLiteConfig;
 import org.sqlite.SQLiteDataSource;
@@ -186,7 +183,6 @@ public class SleuthkitCase {
 	private final String dbPath;
 	private final DbType dbType;
 	private final String caseDirPath;
-	private DatabaseQueryHelper dBqueryHelper;
 	private SleuthkitJNI.CaseDbHandle caseHandle;
 	private String dbBackupPath;
 	private Map<Integer, BlackboardArtifact.Type> typeIdToArtifactTypeMap;
@@ -356,15 +352,6 @@ private void init() throws Exception {
 		typeIdToAttributeTypeMap = new ConcurrentHashMap<>();
 		typeNameToArtifactTypeMap = new ConcurrentHashMap<>();
 		typeNameToAttributeTypeMap = new ConcurrentHashMap<>();
-
-		/*
-		 * Set up the appropriate database helper
-		 */
-		if (dbType == DbType.POSTGRESQL) {
-			dBqueryHelper = new PostgreSQLQueryHelper();
-		} else {
-			dBqueryHelper = new SQLiteQueryHelper();
-		}
 		
 		/*
 		 * The following methods need to be called before updateDatabaseSchema
@@ -2352,18 +2339,10 @@ public static SleuthkitCase openCase(String databaseName, CaseDbConnectionInfo i
 	 */
 	public static SleuthkitCase newCase(String dbPath) throws TskCoreException {
 		try {
-			
-			File dbFile = new File(dbPath);
-			String testingDb = Paths.get(dbFile.getParent(), "testing.db").toString();
-			CaseDatabaseFactory factory = new CaseDatabaseFactory(testingDb);
-			try {
-				factory.createCaseDatabase();
-			} catch (TskCoreException ex) {
-				// Oh no
-				logger.log(Level.SEVERE, "Error in new case code", ex);
-			}
-			
-			SleuthkitJNI.CaseDbHandle caseHandle = SleuthkitJNI.newCaseDb(dbPath);
+			CaseDatabaseFactory factory = new CaseDatabaseFactory(dbPath);
+			factory.createCaseDatabase();
+
+			SleuthkitJNI.CaseDbHandle caseHandle = SleuthkitJNI.openCaseDb(dbPath);
 			return new SleuthkitCase(dbPath, caseHandle, DbType.SQLITE);
 		} catch (Exception ex) {
 			throw new TskCoreException("Failed to create case database at " + dbPath, ex);
@@ -2400,7 +2379,10 @@ public static SleuthkitCase newCase(String caseName, CaseDbConnectionInfo info,
 			 * the case. In this way, we obtain more detailed information if we
 			 * are able, but do not lose any information if unable.
 			 */
-			SleuthkitJNI.CaseDbHandle caseHandle = SleuthkitJNI.newCaseDb(databaseName, info);
+			CaseDatabaseFactory factory = new CaseDatabaseFactory(databaseName, info);
+			factory.createCaseDatabase();
+
+			final SleuthkitJNI.CaseDbHandle caseHandle = SleuthkitJNI.openCaseDb(databaseName, info);
 			return new SleuthkitCase(info.getHost(), Integer.parseInt(info.getPort()),
 					databaseName, info.getUserName(), info.getPassword(), caseHandle, caseDirPath, info.getDbType());
 		} catch (PropertyVetoException exp) {
diff --git a/bindings/java/src/org/sleuthkit/datamodel/databaseutils/PostgreSQLQueryHelper.java b/bindings/java/src/org/sleuthkit/datamodel/databaseutils/PostgreSQLQueryHelper.java
deleted file mode 100644
index 41d2ed73c80d38437ee15aa4bf6f67c2f2a5dbd0..0000000000000000000000000000000000000000
--- a/bindings/java/src/org/sleuthkit/datamodel/databaseutils/PostgreSQLQueryHelper.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Sleuth Kit Data Model
- *
- * Copyright 2020 Basis Technology Corp.
- * Contact: carrier <at> sleuthkit <dot> org
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.sleuthkit.datamodel.databaseutils;
-
-/**
- *
- */
-public class PostgreSQLQueryHelper implements DatabaseQueryHelper {
-	
-	@Override
-	public String getPrimaryKey() {
-		return "BIGSERIAL";
-	}
-
-	@Override
-	public String getBigIntType() {
-		return "BIGINT";
-	}
-
-	@Override
-	public String getBlobType() {
-		return "BYTEA";
-	}
-
-	@Override
-	public String getVSDescColName() {
-		return "descr";
-	}
-}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/databaseutils/SQLiteQueryHelper.java b/bindings/java/src/org/sleuthkit/datamodel/databaseutils/SQLiteQueryHelper.java
deleted file mode 100644
index 05c5ea87da97457d60da7e3587b6734d1d470b26..0000000000000000000000000000000000000000
--- a/bindings/java/src/org/sleuthkit/datamodel/databaseutils/SQLiteQueryHelper.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Sleuth Kit Data Model
- *
- * Copyright 2020 Basis Technology Corp.
- * Contact: carrier <at> sleuthkit <dot> org
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.sleuthkit.datamodel.databaseutils;
-
-/**
- *
- */
-public class SQLiteQueryHelper implements DatabaseQueryHelper {
-
-	@Override
-	public String getPrimaryKey() {
-		return "INTEGER";
-	}
-
-	@Override
-	public String getBigIntType() {
-		return "INTEGER";
-	}
-
-	@Override
-	public String getBlobType() {
-		return "BLOB";
-	}
-
-	@Override
-	public String getVSDescColName() {
-		return "desc";
-	}
-	
-}