diff --git a/briar-core/src/net/sf/briar/db/JdbcDatabase.java b/briar-core/src/net/sf/briar/db/JdbcDatabase.java
index e3a8637e42d15c39bedb6e6dba0d7979014f9402..b884dc6dc56b4a1cbfa04e8454f3c4978924fd89 100644
--- a/briar-core/src/net/sf/briar/db/JdbcDatabase.java
+++ b/briar-core/src/net/sf/briar/db/JdbcDatabase.java
@@ -116,6 +116,8 @@ abstract class JdbcDatabase implements Database<Connection> {
 					+ " raw BLOB NOT NULL,"
 					+ " sendability INT," // Null for private messages
 					+ " contactId INT," // Null for group messages
+					+ " read BOOLEAN NOT NULL,"
+					+ " starred BOOLEAN NOT NULL,"
 					+ " PRIMARY KEY (messageId),"
 					+ " FOREIGN KEY (groupId)"
 					+ " REFERENCES groups (groupId)"
@@ -166,17 +168,6 @@ abstract class JdbcDatabase implements Database<Connection> {
 	private static final String INDEX_STATUSES_BY_CONTACT =
 			"CREATE INDEX statusesByContact ON statuses (contactId)";
 
-	// Locking: message
-	private static final String CREATE_FLAGS =
-			"CREATE TABLE flags"
-					+ " (messageId HASH NOT NULL,"
-					+ " read BOOLEAN NOT NULL,"
-					+ " starred BOOLEAN NOT NULL,"
-					+ " PRIMARY KEY (messageId),"
-					+ " FOREIGN KEY (messageId)"
-					+ " REFERENCES messages (messageId)"
-					+ " ON DELETE CASCADE)";
-
 	// Locking: rating
 	private static final String CREATE_RATINGS =
 			"CREATE TABLE ratings"
@@ -364,7 +355,6 @@ abstract class JdbcDatabase implements Database<Connection> {
 			s.executeUpdate(insertTypeNames(CREATE_STATUSES));
 			s.executeUpdate(INDEX_STATUSES_BY_MESSAGE);
 			s.executeUpdate(INDEX_STATUSES_BY_CONTACT);
-			s.executeUpdate(insertTypeNames(CREATE_FLAGS));
 			s.executeUpdate(insertTypeNames(CREATE_RATINGS));
 			s.executeUpdate(insertTypeNames(CREATE_RETENTION_VERSIONS));
 			s.executeUpdate(insertTypeNames(CREATE_TRANSPORTS));
@@ -593,8 +583,9 @@ abstract class JdbcDatabase implements Database<Connection> {
 		try {
 			String sql = "INSERT INTO messages (messageId, parentId, groupId,"
 					+ " authorId, subject, timestamp, length, bodyStart,"
-					+ " bodyLength, raw, sendability)"
-					+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ZERO())";
+					+ " bodyLength, raw, sendability, read, starred)"
+					+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ZERO(), FALSE,"
+					+ " FALSE)";
 			ps = txn.prepareStatement(sql);
 			ps.setBytes(1, m.getId().getBytes());
 			if(m.getParent() == null) ps.setNull(2, BINARY);
@@ -686,8 +677,8 @@ abstract class JdbcDatabase implements Database<Connection> {
 		try {
 			String sql = "INSERT INTO messages"
 					+ " (messageId, parentId, subject, timestamp, length,"
-					+ " bodyStart, bodyLength, raw, contactId)"
-					+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
+					+ " bodyStart, bodyLength, raw, contactId, read, starred)"
+					+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, FALSE, FALSE)";
 			ps = txn.prepareStatement(sql);
 			ps.setBytes(1, m.getId().getBytes());
 			if(m.getParent() == null) ps.setNull(2, BINARY);
@@ -1140,8 +1131,6 @@ abstract class JdbcDatabase implements Database<Connection> {
 			String sql = "SELECT m.messageId, parentId, authorId,"
 					+ " subject, timestamp, read, starred"
 					+ " FROM messages AS m"
-					+ " LEFT OUTER JOIN flags AS f"
-					+ " ON m.messageId = f.messageId"
 					+ " WHERE groupId = ?";
 			ps = txn.prepareStatement(sql);
 			ps.setBytes(1, g.getBytes());
@@ -1421,7 +1410,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 		PreparedStatement ps = null;
 		ResultSet rs = null;
 		try {
-			String sql = "SELECT read FROM flags WHERE messageId = ?";
+			String sql = "SELECT read FROM messages WHERE messageId = ?";
 			ps = txn.prepareStatement(sql);
 			ps.setBytes(1, m.getBytes());
 			rs = ps.executeQuery();
@@ -1667,7 +1656,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 		PreparedStatement ps = null;
 		ResultSet rs = null;
 		try {
-			String sql = "SELECT starred FROM flags WHERE messageId = ?";
+			String sql = "SELECT starred FROM messages WHERE messageId = ?";
 			ps = txn.prepareStatement(sql);
 			ps.setBytes(1, m.getBytes());
 			rs = ps.executeQuery();
@@ -1894,9 +1883,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 		try {
 			String sql = "SELECT groupId, COUNT(*)"
 					+ " FROM messages AS m"
-					+ " LEFT OUTER JOIN flags AS f"
-					+ " ON m.messageId = f.messageId"
-					+ " WHERE (NOT read) OR (read IS NULL)"
+					+ " WHERE read = FALSE"
 					+ " GROUP BY groupId";
 			ps = txn.prepareStatement(sql);
 			rs = ps.executeQuery();
@@ -2432,44 +2419,24 @@ abstract class JdbcDatabase implements Database<Connection> {
 		PreparedStatement ps = null;
 		ResultSet rs = null;
 		try {
-			String sql = "SELECT read FROM flags WHERE messageId = ?";
+			String sql = "SELECT read FROM messages WHERE messageId = ?";
 			ps = txn.prepareStatement(sql);
 			ps.setBytes(1, m.getBytes());
 			rs = ps.executeQuery();
-			boolean old;
-			if(rs.next()) {
-				// A flag row exists - update it if necessary
-				old = rs.getBoolean(1);
-				if(rs.next()) throw new DbStateException();
-				rs.close();
-				ps.close();
-				if(old != read) {
-					sql = "UPDATE flags SET read = ? WHERE messageId = ?";
-					ps = txn.prepareStatement(sql);
-					ps.setBoolean(1, read);
-					ps.setBytes(2, m.getBytes());
-					int affected = ps.executeUpdate();
-					if(affected != 1) throw new DbStateException();
-					ps.close();
-				}
-			} else {
-				// No flag row exists - create one if necessary
-				ps.close();
-				rs.close();
-				old = false;
-				if(old != read) {
-					sql = "INSERT INTO flags (messageId, read, starred)"
-							+ " VALUES (?, ?, ?)";
-					ps = txn.prepareStatement(sql);
-					ps.setBytes(1, m.getBytes());
-					ps.setBoolean(2, read);
-					ps.setBoolean(3, false);
-					int affected = ps.executeUpdate();
-					if(affected != 1) throw new DbStateException();
-					ps.close();
-				}
-			}
-			return old;
+			if(!rs.next()) throw new DbStateException();
+			boolean wasRead = rs.getBoolean(1);
+			if(rs.next()) throw new DbStateException();
+			rs.close();
+			ps.close();
+			if(wasRead == read) return read;
+			sql = "UPDATE messages SET read = ? WHERE messageId = ?";
+			ps = txn.prepareStatement(sql);
+			ps.setBoolean(1, read);
+			ps.setBytes(2, m.getBytes());
+			int affected = ps.executeUpdate();
+			if(affected != 1) throw new DbStateException();
+			ps.close();
+			return !read;
 		} catch(SQLException e) {
 			tryToClose(rs);
 			tryToClose(ps);
@@ -2580,44 +2547,24 @@ abstract class JdbcDatabase implements Database<Connection> {
 		PreparedStatement ps = null;
 		ResultSet rs = null;
 		try {
-			String sql = "SELECT starred FROM flags WHERE messageId = ?";
+			String sql = "SELECT starred FROM messages WHERE messageId = ?";
 			ps = txn.prepareStatement(sql);
 			ps.setBytes(1, m.getBytes());
 			rs = ps.executeQuery();
-			boolean old;
-			if(rs.next()) {
-				// A flag row exists - update it if necessary
-				old = rs.getBoolean(1);
-				if(rs.next()) throw new DbStateException();
-				rs.close();
-				ps.close();
-				if(old != starred) {
-					sql = "UPDATE flags SET starred = ? WHERE messageId = ?";
-					ps = txn.prepareStatement(sql);
-					ps.setBoolean(1, starred);
-					ps.setBytes(2, m.getBytes());
-					int affected = ps.executeUpdate();
-					if(affected != 1) throw new DbStateException();
-					ps.close();
-				}
-			} else {
-				// No flag row exists - create one if necessary
-				ps.close();
-				rs.close();
-				old = false;
-				if(old != starred) {
-					sql = "INSERT INTO flags (messageId, read, starred)"
-							+ " VALUES (?, ?, ?)";
-					ps = txn.prepareStatement(sql);
-					ps.setBytes(1, m.getBytes());
-					ps.setBoolean(2, false);
-					ps.setBoolean(3, starred);
-					int affected = ps.executeUpdate();
-					if(affected != 1) throw new DbStateException();
-					ps.close();
-				}
-			}
-			return old;
+			if(!rs.next()) throw new DbStateException();
+			boolean wasStarred = rs.getBoolean(1);
+			if(rs.next()) throw new DbStateException();
+			rs.close();
+			ps.close();
+			if(wasStarred == starred) return starred;
+			sql = "UPDATE messages SET starred = ? WHERE messageId = ?";
+			ps = txn.prepareStatement(sql);
+			ps.setBoolean(1, starred);
+			ps.setBytes(2, m.getBytes());
+			int affected = ps.executeUpdate();
+			if(affected != 1) throw new DbStateException();
+			ps.close();
+			return !starred;
 		} catch(SQLException e) {
 			tryToClose(rs);
 			tryToClose(ps);