diff --git a/bindings/java/doxygen/artifact_catalog.dox b/bindings/java/doxygen/artifact_catalog.dox
index 8549dce2c2bc730629e1c1c4777d55f8265b1dfa..ef8144a00cb65b021782abb63a87b0a1c1ecef0a 100644
--- a/bindings/java/doxygen/artifact_catalog.dox
+++ b/bindings/java/doxygen/artifact_catalog.dox
@@ -750,6 +750,7 @@ Contains autofill data for a person's address. Form data is usually saved by a W
 - TSK_LOCATION (The address of the person, e.g., 123 Main St.)
 
 ### OPTIONAL ATTRIBUTES
+- TSK_COMMENT (Comment if the autofill data is encrypted)
 - TSK_COUNT (Number of times the Web form data was used)
 - TSK_DATETIME_ACCESSED (Last accessed timestamp of the Web form data, in seconds since 1970-01-01T00:00:00Z)
 - TSK_DATETIME_MODIFIED (Last modified timestamp of the Web form data, in seconds since 1970-01-01T00:00:00Z)
@@ -758,7 +759,6 @@ Contains autofill data for a person's address. Form data is usually saved by a W
 - TSK_PHONE_NUMBER (Phone number from the form data)
 
 
-
 ---
 ## TSK_WEB_FORM_AUTOFILL
 Contains autofill data for a Web form. Form data is usually saved by a Web browser. Each field value pair in the form should be stored in separate artifacts.
@@ -769,10 +769,11 @@ Contains autofill data for a Web form. Form data is usually saved by a Web brows
 - TSK_VALUE (Value of the autofill field)
 
 ### OPTIONAL ATTRIBUTES
+- TSK_COMMENT (Comment if the form autofill data is encrypted)
 - TSK_COUNT (Number of times this Web form data has been used)
 - TSK_DATETIME_CREATED (Datetime this Web form autofill data was created, in seconds since 1970-01-01T00:00:00Z)
 - TSK_DATETIME_ACCESSED (Datetime this Web form data was last accessed, in seconds since 1970-01-01T00:00:00Z)
-
+- TSK_PROG_NAME (The application that stored this form information)
 
 
 ---
diff --git a/bindings/java/src/org/sleuthkit/datamodel/Blackboard.java b/bindings/java/src/org/sleuthkit/datamodel/Blackboard.java
index 50b106a98cd0863e077b7fa0f9303e4619df8d89..647ea455955609c25f5081b674a3ebc7ac757033 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/Blackboard.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/Blackboard.java
@@ -663,7 +663,9 @@ public BlackboardAttribute.Type getOrAddAttributeType(String typeName, Blackboar
 	public List<BlackboardArtifact.Type> getArtifactTypesInUse(long dataSourceObjId) throws TskCoreException {
 
 		final String queryString = "SELECT DISTINCT arts.artifact_type_id AS artifact_type_id, "
-				+ "types.type_name AS type_name, types.display_name AS display_name "
+				+ "types.type_name AS type_name, "
+				+ "types.display_name AS display_name, "
+				+ "types.category_type AS category_type "
 				+ "FROM blackboard_artifact_types AS types "
 				+ "INNER JOIN blackboard_artifacts AS arts "
 				+ "ON arts.artifact_type_id = types.artifact_type_id "
@@ -677,7 +679,8 @@ public List<BlackboardArtifact.Type> getArtifactTypesInUse(long dataSourceObjId)
 			List<BlackboardArtifact.Type> uniqueArtifactTypes = new ArrayList<>();
 			while (resultSet.next()) {
 				uniqueArtifactTypes.add(new BlackboardArtifact.Type(resultSet.getInt("artifact_type_id"),
-						resultSet.getString("type_name"), resultSet.getString("display_name")));
+						resultSet.getString("type_name"), resultSet.getString("display_name"), 
+						BlackboardArtifact.Category.fromID(resultSet.getInt("category_type"))));
 			}
 			return uniqueArtifactTypes;
 		} catch (SQLException ex) {
diff --git a/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java b/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java
index e3fbc72b66f1f80ee94ecc371e473af8210d063d..a43ce6d2952309dde05b300a160641785b8ec8ab 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java
@@ -23,7 +23,9 @@
 import java.sql.SQLException;
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -898,6 +900,413 @@ private void loadArtifactContent() throws TskCoreException {
 	public static final class Type implements Serializable {
 
 		private static final long serialVersionUID = 1L;
+
+		/**
+		 * A generic information artifact.
+		 */
+		public static final Type TSK_GEN_INFO = new BlackboardArtifact.Type(1, "TSK_GEN_INFO", bundle.getString("BlackboardArtifact.tskGenInfo.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A Web bookmark. Use methods in
+		 * org.sleuthkit.datamodel.blackboardutils.WebBrowserArtifactsHelper to
+		 * create bookmark artifacts.
+		 */
+		public static final Type TSK_WEB_BOOKMARK = new BlackboardArtifact.Type(2, "TSK_WEB_BOOKMARK", bundle.getString("BlackboardArtifact.tskWebBookmark.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A Web cookie. Use methods in
+		 * org.sleuthkit.datamodel.blackboardutils.WebBrowserArtifactsHelper to
+		 * create cookie artifacts.
+		 */
+		public static final Type TSK_WEB_COOKIE = new BlackboardArtifact.Type(3, "TSK_WEB_COOKIE", bundle.getString("BlackboardArtifact.tskWebCookie.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A Web history. Use methods in
+		 * org.sleuthkit.datamodel.blackboardutils.WebBrowserArtifactsHelper to
+		 * create history artifacts.
+		 */
+		public static final Type TSK_WEB_HISTORY = new BlackboardArtifact.Type(4, "TSK_WEB_HISTORY", bundle.getString("BlackboardArtifact.tskWebHistory.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A Web download. Use methods in
+		 * org.sleuthkit.datamodel.blackboardutils.WebBrowserArtifactsHelper to
+		 * create download artifacts.
+		 */
+		public static final Type TSK_WEB_DOWNLOAD = new BlackboardArtifact.Type(5, "TSK_WEB_DOWNLOAD", bundle.getString("BlackboardArtifact.tskWebDownload.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A recent object.
+		 */
+		public static final Type TSK_RECENT_OBJECT = new BlackboardArtifact.Type(6, "TSK_RECENT_OBJ", bundle.getString("BlackboardArtifact.tsk.recentObject.text"), Category.DATA_ARTIFACT);
+
+		// 7 was used for deprecated TSK_GPS_TRACKPOINT. 
+		/**
+		 * An installed program.
+		 */
+		public static final Type TSK_INSTALLED_PROG = new BlackboardArtifact.Type(8, "TSK_INSTALLED_PROG", bundle.getString("BlackboardArtifact.tskInstalledProg.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A search hit for a keyword.
+		 */
+		public static final Type TSK_KEYWORD_HIT = new BlackboardArtifact.Type(9, "TSK_KEYWORD_HIT", bundle.getString("BlackboardArtifact.tskKeywordHits.text"), Category.ANALYSIS_RESULT);
+
+		/**
+		 * A hit for a hash set (hash database).
+		 */
+		public static final Type TSK_HASHSET_HIT = new BlackboardArtifact.Type(10, "TSK_HASHSET_HIT", bundle.getString("BlackboardArtifact.tskHashsetHit.text"), Category.ANALYSIS_RESULT);
+
+		/**
+		 * An attached device.
+		 */
+		public static final Type TSK_DEVICE_ATTACHED = new BlackboardArtifact.Type(11, "TSK_DEVICE_ATTACHED", bundle.getString("BlackboardArtifact.tskDeviceAttached.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * An meta-artifact to call attention to a file deemed to be
+		 * interesting.
+		 */
+		public static final Type TSK_INTERESTING_FILE_HIT = new BlackboardArtifact.Type(12, "TSK_INTERESTING_FILE_HIT", bundle.getString("BlackboardArtifact.tskInterestingFileHit.text"), Category.ANALYSIS_RESULT);
+
+		/**
+		 * An email message.
+		 */
+		public static final Type TSK_EMAIL_MSG = new BlackboardArtifact.Type(13, "TSK_EMAIL_MSG", bundle.getString("BlackboardArtifact.tskEmailMsg.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Text extracted from the source content.
+		 */
+		public static final Type TSK_EXTRACTED_TEXT = new BlackboardArtifact.Type(14, "TSK_EXTRACTED_TEXT", bundle.getString("BlackboardArtifact.tskExtractedText.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A Web search engine query extracted from Web history.
+		 */
+		public static final Type TSK_WEB_SEARCH_QUERY = new BlackboardArtifact.Type(15, "TSK_WEB_SEARCH_QUERY", bundle.getString("BlackboardArtifact.tskWebSearchQuery.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * EXIF metadata.
+		 */
+		public static final Type TSK_METADATA_EXIF = new BlackboardArtifact.Type(16, "TSK_METADATA_EXIF", bundle.getString("BlackboardArtifact.tskMetadataExif.text"), Category.DATA_ARTIFACT);
+
+		// 17 was used for deprecated TSK_TAG_FILE. 
+		// 18 was used for deprecated TSK_TAG_ARTIFACT. 
+		/**
+		 * Information pertaining to an operating system.
+		 */
+		public static final Type TSK_OS_INFO = new BlackboardArtifact.Type(19, "TSK_OS_INFO", bundle.getString("BlackboardArtifact.tskOsInfo.text"), Category.DATA_ARTIFACT);
+
+		// 20 was used for deprecated TSK_OS_ACCOUNT.
+		/**
+		 * An application or Web service account.
+		 */
+		public static final Type TSK_SERVICE_ACCOUNT = new BlackboardArtifact.Type(21, "TSK_SERVICE_ACCOUNT", bundle.getString("BlackboardArtifact.tskServiceAccount.text"), Category.DATA_ARTIFACT);
+
+		// 22 was used for deprecated TSK_TOOL_OUTPUT.
+		/**
+		 * A contact extracted from a phone, or from an address
+		 * book/email/messaging application. Use methods in
+		 * org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper
+		 * to create contact artifacts.
+		 */
+		public static final Type TSK_CONTACT = new BlackboardArtifact.Type(23, "TSK_CONTACT", bundle.getString("BlackboardArtifact.tskContact.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * An SMS/MMS message extracted from phone, or from another messaging
+		 * application, like IM. Use methods in
+		 * org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper
+		 * to create message artifacts.
+		 */
+		public static final Type TSK_MESSAGE = new BlackboardArtifact.Type(24, "TSK_MESSAGE", bundle.getString("BlackboardArtifact.tskMessage.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A phone call log extracted from a phone or softphone application. Use
+		 * methods in
+		 * org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper
+		 * to create call log artifacts.
+		 */
+		public static final Type TSK_CALLLOG = new BlackboardArtifact.Type(25, "TSK_CALLLOG", bundle.getString("BlackboardArtifact.tskCalllog.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A calendar entry from a phone, PIM, or a calendar application.
+		 */
+		public static final Type TSK_CALENDAR_ENTRY = new BlackboardArtifact.Type(26, "TSK_CALENDAR_ENTRY", bundle.getString("BlackboardArtifact.tskCalendarEntry.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A speed dial entry from a phone.
+		 */
+		public static final Type TSK_SPEED_DIAL_ENTRY = new BlackboardArtifact.Type(27, "TSK_SPEED_DIAL_ENTRY", bundle.getString("BlackboardArtifact.tskSpeedDialEntry.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A bluetooth pairing entry.
+		 */
+		public static final Type TSK_BLUETOOTH_PAIRING = new BlackboardArtifact.Type(28, "TSK_BLUETOOTH_PAIRING", bundle.getString("BlackboardArtifact.tskBluetoothPairing.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A GPS bookmark / way point that the user saved.
+		 */
+		public static final Type TSK_GPS_BOOKMARK = new BlackboardArtifact.Type(29, "TSK_GPS_BOOKMARK", bundle.getString("BlackboardArtifact.tskGpsBookmark.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A GPS last known location record.
+		 */
+		public static final Type TSK_GPS_LAST_KNOWN_LOCATION = new BlackboardArtifact.Type(30, "TSK_GPS_LAST_KNOWN_LOCATION", bundle.getString("BlackboardArtifact.tskGpsLastKnownLocation.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A GPS search record.
+		 */
+		public static final Type TSK_GPS_SEARCH = new BlackboardArtifact.Type(31, "TSK_GPS_SEARCH", bundle.getString("BlackboardArtifact.tskGpsSearch.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Application run information.
+		 */
+		public static final Type TSK_PROG_RUN = new BlackboardArtifact.Type(32, "TSK_PROG_RUN", bundle.getString("BlackboardArtifact.tskProgRun.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * An encrypted file.
+		 */
+		public static final Type TSK_ENCRYPTION_DETECTED = new BlackboardArtifact.Type(33, "TSK_ENCRYPTION_DETECTED", bundle.getString("BlackboardArtifact.tskEncryptionDetected.text"), Category.ANALYSIS_RESULT);
+
+		/**
+		 * A file with an extension that does not match its MIME type.
+		 */
+		public static final Type TSK_EXT_MISMATCH_DETECTED = new BlackboardArtifact.Type(34, "TSK_EXT_MISMATCH_DETECTED", bundle.getString("BlackboardArtifact.tskExtMismatchDetected.text"), Category.ANALYSIS_RESULT);
+
+		/**
+		 * An meta-artifact to call attention to an artifact deemed to be
+		 * interesting.
+		 */
+		public static final Type TSK_INTERESTING_ARTIFACT_HIT = new BlackboardArtifact.Type(35, "TSK_INTERESTING_ARTIFACT_HIT", bundle.getString("BlackboardArtifact.tskInterestingArtifactHit.text"), Category.ANALYSIS_RESULT);
+
+		/**
+		 * A route based on GPS coordinates. Use
+		 * org.sleuthkit.datamodel.blackboardutils.GeoArtifactsHelper.addRoute()
+		 * to create route artifacts.
+		 */
+		public static final Type TSK_GPS_ROUTE = new BlackboardArtifact.Type(36, "TSK_GPS_ROUTE", bundle.getString("BlackboardArtifact.tskGpsRoute.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A remote drive.
+		 */
+		public static final Type TSK_REMOTE_DRIVE = new BlackboardArtifact.Type(37, "TSK_REMOTE_DRIVE", bundle.getString("BlackboardArtifact.tskRemoteDrive.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A human face was detected in a media file.
+		 */
+		public static final Type TSK_FACE_DETECTED = new BlackboardArtifact.Type(38, "TSK_FACE_DETECTED", bundle.getString("BlackboardArtifact.tskFaceDetected.text"), Category.ANALYSIS_RESULT);
+
+		/**
+		 * An account.
+		 */
+		public static final Type TSK_ACCOUNT = new BlackboardArtifact.Type(39, "TSK_ACCOUNT", bundle.getString("BlackboardArtifact.tskAccount.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * An encrypted file.
+		 */
+		public static final Type TSK_ENCRYPTION_SUSPECTED = new BlackboardArtifact.Type(40, "TSK_ENCRYPTION_SUSPECTED", bundle.getString("BlackboardArtifact.tskEncryptionSuspected.text"), Category.ANALYSIS_RESULT);
+
+		/*
+		 * A classifier detected an object in a media file.
+		 */
+		public static final Type TSK_OBJECT_DETECTED = new BlackboardArtifact.Type(41, "TSK_OBJECT_DETECTED", bundle.getString("BlackboardArtifact.tskObjectDetected.text"), Category.ANALYSIS_RESULT);
+
+		/**
+		 * A wireless network.
+		 */
+		public static final Type TSK_WIFI_NETWORK = new BlackboardArtifact.Type(42, "TSK_WIFI_NETWORK", bundle.getString("BlackboardArtifact.tskWIFINetwork.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Information related to a device.
+		 */
+		public static final Type TSK_DEVICE_INFO = new BlackboardArtifact.Type(43, "TSK_DEVICE_INFO", bundle.getString("BlackboardArtifact.tskDeviceInfo.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A SIM card.
+		 */
+		public static final Type TSK_SIM_ATTACHED = new BlackboardArtifact.Type(44, "TSK_SIM_ATTACHED", bundle.getString("BlackboardArtifact.tskSimAttached.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A bluetooth adapter.
+		 */
+		public static final Type TSK_BLUETOOTH_ADAPTER = new BlackboardArtifact.Type(45, "TSK_BLUETOOTH_ADAPTER", bundle.getString("BlackboardArtifact.tskBluetoothAdapter.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A wireless network adapter.
+		 */
+		public static final Type TSK_WIFI_NETWORK_ADAPTER = new BlackboardArtifact.Type(46, "TSK_WIFI_NETWORK_ADAPTER", bundle.getString("BlackboardArtifact.tskWIFINetworkAdapter.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Indicates a verification failure
+		 */
+		public static final Type TSK_VERIFICATION_FAILED = new BlackboardArtifact.Type(47, "TSK_VERIFICATION_FAILED", bundle.getString("BlackboardArtifact.tskVerificationFailed.text"), Category.ANALYSIS_RESULT);
+
+		/**
+		 * Categorization information for a data source.
+		 */
+		public static final Type TSK_DATA_SOURCE_USAGE = new BlackboardArtifact.Type(48, "TSK_DATA_SOURCE_USAGE", bundle.getString("BlackboardArtifact.tskDataSourceUsage.text"), Category.ANALYSIS_RESULT);
+
+		/**
+		 * Indicates auto fill data from a Web form. Use methods in
+		 * org.sleuthkit.datamodel.blackboardutils.WebBrowserArtifactsHelper to
+		 * create web form autofill artifacts.
+		 */
+		public static final Type TSK_WEB_FORM_AUTOFILL = new BlackboardArtifact.Type(49, "TSK_WEB_FORM_AUTOFILL", bundle.getString("BlackboardArtifact.tskWebFormAutofill.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Indicates an person's address filled in a web form. Use methods in
+		 * org.sleuthkit.datamodel.blackboardutils.WebBrowserArtifactsHelper to
+		 * create web form address artifacts.
+		 */
+		public static final Type TSK_WEB_FORM_ADDRESS = new BlackboardArtifact.Type(50, "TSK_WEB_FORM_ADDRESSES ", bundle.getString("BlackboardArtifact.tskWebFormAddresses.text"), Category.DATA_ARTIFACT);
+
+		// 51 was used for deprecated TSK_DOWNLOAD_SOURCE
+		/**
+		 * Indicates web cache data
+		 */
+		public static final Type TSK_WEB_CACHE = new BlackboardArtifact.Type(52, "TSK_WEB_CACHE", bundle.getString("BlackboardArtifact.tskWebCache.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * A generic (timeline) event.
+		 */
+		public static final Type TSK_TL_EVENT = new BlackboardArtifact.Type(53, "TSK_TL_EVENT", bundle.getString("BlackboardArtifact.tskTLEvent.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Indicates clipboard content
+		 */
+		public static final Type TSK_CLIPBOARD_CONTENT = new BlackboardArtifact.Type(54, "TSK_CLIPBOARD_CONTENT", bundle.getString("BlackboardArtifact.tskClipboardContent.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * An associated object.
+		 */
+		public static final Type TSK_ASSOCIATED_OBJECT = new BlackboardArtifact.Type(55, "TSK_ASSOCIATED_OBJECT", bundle.getString("BlackboardArtifact.tskAssociatedObject.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Indicates file may have been created by the user.
+		 */
+		public static final Type TSK_USER_CONTENT_SUSPECTED = new BlackboardArtifact.Type(56, "TSK_USER_CONTENT_SUSPECTED", bundle.getString("BlackboardArtifact.tskUserContentSuspected.text"), Category.ANALYSIS_RESULT);
+
+		/**
+		 * Stores metadata about an object.
+		 */
+		public static final Type TSK_METADATA = new BlackboardArtifact.Type(57, "TSK_METADATA", bundle.getString("BlackboardArtifact.tskMetadata.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Stores a GPS track log. Use
+		 * org.sleuthkit.datamodel.blackboardutils.GeoArtifactsHelper.addTrack()
+		 * to create track artifacts.
+		 */
+		public static final Type TSK_GPS_TRACK = new BlackboardArtifact.Type(58, "TSK_GPS_TRACK", bundle.getString("BlackboardArtifact.tskTrack.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Stores a role on a given domain.
+		 */
+		public static final Type TSK_WEB_ACCOUNT_TYPE = new BlackboardArtifact.Type(59, "TSK_WEB_ACCOUNT_TYPE", bundle.getString("BlackboardArtifact.tskWebAccountType.text"), Category.ANALYSIS_RESULT);
+
+		/**
+		 * Screen shots from device or Application.
+		 */
+		public static final Type TSK_SCREEN_SHOTS = new BlackboardArtifact.Type(60, "TSK_SCREEN_SHOTS", bundle.getString("BlackboardArtifact.tskScreenShots.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Notifications Sent to User.
+		 */
+		public static final Type TSK_PROG_NOTIFICATIONS = new BlackboardArtifact.Type(62, "TSK_PROG_NOTIFICATIONS", bundle.getString("BlackboardArtifact.tskProgNotifications.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * System/Application/File backup.
+		 */
+		public static final Type TSK_BACKUP_EVENT = new BlackboardArtifact.Type(63, "TSK_BACKUP_EVENT", bundle.getString("BlackboardArtifact.tskBackupEvent.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Programs that have been deleted.
+		 */
+		public static final Type TSK_DELETED_PROG = new BlackboardArtifact.Type(64, "TSK_DELETED_PROG", bundle.getString("BlackboardArtifact.tskDeletedProg.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Activity on the System/Application.
+		 */
+		public static final Type TSK_USER_DEVICE_EVENT = new BlackboardArtifact.Type(65, "TSK_USER_DEVICE_EVENT", bundle.getString("BlackboardArtifact.tskUserDeviceEvent.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Indicates that the file had a yara pattern match hit.
+		 */
+		public static final Type TSK_YARA_HIT = new BlackboardArtifact.Type(66, "TSK_YARA_HIT", bundle.getString("BlackboardArtifact.tskYaraHit.text"), Category.ANALYSIS_RESULT);
+
+		/**
+		 * Stores the outline of an area using GPS coordinates.
+		 */
+		public static final Type TSK_GPS_AREA = new BlackboardArtifact.Type(67, "TSK_GPS_AREA", bundle.getString("BlackboardArtifact.tskGPSArea.text"), Category.DATA_ARTIFACT);
+
+		/**
+		 * Defines a category for a particular domain.
+		 */
+		public static final Type TSK_WEB_CATEGORIZATION = new BlackboardArtifact.Type(68, "TSK_WEB_CATEGORIZATION", bundle.getString("BlackboardArtifact.tskWebCategorization.text"), Category.ANALYSIS_RESULT);
+
+		// NOTE: When adding a new standard BlackboardArtifact.Type, add the instance and then add to the STANDARD_TYPES list.
+		/**
+		 * A list of all the standard artifact types.
+		 */
+		static final List<Type> STANDARD_TYPES = Collections.unmodifiableList(Arrays.asList(
+				TSK_GEN_INFO,
+				TSK_WEB_BOOKMARK,
+				TSK_WEB_COOKIE,
+				TSK_WEB_HISTORY,
+				TSK_WEB_DOWNLOAD,
+				TSK_RECENT_OBJECT,
+				TSK_INSTALLED_PROG,
+				TSK_KEYWORD_HIT,
+				TSK_HASHSET_HIT,
+				TSK_DEVICE_ATTACHED,
+				TSK_INTERESTING_FILE_HIT,
+				TSK_EMAIL_MSG,
+				TSK_EXTRACTED_TEXT,
+				TSK_WEB_SEARCH_QUERY,
+				TSK_METADATA_EXIF,
+				TSK_OS_INFO,
+				TSK_SERVICE_ACCOUNT,
+				TSK_CONTACT,
+				TSK_MESSAGE,
+				TSK_CALLLOG,
+				TSK_CALENDAR_ENTRY,
+				TSK_SPEED_DIAL_ENTRY,
+				TSK_BLUETOOTH_PAIRING,
+				TSK_GPS_BOOKMARK,
+				TSK_GPS_LAST_KNOWN_LOCATION,
+				TSK_GPS_SEARCH,
+				TSK_PROG_RUN,
+				TSK_ENCRYPTION_DETECTED,
+				TSK_EXT_MISMATCH_DETECTED,
+				TSK_INTERESTING_ARTIFACT_HIT,
+				TSK_GPS_ROUTE,
+				TSK_REMOTE_DRIVE,
+				TSK_FACE_DETECTED,
+				TSK_ACCOUNT,
+				TSK_ENCRYPTION_SUSPECTED,
+				TSK_OBJECT_DETECTED,
+				TSK_WIFI_NETWORK,
+				TSK_DEVICE_INFO,
+				TSK_SIM_ATTACHED,
+				TSK_BLUETOOTH_ADAPTER,
+				TSK_WIFI_NETWORK_ADAPTER,
+				TSK_VERIFICATION_FAILED,
+				TSK_DATA_SOURCE_USAGE,
+				TSK_WEB_FORM_AUTOFILL,
+				TSK_WEB_FORM_ADDRESS,
+				TSK_WEB_CACHE,
+				TSK_TL_EVENT,
+				TSK_CLIPBOARD_CONTENT,
+				TSK_ASSOCIATED_OBJECT,
+				TSK_USER_CONTENT_SUSPECTED,
+				TSK_METADATA,
+				TSK_GPS_TRACK,
+				TSK_WEB_ACCOUNT_TYPE,
+				TSK_SCREEN_SHOTS,
+				TSK_PROG_NOTIFICATIONS,
+				TSK_BACKUP_EVENT,
+				TSK_DELETED_PROG,
+				TSK_USER_DEVICE_EVENT,
+				TSK_YARA_HIT,
+				TSK_GPS_AREA,
+				TSK_WEB_CATEGORIZATION
+		));
+
 		private final String typeName;
 		private final int typeID;
 		private final String displayName;
diff --git a/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java b/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java
index 4fa47ca93750237d5de63edc856e29d9368c3b11..5696355d4cd0f109aa1d5887208f19d78342418c 100755
--- a/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java
@@ -42,7 +42,7 @@
  * attribute by calling the appropriate BlackboardAttribute constructor. It can
  * also be used to do blackboard queries involving the custom type.
  */
-public class BlackboardAttribute extends AbstractAttribute{
+public class BlackboardAttribute extends AbstractAttribute {
 
 	private static final Logger LOGGER = Logger.getLogger(BlackboardAttribute.class.getName());
 
@@ -50,9 +50,9 @@ public class BlackboardAttribute extends AbstractAttribute{
 
 	private String context;
 	private String sources;
-	
+
 	private long artifactID;
-	
+
 	// Cached parent artifact. This field is populated lazily upon the first
 	// call to getParentArtifact().
 	private BlackboardArtifact parentArtifact;
@@ -311,7 +311,6 @@ public BlackboardArtifact getParentArtifact() throws TskCoreException {
 		return parentArtifact;
 	}
 
-
 	@Override
 	public int hashCode() {
 		return Objects.hash(
@@ -365,7 +364,7 @@ public String getDisplayString() {
 				// return time string in default timezone
 				return TimeUtilities.epochToTime(getValueLong());
 			}
-			default:{
+			default: {
 				return super.getDisplayString();
 			}
 		}
@@ -400,8 +399,8 @@ public String getDisplayString() {
 	}
 
 	/**
-	 * Sets the parent data source id. The parent data source is defined
-	 * as being the data source of the parent artifact.
+	 * Sets the parent data source id. The parent data source is defined as
+	 * being the data source of the parent artifact.
 	 *
 	 * @param parentDataSourceID The parent data source id.
 	 */
@@ -426,6 +425,345 @@ String getSourcesCSV() {
 	 */
 	public static final class Type implements Serializable {
 
+		public static final Type TSK_URL = new Type(1, "TSK_URL", bundle.getString("BlackboardAttribute.tskUrl.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_DATETIME = new Type(2, "TSK_DATETIME", bundle.getString("BlackboardAttribute.tskDatetime.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME);
+		public static final Type TSK_NAME = new Type(3, "TSK_NAME", bundle.getString("BlackboardAttribute.tskName.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_PROG_NAME = new Type(4, "TSK_PROG_NAME", bundle.getString("BlackboardAttribute.tskProgName.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_VALUE = new Type(6, "TSK_VALUE", bundle.getString("BlackboardAttribute.tskValue.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_FLAG = new Type(7, "TSK_FLAG", bundle.getString("BlackboardAttribute.tskFlag.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_PATH = new Type(8, "TSK_PATH", bundle.getString("BlackboardAttribute.tskPath.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_KEYWORD = new Type(10, "TSK_KEYWORD", bundle.getString("BlackboardAttribute.tskKeyword.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_KEYWORD_REGEXP = new Type(11, "TSK_KEYWORD_REGEXP", bundle.getString("BlackboardAttribute.tskKeywordRegexp.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_KEYWORD_PREVIEW = new Type(12, "TSK_KEYWORD_PREVIEW", bundle.getString("BlackboardAttribute.tskKeywordPreview.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+
+		// TSK_KEYWORD_SET (id: 13) has been deprecated.  Please use TSK_SET_NAME instead.
+		public static final Type TSK_USER_NAME = new Type(14, "TSK_USER_NAME", bundle.getString("BlackboardAttribute.tskUserName.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_DOMAIN = new Type(15, "TSK_DOMAIN", bundle.getString("BlackboardAttribute.tskDomain.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_PASSWORD = new Type(16, "TSK_PASSWORD", bundle.getString("BlackboardAttribute.tskPassword.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_NAME_PERSON = new Type(17, "TSK_NAME_PERSON", bundle.getString("BlackboardAttribute.tskNamePerson.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_DEVICE_MODEL = new Type(18, "TSK_DEVICE_MODEL", bundle.getString("BlackboardAttribute.tskDeviceModel.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_DEVICE_MAKE = new Type(19, "TSK_DEVICE_MAKE", bundle.getString("BlackboardAttribute.tskDeviceMake.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_DEVICE_ID = new Type(20, "TSK_DEVICE_ID", bundle.getString("BlackboardAttribute.tskDeviceId.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_EMAIL = new Type(21, "TSK_EMAIL", bundle.getString("BlackboardAttribute.tskEmail.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_HASH_MD5 = new Type(22, "TSK_HASH_MD5", bundle.getString("BlackboardAttribute.tskHashMd5.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_HASH_SHA1 = new Type(23, "TSK_HASH_SHA1", bundle.getString("BlackboardAttribute.tskHashSha1.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_HASH_SHA2_256 = new Type(24, "TSK_HASH_SHA2_256", bundle.getString("BlackboardAttribute.tskHashSha225.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_HASH_SHA2_512 = new Type(25, "TSK_HASH_SHA2_512", bundle.getString("BlackboardAttribute.tskHashSha2512.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_TEXT = new Type(26, "TSK_TEXT", bundle.getString("BlackboardAttribute.tskText.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_TEXT_FILE = new Type(27, "TSK_TEXT_FILE", bundle.getString("BlackboardAttribute.tskTextFile.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_TEXT_LANGUAGE = new Type(28, "TSK_TEXT_LANGUAGE", bundle.getString("BlackboardAttribute.tskTextLanguage.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_ENTROPY = new Type(29, "TSK_ENTROPY", bundle.getString("BlackboardAttribute.tskEntropy.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE);
+
+		// TSK_HASHSET_NAME (id: 30) has been deprecated.  Please use TSK_SET_NAME instead.
+		// TSK_INTERESTING_FILE (id: 31) has been deprecated.  Please use TSK_INTERESTING_FILE_HIT instead.
+		public static final Type TSK_REFERRER = new Type(32, "TSK_REFERRER", bundle.getString("BlackboardAttribute.tskReferrer.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_DATETIME_ACCESSED = new Type(33, "TSK_DATETIME_ACCESSED", bundle.getString("BlackboardAttribute.tskDateTimeAccessed.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME);
+		public static final Type TSK_IP_ADDRESS = new Type(34, "TSK_IP_ADDRESS", bundle.getString("BlackboardAttribute.tskIpAddress.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_PHONE_NUMBER = new Type(35, "TSK_PHONE_NUMBER", bundle.getString("BlackboardAttribute.tskPhoneNumber.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_PATH_ID = new Type(36, "TSK_PATH_ID", bundle.getString("BlackboardAttribute.tskPathId.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.LONG);
+		public static final Type TSK_SET_NAME = new Type(37, "TSK_SET_NAME", bundle.getString("BlackboardAttribute.tskSetName.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+
+		// TSK_ENCRYPTION_DETECTED (id: 38) has been deprecated.  Please use TSK_ENCRYPTION_DETECTED as an artifact.
+		public static final Type TSK_MALWARE_DETECTED = new Type(39, "TSK_MALWARE_DETECTED", bundle.getString("BlackboardAttribute.tskMalwareDetected.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.INTEGER);
+		public static final Type TSK_STEG_DETECTED = new Type(40, "TSK_STEG_DETECTED", bundle.getString("BlackboardAttribute.tskStegDetected.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.INTEGER);
+		public static final Type TSK_EMAIL_TO = new Type(41, "TSK_EMAIL_TO", bundle.getString("BlackboardAttribute.tskEmailTo.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_EMAIL_CC = new Type(42, "TSK_EMAIL_CC", bundle.getString("BlackboardAttribute.tskEmailCc.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_EMAIL_BCC = new Type(43, "TSK_EMAIL_BCC", bundle.getString("BlackboardAttribute.tskEmailBcc.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_EMAIL_FROM = new Type(44, "TSK_EMAIL_FROM", bundle.getString("BlackboardAttribute.tskEmailFrom.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_EMAIL_CONTENT_PLAIN = new Type(45, "TSK_EMAIL_CONTENT_PLAIN", bundle.getString("BlackboardAttribute.tskEmailContentPlain.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_EMAIL_CONTENT_HTML = new Type(46, "TSK_EMAIL_CONTENT_HTML", bundle.getString("BlackboardAttribute.tskEmailContentHtml.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_EMAIL_CONTENT_RTF = new Type(47, "TSK_EMAIL_CONTENT_RTF", bundle.getString("BlackboardAttribute.tskEmailContentRtf.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_MSG_ID = new Type(48, "TSK_MSG_ID", bundle.getString("BlackboardAttribute.tskMsgId.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_MSG_REPLY_ID = new Type(49, "TSK_MSG_REPLY_ID", bundle.getString("BlackboardAttribute.tskMsgReplyId.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_DATETIME_RCVD = new Type(50, "TSK_DATETIME_RCVD", bundle.getString("BlackboardAttribute.tskDateTimeRcvd.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME);
+		public static final Type TSK_DATETIME_SENT = new Type(51, "TSK_DATETIME_SENT", bundle.getString("BlackboardAttribute.tskDateTimeSent.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME);
+		public static final Type TSK_SUBJECT = new Type(52, "TSK_SUBJECT", bundle.getString("BlackboardAttribute.tskSubject.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_TITLE = new Type(53, "TSK_TITLE", bundle.getString("BlackboardAttribute.tskTitle.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_GEO_LATITUDE = new Type(54, "TSK_GEO_LATITUDE", bundle.getString("BlackboardAttribute.tskGeoLatitude.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE);
+		public static final Type TSK_GEO_LONGITUDE = new Type(55, "TSK_GEO_LONGITUDE", bundle.getString("BlackboardAttribute.tskGeoLongitude.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE);
+		public static final Type TSK_GEO_VELOCITY = new Type(56, "TSK_GEO_VELOCITY", bundle.getString("BlackboardAttribute.tskGeoVelocity.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE);
+		public static final Type TSK_GEO_ALTITUDE = new Type(57, "TSK_GEO_ALTITUDE", bundle.getString("BlackboardAttribute.tskGeoAltitude.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE);
+		public static final Type TSK_GEO_BEARING = new Type(58, "TSK_GEO_BEARING", bundle.getString("BlackboardAttribute.tskGeoBearing.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_GEO_HPRECISION = new Type(59, "TSK_GEO_HPRECISION", bundle.getString("BlackboardAttribute.tskGeoHPrecision.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE);
+		public static final Type TSK_GEO_VPRECISION = new Type(60, "TSK_GEO_VPRECISION", bundle.getString("BlackboardAttribute.tskGeoVPrecision.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE);
+		public static final Type TSK_GEO_MAPDATUM = new Type(61, "TSK_GEO_MAPDATUM", bundle.getString("BlackboardAttribute.tskGeoMapDatum.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+
+		// TSK_FILE_TYPE_SIG (id: 62) has been deprecated.  Please use the mime type field of the AbstractFile object instead.
+		public static final Type TSK_FILE_TYPE_EXT = new Type(63, "TSK_FILE_TYPE_EXT", bundle.getString("BlackboardAttribute.tskFileTypeExt.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+
+		// TSK_TAGGED_ARTIFACT (id: 64) has been deprected.  Please create a tag as an artifact.
+		// TSK_TAG_NAME (id: 65) has been deprecated.  Please create a tag as an artifact.
+		public static final Type TSK_COMMENT = new Type(66, "TSK_COMMENT", bundle.getString("BlackboardAttribute.tskComment.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_URL_DECODED = new Type(67, "TSK_URL_DECODED", bundle.getString("BlackboardAttribute.tskUrlDecoded.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_DATETIME_CREATED = new Type(68, "TSK_DATETIME_CREATED", bundle.getString("BlackboardAttribute.tskDateTimeCreated.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME);
+		public static final Type TSK_DATETIME_MODIFIED = new Type(69, "TSK_DATETIME_MODIFIED", bundle.getString("BlackboardAttribute.tskDateTimeModified.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME);
+		public static final Type TSK_PROCESSOR_ARCHITECTURE = new Type(70, "TSK_PROCESSOR_ARCHITECTURE", bundle.getString("BlackboardAttribute.tskProcessorArchitecture.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_VERSION = new Type(71, "TSK_VERSION", bundle.getString("BlackboardAttribute.tskVersion.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_USER_ID = new Type(72, "TSK_USER_ID", bundle.getString("BlackboardAttribute.tskUserId.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_DESCRIPTION = new Type(73, "TSK_DESCRIPTION", bundle.getString("BlackboardAttribute.tskDescription.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_MESSAGE_TYPE = new Type(74, "TSK_MESSAGE_TYPE", bundle.getString("BlackboardAttribute.tskMessageType.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // SMS or MMS or IM ...
+		public static final Type TSK_PHONE_NUMBER_HOME = new Type(75, "TSK_PHONE_NUMBER_HOME", bundle.getString("BlackboardAttribute.tskPhoneNumberHome.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_PHONE_NUMBER_OFFICE = new Type(76, "TSK_PHONE_NUMBER_OFFICE", bundle.getString("BlackboardAttribute.tskPhoneNumberOffice.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_PHONE_NUMBER_MOBILE = new Type(77, "TSK_PHONE_NUMBER_MOBILE", bundle.getString("BlackboardAttribute.tskPhoneNumberMobile.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_PHONE_NUMBER_FROM = new Type(78, "TSK_PHONE_NUMBER_FROM", bundle.getString("BlackboardAttribute.tskPhoneNumberFrom.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_PHONE_NUMBER_TO = new Type(79, "TSK_PHONE_NUMBER_TO", bundle.getString("BlackboardAttribute.tskPhoneNumberTo.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_DIRECTION = new Type(80, "TSK_DIRECTION", bundle.getString("BlackboardAttribute.tskDirection.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // Msg/Call direction: incoming, outgoing
+		public static final Type TSK_EMAIL_HOME = new Type(81, "TSK_EMAIL_HOME", bundle.getString("BlackboardAttribute.tskEmailHome.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_EMAIL_OFFICE = new Type(82, "TSK_EMAIL_OFFICE", bundle.getString("BlackboardAttribute.tskEmailOffice.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_DATETIME_START = new Type(83, "TSK_DATETIME_START", bundle.getString("BlackboardAttribute.tskDateTimeStart.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME); // start time of an event - call log, Calendar entry
+		public static final Type TSK_DATETIME_END = new Type(84, "TSK_DATETIME_END", bundle.getString("BlackboardAttribute.tskDateTimeEnd.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME); // end time of an event - call log, Calendar entry
+		public static final Type TSK_CALENDAR_ENTRY_TYPE = new Type(85, "TSK_CALENDAR_ENTRY_TYPE", bundle.getString("BlackboardAttribute.tskCalendarEntryType.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // meeting, task,
+		public static final Type TSK_LOCATION = new Type(86, "TSK_LOCATION", bundle.getString("BlackboardAttribute.tskLocation.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // Location string associated with an event - Conf Room Name, Address ....
+		public static final Type TSK_SHORTCUT = new Type(87, "TSK_SHORTCUT", bundle.getString("BlackboardAttribute.tskShortcut.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // Short Cut string - short code or dial string for Speed dial, a URL short cut - e.g. bitly string, Windows Desktop Short cut name etc.
+		public static final Type TSK_DEVICE_NAME = new Type(88, "TSK_DEVICE_NAME", bundle.getString("BlackboardAttribute.tskDeviceName.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // device name - a user assigned (usually) device name - such as "Joe's computer", "bob_win8", "BT Headset"
+		public static final Type TSK_CATEGORY = new Type(89, "TSK_CATEGORY", bundle.getString("BlackboardAttribute.tskCategory.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // category/type, possible value set varies by the artifact
+		public static final Type TSK_EMAIL_REPLYTO = new Type(90, "TSK_EMAIL_REPLYTO", bundle.getString("BlackboardAttribute.tskEmailReplyTo.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // ReplyTo address
+		public static final Type TSK_SERVER_NAME = new Type(91, "TSK_SERVER_NAME", bundle.getString("BlackboardAttribute.tskServerName.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // server name, e.g. a mail server name - "smtp.google.com", a DNS server name...
+		public static final Type TSK_COUNT = new Type(92, "TSK_COUNT", bundle.getString("BlackboardAttribute.tskCount.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.INTEGER); // Count related to the artifact
+		public static final Type TSK_MIN_COUNT = new Type(93, "TSK_MIN_COUNT", bundle.getString("BlackboardAttribute.tskMinCount.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.INTEGER); // Minimum number/count
+		public static final Type TSK_PATH_SOURCE = new Type(94, "TSK_PATH_SOURCE", bundle.getString("BlackboardAttribute.tskPathSource.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // Path to a source file related to the artifact
+		public static final Type TSK_PERMISSIONS = new Type(95, "TSK_PERMISSIONS", bundle.getString("BlackboardAttribute.tskPermissions.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // Permissions
+		public static final Type TSK_ASSOCIATED_ARTIFACT = new Type(96, "TSK_ASSOCIATED_ARTIFACT", bundle.getString("BlackboardAttribute.tskAssociatedArtifact.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.LONG); // Artifact ID of a related artifact
+		public static final Type TSK_ISDELETED = new Type(97, "TSK_ISDELETED", bundle.getString("BlackboardAttribute.tskIsDeleted.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // boolean to indicate that the artifact is recovered fom deleted content
+		public static final Type TSK_GEO_LATITUDE_START = new Type(98, "TSK_GEO_LATITUDE_START", bundle.getString("BlackboardAttribute.tskGeoLatitudeStart.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE); // Starting location lattitude
+		public static final Type TSK_GEO_LATITUDE_END = new Type(99, "TSK_GEO_LATITUDE_END", bundle.getString("BlackboardAttribute.tskGeoLatitudeEnd.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE); // Ending location lattitude
+		public static final Type TSK_GEO_LONGITUDE_START = new Type(100, "TSK_GEO_LONGITUDE_START", bundle.getString("BlackboardAttribute.tskGeoLongitudeStart.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE); // Starting location longitude
+		public static final Type TSK_GEO_LONGITUDE_END = new Type(101, "TSK_GEO_LONGITUDE_END", bundle.getString("BlackboardAttribute.tskGeoLongitudeEnd.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE); //Ending Location longitude
+		public static final Type TSK_READ_STATUS = new Type(102, "TSK_READ_STATUS", bundle.getString("BlackboardAttribute.tskReadStatus.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.INTEGER); // Message read status: 1 if read, 0 if unread
+		public static final Type TSK_LOCAL_PATH = new Type(103, "TSK_LOCAL_PATH", bundle.getString("BlackboardAttribute.tskLocalPath.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // Local path to a network drive
+		public static final Type TSK_REMOTE_PATH = new Type(104, "TSK_REMOTE_PATH", bundle.getString("BlackboardAttribute.tskRemotePath.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // Remote path of a network drive
+		public static final Type TSK_TEMP_DIR = new Type(105, "TSK_TEMP_DIR", bundle.getString("BlackboardAttribute.tskTempDir.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // Default temporary files directory
+		public static final Type TSK_PRODUCT_ID = new Type(106, "TSK_PRODUCT_ID", bundle.getString("BlackboardAttribute.tskProductId.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // Product ID
+		public static final Type TSK_OWNER = new Type(107, "TSK_OWNER", bundle.getString("BlackboardAttribute.tskOwner.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // Registered owner of a piece of software
+		public static final Type TSK_ORGANIZATION = new Type(108, "TSK_ORGANIZATION", bundle.getString("BlackboardAttribute.tskOrganization.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING); // Registered Organization for a piece of software
+		public static final Type TSK_CARD_NUMBER = new Type(109, "TSK_CARD_NUMBER", bundle.getString("BlackboardAttribute.tskCardNumber.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_CARD_EXPIRATION = new Type(110, "TSK_CARD_EXPIRATION", bundle.getString("BlackboardAttribute.tskCardExpiration.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_CARD_SERVICE_CODE = new Type(111, "TSK_CARD_SERVICE_CODE", bundle.getString("BlackboardAttribute.tskCardServiceCode.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_CARD_DISCRETIONARY = new Type(112, "TSK_CARD_DISCRETIONARY", bundle.getString("BlackboardAttribute.tskCardDiscretionary.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_CARD_LRC = new Type(113, "TSK_CARD_LRC", bundle.getString("BlackboardAttribute.tskCardLRC.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_KEYWORD_SEARCH_DOCUMENT_ID = new Type(114, "TSK_KEYWORD_SEARCH_DOCUMENT_ID", bundle.getString("BlackboardAttribute.tskKeywordSearchDocumentID.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_CARD_SCHEME = new Type(115, "TSK_CARD_SCHEME", bundle.getString("BlackboardAttribute.tskCardScheme.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_CARD_TYPE = new Type(116, "TSK_CARD_TYPE", bundle.getString("BlackboardAttribute.tskCardType.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_BRAND_NAME = new Type(117, "TSK_BRAND_NAME", bundle.getString("BlackboardAttribute.tskBrandName.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_BANK_NAME = new Type(118, "TSK_BANK_NAME", bundle.getString("BlackboardAttribute.tskBankName.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_COUNTRY = new Type(119, "TSK_COUNTRY", bundle.getString("BlackboardAttribute.tskCountry.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_CITY = new Type(120, "TSK_CITY", bundle.getString("BlackboardAttribute.tskCity.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_ACCOUNT_TYPE = new Type(121, "TSK_ACCOUNT_TYPE", bundle.getString("BlackboardAttribute.tskAccountType.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+
+		/**
+		 * Keyword search type: exact match, sub-string, or regex.
+		 */
+		public static final Type TSK_KEYWORD_SEARCH_TYPE = new Type(122, "TSK_KEYWORD_SEARCH_TYPE", bundle.getString("BlackboardAttribute.tskKeywordSearchType.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.INTEGER);
+		public static final Type TSK_HEADERS = new Type(123, "TSK_HEADERS", bundle.getString("BlackboardAttribute.tskHeaders.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_ID = new Type(124, "TSK_ID", bundle.getString("BlackboardAttribute.tskId.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_SSID = new Type(125, "TSK_SSID", bundle.getString("BlackboardAttribute.tskSsid.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_BSSID = new Type(126, "TSK_BSSID", bundle.getString("BlackboardAttribute.tskBssid.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_MAC_ADDRESS = new Type(127, "TSK_MAC_ADDRESS", bundle.getString("BlackboardAttribute.tskMacAddress.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_IMEI = new Type(128, "TSK_IMEI", bundle.getString("BlackboardAttribute.tskImei.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_IMSI = new Type(129, "TSK_IMSI", bundle.getString("BlackboardAttribute.tskImsi.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_ICCID = new Type(130, "TSK_ICCID", bundle.getString("BlackboardAttribute.tskIccid.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_THREAD_ID = new Type(131, "TSK_THREAD_ID", bundle.getString("BlackboardAttribute.tskthreadid.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		/**
+		 * The event type of a TSK_TL_EVENT artifact. The value should be the id
+		 * of the EventType in the tsk_event_types table.
+		 */
+		public static final Type TSK_TL_EVENT_TYPE = new Type(132, "TSK_TL_EVENT_TYPE", bundle.getString("BlackboardAttribute.tskTLEventType.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.LONG);
+		public static final Type TSK_DATETIME_DELETED = new Type(133, "TSK_DATETIME_DELETED", bundle.getString("BlackboardAttribute.tskdatetimedeleted.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME);
+		public static final Type TSK_DATETIME_PASSWORD_RESET = new Type(134, "TSK_DATETIME_PASSWORD_RESET", bundle.getString("BlackboardAttribute.tskdatetimepwdreset.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME);
+		public static final Type TSK_DATETIME_PASSWORD_FAIL = new Type(135, "TSK_DATETIME_PWD_FAIL", bundle.getString("BlackboardAttribute.tskdatetimepwdfail.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME);
+		public static final Type TSK_DISPLAY_NAME = new Type(136, "TSK_DISPLAY_NAME", bundle.getString("BlackboardAttribute.tskdisplayname.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_PASSWORD_SETTINGS = new Type(137, "TSK_PASSWORD_SETTINGS", bundle.getString("BlackboardAttribute.tskpasswordsettings.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_ACCOUNT_SETTINGS = new Type(138, "TSK_ACCOUNT_SETTINGS", bundle.getString("BlackboardAttribute.tskaccountsettings.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_PASSWORD_HINT = new Type(139, "TSK_PASSWORD_HINT", bundle.getString("BlackboardAttribute.tskpasswordhint.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_GROUPS = new Type(140, "TSK_GROUPS", bundle.getString("BlackboardAttribute.tskgroups.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		/*
+		 * Use
+		 * org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments
+		 * to create and process TSK_ATTACHMENTS attributes.
+		 */
+		public static final Type TSK_ATTACHMENTS = new Type(141, "TSK_ATTACHMENTS", bundle.getString("BlackboardAttribute.tskattachments.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.JSON);
+		/*
+		 * Use org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints
+		 * to create and process TSK_GEO_TRACKPOINTS attributes.
+		 */
+		public static final Type TSK_GEO_TRACKPOINTS = new Type(142, "TSK_GEO_TRACKPOINTS", bundle.getString("BlackboardAttribute.tskgeopath.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.JSON);
+		/*
+		 * Use org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints
+		 * to create and process TSK_GEO_WAYPOINTS attributes.
+		 */
+		public static final Type TSK_GEO_WAYPOINTS = new Type(143, "TSK_GEO_WAYPOINTS", bundle.getString("BlackboardAttribute.tskgeowaypoints.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.JSON);
+		public static final Type TSK_DISTANCE_TRAVELED = new Type(144, "TSK_DISTANCE_TRAVELED", bundle.getString("BlackboardAttribute.tskdistancetraveled.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE);
+		public static final Type TSK_DISTANCE_FROM_HOMEPOINT = new Type(145, "TSK_DISTANCE_FROM_HOMEPOINT", bundle.getString("BlackboardAttribute.tskdistancefromhome.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE);
+		public static final Type TSK_HASH_PHOTODNA = new Type(146, "TSK_HASH_PHOTODNA", bundle.getString("BlackboardAttribute.tskhashphotodna.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_BYTES_SENT = new Type(147, "TSK_BYTES_SENT", bundle.getString("BlackboardAttribute.tskbytessent.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.LONG);
+		public static final Type TSK_BYTES_RECEIVED = new Type(148, "TSK_BYTES_RECEIVED", bundle.getString("BlackboardAttribute.tskbytesreceived.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.LONG);
+		public static final Type TSK_LAST_PRINTED_DATETIME = new Type(149, "TSK_LAST_PRINTED_DATETIME", bundle.getString("BlackboardAttribute.tsklastprinteddatetime.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME);
+		public static final Type TSK_RULE = new Type(150, "TSK_RULE", bundle.getString("BlackboardAttribute.tskrule.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_ACTIVITY_TYPE = new Type(151, "TSK_ACTIVITY_TYPE", bundle.getString("BlackboardAttribute.tskActivityType.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		/*
+		 * Use org.sleuthkit.datamodel.blackboardutils.attributes.GeoAreaPoints
+		 * to create and process TSK_GEO_AREAPOINTS attributes.
+		 */
+		public static final Type TSK_GEO_AREAPOINTS = new Type(152, "TSK_GEO_AREAPOINTS", bundle.getString("BlackboardAttribute.tskgeoareapoints.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.JSON);
+		public static final Type TSK_REALM = new Type(153, "TSK_REALM", bundle.getString("BlackboardAttribute.tskRealm.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_HOST = new Type(154, "TSK_HOST", bundle.getString("BlackboardAttribute.tskHost.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_HOME_DIR = new Type(155, "TSK_HOME_DIR", bundle.getString("BlackboardAttribute.tskHomeDir.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING);
+		public static final Type TSK_IS_ADMIN = new Type(156, "TSK_IS_ADMIN", bundle.getString("BlackboardAttribute.tskIsAdmin.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.INTEGER);
+		// NOTE: When adding a new standard BlackboardAttribute.Type, add the instance and then add to the STANDARD_TYPES list.
+		/**
+		 * A list of all the standard attribute types.
+		 */
+		
+		static final List<Type> STANDARD_TYPES = Collections.unmodifiableList(Arrays.asList(
+				TSK_URL,
+				TSK_DATETIME,
+				TSK_NAME,
+				TSK_PROG_NAME,
+				TSK_VALUE,
+				TSK_FLAG,
+				TSK_PATH,
+				TSK_KEYWORD,
+				TSK_KEYWORD_REGEXP,
+				TSK_KEYWORD_PREVIEW,
+				TSK_USER_NAME,
+				TSK_DOMAIN,
+				TSK_PASSWORD,
+				TSK_NAME_PERSON,
+				TSK_DEVICE_MODEL,
+				TSK_DEVICE_MAKE,
+				TSK_DEVICE_ID,
+				TSK_EMAIL,
+				TSK_HASH_MD5,
+				TSK_HASH_SHA1,
+				TSK_HASH_SHA2_256,
+				TSK_HASH_SHA2_512,
+				TSK_TEXT,
+				TSK_TEXT_FILE,
+				TSK_TEXT_LANGUAGE,
+				TSK_ENTROPY,
+				TSK_REFERRER,
+				TSK_DATETIME_ACCESSED,
+				TSK_IP_ADDRESS,
+				TSK_PHONE_NUMBER,
+				TSK_PATH_ID,
+				TSK_SET_NAME,
+				TSK_MALWARE_DETECTED,
+				TSK_STEG_DETECTED,
+				TSK_EMAIL_TO,
+				TSK_EMAIL_CC,
+				TSK_EMAIL_BCC,
+				TSK_EMAIL_FROM,
+				TSK_EMAIL_CONTENT_PLAIN,
+				TSK_EMAIL_CONTENT_HTML,
+				TSK_EMAIL_CONTENT_RTF,
+				TSK_MSG_ID,
+				TSK_MSG_REPLY_ID,
+				TSK_DATETIME_RCVD,
+				TSK_DATETIME_SENT,
+				TSK_SUBJECT,
+				TSK_TITLE,
+				TSK_GEO_LATITUDE,
+				TSK_GEO_LONGITUDE,
+				TSK_GEO_VELOCITY,
+				TSK_GEO_ALTITUDE,
+				TSK_GEO_BEARING,
+				TSK_GEO_HPRECISION,
+				TSK_GEO_VPRECISION,
+				TSK_GEO_MAPDATUM,
+				TSK_FILE_TYPE_EXT,
+				TSK_COMMENT,
+				TSK_URL_DECODED,
+				TSK_DATETIME_CREATED,
+				TSK_DATETIME_MODIFIED,
+				TSK_PROCESSOR_ARCHITECTURE,
+				TSK_VERSION,
+				TSK_USER_ID,
+				TSK_DESCRIPTION,
+				TSK_MESSAGE_TYPE,
+				TSK_PHONE_NUMBER_HOME,
+				TSK_PHONE_NUMBER_OFFICE,
+				TSK_PHONE_NUMBER_MOBILE,
+				TSK_PHONE_NUMBER_FROM,
+				TSK_PHONE_NUMBER_TO,
+				TSK_DIRECTION,
+				TSK_EMAIL_HOME,
+				TSK_EMAIL_OFFICE,
+				TSK_DATETIME_START,
+				TSK_DATETIME_END,
+				TSK_CALENDAR_ENTRY_TYPE,
+				TSK_LOCATION,
+				TSK_SHORTCUT,
+				TSK_DEVICE_NAME,
+				TSK_CATEGORY,
+				TSK_EMAIL_REPLYTO,
+				TSK_SERVER_NAME,
+				TSK_COUNT,
+				TSK_MIN_COUNT,
+				TSK_PATH_SOURCE,
+				TSK_PERMISSIONS,
+				TSK_ASSOCIATED_ARTIFACT,
+				TSK_ISDELETED,
+				TSK_GEO_LATITUDE_START,
+				TSK_GEO_LATITUDE_END,
+				TSK_GEO_LONGITUDE_START,
+				TSK_GEO_LONGITUDE_END,
+				TSK_READ_STATUS,
+				TSK_LOCAL_PATH,
+				TSK_REMOTE_PATH,
+				TSK_TEMP_DIR,
+				TSK_PRODUCT_ID,
+				TSK_OWNER,
+				TSK_ORGANIZATION,
+				TSK_CARD_NUMBER,
+				TSK_CARD_EXPIRATION,
+				TSK_CARD_SERVICE_CODE,
+				TSK_CARD_DISCRETIONARY,
+				TSK_CARD_LRC,
+				TSK_KEYWORD_SEARCH_DOCUMENT_ID,
+				TSK_CARD_SCHEME,
+				TSK_CARD_TYPE,
+				TSK_BRAND_NAME,
+				TSK_BANK_NAME,
+				TSK_COUNTRY,
+				TSK_CITY,
+				TSK_ACCOUNT_TYPE,
+				TSK_KEYWORD_SEARCH_TYPE,
+				TSK_HEADERS,
+				TSK_ID,
+				TSK_SSID,
+				TSK_BSSID,
+				TSK_MAC_ADDRESS,
+				TSK_IMEI,
+				TSK_IMSI,
+				TSK_ICCID,
+				TSK_THREAD_ID,
+				TSK_TL_EVENT_TYPE,
+				TSK_DATETIME_DELETED,
+				TSK_DATETIME_PASSWORD_RESET,
+				TSK_DATETIME_PASSWORD_FAIL,
+				TSK_DISPLAY_NAME,
+				TSK_PASSWORD_SETTINGS,
+				TSK_ACCOUNT_SETTINGS,
+				TSK_PASSWORD_HINT,
+				TSK_GROUPS,
+				TSK_ATTACHMENTS,
+				TSK_GEO_TRACKPOINTS,
+				TSK_GEO_WAYPOINTS,
+				TSK_DISTANCE_TRAVELED,
+				TSK_DISTANCE_FROM_HOMEPOINT,
+				TSK_HASH_PHOTODNA,
+				TSK_BYTES_SENT,
+				TSK_BYTES_RECEIVED,
+				TSK_LAST_PRINTED_DATETIME,
+				TSK_RULE,
+				TSK_ACTIVITY_TYPE,
+				TSK_GEO_AREAPOINTS,
+				TSK_REALM,
+				TSK_HOST,
+				TSK_HOME_DIR,
+				TSK_IS_ADMIN
+		));
+
 		private static final long serialVersionUID = 1L;
 		private final String typeName;
 		private final int typeID;
@@ -1191,8 +1529,7 @@ public enum ATTRIBUTE_TYPE {
 				TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING),
 		TSK_IS_ADMIN(156, "TSK_IS_ADMIN",
 				bundle.getString("BlackboardAttribute.tskIsAdmin.text"),
-				TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.INTEGER),
-		;
+				TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.INTEGER),;
 
 		private final int typeID;
 		private final String typeName;
diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
index cf1bffd9895980e93f681b3678c5b00160e091c5..a728ac4e1c045327bd149422eff342e433745448 100755
--- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
@@ -3825,11 +3825,12 @@ public Iterable<BlackboardArtifact.Type> getArtifactTypes() throws TskCoreExcept
 		ResultSet rs = null;
 		try {
 			s = connection.createStatement();
-			rs = connection.executeQuery(s, "SELECT artifact_type_id, type_name, display_name FROM blackboard_artifact_types"); //NON-NLS
+			rs = connection.executeQuery(s, "SELECT artifact_type_id, type_name, display_name, category_type FROM blackboard_artifact_types"); //NON-NLS
 			ArrayList<BlackboardArtifact.Type> artifactTypes = new ArrayList<BlackboardArtifact.Type>();
 			while (rs.next()) {
 				artifactTypes.add(new BlackboardArtifact.Type(rs.getInt("artifact_type_id"),
-						rs.getString("type_name"), rs.getString("display_name")));
+						rs.getString("type_name"), rs.getString("display_name"), 
+						BlackboardArtifact.Category.fromID(rs.getInt("category_type"))));
 			}
 			return artifactTypes;
 		} catch (SQLException ex) {
@@ -3901,14 +3902,17 @@ public List<BlackboardArtifact.Type> getArtifactTypesInUse() throws TskCoreExcep
 			s = connection.createStatement();
 			rs = connection.executeQuery(s,
 					"SELECT DISTINCT arts.artifact_type_id AS artifact_type_id, "
-					+ "types.type_name AS type_name, types.display_name AS display_name "
+					+ "types.type_name AS type_name, "
+					+ "types.display_name AS display_name, "
+					+ "types.category_type AS category_type "
 					+ "FROM blackboard_artifact_types AS types "
 					+ "INNER JOIN blackboard_artifacts AS arts "
 					+ "ON arts.artifact_type_id = types.artifact_type_id"); //NON-NLS
 			List<BlackboardArtifact.Type> uniqueArtifactTypes = new ArrayList<BlackboardArtifact.Type>();
 			while (rs.next()) {
 				uniqueArtifactTypes.add(new BlackboardArtifact.Type(rs.getInt("artifact_type_id"),
-						rs.getString("type_name"), rs.getString("display_name")));
+						rs.getString("type_name"), rs.getString("display_name"), 
+						BlackboardArtifact.Category.fromID(rs.getInt("category_type"))));
 			}
 			return uniqueArtifactTypes;
 		} catch (SQLException ex) {
@@ -4719,7 +4723,8 @@ public BlackboardArtifact.Type getArtifactType(String artTypeName) throws TskCor
 			BlackboardArtifact.Type type = null;
 			if (rs.next()) {
 				type = new BlackboardArtifact.Type(rs.getInt("artifact_type_id"),
-						rs.getString("type_name"), rs.getString("display_name"), BlackboardArtifact.Category.fromID(rs.getInt("category_type")));
+						rs.getString("type_name"), rs.getString("display_name"), 
+						BlackboardArtifact.Category.fromID(rs.getInt("category_type")));
 				this.typeIdToArtifactTypeMap.put(type.getTypeID(), type);
 				this.typeNameToArtifactTypeMap.put(artTypeName, type);
 			}
@@ -4758,7 +4763,8 @@ BlackboardArtifact.Type getArtifactType(int artTypeId) throws TskCoreException {
 			BlackboardArtifact.Type type = null;
 			if (rs.next()) {
 				type = new BlackboardArtifact.Type(rs.getInt("artifact_type_id"),
-						rs.getString("type_name"), rs.getString("display_name"), BlackboardArtifact.Category.fromID(rs.getInt("category_type")));
+						rs.getString("type_name"), rs.getString("display_name"), 
+						BlackboardArtifact.Category.fromID(rs.getInt("category_type")));
 				this.typeIdToArtifactTypeMap.put(artTypeId, type);
 				this.typeNameToArtifactTypeMap.put(type.getTypeName(), type);
 			}
@@ -7980,6 +7986,52 @@ public boolean equals(Object obj) {
 		}
 	}	
 
+	/**
+	 * Utility class to create keys for the cache used in isRootDirectory().
+	 * The dataSourceId must be set but the fileSystemId can be null 
+	 * (for local directories, for example).
+	 */
+	private class RootDirectoryKey {
+		private long dataSourceId;
+		private Long fileSystemId;
+		
+		RootDirectoryKey(long dataSourceId, Long fileSystemId) {
+			this.dataSourceId = dataSourceId;
+			this.fileSystemId = fileSystemId;
+		}
+		
+        @Override
+        public int hashCode() {
+            int hash = 7;
+			hash = 41 * hash + Objects.hashCode(dataSourceId);
+            hash = 41 * hash + Objects.hashCode(fileSystemId);
+            return hash;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+			
+			RootDirectoryKey otherKey = (RootDirectoryKey)obj;
+			if (dataSourceId != otherKey.dataSourceId) {
+				return false;
+			}
+			
+			if (fileSystemId != null) {
+				return fileSystemId.equals(otherKey.fileSystemId);
+			}
+			return (otherKey.fileSystemId == null);
+		}
+	}
+	
 	/**
 	 * Check whether a given AbstractFile is the "root" directory. True if the
 	 * AbstractFile either has no parent or its parent is an image, volume,
@@ -7992,8 +8044,7 @@ public boolean equals(Object obj) {
 	 *
 	 * @throws TskCoreException
 	 */
-	private boolean isRootDirectory(AbstractFile file, CaseDbTransaction transaction) throws TskCoreException {
-		
+	private boolean isRootDirectory(AbstractFile file, CaseDbTransaction transaction) throws TskCoreException {	
 		// First check if we know the root directory for this data source and optionally 
 		// file system. There is only one root, so if we know it we can simply compare 
 		// this file ID to the known root directory.
@@ -8052,7 +8103,6 @@ private boolean isRootDirectory(AbstractFile file, CaseDbTransaction transaction
 					rootDirectoryMap.put(key, file.getId());
 				}
 				isRootDirectoryCache.put(file.getId(), true);
-				
 				return true; // The file has no parent
 			}
 		} catch (SQLException ex) {
diff --git a/tools/autotools/Makefile.am b/tools/autotools/Makefile.am
index 8058968f8be96ddcd593b01bb6dfea43b11840b6..4e686160a6710e41a72d255c81e8fcff19208219 100644
--- a/tools/autotools/Makefile.am
+++ b/tools/autotools/Makefile.am
@@ -4,11 +4,12 @@ LDADD = ../../tsk/libtsk.la
 LDFLAGS += -static
 EXTRA_DIST = .indent.pro
 
-bin_PROGRAMS = tsk_recover tsk_loaddb tsk_comparedir tsk_gettimes
+bin_PROGRAMS = tsk_recover tsk_loaddb tsk_comparedir tsk_gettimes tsk_imageinfo
 tsk_recover_SOURCES = tsk_recover.cpp 
 tsk_loaddb_SOURCES = tsk_loaddb.cpp 
 tsk_gettimes_SOURCES = tsk_gettimes.cpp 
 tsk_comparedir_SOURCES = tsk_comparedir.cpp tsk_comparedir.h
+tsk_imageinfo_SOURCES = tsk_imageinfo.cpp 
 
 indent:
 	indent *.cpp
diff --git a/tools/autotools/tsk_imageinfo.cpp b/tools/autotools/tsk_imageinfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3cad8b3435e0112250ea39d6a94609eff657f734
--- /dev/null
+++ b/tools/autotools/tsk_imageinfo.cpp
@@ -0,0 +1,152 @@
+/*
+ ** tsk_imageinfo
+ ** The Sleuth Kit 
+ **
+ ** Brian Carrier [carrier <at> sleuthkit [dot] org]
+ ** Copyright (c) 2021 Brian Carrier.  All Rights reserved
+ **
+ ** This software is distributed under the Common Public License 1.0
+ **
+ */
+
+#include "tsk/tsk_tools_i.h"
+#include "tsk/auto/tsk_is_image_supported.h"
+#include <locale.h>
+#include <time.h>
+
+
+static TSK_TCHAR *progname;
+
+static void
+usage()
+{
+    TFPRINTF(stderr,
+        _TSK_T
+        ("usage: %s [-vV] [-i imgtype] [-b dev_sector_size] image\n"),
+        progname);
+    tsk_fprintf(stderr,
+        "\t-i imgtype: The format of the image file (use '-i list' for supported types)\n");
+    tsk_fprintf(stderr,
+        "\t-b dev_sector_size: The size (in bytes) of the device sectors\n");
+    tsk_fprintf(stderr, "\t-v: verbose output to stderr\n");
+    tsk_fprintf(stderr, "\t-V: Print version\n");
+    
+
+    exit(1);
+}
+
+int
+main(int argc, char **argv1)
+{
+    TSK_IMG_TYPE_ENUM imgtype = TSK_IMG_TYPE_DETECT;
+    int ch;
+    TSK_TCHAR **argv;
+    unsigned int ssize = 0;
+    TSK_TCHAR *cp;
+	bool do_hash = false;
+
+#ifdef TSK_WIN32
+    // On Windows, get the wide arguments (mingw doesn't support wmain)
+    argv = CommandLineToArgvW(GetCommandLineW(), &argc);
+    if (argv == NULL) {
+        fprintf(stderr, "Error getting wide arguments\n");
+        exit(1);
+    }
+#else
+    argv = (TSK_TCHAR **) argv1;
+#endif
+
+    progname = argv[0];
+    setlocale(LC_ALL, "");
+
+    while ((ch = GETOPT(argc, argv, _TSK_T("b:i:vV"))) > 0) {
+        switch (ch) {
+        case _TSK_T('?'):
+        default:
+            TFPRINTF(stderr, _TSK_T("Invalid argument: %s\n"),
+                argv[OPTIND]);
+            usage();
+
+            
+        case _TSK_T('b'):
+            ssize = (unsigned int) TSTRTOUL(OPTARG, &cp, 0);
+            if (*cp || *cp == *OPTARG || ssize < 1) {
+                TFPRINTF(stderr,
+                    _TSK_T
+                    ("invalid argument: sector size must be positive: %s\n"),
+                    OPTARG);
+                usage();
+            }
+            break;
+                
+
+
+        case _TSK_T('i'):
+            if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) {
+                tsk_img_type_print(stderr);
+                exit(1);
+            }
+            imgtype = tsk_img_type_toid(OPTARG);
+            if (imgtype == TSK_IMG_TYPE_UNSUPP) {
+                TFPRINTF(stderr, _TSK_T("Unsupported image type: %s\n"),
+                    OPTARG);
+                usage();
+            }
+            break;
+
+        case _TSK_T('v'):
+            tsk_verbose++;
+            break;
+
+        case _TSK_T('V'):
+            tsk_version_print(stdout);
+            exit(0);
+                
+        }
+    }
+
+    /* We need at least one more argument */
+    if (OPTIND >= argc) {
+        tsk_fprintf(stderr,
+            "Missing image name\n");
+        usage();
+    }
+
+    int imageCount = argc - OPTIND;
+    if (imageCount != 1) {
+        tsk_fprintf(stderr,
+            "Only one image supported\n");
+        usage();
+    }
+
+    TskIsImageSupported imageProcessor;
+    if (imageProcessor.openImage(imageCount, &argv[OPTIND], imgtype, ssize)) {
+        tsk_error_print(stderr);
+        exit(1);
+    }
+
+    // Run findFilesInImage to process the image and set the flags
+    int findFilesResult;
+    findFilesResult = imageProcessor.findFilesInImg();
+
+    tsk_printf("Is Supported: ");
+    if (findFilesResult != 0) {
+        tsk_printf("false\n");
+    }
+    else if (imageProcessor.isImageSupported()) {
+        tsk_printf("true\n");
+    }
+    else {
+        tsk_printf("false\n");
+    }
+
+    tsk_printf("Is Encrypted: ");
+    if (imageProcessor.isImageEncrypted()) {
+        tsk_printf("true\n");
+    }
+    else {
+        tsk_printf("false\n");
+    }
+    
+    exit(0);
+}
diff --git a/tsk/auto/is_image_supported.cpp b/tsk/auto/is_image_supported.cpp
index 84a50627ce253c31bf85b803aaa3030a1a9488fb..7b398de088687743f6d195ff66225d7c06d5c775 100644
--- a/tsk/auto/is_image_supported.cpp
+++ b/tsk/auto/is_image_supported.cpp
@@ -25,6 +25,7 @@
 TskIsImageSupported::TskIsImageSupported()
 {
     m_wasDataFound = false;
+    m_wasEncryptionFound = false;
 }
 
 bool TskIsImageSupported::isImageSupported()
@@ -32,6 +33,11 @@ bool TskIsImageSupported::isImageSupported()
     return m_wasDataFound ;
 }
 
+bool TskIsImageSupported::isImageEncrypted()
+{
+    return m_wasEncryptionFound;
+}
+
 
 uint8_t TskIsImageSupported::handleError() 
 {
@@ -55,6 +61,21 @@ TskIsImageSupported::filterFs(TSK_FS_INFO * /*fs_info*/)
     return TSK_FILTER_SKIP;
 }
 
+TSK_FILTER_ENUM
+TskIsImageSupported::filterPool(const TSK_POOL_INFO * pool_info)
+{
+    // There's nothing to do, but we need to override this to allow the pool
+    // to be processed.
+    return TSK_FILTER_CONT;
+}
+
+TSK_FILTER_ENUM
+TskIsImageSupported::filterPoolVol(const TSK_POOL_VOLUME_INFO * pool_vol)
+{
+    // There's nothing to do, but we need to override this to allow the pool
+    // to be processed.
+    return TSK_FILTER_CONT;
+}
 
 TSK_FILTER_ENUM
 TskIsImageSupported::filterVol(const TSK_VS_PART_INFO * /*vs_part*/)
diff --git a/tsk/auto/tsk_is_image_supported.h b/tsk/auto/tsk_is_image_supported.h
index 9993d8226dbe46894f826fa426c48de7ac2accd2..c7d1460654a2bf21aaa377e5d07509cda162f7ce 100644
--- a/tsk/auto/tsk_is_image_supported.h
+++ b/tsk/auto/tsk_is_image_supported.h
@@ -28,10 +28,14 @@ class TskIsImageSupported:public TskAuto {
     TskIsImageSupported();
     virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE * fs_file, const char *path);
     virtual TSK_FILTER_ENUM filterVol(const TSK_VS_PART_INFO * vs_part);
+    virtual TSK_FILTER_ENUM filterPool(const TSK_POOL_INFO * pool_info);
+    virtual TSK_FILTER_ENUM filterPoolVol(const TSK_POOL_VOLUME_INFO * pool_vol);
     virtual TSK_FILTER_ENUM filterFs(TSK_FS_INFO * fs_info);
     virtual uint8_t handleError();
     bool isImageSupported();
+    bool isImageEncrypted();
     
 private:
     bool m_wasDataFound;
+    bool m_wasEncryptionFound;
 };
\ No newline at end of file
diff --git a/tsk/fs/exfatfs_meta.c b/tsk/fs/exfatfs_meta.c
index cd895319a43471f2c6305800ad38cef0108e0d96..71bbcf152382f4bf0aaa743e911d0c9586bf1978 100755
--- a/tsk/fs/exfatfs_meta.c
+++ b/tsk/fs/exfatfs_meta.c
@@ -50,12 +50,10 @@ exfatfs_is_cluster_alloc(FATFS_INFO *a_fatfs, TSK_DADDR_T a_cluster_addr)
     uint8_t bitmap_byte;
     ssize_t bytes_read = 0;
 
-    assert(a_fatfs != NULL);
     if (fatfs_ptr_arg_is_null(a_fatfs, "a_fatfs", func_name)) {
         return -1;
     }
 
-    assert((a_cluster_addr >= FATFS_FIRST_CLUSTER_ADDR) && (a_cluster_addr <= a_fatfs->lastclust));
     if ((a_cluster_addr < FATFS_FIRST_CLUSTER_ADDR) || (a_cluster_addr > a_fatfs->lastclust)) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_FS_ARG);
@@ -109,7 +107,6 @@ exfatfs_is_vol_label_dentry(FATFS_DENTRY *a_dentry, FATFS_DATA_UNIT_ALLOC_STATUS
     EXFATFS_VOL_LABEL_DIR_ENTRY *dentry = (EXFATFS_VOL_LABEL_DIR_ENTRY*)a_dentry;
     uint8_t i = 0;
     
-    assert(a_dentry != NULL);
     if (fatfs_ptr_arg_is_null(a_dentry, "a_dentry", func_name)) {
         return 0;
     }
@@ -176,7 +173,6 @@ exfatfs_is_vol_guid_dentry(FATFS_DENTRY *a_dentry, FATFS_DATA_UNIT_ALLOC_STATUS_
     const char *func_name = "exfatfs_is_vol_guid_dentry";
     EXFATFS_VOL_GUID_DIR_ENTRY *dentry = (EXFATFS_VOL_GUID_DIR_ENTRY*)a_dentry;
     
-    assert(a_dentry != NULL);
     if (fatfs_ptr_arg_is_null(a_dentry, "a_dentry", func_name)) {
         return 0;
     }
@@ -217,7 +213,6 @@ exfatfs_is_alloc_bitmap_dentry(FATFS_DENTRY *a_dentry, FATFS_DATA_UNIT_ALLOC_STA
     uint32_t first_cluster_of_bitmap = 0;
     uint64_t length_of_alloc_bitmap_in_bytes = 0;
 
-    assert(a_dentry != NULL);
     if (fatfs_ptr_arg_is_null(a_dentry, "a_dentry", func_name)) {
         return 0;
     }
@@ -297,7 +292,6 @@ exfatfs_is_upcase_table_dentry(FATFS_DENTRY *a_dentry, FATFS_DATA_UNIT_ALLOC_STA
     uint64_t table_size = 0;
     uint32_t first_cluster_of_table = 0;
 
-    assert(a_dentry != NULL);
     if (fatfs_ptr_arg_is_null(a_dentry, "a_dentry", func_name)) {
         return 0;
     }
@@ -377,7 +371,6 @@ exfatfs_is_texfat_dentry(FATFS_DENTRY *a_dentry, FATFS_DATA_UNIT_ALLOC_STATUS_EN
     const char *func_name = "exfatfs_is_texfat_dentry";
     EXFATFS_TEXFAT_DIR_ENTRY *dentry = (EXFATFS_TEXFAT_DIR_ENTRY*)a_dentry;
     
-    assert(a_dentry != NULL);
     if (fatfs_ptr_arg_is_null(a_dentry, "a_dentry", func_name)) {
         return 0;
     }
@@ -412,7 +405,6 @@ exfatfs_is_access_ctrl_table_dentry(FATFS_DENTRY *a_dentry, FATFS_DATA_UNIT_ALLO
     const char *func_name = "exfatfs_is_texfat_dentry";
     EXFATFS_TEXFAT_DIR_ENTRY *dentry = (EXFATFS_TEXFAT_DIR_ENTRY*)a_dentry;
     
-    assert(a_dentry != NULL);
     if (fatfs_ptr_arg_is_null(a_dentry, "a_dentry", func_name)) {
         return 0;
     }
@@ -476,7 +468,6 @@ exfatfs_is_file_dentry_standalone(FATFS_DENTRY *a_dentry, TSK_ENDIAN_ENUM a_endi
     const char *func_name = "exfatfs_is_file_dentry";
     EXFATFS_FILE_DIR_ENTRY *dentry = (EXFATFS_FILE_DIR_ENTRY*)a_dentry;
 
-    assert(a_dentry != NULL);
     if (fatfs_ptr_arg_is_null(a_dentry, "a_dentry", func_name)) {
         return 0;
     }
@@ -587,7 +578,6 @@ exfatfs_is_file_stream_dentry_standalone(FATFS_DENTRY *a_dentry, TSK_ENDIAN_ENUM
     uint64_t file_size = 0;
     uint32_t first_cluster = 0;
 
-    assert(a_dentry != NULL);
     if (fatfs_ptr_arg_is_null(a_dentry, "a_dentry", func_name)) {
         return 0;
     }
@@ -647,7 +637,6 @@ exfatfs_is_file_name_dentry(FATFS_DENTRY *a_dentry)
     const char *func_name = "exfatfs_is_file_name_dentry";
     EXFATFS_FILE_NAME_DIR_ENTRY *dentry = (EXFATFS_FILE_NAME_DIR_ENTRY*)a_dentry;
     
-    assert(a_dentry != NULL);
     if (fatfs_ptr_arg_is_null(a_dentry, "a_dentry", func_name)) {
         return 0;
     }
@@ -675,7 +664,6 @@ exfatfs_is_dentry(FATFS_INFO *a_fatfs, FATFS_DENTRY *a_dentry, FATFS_DATA_UNIT_A
 {
     const char *func_name = "exfatfs_is_dentry";
 
-    assert(a_dentry != NULL);
     if (fatfs_ptr_arg_is_null(a_dentry, "a_dentry", func_name)) {
         return 0;
     }
diff --git a/tsk/fs/ext2fs.c b/tsk/fs/ext2fs.c
index d6abbd9f5a162c7d952c2a8d48aadf32ff02c364..b319db43cbe9e6d1da8ad2fcc8b25093a105e24b 100755
--- a/tsk/fs/ext2fs.c
+++ b/tsk/fs/ext2fs.c
@@ -1155,11 +1155,15 @@ ext2fs_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start_inum,
 
     }
 
-    if ((fs_file = tsk_fs_file_alloc(fs)) == NULL)
+    fs_file = tsk_fs_file_alloc(fs);
+    if (fs_file == NULL)
         return 1;
-    if ((fs_file->meta =
-            tsk_fs_meta_alloc(EXT2FS_FILE_CONTENT_LEN)) == NULL)
+
+    fs_file->meta = tsk_fs_meta_alloc(EXT2FS_FILE_CONTENT_LEN);
+    if (fs_file->meta == NULL) {
+        free(fs_file);
         return 1;
+    }
 
     // we need to handle fs->last_inum specially because it is for the
     // virtual ORPHANS directory.  Handle it outside of the loop.
@@ -1174,7 +1178,11 @@ ext2fs_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start_inum,
     size =
         ext2fs->inode_size >
         sizeof(ext2fs_inode) ? ext2fs->inode_size : sizeof(ext2fs_inode);
-    if ((dino_buf = (ext2fs_inode *) tsk_malloc(size)) == NULL) {
+
+    dino_buf = (ext2fs_inode *) tsk_malloc(size);
+    if (dino_buf == NULL) {
+        free(fs_file->meta);
+        free(fs_file);
         return 1;
     }
 
@@ -1196,6 +1204,7 @@ ext2fs_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start_inum,
         if (ext2fs_imap_load(ext2fs, grp_num)) {
             tsk_release_lock(&ext2fs->lock);
             free(dino_buf);
+            tsk_fs_file_close(fs_file);
             return 1;
         }
         ibase =
@@ -1208,6 +1217,8 @@ ext2fs_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start_inum,
         if ((inum - ibase) > fs->block_size*8) {
             tsk_release_lock(&ext2fs->lock);
             free(dino_buf);
+            tsk_fs_file_close(fs_file);
+
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_FS_WALK_RNG);
             tsk_error_set_errstr("%s: Invalid offset into imap_buf (inum %" PRIuINUM " - ibase %" PRIuINUM ")",
@@ -1227,8 +1238,9 @@ ext2fs_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start_inum,
             continue;
 
         if (ext2fs_dinode_load(ext2fs, inum, dino_buf, &ea_buf, &ea_buf_len)) {
-            tsk_fs_file_close(fs_file);
             free(dino_buf);
+            tsk_fs_file_close(fs_file);
+
             return 1;
         }
 
@@ -1257,20 +1269,23 @@ ext2fs_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start_inum,
          * to the application.
          */
         if (ext2fs_dinode_copy(ext2fs, fs_file, inum, dino_buf, ea_buf, ea_buf_len)) {
-            tsk_fs_meta_close(fs_file->meta);
             free(dino_buf);
+            tsk_fs_file_close(fs_file);
+
             return 1;
         }
 
         retval = a_action(fs_file, a_ptr);
         if (retval == TSK_WALK_STOP) {
-            tsk_fs_file_close(fs_file);
             free(dino_buf);
+            tsk_fs_file_close(fs_file);
+
             return 0;
         }
         else if (retval == TSK_WALK_ERROR) {
-            tsk_fs_file_close(fs_file);
             free(dino_buf);
+            tsk_fs_file_close(fs_file);
+
             return 1;
         }
     }
@@ -1282,8 +1297,9 @@ ext2fs_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start_inum,
         int retval;
 
         if (tsk_fs_dir_make_orphan_dir_meta(fs, fs_file->meta)) {
-            tsk_fs_file_close(fs_file);
             free(dino_buf);
+            tsk_fs_file_close(fs_file);
+
             return 1;
         }
         /* call action */
@@ -1291,11 +1307,14 @@ ext2fs_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start_inum,
         if (retval == TSK_WALK_STOP) {
             tsk_fs_file_close(fs_file);
             free(dino_buf);
+            tsk_fs_file_close(fs_file);
+
             return 0;
         }
         else if (retval == TSK_WALK_ERROR) {
-            tsk_fs_file_close(fs_file);
             free(dino_buf);
+            tsk_fs_file_close(fs_file);
+
             return 1;
         }
     }
@@ -1303,8 +1322,8 @@ ext2fs_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start_inum,
     /*
      * Cleanup.
      */
-    tsk_fs_file_close(fs_file);
     free(dino_buf);
+    tsk_fs_file_close(fs_file);
 
     return 0;
 }
diff --git a/tsk/fs/fs_dir.c b/tsk/fs/fs_dir.c
index 33e2a0d2c8ff37a6702eb60a2e5a2e6bd20d408f..b80c0012fbaa0895f28c27fe24c01ef5f76d2db5 100644
--- a/tsk/fs/fs_dir.c
+++ b/tsk/fs/fs_dir.c
@@ -790,6 +790,9 @@ tsk_fs_dir_walk_lcl(TSK_FS_INFO * a_fs, DENT_DINFO * a_dinfo,
                             PRIuINUM " exceeded max length / depth\n", fs_file->name->meta_addr);
                     }
 
+                    tsk_fs_dir_close(fs_dir);
+                    fs_file->name = NULL;
+                    tsk_fs_file_close(fs_file);
                     if (indexToOrderedIndex != NULL) {
                         free(indexToOrderedIndex);
                     }
diff --git a/tsk/fs/hfs.c b/tsk/fs/hfs.c
index 22618534ee3f0411b88407eae8217a863d0b8eec..e3221152b7e8cb68287d3dc500881b10db358cde 100644
--- a/tsk/fs/hfs.c
+++ b/tsk/fs/hfs.c
@@ -469,6 +469,16 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
                 size_t rec_off;
                 hfs_btree_key_ext *key;
 
+                // Make sure node is large enough, note that (rec + 1) * 2 is an offset
+                // relative to the end of node
+                if ((rec + 1) * 2 > (int) nodesize) {
+                    tsk_error_set_errno(TSK_ERR_FS_GENFS);
+                    tsk_error_set_errstr
+                        ("hfs_ext_find_extent_record: offset of record %d in leaf node %d too small (%"
+                        PRIu16 ")", rec, cur_node, nodesize);
+                    free(node);
+                    return 1;
+                }
                 // get the record offset in the node
                 rec_off =
                     tsk_getu16(fs->endian,
@@ -554,11 +564,21 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
                 int keylen;
                 TSK_FS_ATTR_RUN *attr_run;
 
+                // Make sure node is large enough, note that (rec + 1) * 2 is an offset
+                // relative to the end of node
+                if ((rec + 1) * 2 > (int) nodesize) {
+                    tsk_error_set_errno(TSK_ERR_FS_GENFS);
+                    tsk_error_set_errstr
+                        ("hfs_ext_find_extent_record_attr: offset of record %d in leaf node %d too small (%"
+                        PRIu16 ")", rec, cur_node, nodesize);
+                    free(node);
+                    return 1;
+                }
                 // get the record offset in the node
                 rec_off =
                     tsk_getu16(fs->endian,
                     &node[nodesize - (rec + 1) * 2]);
-                if (rec_off > nodesize) {
+                if (rec_off >= nodesize) {
                     tsk_error_set_errno(TSK_ERR_FS_GENFS);
                     tsk_error_set_errstr
                         ("hfs_ext_find_extent_record_attr: offset of record %d in leaf node %d too large (%d vs %"
@@ -821,11 +841,21 @@ hfs_cat_traverse(HFS_INFO * hfs,
                 uint8_t retval;
                 int keylen;
 
+                // Make sure node is large enough, note that (rec + 1) * 2 is an offset
+                // relative to the end of node
+                if ((rec + 1) * 2 > (int) nodesize) {
+                    tsk_error_set_errno(TSK_ERR_FS_GENFS);
+                    tsk_error_set_errstr
+                        ("hfs_cat_traverse: offset of record %d in leaf node %d too small (%"
+                        PRIu16 ")", rec, cur_node, nodesize);
+                    free(node);
+                    return 1;
+                }
                 // get the record offset in the node
                 rec_off =
                     tsk_getu16(fs->endian,
                     &node[nodesize - (rec + 1) * 2]);
-                if (rec_off > nodesize) {
+                if (rec_off >= nodesize) {
                     tsk_error_set_errno(TSK_ERR_FS_GENFS);
                     tsk_error_set_errstr
                         ("hfs_cat_traverse: offset of record %d in index node %d too large (%d vs %"
@@ -838,10 +868,11 @@ hfs_cat_traverse(HFS_INFO * hfs,
                 key = (hfs_btree_key_cat *) & node[rec_off];
                 keylen = 2 + tsk_getu16(hfs->fs_info.endian, key->key_len);
 
-                if (keylen > nodesize - rec_off) {
+                // Want a key of at least 6 bytes, the size of the first 2 members of hfs_btree_key_cat
+                if ((keylen < 6) || (keylen > nodesize - rec_off)) {
                     tsk_error_set_errno(TSK_ERR_FS_GENFS);
                     tsk_error_set_errstr
-                        ("hfs_cat_traverse: length of key %d in index node %d too large (%d vs %"
+                        ("hfs_cat_traverse: length of key %d in index node %d out of bounds (6 < %d < %"
                         PRIu16 ")", rec, cur_node, keylen, (nodesize - rec_off));
                     free(node);
                     return 1;
@@ -931,11 +962,23 @@ hfs_cat_traverse(HFS_INFO * hfs,
                 uint8_t retval;
                 int keylen;
 
+                // Make sure node is large enough, note that (rec + 1) * 2 is an offset
+                // relative to the end of node
+                if ((rec + 1) * 2 > (int) nodesize) {
+                    tsk_error_set_errno(TSK_ERR_FS_GENFS);
+                    tsk_error_set_errstr
+                        ("hfs_cat_traverse: offset of record %d in leaf node %d too small (%"
+                        PRIu16 ")", rec, cur_node, nodesize);
+                    free(node);
+                    return 1;
+                }
                 // get the record offset in the node
                 rec_off =
                     tsk_getu16(fs->endian,
                     &node[nodesize - (rec + 1) * 2]);
-                if (rec_off > nodesize) {
+
+                // Need at least 2 bytes for key_len
+                if (rec_off >= nodesize - 2) {
                     tsk_error_set_errno(TSK_ERR_FS_GENFS);
                     tsk_error_set_errstr
                         ("hfs_cat_traverse: offset of record %d in leaf node %d too large (%d vs %"
@@ -948,10 +991,11 @@ hfs_cat_traverse(HFS_INFO * hfs,
                 key = (hfs_btree_key_cat *) & node[rec_off];
                 keylen = 2 + tsk_getu16(hfs->fs_info.endian, key->key_len);
 
-                if (keylen > nodesize - rec_off) {
+                // Want a key of at least 6 bytes, the size of the first 2 members of hfs_btree_key_cat
+                if ((keylen < 6) || (keylen > nodesize - rec_off)) {
                     tsk_error_set_errno(TSK_ERR_FS_GENFS);
                     tsk_error_set_errstr
-                        ("hfs_cat_traverse: length of key %d in leaf node %d too large (%d vs %"
+                        ("hfs_cat_traverse: length of key %d in leaf node %d out of bounds (6 < %d < %"
                         PRIu16 ")", rec, cur_node, keylen, nodesize);
                     free(node);
                     return 1;
@@ -3854,6 +3898,13 @@ hfs_load_extended_attrs(TSK_FS_FILE * fs_file,
         return 0;
     }
 
+    if (attrFile.nodeSize < sizeof(hfs_btree_node)) {
+        error_returned
+            ("hfs_load_extended_attrs: node size too small");
+        close_attr_file(&attrFile);
+        return 1;
+    }
+
     // A place to hold one node worth of data
     nodeData = (uint8_t *) malloc(attrFile.nodeSize);
     if (nodeData == NULL) {
@@ -3953,7 +4004,7 @@ hfs_load_extended_attrs(TSK_FS_FILE * fs_file,
             //uint8_t * nextRecOffsetData = &nodeData[attrFile.nodeSize - 2* (recIndx+2)];
 
             // make sure the record and first fields are in the buffer
-            if (recOffset + 14 > attrFile.nodeSize) {
+            if ((attrFile.nodeSize < 14) || (recOffset >= attrFile.nodeSize - 14)) {
                 error_detected(TSK_ERR_FS_READ,
                     "hfs_load_extended_attrs: Unable to process attribute (offset too big)");
                 goto on_error;
@@ -4010,7 +4061,7 @@ hfs_load_extended_attrs(TSK_FS_FILE * fs_file,
             // make sure the fields we care about are still in the buffer
             // +2 is because key_len doesn't include its own length
             // +4 is because of the amount of data we read from the data
-            if (recOffset + keyLength + 2 + 4 > attrFile.nodeSize) {
+            if ((keyLength > attrFile.nodeSize - 2 - 4) || (recOffset >= attrFile.nodeSize - 2 - 4 - keyLength)) {
                 error_detected(TSK_ERR_FS_READ,
                     "hfs_load_extended_attrs: Unable to process attribute");
                 goto on_error;
@@ -4067,7 +4118,7 @@ hfs_load_extended_attrs(TSK_FS_FILE * fs_file,
             uint32_t keyFileID;
 
             // make sure the record and first fields are in the buffer
-            if (recOffset + 14 > attrFile.nodeSize) {
+            if (recOffset >= attrFile.nodeSize - 14) {
                 error_detected(TSK_ERR_FS_READ,
                     "hfs_load_extended_attrs: Unable to process attribute (offset too big)");
                 goto on_error;
@@ -4120,7 +4171,7 @@ hfs_load_extended_attrs(TSK_FS_FILE * fs_file,
                 // make sure the fields we care about are still in the buffer
                 // +2 because key_len doesn't include its own length
                 // +16 for the amount of data we'll read from data
-                if (recOffset + keyLength + 2 + 16 > attrFile.nodeSize) {
+                if ((attrFile.nodeSize < 2 + 16) || (keyLength > attrFile.nodeSize - 2 - 16) || (recOffset >= attrFile.nodeSize - 2 - 16 - keyLength)) {
                     error_detected(TSK_ERR_FS_READ,
                         "hfs_load_extended_attrs: Unable to process attribute");
                     goto on_error;
@@ -4150,7 +4201,7 @@ hfs_load_extended_attrs(TSK_FS_FILE * fs_file,
 
                 // Check the attribute fits in the node
                 //if (recordType != HFS_ATTR_RECORD_INLINE_DATA) {
-                if (recOffset + keyLength + 2 + attributeLength > attrFile.nodeSize) {
+                if ((attributeLength > attrFile.nodeSize - 2 - 16 - keyLength) || (recOffset >= attrFile.nodeSize - 2 - 16 - keyLength - attributeLength)) {
                     error_detected(TSK_ERR_FS_READ,
                         "hfs_load_extended_attrs: Unable to process attribute");
                     goto on_error;
diff --git a/tsk/fs/iso9660.c b/tsk/fs/iso9660.c
index 779d1cf5c56e06d90cc16a5bf7c0b9740cf458fd..3815517638aeea612adc6003858f6b55ba1590e7 100755
--- a/tsk/fs/iso9660.c
+++ b/tsk/fs/iso9660.c
@@ -90,10 +90,11 @@ iso9660_inode_list_free(TSK_FS_INFO * fs)
  * @param buf Buffer of data to process
  * @param count Length of buffer in bytes.
  * @param hFile File handle to print details to  (or NULL for no printing)
+ * @param recursion_depth Recursion depth to limit the number of self-calls
  * @returns NULL on error
  */
 static rockridge_ext *
-parse_susp(TSK_FS_INFO * fs, char *buf, int count, FILE * hFile)
+parse_susp(TSK_FS_INFO * fs, char *buf, int count, FILE * hFile, int recursion_depth)
 {
     rockridge_ext *rr;
     ISO_INFO *iso = (ISO_INFO *) fs;
@@ -103,6 +104,11 @@ parse_susp(TSK_FS_INFO * fs, char *buf, int count, FILE * hFile)
     if (tsk_verbose)
         tsk_fprintf(stderr, "parse_susp: count is: %d\n", count);
 
+    // 32 is an arbitrary chosen value.
+    if (recursion_depth > 32) {
+        return NULL;
+    }
+
     // allocate the output data structure
     rr = (rockridge_ext *) tsk_malloc(sizeof(rockridge_ext));
     if (rr == NULL) {
@@ -156,8 +162,17 @@ parse_susp(TSK_FS_INFO * fs, char *buf, int count, FILE * hFile)
                     ssize_t cnt =
                         tsk_fs_read(fs, off, buf2,
                         tsk_getu32(fs->endian, ce->celen_m));
+
                     if (cnt == tsk_getu32(fs->endian, ce->celen_m)) {
-                        parse_susp(fs, buf2, (int) cnt, hFile);
+                        rockridge_ext *rr_sub_entry = parse_susp(fs, buf2, (int) cnt, hFile, recursion_depth + 1);
+
+                        // Prevent an infinite loop
+                        if (rr_sub_entry == NULL) {
+                          free(buf2);
+                          free(rr);
+                          return NULL;
+			}
+                        free(rr_sub_entry);
                     }
                     else if (tsk_verbose) {
                         fprintf(stderr,
@@ -298,7 +313,7 @@ parse_susp(TSK_FS_INFO * fs, char *buf, int count, FILE * hFile)
 
             rr_nm = (iso9660_rr_nm_entry *) buf;
 
-            if ((uintptr_t)&rr_nm->name[0] + (int) rr_nm->len - 5 - 1> (uintptr_t)end) {
+            if ((rr_nm->len < 6) || ((uintptr_t)&rr_nm->name[0] + (int) rr_nm->len - 5 - 1> (uintptr_t)end)) {
                 if (tsk_verbose) 
                     tsk_fprintf(stderr, "parse_susp: not enough room for RR alternative name\n");
                 break;
@@ -537,6 +552,8 @@ iso9660_load_inodes_dir(TSK_FS_INFO * fs, TSK_OFF_T a_offs, int count,
                         if (tsk_verbose)
                             tsk_fprintf(stderr,
                                         "iso9660_load_inodes_dir: UTF-16 name length is too large, bailing\n");
+                        free(in_node);
+                        in_node = NULL;
                         break;
                     }
 
@@ -582,6 +599,8 @@ iso9660_load_inodes_dir(TSK_FS_INFO * fs, TSK_OFF_T a_offs, int count,
                         if (tsk_verbose)
                             tsk_fprintf(stderr,
                                         "iso9660_load_inodes_dir: ASCII name length is too large, bailing\n");
+                        free(in_node);
+                        in_node = NULL;
                         break;
                     }
 
@@ -595,6 +614,8 @@ iso9660_load_inodes_dir(TSK_FS_INFO * fs, TSK_OFF_T a_offs, int count,
                     tsk_error_set_errno(TSK_ERR_FS_ARG);
                     tsk_error_set_errstr
                         ("Invalid ctype in iso9660_load_inodes_dir");
+                    free(in_node);
+                    in_node = NULL;
                     return -1;
                 }
 
@@ -618,6 +639,7 @@ iso9660_load_inodes_dir(TSK_FS_INFO * fs, TSK_OFF_T a_offs, int count,
                         tsk_fprintf(stderr,
                                     "iso9660_load_inodes_dir: length of name after processing is 0. bailing\n");
                     free(in_node);
+                    in_node = NULL;
                     break;
                     
                 }
@@ -637,6 +659,7 @@ iso9660_load_inodes_dir(TSK_FS_INFO * fs, TSK_OFF_T a_offs, int count,
                                 "iso9660_load_inodes_dir: file starts past end of image (%"PRIu32"). bailing\n",
                                 tsk_getu32(fs->endian, dentry->ext_loc_m));
                 free(in_node);
+                in_node = NULL;
                 break;
             }
             in_node->offset =
@@ -648,6 +671,7 @@ iso9660_load_inodes_dir(TSK_FS_INFO * fs, TSK_OFF_T a_offs, int count,
                                 "iso9660_load_inodes_dir: file ends past end of image (%"PRIu32" bytes). bailing\n",
                                 tsk_getu32(fs->endian, in_node->inode.dr.data_len_m) + in_node->offset);
                 free(in_node);
+                in_node = NULL;
                 break;
             }
             /* record size to make sure fifos show up as unique files */
@@ -675,12 +699,13 @@ iso9660_load_inodes_dir(TSK_FS_INFO * fs, TSK_OFF_T a_offs, int count,
                 in_node->inode.rr =
                     parse_susp(fs,
                     &buf[b_offs + sizeof(iso9660_dentry) + dentry->fi_len],
-                    extra_bytes, NULL);
+                    extra_bytes, NULL, 0);
                 if (in_node->inode.rr == NULL) {
                     if (tsk_verbose)
                         tsk_fprintf(stderr,
                                     "iso9660_load_inodes_dir: parse_susp returned error (%s). bailing\n", tsk_error_get());
                     free(in_node);
+                    in_node = NULL;
                     break;
                 }
                 
@@ -784,7 +809,9 @@ iso9660_load_inodes_pt_joliet(TSK_FS_INFO * fs, iso9660_svd * svd,
     pt_len = tsk_getu32(fs->endian, svd->pt_size_m);
 
     while (pt_len > 0) {
-        char utf16_buf[ISO9660_MAXNAMLEN_JOL + 1];      // UTF-16 name from img
+        // Since further on cnt + 1 is used and cnt can be ISO9660_MAXNAMLEN_JOL
+        // + 2 ensures utf16_buf is sufficiently large.
+        char utf16_buf[ISO9660_MAXNAMLEN_JOL + 2];      // UTF-16 name from img
         char utf8buf[2 * ISO9660_MAXNAMLEN_JOL + 1];    // UTF-8 version of name
         int readlen;
         TSK_OFF_T extent;       /* offset of extent for current directory */
@@ -812,7 +839,7 @@ iso9660_load_inodes_pt_joliet(TSK_FS_INFO * fs, iso9660_svd * svd,
         if (dir.len_di > ISO9660_MAXNAMLEN_JOL)
             readlen = ISO9660_MAXNAMLEN_JOL;
 
-        memset(utf16_buf, 0, ISO9660_MAXNAMLEN_JOL);
+        memset(utf16_buf, 0, ISO9660_MAXNAMLEN_JOL + 2);
         /* get UCS-2 filename for the entry */
         cnt = tsk_fs_read(fs, pt_offs, (char *) utf16_buf, readlen);
         if (cnt != dir.len_di) {
@@ -2123,10 +2150,12 @@ iso9660_istat(TSK_FS_INFO * fs, TSK_FS_ISTAT_FLAG_ENUM istat_flags, FILE * hFile
             cnt =
                 tsk_fs_read(fs, dinode->susp_off, buf2,
                 (size_t) dinode->susp_len);
+
+            rockridge_ext *rr_entry = NULL;
             if (cnt == dinode->susp_len) {
-                parse_susp(fs, buf2, (int) cnt, hFile);
+                rr_entry = parse_susp(fs, buf2, (int) cnt, hFile, 0);
             }
-            else {
+            if (rr_entry == NULL) {
                 fprintf(hFile, "Error reading Rock Ridge Location\n");
                 if (tsk_verbose) {
                     fprintf(stderr,
diff --git a/tsk/fs/ntfs.c b/tsk/fs/ntfs.c
index 631fe2ff38cb83cc62ced5f6eb491c2314fcc2ac..4f73e55239e78e415b23570b51c8c038ed290c59 100755
--- a/tsk/fs/ntfs.c
+++ b/tsk/fs/ntfs.c
@@ -375,9 +375,20 @@ ntfs_dinode_lookup(NTFS_INFO * a_ntfs, char *a_buf, TSK_INUM_T a_mftnum)
             ("dinode_lookup: More Update Sequence Entries than MFT size");
         return TSK_COR;
     }
-    if (tsk_getu16(fs->endian, mft->upd_off) + 
-            sizeof(ntfs_upd) + 
-            2*(tsk_getu16(fs->endian, mft->upd_cnt) - 1) > a_ntfs->mft_rsize_b) {
+    uint16_t upd_cnt = tsk_getu16(fs->endian, mft->upd_cnt);
+    uint16_t upd_off = tsk_getu16(fs->endian, mft->upd_off);
+
+    // Make sure upd_cnt > 0 to prevent an integer wrap around.
+    if ((upd_cnt == 0) || (upd_cnt > (((a_ntfs->mft_rsize_b) / 2) + 1))) {
+        tsk_error_reset();
+        tsk_error_set_errno(TSK_ERR_FS_INODE_COR);
+        tsk_error_set_errstr
+            ("dinode_lookup: Invalid update count value out of bounds");
+        return TSK_COR;
+    }
+    size_t mft_rsize_b = ((size_t) upd_cnt - 1) * 2;
+
+    if ((size_t) upd_off + sizeof(ntfs_upd) > (a_ntfs->mft_rsize_b - mft_rsize_b)) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_FS_INODE_COR);
         tsk_error_set_errstr
@@ -386,9 +397,8 @@ ntfs_dinode_lookup(NTFS_INFO * a_ntfs, char *a_buf, TSK_INUM_T a_mftnum)
     }
 
     /* Apply the update sequence structure template */
-    upd =
-        (ntfs_upd *) ((uintptr_t) a_buf + tsk_getu16(fs->endian,
-            mft->upd_off));
+
+    upd = (ntfs_upd *) ((uintptr_t) a_buf + upd_off);
     /* Get the sequence value that each 16-bit value should be */
     sig_seq = tsk_getu16(fs->endian, upd->upd_val);
     /* cycle through each sector */
@@ -594,7 +604,8 @@ ntfs_make_data_run(NTFS_INFO * ntfs, TSK_OFF_T start_vcn,
         int64_t addr_offset = 0;
 
         /* allocate a new tsk_fs_attr_run */
-        if ((data_run = tsk_fs_attr_run_alloc()) == NULL) {
+        data_run = tsk_fs_attr_run_alloc();
+        if (data_run == NULL) {
             tsk_fs_attr_run_free(*a_data_run_head);
             *a_data_run_head = NULL;
             return TSK_ERR;
@@ -2049,8 +2060,10 @@ ntfs_proc_attrseq(NTFS_INFO * ntfs,
                 tsk_error_set_errno(TSK_ERR_FS_CORRUPT);
                 tsk_error_set_errstr("ntfs_proc_attrseq: Compression unit size 2^%d too large",
                     tsk_getu16(fs->endian, attr->c.nr.compusize));
-                if (fs_attr_run)
+                if (fs_attr_run) {
                     tsk_fs_attr_run_free(fs_attr_run);
+                    fs_attr_run = NULL;
+                }
                 return TSK_COR;
             }
 
@@ -2090,9 +2103,10 @@ ntfs_proc_attrseq(NTFS_INFO * ntfs,
                             TSK_FS_ATTR_RES)) == NULL) {
                     tsk_error_errstr2_concat(" - proc_attrseq: getnew");
                     // JRB: Coverity found leak.
-                    if (fs_attr_run)
+                    if (fs_attr_run) {
                         tsk_fs_attr_run_free(fs_attr_run);
-                    fs_attr_run = NULL;
+                        fs_attr_run = NULL;
+                    }
                     return TSK_ERR;
                 }
 
@@ -2132,10 +2146,15 @@ ntfs_proc_attrseq(NTFS_INFO * ntfs,
                     tsk_error_errstr2_concat("- proc_attrseq: set run");
                     
                     // If the run wasn't saved to the attribute, free it now
-                    if (fs_attr_run && (fs_attr->nrd.run == NULL))
+                    if (fs_attr_run && (fs_attr->nrd.run == NULL)) {
                         tsk_fs_attr_run_free(fs_attr_run);
+                        fs_attr_run = NULL;
+                    }
                     return TSK_COR;
                 }
+                // fs_file has taken over management of fs_attr_run
+                fs_attr_run = NULL;
+
                 // set the special functions
                 if (fs_file->meta->flags & TSK_FS_META_FLAG_COMP) {
                     fs_attr->w = ntfs_attr_walk_special;
@@ -2146,6 +2165,10 @@ ntfs_proc_attrseq(NTFS_INFO * ntfs,
             else {
                 if (tsk_fs_attr_add_run(fs, fs_attr, fs_attr_run)) {
                     tsk_error_errstr2_concat(" - proc_attrseq: put run");
+                    if (fs_attr_run) {
+                        tsk_fs_attr_run_free(fs_attr_run);
+                        fs_attr_run = NULL;
+                    }
                     return TSK_COR;
                 }
             }
@@ -2598,6 +2621,8 @@ ntfs_proc_attrlist(NTFS_INFO * ntfs,
             free(mft);
             free(map);
             free(buf);
+            if (mftSeenList != NULL)
+                tsk_stack_free(mftSeenList);
             tsk_error_errstr2_concat(" - proc_attrlist");
             return TSK_ERR;
         }
@@ -2627,6 +2652,8 @@ ntfs_proc_attrlist(NTFS_INFO * ntfs,
                 free(mft);
                 free(map);
                 free(buf);
+                if (mftSeenList != NULL)
+                    tsk_stack_free(mftSeenList);
                 return TSK_COR;
             }
         }
@@ -2654,6 +2681,8 @@ ntfs_proc_attrlist(NTFS_INFO * ntfs,
             free(mft);
             free(map);
             free(buf);
+            if (mftSeenList != NULL)
+                tsk_stack_free(mftSeenList);
             return TSK_COR;
         }
 
diff --git a/tsk/fs/unix_misc.c b/tsk/fs/unix_misc.c
index 3f114c8a2c7b2f88b8fc585bb4f423c5cb10bae7..896bba66ee4ad497223023b5262a4be3376884c2 100644
--- a/tsk/fs/unix_misc.c
+++ b/tsk/fs/unix_misc.c
@@ -180,6 +180,7 @@ unix_make_data_run_indirect(TSK_FS_INFO * fs, TSK_FS_ATTR * fs_attr,
             }
             tsk_error_set_errstr2("unix_make_data_run_indir: Block %"
                 PRIuDADDR, addr);
+            free(data_run);
             return -1;
         }
     }
@@ -187,6 +188,8 @@ unix_make_data_run_indirect(TSK_FS_INFO * fs, TSK_FS_ATTR * fs_attr,
     // save the run
     tsk_fs_attr_append_run(fs, fs_attr_indir, data_run);
 
+    data_run = NULL;
+
     // convert the raw addresses to the correct endian ordering
     if ((fs->ftype == TSK_FS_TYPE_FFS1)
         || (fs->ftype == TSK_FS_TYPE_FFS1B)
@@ -232,10 +235,10 @@ unix_make_data_run_indirect(TSK_FS_INFO * fs, TSK_FS_ATTR * fs_attr,
         }
     }
 
-    if (retval == -1)
+    if (retval == -1) {
         return -1;
-    else
-        return length - length_remain;
+    }
+    return length - length_remain;
 }
 
 
diff --git a/win32/tsk-win.sln b/win32/tsk-win.sln
index 7aa2bca8cc9f1672907d050c358d28e5ba5adcd8..58c4a67e4a37e816e88010adda9f14c97aea42ac 100644
--- a/win32/tsk-win.sln
+++ b/win32/tsk-win.sln
@@ -159,6 +159,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Rejistry++", "rejistry++\Re
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pstat", "pstat\pstat.vcxproj", "{5D75FBFB-539A-4014-ACEB-520BB1451F00}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tsk_imageinfo", "tsk_imageinfo\tsk_imageinfo.vcxproj", "{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug_NoLibs|Win32 = Debug_NoLibs|Win32
@@ -697,6 +699,22 @@ Global
 		{5D75FBFB-539A-4014-ACEB-520BB1451F00}.Release|Win32.Build.0 = Release|Win32
 		{5D75FBFB-539A-4014-ACEB-520BB1451F00}.Release|x64.ActiveCfg = Release|x64
 		{5D75FBFB-539A-4014-ACEB-520BB1451F00}.Release|x64.Build.0 = Release|x64
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Debug|Win32.Build.0 = Debug|Win32
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Debug|x64.ActiveCfg = Debug|x64
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Debug|x64.Build.0 = Debug|x64
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Release_NoLibs|Win32.ActiveCfg = Release_NoLibs|Win32
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Release_NoLibs|Win32.Build.0 = Release_NoLibs|Win32
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Release_NoLibs|x64.ActiveCfg = Release_NoLibs|x64
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Release_NoLibs|x64.Build.0 = Release_NoLibs|x64
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Release|Win32.ActiveCfg = Release|Win32
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Release|Win32.Build.0 = Release|Win32
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Release|x64.ActiveCfg = Release|x64
+		{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/win32/tsk_imageinfo/tsk_imageinfo.vcxproj b/win32/tsk_imageinfo/tsk_imageinfo.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..046e460f9f886bb6a8bae54bf63368d3464e2702
--- /dev/null
+++ b/win32/tsk_imageinfo/tsk_imageinfo.vcxproj
@@ -0,0 +1,334 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug_NoLibs|Win32">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release_NoLibs|Win32">
+      <Configuration>Release_NoLibs</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release_NoLibs|x64">
+      <Configuration>Release_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{09E82DEB-4BC3-44B5-A9F6-4D65F885F88C}</ProjectGuid>
+    <RootNamespace>tsk_imageinfo</RootNamespace>
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <CLRSupport>true</CLRSupport>
+    <PlatformToolset>v140_xp</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <CLRSupport>false</CLRSupport>
+    <PlatformToolset>v140_xp</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <CLRSupport>true</CLRSupport>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v140_xp</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_NoLibs|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <CLRSupport>false</CLRSupport>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v140_xp</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <CLRSupport>false</CLRSupport>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v140_xp</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <CLRSupport>false</CLRSupport>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v140_xp</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <CLRSupport>true</CLRSupport>
+    <PlatformToolset>v140_xp</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <CLRSupport>false</CLRSupport>
+    <PlatformToolset>v140_xp</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_NoLibs|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_NoLibs|x64'">$(OutDir)</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_NoLibs|Win32'">$(IntDir)</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_NoLibs|x64'">$(IntDir)</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release_NoLibs|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release_NoLibs|x64'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(IntDir)</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(IntDir)</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
+    <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</IgnoreImportLibrary>
+    <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release_NoLibs|x64'">false</IgnoreImportLibrary>
+  </PropertyGroup>
+  <Import Project="$(SolutionDir)\NugetPackages.props" />
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CRT_SECURE_NO_DEPRECATE;_ITERATOR_DEBUG_LEVEL=2;WINVER=0x0601;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libvhdi.lib;libvmdk.lib;libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(TskNugetLibs);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AssemblyDebug>true</AssemblyDebug>
+      <TargetMachine>MachineX86</TargetMachine>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CRT_SECURE_NO_DEPRECATE;WINVER=0x0601;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libvhdi.lib;libvmdk.lib;libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(TskNugetLibs);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AssemblyDebug>true</AssemblyDebug>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CRT_SECURE_NO_DEPRECATE;WINVER=0x0501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libvhdi.lib;libvmdk.lib;libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(TskNugetLibs);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <TargetMachine>MachineX86</TargetMachine>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_NoLibs|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CRT_SECURE_NO_DEPRECATE;WINVER=0x0601;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAsManaged>false</CompileAsManaged>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <TargetMachine>MachineX86</TargetMachine>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CRT_SECURE_NO_DEPRECATE;WINVER=0x0601;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libvhdi.lib;libvmdk.lib;libewf.lib;zlib.lib;libcrypto.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(TskNugetLibs);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_NoLibs|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CRT_SECURE_NO_DEPRECATE;WINVER=0x0601;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAsManaged>false</CompileAsManaged>
+      <MinimalRebuild>false</MinimalRebuild>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <ExceptionHandling>Async</ExceptionHandling>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CRT_SECURE_NO_DEPRECATE;WINVER=0x0601;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AssemblyDebug>true</AssemblyDebug>
+      <TargetMachine>MachineX86</TargetMachine>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CRT_SECURE_NO_DEPRECATE;WINVER=0x0601;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AssemblyDebug>true</AssemblyDebug>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Reference Include="System">
+      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
+    </Reference>
+    <Reference Include="System.Data">
+      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
+    </Reference>
+    <Reference Include="System.Xml">
+      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\tools\autotools\tsk_imageinfo.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\libtsk\libtsk.vcxproj">
+      <Project>{76efc06c-1f64-4478-abe8-79832716b393}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/win32/tsk_imageinfo/tsk_imageinfo.vcxproj.filters b/win32/tsk_imageinfo/tsk_imageinfo.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..8e8d4e7431d53e1e092d83f756c6cf1e522eb74b
--- /dev/null
+++ b/win32/tsk_imageinfo/tsk_imageinfo.vcxproj.filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\tools\autotools\tsk_imageinfo.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file