diff --git a/bindings/java/src/org/sleuthkit/datamodel/OsAccountManager.java b/bindings/java/src/org/sleuthkit/datamodel/OsAccountManager.java
index 3e883622979eebc9656d2ef50970ed47a959ae91..24297c6f4cc51398de0b39ef1b48b023a64c34c0 100755
--- a/bindings/java/src/org/sleuthkit/datamodel/OsAccountManager.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/OsAccountManager.java
@@ -1277,26 +1277,31 @@ private <T> void updateAccountColumn(long accountObjId, String colName, T colVal
 				+ " SET " + colName + " = ? "
 				+ " WHERE os_account_obj_id = ?";
 
-		PreparedStatement preparedStatement = connection.getPreparedStatement(updateSQL, Statement.NO_GENERATED_KEYS);
-		preparedStatement.clearParameters();
+		db.acquireSingleUserCaseWriteLock();
+		try {
+			PreparedStatement preparedStatement = connection.getPreparedStatement(updateSQL, Statement.NO_GENERATED_KEYS);
+			preparedStatement.clearParameters();
 
-		if (Objects.isNull(colValue)) {
-			preparedStatement.setNull(1, Types.NULL); // handle null value
-		} else {
-			if (colValue instanceof String) {
-				preparedStatement.setString(1, (String) colValue);
-			} else if (colValue instanceof Long) {
-				preparedStatement.setLong(1, (Long) colValue);
-			} else if (colValue instanceof Integer) {
-				preparedStatement.setInt(1, (Integer) colValue);
+			if (Objects.isNull(colValue)) {
+				preparedStatement.setNull(1, Types.NULL); // handle null value
 			} else {
-				throw new TskCoreException(String.format("Unhandled column data type received while updating the account (%d) ", accountObjId));
+				if (colValue instanceof String) {
+					preparedStatement.setString(1, (String) colValue);
+				} else if (colValue instanceof Long) {
+					preparedStatement.setLong(1, (Long) colValue);
+				} else if (colValue instanceof Integer) {
+					preparedStatement.setInt(1, (Integer) colValue);
+				} else {
+					throw new TskCoreException(String.format("Unhandled column data type received while updating the account (%d) ", accountObjId));
+				}
 			}
-		}
 
-		preparedStatement.setLong(2, accountObjId);
-		
-		connection.executeUpdate(preparedStatement);
+			preparedStatement.setLong(2, accountObjId);
+
+			connection.executeUpdate(preparedStatement);
+		} finally {
+			db.releaseSingleUserCaseWriteLock();
+		}
 	}
 	
 	/**
@@ -1444,16 +1449,19 @@ private OsAccountUpdateResult updateOsAccountCore(OsAccount osAccount, String ad
 				updateStatusCode = OsAccountUpdateStatus.UPDATED;
 			}
 
-			// update signature if needed
-			if (updateStatusCode == OsAccountUpdateStatus.UPDATED) {
-				String newSignature = getOsAccountSignature(address, loginName);
-				updateAccountSignature(osAccount.getId(), newSignature, connection);
-			}
-
 			// if nothing is changed, return
 			if (updateStatusCode == OsAccountUpdateStatus.NO_CHANGE) {
 				return new OsAccountUpdateResult(updateStatusCode, osAccount);
 			}
+
+			// update signature if needed, based on the most current addr/loginName
+			OsAccount currAccount = getOsAccountByObjectId(osAccount.getId(), connection);
+			String newAddress = currAccount.getAddr().orElse(null);
+			String newLoginName = currAccount.getLoginName().orElse(null);
+
+			String newSignature = getOsAccountSignature(newAddress, newLoginName);
+			updateAccountSignature(osAccount.getId(), newSignature, connection);
+
 			// get the updated account from database
 			updatedAccount = getOsAccountByObjectId(osAccount.getId(), connection);
 
@@ -1467,7 +1475,6 @@ private OsAccountUpdateResult updateOsAccountCore(OsAccount osAccount, String ad
 		}
 	}
 
-	
 	/**
 	 * Returns a list of hosts where the OsAccount has appeared.
 	 *
diff --git a/bindings/java/src/org/sleuthkit/datamodel/OsAccountRealmManager.java b/bindings/java/src/org/sleuthkit/datamodel/OsAccountRealmManager.java
index c9ebe104eb3b02a50ea099822e1a590233a0bea0..f3b3751415e00671e658fad7adef03e87590109c 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/OsAccountRealmManager.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/OsAccountRealmManager.java
@@ -24,8 +24,10 @@
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.sql.Types;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.UUID;
 import java.util.logging.Logger;
@@ -303,74 +305,113 @@ public OsRealmUpdateResult updateRealm(OsAccountRealm realm, String realmAddr, S
 	 * @throws TskCoreException If there is a database error or if a realm
 	 *                          already exists with that information.
 	 */
-	private OsRealmUpdateResult updateRealm(OsAccountRealm realm, String realmAddr, String realmName,  CaseDbConnection connection) throws TskCoreException {
-		
+	private OsRealmUpdateResult updateRealm(OsAccountRealm realm, String realmAddr, String realmName, CaseDbConnection connection) throws TskCoreException {
+
 		// need at least one of the two
 		if (StringUtils.isBlank(realmAddr) && StringUtils.isBlank(realmName)) {
 			throw new TskCoreException("Realm address or name is required to update realm.");
 		}
-		
+
 		OsRealmUpdateStatus updateStatusCode = OsRealmUpdateStatus.NO_CHANGE;
 		OsAccountRealm updatedRealm = null;
-		
-		List<String> realmNames = realm.getRealmNames();
-		String currRealmName = realmNames.isEmpty() ? null : realmNames.get(0);	// currently there is only one name.
-		String currRealmAddr = realm.getRealmAddr().orElse(null);
-		
-		
-		// set name and address to new values only if the current value is blank and the new value isn't.		
-		String newRealmAddr;
-		if ( (StringUtils.isBlank(currRealmAddr) && StringUtils.isNotBlank(realmAddr))) {
-			newRealmAddr = realmAddr;
-			updateStatusCode = OsRealmUpdateStatus.UPDATED;
-		} else {
-			newRealmAddr = currRealmAddr;
-		}
-		
-		String newRealmName;
-		if (StringUtils.isBlank(currRealmName) && StringUtils.isNotBlank(realmName)) {
-			newRealmName = realmName;
-			updateStatusCode = OsRealmUpdateStatus.UPDATED;
-		} else {
-			newRealmName = currRealmName;
-		}
-		
-		// make new signature
-		String newSignature = makeRealmSignature(newRealmAddr, newRealmName, realm.getScopeHost().orElse(null));
-		
-		// if nothing is to be changed, return
-		if ( updateStatusCode == OsRealmUpdateStatus.NO_CHANGE) {
-			return new OsRealmUpdateResult(updateStatusCode, realm);
-		}
-		
-		
+
 		db.acquireSingleUserCaseWriteLock();
 		try {
-			// We only alow realm addr, name and signature to be updated at this time. 
+			List<String> realmNames = realm.getRealmNames();
+			String currRealmName = realmNames.isEmpty() ? null : realmNames.get(0);	// currently there is only one name.
+			String currRealmAddr = realm.getRealmAddr().orElse(null);
+
+			// set name and address to new values only if the current value is blank and the new value isn't.		
+			if ((StringUtils.isBlank(currRealmAddr) && StringUtils.isNotBlank(realmAddr))) {
+				updateRealmColumn(realm.getRealmId(), "realm_addr", realmAddr, connection);
+				updateStatusCode = OsRealmUpdateStatus.UPDATED;
+			}
+
+			if (StringUtils.isBlank(currRealmName) && StringUtils.isNotBlank(realmName)) {
+				updateRealmColumn(realm.getRealmId(), "realm_name", realmName, connection);
+				updateStatusCode = OsRealmUpdateStatus.UPDATED;
+			}
+
+			// if nothing is to be changed, return
+			if (updateStatusCode == OsRealmUpdateStatus.NO_CHANGE) {
+				return new OsRealmUpdateResult(updateStatusCode, realm);
+			}
+
+			// update realm signature - based on the most current address and name
+			OsAccountRealm currRealm = getRealmByRealmId(realm.getRealmId(), connection);
+			String newRealmAddr = currRealm.getRealmAddr().orElse(null);
+			String newRealmName = (currRealm.getRealmNames().isEmpty() == false) ? currRealm.getRealmNames().get(0) : null;
+
+			// make new signature
+			String newSignature = makeRealmSignature(newRealmAddr, newRealmName, realm.getScopeHost().orElse(null));
+
 			// Use a random string as the signature if the realm is not active.
-			String updateSQL = "UPDATE tsk_os_account_realms SET realm_name = ?,  realm_addr = ?, " 
-					+  " realm_signature = "
+			String updateSQL = "UPDATE tsk_os_account_realms SET  "
+					+ " realm_signature = "
 					+ "   CASE WHEN db_status = " + OsAccountRealm.RealmDbStatus.ACTIVE.getId() + " THEN ? ELSE realm_signature END "
 					+ " WHERE id = ?";
 			PreparedStatement preparedStatement = connection.getPreparedStatement(updateSQL, Statement.NO_GENERATED_KEYS);
 			preparedStatement.clearParameters();
-			
-			preparedStatement.setString(1, newRealmName);
-			preparedStatement.setString(2, newRealmAddr);
-			preparedStatement.setString(3, newSignature); // Is only set for active accounts
-			preparedStatement.setLong(4, realm.getRealmId());
+
+			preparedStatement.setString(1, newSignature); // Is only set for active accounts
+			preparedStatement.setLong(2, realm.getRealmId());
 			connection.executeUpdate(preparedStatement);
-			
+
 			// read the updated realm
 			updatedRealm = this.getRealmByRealmId(realm.getRealmId(), connection);
-			
+
 			return new OsRealmUpdateResult(updateStatusCode, updatedRealm);
 		} catch (SQLException ex) {
-			throw new TskCoreException(String.format("Error updating realm with id = %d, name = %s, addr = %s", realm.getRealmId(), realmName != null ? realmName : "Null", realm.getRealmAddr().orElse("Null") ), ex);
+			throw new TskCoreException(String.format("Error updating realm with id = %d, name = %s, addr = %s", realm.getRealmId(), realmName != null ? realmName : "Null", realm.getRealmAddr().orElse("Null")), ex);
+		} finally {
+			db.releaseSingleUserCaseWriteLock();
+		}
+
+	}
+
+	/**
+	 * Updates specified column in the tsk_os_account_realms table to the specified value.
+	 * 
+	 * @param <T> Type of value - must be a String, Long or an Integer. 
+	 * @param realmId Id of the realm to be updated.
+	 * @param colName Name of column o be updated.
+	 * @param colValue New column value. 
+	 * @param connection Database connection to use.
+	 * 
+	 * @throws SQLException If there is an error updating the database.
+	 * @throws TskCoreException  If the value type is not handled.
+	 */
+	private <T> void updateRealmColumn(long realmId, String colName, T colValue, CaseDbConnection connection) throws SQLException, TskCoreException {
+
+		String updateSQL = "UPDATE tsk_os_account_realms "
+				+ " SET " + colName + " = ? "
+				+ " WHERE id = ?";
+
+		db.acquireSingleUserCaseWriteLock();
+		try {
+			PreparedStatement preparedStatement = connection.getPreparedStatement(updateSQL, Statement.NO_GENERATED_KEYS);
+			preparedStatement.clearParameters();
+
+			if (Objects.isNull(colValue)) {
+				preparedStatement.setNull(1, Types.NULL); // handle null value
+			} else {
+				if (colValue instanceof String) {
+					preparedStatement.setString(1, (String) colValue);
+				} else if (colValue instanceof Long) {
+					preparedStatement.setLong(1, (Long) colValue);
+				} else if (colValue instanceof Integer) {
+					preparedStatement.setInt(1, (Integer) colValue);
+				} else {
+					throw new TskCoreException(String.format("Unhandled column data type received while updating the realm (id = %d) ", realmId));
+				}
+			}
+
+			preparedStatement.setLong(2, realmId);
+
+			connection.executeUpdate(preparedStatement);
 		} finally {
 			db.releaseSingleUserCaseWriteLock();
 		}
-		
 	}
 	
 	private final static String REALM_QUERY_STRING = "SELECT realms.id as realm_id, realms.realm_name as realm_name,"
diff --git a/bindings/java/test/org/sleuthkit/datamodel/OsAccountTest.java b/bindings/java/test/org/sleuthkit/datamodel/OsAccountTest.java
index eeb5d566e5c381dc38112b6787574e8f8c1ad34c..7c14f3e124b799ad10e4d468b58166d0f3021974 100644
--- a/bindings/java/test/org/sleuthkit/datamodel/OsAccountTest.java
+++ b/bindings/java/test/org/sleuthkit/datamodel/OsAccountTest.java
@@ -906,4 +906,70 @@ public void windowsAccountRealmUpdateTests() throws TskCoreException, OsAccountM
 	
 	}
 	
+	
+	@Test
+	public void windowsAccountUpdateTests() throws TskCoreException, OsAccountManager.NotUserSIDException {
+
+		
+		String hostname1 = "host55555";
+		Host host1 = caseDB.getHostManager().newHost(hostname1);
+		
+	
+		// Test 1: create an account with a SID alone. Then update the loginName.
+		
+		String ownerUid1 = "S-1-5-21-111111111-222222222-555555555-0001";
+		OsAccount osAccount1 = caseDB.getOsAccountManager().newWindowsOsAccount(ownerUid1, null, null, host1, OsAccountRealm.RealmScope.DOMAIN);
+		
+		
+		// now update the account login name
+		String loginname1 = "jbravo";
+		
+		OsAccountUpdateResult updateResult = caseDB.getOsAccountManager().updateCoreWindowsOsAccountAttributes(osAccount1, null, loginname1, null, host1);
+		assertEquals(updateResult.getUpdateStatusCode(), OsAccountManager.OsAccountUpdateStatus.UPDATED);
+		assertEquals(updateResult.getUpdatedAccount().isPresent(), true);
+		OsAccount updatedAccount = updateResult.getUpdatedAccount().orElseThrow(() ->  new TskCoreException("Updated account not found."));
+		
+		// verify that account has both addr and loginName, and that signature is the addr
+		assertTrue(updatedAccount.getAddr().orElse("").equalsIgnoreCase(ownerUid1));
+		assertTrue(updatedAccount.getLoginName().orElse("").equalsIgnoreCase(loginname1));
+		assertTrue(updatedAccount.getSignature().equalsIgnoreCase(ownerUid1));	// account signature should not change
+		
+		
+		String realmAddr1 = "S-1-5-21-111111111-222222222-555555555";
+		String realmSignature1 = realmAddr1 + "_DOMAIN";	// for a domain realm - signature is sid/name + "_DOMAIN"
+		
+		OsAccountRealm realm1 = caseDB.getOsAccountRealmManager().getRealmByRealmId(updatedAccount.getRealmId());
+		assertTrue(realm1.getRealmAddr().orElse("").equalsIgnoreCase(realmAddr1));
+		assertTrue(realm1.getSignature().equalsIgnoreCase(realmSignature1));	
+		
+		
+		// TBD Test2: create an account with realmName/loginname and then update the SID
+		
+		String loginname2 = "janeB";
+		String realmName2 = "realm55555";
+		OsAccount osAccount2 = caseDB.getOsAccountManager().newWindowsOsAccount(null, loginname2, realmName2, host1, OsAccountRealm.RealmScope.DOMAIN);
+		
+		assertFalse(osAccount2.getAddr().isPresent());
+		assertTrue(osAccount2.getLoginName().orElse("").equalsIgnoreCase(loginname2));
+		assertTrue(osAccount2.getSignature().equalsIgnoreCase(loginname2));	// account signature should be the login name
+		
+		// now update the account SID
+		String ownerUid2 = "S-1-5-21-111111111-222222222-555555555-0007";
+		OsAccountUpdateResult updateResult2 = caseDB.getOsAccountManager().updateCoreWindowsOsAccountAttributes(osAccount2, ownerUid2, null, realmName2, host1);
+		assertEquals(updateResult2.getUpdateStatusCode(), OsAccountManager.OsAccountUpdateStatus.UPDATED);
+		assertEquals(updateResult2.getUpdatedAccount().isPresent(), true);
+		OsAccount updatedAccount2 = updateResult2.getUpdatedAccount().orElseThrow(() ->  new TskCoreException("Updated account not found."));
+		
+		// verify that account has both addr and loginName, and that signature is the addr
+		assertTrue(updatedAccount2.getAddr().orElse("").equalsIgnoreCase(ownerUid2));
+		assertTrue(updatedAccount2.getLoginName().orElse("").equalsIgnoreCase(loginname2));
+		assertTrue(updatedAccount2.getSignature().equalsIgnoreCase(ownerUid2));	// account signature should now be addr
+		
+		// RAMAN TODO: CT-4284
+//		OsAccountRealm realm2 = caseDB.getOsAccountRealmManager().getRealmByRealmId(updatedAccount2.getRealmId());
+//		assertTrue(realm2.getRealmAddr().orElse("").equalsIgnoreCase(realmAddr1));
+//		assertTrue(realm2.getSignature().equalsIgnoreCase(realmSignature1));	
+	}
+	
+	
 }