diff --git a/components/net/sf/briar/db/Database.java b/components/net/sf/briar/db/Database.java
index 99809c23a9e331f6249a5b10caf5a2a854064418..f6a459aba15920d4ed7b428b9c4a4ebf70832a48 100644
--- a/components/net/sf/briar/db/Database.java
+++ b/components/net/sf/briar/db/Database.java
@@ -270,6 +270,16 @@ interface Database<T> {
 	 */
 	int getSendability(T txn, MessageId m) throws DbException;
 
+	/**
+	 * Returns the IDs of some messages that are eligible to be sent to the
+	 * given contact.
+	 * <p>
+	 * Locking: contacts read, messages read, messageStatuses read,
+	 * subscriptions read.
+	 */
+	Collection<MessageId> getSendableMessages(T txn, ContactId c)
+	throws DbException;
+
 	/**
 	 * Returns the IDs of some messages that are eligible to be sent to the
 	 * given contact, with a total size less than or equal to the given size.
diff --git a/components/net/sf/briar/db/DatabaseComponentImpl.java b/components/net/sf/briar/db/DatabaseComponentImpl.java
index dabf177c92aa260c3329f2334cc8cf2eb7c5aa4e..82bd27f78bd2070a2eb96c1f623542656e6baa90 100644
--- a/components/net/sf/briar/db/DatabaseComponentImpl.java
+++ b/components/net/sf/briar/db/DatabaseComponentImpl.java
@@ -564,8 +564,7 @@ DatabaseCleaner.Callback {
 				try {
 					T txn = db.startTransaction();
 					try {
-						sendable = db.getSendableMessages(txn, c,
-								Integer.MAX_VALUE);
+						sendable = db.getSendableMessages(txn, c);
 						db.commitTransaction(txn);
 					} catch(DbException e) {
 						db.abortTransaction(txn);
diff --git a/components/net/sf/briar/db/JdbcDatabase.java b/components/net/sf/briar/db/JdbcDatabase.java
index 9fc7139c366a704ce3f00e5372ad9b22e7a29e98..0a34ff0699a96f477999328ba5536bcbee0ca1bf 100644
--- a/components/net/sf/briar/db/JdbcDatabase.java
+++ b/components/net/sf/briar/db/JdbcDatabase.java
@@ -1185,6 +1185,58 @@ abstract class JdbcDatabase implements Database<Connection> {
 		}
 	}
 
+	public Collection<MessageId> getSendableMessages(Connection txn,
+			ContactId c) throws DbException {
+		PreparedStatement ps = null;
+		ResultSet rs = null;
+		try {
+			// Do we have any sendable private messages?
+			String sql = "SELECT messages.messageId FROM messages"
+				+ " JOIN statuses ON messages.messageId = statuses.messageId"
+				+ " WHERE messages.contactId = ? AND status = ?"
+				+ " ORDER BY timestamp";
+			ps = txn.prepareStatement(sql);
+			ps.setInt(1, c.getInt());
+			ps.setShort(2, (short) Status.NEW.ordinal());
+			rs = ps.executeQuery();
+			Collection<MessageId> ids = new ArrayList<MessageId>();
+			while(rs.next()) ids.add(new MessageId(rs.getBytes(2)));
+			rs.close();
+			ps.close();
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine(ids.size() + " sendable private messages");
+			// Do we have any sendable group messages?
+			sql = "SELECT messages.messageId FROM messages"
+				+ " JOIN contactSubscriptions"
+				+ " ON messages.groupId = contactSubscriptions.groupId"
+				+ " JOIN visibilities"
+				+ " ON messages.groupId = visibilities.groupId"
+				+ " AND contactSubscriptions.contactId = visibilities.contactId"
+				+ " JOIN statuses"
+				+ " ON messages.messageId = statuses.messageId"
+				+ " AND contactSubscriptions.contactId = statuses.contactId"
+				+ " WHERE contactSubscriptions.contactId = ?"
+				+ " AND timestamp >= start"
+				+ " AND status = ?"
+				+ " AND sendability > ZERO()"
+				+ " ORDER BY timestamp";
+			ps = txn.prepareStatement(sql);
+			ps.setInt(1, c.getInt());
+			ps.setShort(2, (short) Status.NEW.ordinal());
+			rs = ps.executeQuery();
+			while(rs.next()) ids.add(new MessageId(rs.getBytes(2)));
+			rs.close();
+			ps.close();
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine(ids.size() + " sendable private and group messages");
+			return ids;
+		} catch(SQLException e) {
+			tryToClose(rs);
+			tryToClose(ps);
+			throw new DbException(e);
+		}
+	}
+
 	public Collection<MessageId> getSendableMessages(Connection txn,
 			ContactId c, int capacity) throws DbException {
 		PreparedStatement ps = null;
diff --git a/test/net/sf/briar/db/DatabaseComponentTest.java b/test/net/sf/briar/db/DatabaseComponentTest.java
index 7540c5b39ee24c5bc904e16a00c5023ecb94f9c1..91784f74a6d82fe0f0392c10d9c57ce5ea251f50 100644
--- a/test/net/sf/briar/db/DatabaseComponentTest.java
+++ b/test/net/sf/briar/db/DatabaseComponentTest.java
@@ -826,8 +826,7 @@ public abstract class DatabaseComponentTest extends TestCase {
 			allowing(database).containsContact(txn, contactId);
 			will(returnValue(true));
 			// Get the sendable message IDs
-			oneOf(database).getSendableMessages(txn, contactId,
-					Integer.MAX_VALUE);
+			oneOf(database).getSendableMessages(txn, contactId);
 			will(returnValue(sendable));
 			// Try to add both IDs to the writer - only manage to add one
 			oneOf(offerWriter).writeMessageId(messageId);