diff --git a/bindings/java/doxygen/artifact_catalog.dox b/bindings/java/doxygen/artifact_catalog.dox
index 945f94ac40b9055e2b61549b8076e28102200050..39d548bf7df9162b084a5f410f53da9312721e10 100644
--- a/bindings/java/doxygen/artifact_catalog.dox
+++ b/bindings/java/doxygen/artifact_catalog.dox
@@ -195,13 +195,12 @@ Details about a device data source.
 ## TSK_EMAIL_MSG
 An email message found in an application file or database.
 
-### REQUIRED ATTRIBUTES
+### OPTIONAL ATTRIBUTES
 - At least one of:
 -  TSK_EMAIL_CONTENT_HTML (Representation of email as HTML)
 -  TSK_EMAIL_CONTENT_PLAIN (Representation of email as plain text)
 -  TSK_EMAIL_CONTENT_RTF (Representation of email as RTF)
 
-### OPTIONAL ATTRIBUTES
 - TSK_DATETIME_RCVD (When email message was received, in seconds since 1970-01-01T00:00:00Z)
 - TSK_DATETIME_SENT (When email message was sent, in seconds since 1970-01-01T00:00:00Z)
 - TSK_EMAIL_BCC (BCC'd recipient, multiple recipients should be in a comma separated string)
@@ -415,15 +414,6 @@ Indication that the source file matches some set of criteria (possibly user defi
 
 
 
----
-## TSK_IP_DHCP
-DHCP information that is stored.
-
-### REQUIRED ATTRIBUTES
-- TSK_NAME (Description of Information)
-- TSK_VALUE (Value of Information)
-
-
 ---
 ## TSK_KEYWORD_HIT
 Indication that the source artifact or file contains a keyword. Keywords are grouped into named sets.
diff --git a/bindings/java/src/org/sleuthkit/datamodel/AbstractContent.java b/bindings/java/src/org/sleuthkit/datamodel/AbstractContent.java
index b2c7aa3e34966886bbd2e53a255b38723c8fe78b..eec894d2bd1581243cd0e6a25d33c3983c464831 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/AbstractContent.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/AbstractContent.java
@@ -42,8 +42,8 @@ public abstract class AbstractContent implements Content {
 	private final SleuthkitCase db;
 	private final long objId;
 	private final String name;
-	private Content parent;
-	private String uniquePath;
+	private volatile Content parent;
+	private volatile String uniquePath;
 	protected long parentId;
 	private volatile boolean hasChildren;
 	private volatile boolean checkedHasChildren;
@@ -72,17 +72,22 @@ public String getName() {
 	 * interleaving forward slashes).
 	 */
 	@Override
-	public synchronized String getUniquePath() throws TskCoreException {
+	public String getUniquePath() throws TskCoreException {
+		// It is possible that multiple threads could be doing this calculation
+		// simultaneously, but it's worth the potential extra processing to prevent deadlocks.
 		if (uniquePath == null) {
-			uniquePath = "";
+			String tempUniquePath = "";
 			if (!name.isEmpty()) {
-				uniquePath = "/" + getName();
+				tempUniquePath = "/" + getName();
 			}
 
 			Content myParent = getParent();
 			if (myParent != null) {
-				uniquePath = myParent.getUniquePath() + uniquePath;
+				tempUniquePath = myParent.getUniquePath() + tempUniquePath;
 			}
+			
+			// Don't update uniquePath until it is complete.
+			uniquePath = tempUniquePath;
 		}
 		return uniquePath;
 	}
@@ -114,7 +119,9 @@ public int getChildrenCount() throws TskCoreException {
 	}
 
 	@Override
-	public synchronized Content getParent() throws TskCoreException {
+	public Content getParent() throws TskCoreException {
+		// It is possible that multiple threads could be doing this calculation
+		// simultaneously, but it's worth the potential extra processing to prevent deadlocks.
 		if (parent == null) {
 			ObjectInfo parentInfo;
 			parentInfo = db.getParentInfo(this);
diff --git a/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java b/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java
index 61aa3e815e32b777182e6478ba562370208d668a..4231c89537ddddd1982644761e523f2230ff25a6 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java
@@ -62,8 +62,8 @@ public class BlackboardArtifact implements Content {
 	private final SleuthkitCase sleuthkitCase;
 	private final List<BlackboardAttribute> attrsCache = new ArrayList<BlackboardAttribute>();
 	private boolean loadedCacheFromDb = false;
-	private Content parent;
-	private String uniquePath;
+	private volatile Content parent;
+	private volatile String uniquePath;
 
 	private byte[] contentBytes = null;
 
@@ -432,21 +432,27 @@ public void addAttributes(Collection<BlackboardAttribute> attributes, final Sleu
 	 * @throws org.sleuthkit.datamodel.TskCoreException
 	 */
 	@Override
-	public synchronized String getUniquePath() throws TskCoreException {
-
-		// Return the path of the parrent file
+	public String getUniquePath() throws TskCoreException {
+		// Return the path of the parent file
+		// It is possible that multiple threads could be doing this calculation
+		// simultaneously, but it's worth the potential extra processing to prevent deadlocks.
 		if (uniquePath == null) {
-			uniquePath = "";
+			String tempUniquePath = "";
 			Content myParent = getParent();
 			if (myParent != null) {
-				uniquePath = myParent.getUniquePath();
+				tempUniquePath = myParent.getUniquePath();
 			}
+			
+			// Don't update uniquePath until it is complete.
+			uniquePath = tempUniquePath;
 		}
 		return uniquePath;
 	}
 
 	@Override
-	public synchronized Content getParent() throws TskCoreException {
+	public Content getParent() throws TskCoreException {
+		// It is possible that multiple threads could be doing this calculation
+		// simultaneously, but it's worth the potential extra processing to prevent deadlocks.
 		if (parent == null) {
 			ObjectInfo parentInfo;
 			parentInfo = getSleuthkitCase().getParentInfo(this);
@@ -1363,11 +1369,6 @@ public enum ARTIFACT_TYPE implements SleuthkitVisitableItem {
 		 */
 		TSK_SCREEN_SHOTS(60, "TSK_SCREEN_SHOTS",
 				bundle.getString("BlackboardArtifact.tskScreenShots.text")),
-		/**
-		 * DHCP Information that is store for a device.
-		 */
-		TSK_IP_DHCP(61, "TSK_IP_DHCP",
-				bundle.getString("BlackboardArtifact.tskDhcpInfo.text")),
 		/**
 		 * Notifications Sent to User.
 		 */
diff --git a/bindings/java/src/org/sleuthkit/datamodel/FsContent.java b/bindings/java/src/org/sleuthkit/datamodel/FsContent.java
index dba56f8a6c1fd2b348c8c778d42f7e952c444eea..56e872ecaa9c2be066f583412e9ae2c48e99a856 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/FsContent.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/FsContent.java
@@ -39,7 +39,7 @@
 public abstract class FsContent extends AbstractFile {
 
 	private static final Logger logger = Logger.getLogger(FsContent.class.getName());
-	private String uniquePath;
+	private volatile String uniquePath;
 	private List<String> metaDataText = null;
 	private volatile FileSystem parentFileSystem;
 
@@ -261,7 +261,9 @@ public Content getDataSource() throws TskCoreException {
 	 * @throws TskCoreException if there is an error querying the case database.
 	 */
 	@Override
-	public synchronized String getUniquePath() throws TskCoreException {
+	public String getUniquePath() throws TskCoreException {
+		// It is possible that multiple threads could be doing this calculation
+		// simultaneously, but it's worth the potential extra processing to prevent deadlocks.
 		if (uniquePath == null) {
 			StringBuilder sb = new StringBuilder();
 			sb.append(getFileSystem().getUniquePath());
diff --git a/bindings/java/src/org/sleuthkit/datamodel/Volume.java b/bindings/java/src/org/sleuthkit/datamodel/Volume.java
index 75778e23e56dc42d880370e9bf7516abce164e2c..8350105e5abd072ade826f7bc11e78e0db691bda 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/Volume.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/Volume.java
@@ -34,7 +34,7 @@ public class Volume extends AbstractContent {
 	private long flags;
 	private String desc;
 	private volatile long volumeHandle = 0;
-	private String uniquePath;
+	private volatile String uniquePath;
 	private static ResourceBundle bundle = ResourceBundle.getBundle("org.sleuthkit.datamodel.Bundle");
 
 	/**
@@ -107,18 +107,23 @@ public long getSize() {
 	}
 
 	@Override
-	public synchronized String getUniquePath() throws TskCoreException {
+	public String getUniquePath() throws TskCoreException {
+		// It is possible that multiple threads could be doing this calculation
+		// simultaneously, but it's worth the potential extra processing to prevent deadlocks.
 		if(uniquePath == null) {
-			uniquePath = "";
+			String tempUniquePath = "";
 			String name = getName();
 			if (!name.isEmpty()) {
-				uniquePath = "/vol_" + name; //NON-NLS
+				tempUniquePath = "/vol_" + name; //NON-NLS
 			}
 
 			Content myParent = getParent();
 			if (myParent != null) {
-				uniquePath = myParent.getUniquePath() + uniquePath;
+				tempUniquePath = myParent.getUniquePath() + tempUniquePath;
 			}
+			
+			// Don't update uniquePath until it is complete.
+			uniquePath = tempUniquePath;
 		}
 		return uniquePath;
 	}