diff --git a/briar-android/src/org/briarproject/android/AndroidComponent.java b/briar-android/src/org/briarproject/android/AndroidComponent.java
index a5880d33686c970c759ea1f33008fd34e2c9b39d..ce051f5349f136428e6921607bca39516f24abe4 100644
--- a/briar-android/src/org/briarproject/android/AndroidComponent.java
+++ b/briar-android/src/org/briarproject/android/AndroidComponent.java
@@ -30,6 +30,7 @@ import org.briarproject.api.keyagreement.PayloadEncoder;
 import org.briarproject.api.keyagreement.PayloadParser;
 import org.briarproject.api.lifecycle.IoExecutor;
 import org.briarproject.api.lifecycle.LifecycleManager;
+import org.briarproject.api.messaging.ConversationManager;
 import org.briarproject.api.messaging.MessagingManager;
 import org.briarproject.api.messaging.PrivateMessageFactory;
 import org.briarproject.api.plugins.ConnectionRegistry;
@@ -86,6 +87,8 @@ public interface AndroidComponent extends CoreEagerSingletons {
 
 	ContactManager contactManager();
 
+	ConversationManager conversationManager();
+
 	MessagingManager messagingManager();
 
 	PrivateMessageFactory privateMessageFactory();
diff --git a/briar-android/src/org/briarproject/android/contact/BaseContactListAdapter.java b/briar-android/src/org/briarproject/android/contact/BaseContactListAdapter.java
index b1ab777c442989c4735d3b2d210729d4482ba065..633ced849e037c0896ea6202028828bf527a59f0 100644
--- a/briar-android/src/org/briarproject/android/contact/BaseContactListAdapter.java
+++ b/briar-android/src/org/briarproject/android/contact/BaseContactListAdapter.java
@@ -96,8 +96,10 @@ public abstract class BaseContactListAdapter<VH extends BaseContactListAdapter.B
 		int count = getItemCount();
 		for (int i = 0; i < count; i++) {
 			ContactListItem item = getItemAt(i);
-			if (item != null && item.getGroupId().equals(g))
+			if (item != null && item.getGroupId() != null &&
+					item.getGroupId().equals(g)) {
 				return i;
+			}
 		}
 		return INVALID_POSITION; // Not found
 	}
diff --git a/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java b/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java
index a2cf8012d3eae990d857108fa282a63234822805..f7c3444adc24f5253900efa9c5aa87433c293b00 100644
--- a/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java
+++ b/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java
@@ -35,7 +35,7 @@ public class ContactListAdapter
 		if (item == null) return;
 
 		// unread count
-		int unread = item.getUnreadCount();
+		long unread = item.getUnreadCount();
 		if (unread > 0) {
 			ui.unread.setText(String.valueOf(unread));
 			ui.unread.setVisibility(View.VISIBLE);
diff --git a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java
index 5feb4d3a15a3014145aec79ac0d0e033e77770b1..637d893fa92193b46108916ca6768250d8ce3f48 100644
--- a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java
+++ b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java
@@ -21,13 +21,12 @@ import org.briarproject.android.api.AndroidNotificationManager;
 import org.briarproject.android.fragment.BaseFragment;
 import org.briarproject.android.keyagreement.KeyAgreementActivity;
 import org.briarproject.android.view.BriarRecyclerView;
-import org.briarproject.api.blogs.BlogSharingManager;
+import org.briarproject.api.clients.MessageTracker.GroupCount;
 import org.briarproject.api.contact.Contact;
 import org.briarproject.api.contact.ContactId;
 import org.briarproject.api.contact.ContactManager;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.db.NoSuchContactException;
-import org.briarproject.api.event.ContactAddedEvent;
 import org.briarproject.api.event.ContactConnectedEvent;
 import org.briarproject.api.event.ContactDisconnectedEvent;
 import org.briarproject.api.event.ContactRemovedEvent;
@@ -40,21 +39,18 @@ import org.briarproject.api.event.IntroductionResponseReceivedEvent;
 import org.briarproject.api.event.InvitationReceivedEvent;
 import org.briarproject.api.event.InvitationResponseReceivedEvent;
 import org.briarproject.api.event.PrivateMessageReceivedEvent;
-import org.briarproject.api.forum.ForumSharingManager;
 import org.briarproject.api.identity.IdentityManager;
 import org.briarproject.api.identity.LocalAuthor;
-import org.briarproject.api.introduction.IntroductionManager;
-import org.briarproject.api.introduction.IntroductionMessage;
 import org.briarproject.api.introduction.IntroductionRequest;
 import org.briarproject.api.introduction.IntroductionResponse;
-import org.briarproject.api.messaging.MessagingManager;
+import org.briarproject.api.messaging.ConversationManager;
 import org.briarproject.api.messaging.PrivateMessageHeader;
 import org.briarproject.api.plugins.ConnectionRegistry;
-import org.briarproject.api.sharing.InvitationMessage;
+import org.briarproject.api.sharing.InvitationRequest;
+import org.briarproject.api.sharing.InvitationResponse;
 import org.briarproject.api.sync.GroupId;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import java.util.logging.Logger;
 
@@ -88,13 +84,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 	@Inject
 	protected volatile IdentityManager identityManager;
 	@Inject
-	protected volatile MessagingManager messagingManager;
-	@Inject
-	protected volatile IntroductionManager introductionManager;
-	@Inject
-	protected volatile ForumSharingManager forumSharingManager;
-	@Inject
-	protected volatile BlogSharingManager blogSharingManager;
+	protected volatile ConversationManager conversationManager;
 
 	public static ContactListFragment newInstance() {
 
@@ -130,8 +120,8 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 				new ContactListAdapter.OnItemClickListener() {
 					@Override
 					public void onItemClick(View view, ContactListItem item) {
-
 						GroupId groupId = item.getGroupId();
+						if (groupId == null) return;
 						Intent i = new Intent(getActivity(),
 								ConversationActivity.class);
 						i.putExtra(GROUP_ID, groupId.getBytes());
@@ -215,15 +205,15 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 						try {
 							ContactId id = c.getId();
 							GroupId groupId =
-									messagingManager.getConversationId(id);
-							Collection<ConversationItem> messages =
-									getMessages(id);
+									conversationManager.getConversationId(id);
+							GroupCount count =
+									conversationManager.getGroupCount(id);
 							boolean connected =
 									connectionRegistry.isConnected(c.getId());
 							LocalAuthor localAuthor = identityManager
 									.getLocalAuthor(c.getLocalAuthorId());
 							contacts.add(new ContactListItem(c, localAuthor,
-									connected, groupId, messages));
+									connected, groupId, count));
 						} catch (NoSuchContactException e) {
 							// Continue
 						}
@@ -252,14 +242,9 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 
 	@Override
 	public void eventOccurred(Event e) {
-		if (e instanceof ContactAddedEvent) {
-			if (((ContactAddedEvent) e).isActive()) {
-				LOG.info("Contact added as active, reloading");
-				loadContacts();
-			}
-		} else if (e instanceof ContactStatusChangedEvent) {
+		if (e instanceof ContactStatusChangedEvent) {
 			LOG.info("Contact Status changed, reloading");
-			// TODO We can update the contact state without needing to reload
+			// is also broadcast when contact was added
 			loadContacts();
 		} else if (e instanceof ContactConnectedEvent) {
 			setConnected(((ContactConnectedEvent) e).getContactId(), true);
@@ -286,49 +271,19 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 			IntroductionResponse ir = m.getIntroductionResponse();
 			updateItem(m.getContactId(), ConversationItem.from(ir));
 		} else if (e instanceof InvitationReceivedEvent) {
-			LOG.info("Invitation received, reloading conversation...");
+			LOG.info("Invitation Request received, update contact");
 			InvitationReceivedEvent m = (InvitationReceivedEvent) e;
-			reloadConversation(m.getContactId());
+			InvitationRequest ir = m.getRequest();
+			updateItem(m.getContactId(), ConversationItem.from(ir));
 		} else if (e instanceof InvitationResponseReceivedEvent) {
-			LOG.info("Invitation Response received, reloading ...");
+			LOG.info("Invitation Response received, update contact");
 			InvitationResponseReceivedEvent m =
 					(InvitationResponseReceivedEvent) e;
-			reloadConversation(m.getContactId());
+			InvitationResponse ir = m.getResponse();
+			updateItem(m.getContactId(), ConversationItem.from(ir));
 		}
 	}
 
-	private void reloadConversation(final ContactId c) {
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<ConversationItem> messages = getMessages(c);
-					updateItem(c, messages);
-				} catch (NoSuchContactException e) {
-					LOG.info("Contact removed");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
-			}
-		});
-	}
-
-	private void updateItem(final ContactId c,
-			final Collection<ConversationItem> messages) {
-		listener.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				int position = adapter.findItemPosition(c);
-				ContactListItem item = adapter.getItemAt(position);
-				if (item != null) {
-					item.setMessages(messages);
-					adapter.updateItemAt(position, item);
-				}
-			}
-		});
-	}
-
 	private void updateItem(final ContactId c, final ConversationItem m) {
 		listener.runOnUiThread(new Runnable() {
 			@Override
@@ -382,50 +337,4 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 		});
 	}
 
-	// This needs to be called from the DB thread
-	// Do not call getActivty() here as it might return null
-	private Collection<ConversationItem> getMessages(ContactId id)
-			throws DbException {
-
-		long now = System.currentTimeMillis();
-
-		Collection<ConversationItem> messages = new ArrayList<>();
-
-		Collection<PrivateMessageHeader> headers =
-				messagingManager.getMessageHeaders(id);
-		for (PrivateMessageHeader h : headers) {
-			messages.add(ConversationItem.from(h));
-		}
-		long duration = System.currentTimeMillis() - now;
-		if (LOG.isLoggable(INFO))
-			LOG.info("Loading message headers took " + duration + " ms");
-
-		now = System.currentTimeMillis();
-		Collection<IntroductionMessage> introductions =
-				introductionManager
-						.getIntroductionMessages(id);
-		for (IntroductionMessage m : introductions) {
-			messages.add(ConversationItem.from(m));
-		}
-		duration = System.currentTimeMillis() - now;
-		if (LOG.isLoggable(INFO))
-			LOG.info("Loading introduction messages took " + duration + " ms");
-
-		now = System.currentTimeMillis();
-		Collection<InvitationMessage> forumInvitations =
-				forumSharingManager.getInvitationMessages(id);
-		for (InvitationMessage i : forumInvitations) {
-			messages.add(ConversationItem.from(i));
-		}
-		Collection<InvitationMessage> blogInvitations =
-				blogSharingManager.getInvitationMessages(id);
-		for (InvitationMessage i : blogInvitations) {
-			messages.add(ConversationItem.from(i));
-		}
-		duration = System.currentTimeMillis() - now;
-		if (LOG.isLoggable(INFO))
-			LOG.info("Loading invitations took " + duration + " ms");
-
-		return messages;
-	}
 }
diff --git a/briar-android/src/org/briarproject/android/contact/ContactListItem.java b/briar-android/src/org/briarproject/android/contact/ContactListItem.java
index e436d4a9b230067ff294cffa28c823855dc97bb1..9a6b8ea998668a3341de18733eaf6de6ea8e4c3f 100644
--- a/briar-android/src/org/briarproject/android/contact/ContactListItem.java
+++ b/briar-android/src/org/briarproject/android/contact/ContactListItem.java
@@ -1,14 +1,15 @@
 package org.briarproject.android.contact;
 
+import android.support.annotation.Nullable;
+
+import org.briarproject.api.clients.MessageTracker.GroupCount;
 import org.briarproject.api.contact.Contact;
 import org.briarproject.api.identity.LocalAuthor;
 import org.briarproject.api.sync.GroupId;
 
-import java.util.Collection;
-
 import static org.briarproject.android.contact.ConversationItem.IncomingItem;
 
-// This class is not thread-safe
+// This class is NOT thread-safe
 public class ContactListItem {
 
 	private final Contact contact;
@@ -16,28 +17,17 @@ public class ContactListItem {
 	private final GroupId groupId;
 	private boolean connected, empty;
 	private long timestamp;
-	private int unread;
+	private long unread;
 
 	public ContactListItem(Contact contact, LocalAuthor localAuthor,
-			boolean connected,
-			GroupId groupId,
-			Collection<ConversationItem> messages) {
+			boolean connected, @Nullable GroupId groupId, GroupCount count) {
 		this.contact = contact;
 		this.localAuthor = localAuthor;
 		this.groupId = groupId;
 		this.connected = connected;
-		setMessages(messages);
-	}
-
-	void setMessages(Collection<ConversationItem> messages) {
-		empty = messages == null || messages.isEmpty();
-		timestamp = 0;
-		unread = 0;
-		if (!empty) {
-			for (ConversationItem i : messages) {
-				addMessage(i);
-			}
-		}
+		this.empty = count.getMsgCount() == 0;
+		this.unread = count.getUnreadCount();
+		this.timestamp = count.getLatestMsgTime();
 	}
 
 	void addMessage(ConversationItem message) {
@@ -58,6 +48,7 @@ public class ContactListItem {
 		return localAuthor;
 	}
 
+	@Nullable
 	GroupId getGroupId() {
 		return groupId;
 	}
@@ -78,7 +69,7 @@ public class ContactListItem {
 		return timestamp;
 	}
 
-	int getUnreadCount() {
+	long getUnreadCount() {
 		return unread;
 	}
 }
\ No newline at end of file
diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
index 1329892656f3b76b761171c4ebc635a0a63341d1..14851da07a97be6cebe980f67600e7c3e9e5a0a5 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
@@ -34,6 +34,7 @@ import org.briarproject.android.view.TextInputView;
 import org.briarproject.android.view.TextInputView.TextInputListener;
 import org.briarproject.api.FormatException;
 import org.briarproject.api.blogs.BlogSharingManager;
+import org.briarproject.api.clients.BaseMessageHeader;
 import org.briarproject.api.clients.SessionId;
 import org.briarproject.api.contact.Contact;
 import org.briarproject.api.contact.ContactId;
@@ -476,28 +477,27 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void markMessagesRead() {
-		List<MessageId> unread = new ArrayList<>();
+		Map<MessageId, GroupId> unread = new HashMap<>();
 		SparseArray<IncomingItem> list = adapter.getIncomingMessages();
 		for (int i = 0; i < list.size(); i++) {
 			IncomingItem item = list.valueAt(i);
-			if (!item.isRead()) unread.add(item.getId());
+			if (!item.isRead()) unread.put(item.getId(), item.getGroupId());
 		}
 		if (unread.isEmpty()) return;
 		if (LOG.isLoggable(INFO))
 			LOG.info("Marking " + unread.size() + " messages read");
-		markMessagesRead(Collections.unmodifiableList(unread));
+		markMessagesRead(Collections.unmodifiableMap(unread));
 	}
 
-	private void markMessagesRead(final Collection<MessageId> unread) {
+	private void markMessagesRead(final Map<MessageId, GroupId> unread) {
 		runOnDbThread(new Runnable() {
 			@Override
 			public void run() {
 				try {
 					long now = System.currentTimeMillis();
-					for (MessageId m : unread)
-						// not really clean, but the messaging manager can
-						// handle introduction messages as well
-						messagingManager.setReadFlag(groupId, m, true);
+					for (Map.Entry<MessageId, GroupId> e : unread.entrySet())
+						messagingManager
+								.setReadFlag(e.getValue(), e.getKey(), true);
 					long duration = System.currentTimeMillis() - now;
 					if (LOG.isLoggable(INFO))
 						LOG.info("Marking read took " + duration + " ms");
@@ -560,6 +560,7 @@ public class ConversationActivity extends BriarActivity
 				IntroductionRequest ir = event.getIntroductionRequest();
 				ConversationItem item = new ConversationIntroductionInItem(ir);
 				addConversationItem(item);
+				markMessageReadIfNew(ir);
 			}
 		} else if (e instanceof IntroductionResponseReceivedEvent) {
 			IntroductionResponseReceivedEvent event =
@@ -570,25 +571,33 @@ public class ConversationActivity extends BriarActivity
 				ConversationItem item =
 						ConversationItem.from(this, contactName, ir);
 				addConversationItem(item);
+				markMessageReadIfNew(ir);
 			}
 		} else if (e instanceof InvitationReceivedEvent) {
 			InvitationReceivedEvent event =
 					(InvitationReceivedEvent) e;
 			if (event.getContactId().equals(contactId)) {
-				LOG.info("Invitation received, reloading...");
-				loadMessages();
+				LOG.info("Invitation received, adding...");
+				InvitationRequest ir = event.getRequest();
+				ConversationItem item = ConversationItem.from(ir);
+				addConversationItem(item);
+				markMessageReadIfNew(ir);
 			}
 		} else if (e instanceof InvitationResponseReceivedEvent) {
 			InvitationResponseReceivedEvent event =
 					(InvitationResponseReceivedEvent) e;
 			if (event.getContactId().equals(contactId)) {
-				LOG.info("Invitation response received, reloading...");
-				loadMessages();
+				LOG.info("Invitation response received, adding...");
+				InvitationResponse ir = event.getResponse();
+				ConversationItem item =
+						ConversationItem.from(this, contactName, ir);
+				addConversationItem(item);
+				markMessageReadIfNew(ir);
 			}
 		}
 	}
 
-	private void markMessageReadIfNew(final PrivateMessageHeader h) {
+	private void markMessageReadIfNew(final BaseMessageHeader h) {
 		runOnUiThread(new Runnable() {
 			@Override
 			public void run() {
@@ -597,22 +606,23 @@ public class ConversationActivity extends BriarActivity
 					// Mark the message read if it's the newest message
 					long lastMsgTime = item.getTime();
 					long newMsgTime = h.getTimestamp();
-					if (newMsgTime > lastMsgTime) markNewMessageRead(h.getId());
+					if (newMsgTime > lastMsgTime)
+						markNewMessageRead(h.getGroupId(), h.getId());
 					else loadMessages();
 				} else {
 					// mark the message as read as well if it is the first one
-					markNewMessageRead(h.getId());
+					markNewMessageRead(h.getGroupId(), h.getId());
 				}
 			}
 		});
 	}
 
-	private void markNewMessageRead(final MessageId m) {
+	private void markNewMessageRead(final GroupId g, final MessageId m) {
 		runOnDbThread(new Runnable() {
 			@Override
 			public void run() {
 				try {
-					messagingManager.setReadFlag(groupId, m, true);
+					messagingManager.setReadFlag(g, m, true);
 					loadMessages();
 				} catch (DbException e) {
 					if (LOG.isLoggable(WARNING))
diff --git a/briar-android/src/org/briarproject/android/forum/ForumListItem.java b/briar-android/src/org/briarproject/android/forum/ForumListItem.java
index 88a710d4e927719cd2d7ab8b6813f01f0a6a396d..27ba86815e770d2a28115c096e1f905bbc39efbb 100644
--- a/briar-android/src/org/briarproject/android/forum/ForumListItem.java
+++ b/briar-android/src/org/briarproject/android/forum/ForumListItem.java
@@ -5,6 +5,7 @@ import org.briarproject.api.forum.ForumPostHeader;
 
 import java.util.Collection;
 
+// This class is NOT thread-safe
 class ForumListItem {
 
 	private final Forum forum;
diff --git a/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java b/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java
index ce25c8836ac5618799b7080453b1d1b8cdeaa674..0a7ffe7bd2c0b16316e0dc3ceae7cd2bb1be48f2 100644
--- a/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java
+++ b/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java
@@ -15,9 +15,9 @@ import org.briarproject.R;
 import org.briarproject.android.ActivityComponent;
 import org.briarproject.android.contact.ContactListAdapter;
 import org.briarproject.android.contact.ContactListItem;
-import org.briarproject.android.contact.ConversationItem;
 import org.briarproject.android.fragment.BaseFragment;
 import org.briarproject.android.view.BriarRecyclerView;
+import org.briarproject.api.clients.MessageTracker.GroupCount;
 import org.briarproject.api.contact.Contact;
 import org.briarproject.api.contact.ContactId;
 import org.briarproject.api.contact.ContactManager;
@@ -25,21 +25,16 @@ import org.briarproject.api.db.DbException;
 import org.briarproject.api.identity.AuthorId;
 import org.briarproject.api.identity.IdentityManager;
 import org.briarproject.api.identity.LocalAuthor;
-import org.briarproject.api.introduction.IntroductionManager;
-import org.briarproject.api.introduction.IntroductionMessage;
-import org.briarproject.api.messaging.MessagingManager;
-import org.briarproject.api.messaging.PrivateMessageHeader;
+import org.briarproject.api.messaging.ConversationManager;
 import org.briarproject.api.plugins.ConnectionRegistry;
 import org.briarproject.api.sync.GroupId;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
 
-import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
 
 public class ContactChooserFragment extends BaseFragment {
@@ -61,9 +56,7 @@ public class ContactChooserFragment extends BaseFragment {
 	@Inject
 	protected volatile IdentityManager identityManager;
 	@Inject
-	protected volatile MessagingManager messagingManager;
-	@Inject
-	protected volatile IntroductionManager introductionManager;
+	protected volatile ConversationManager conversationManager;
 	@Inject
 	protected volatile ConnectionRegistry connectionRegistry;
 
@@ -159,23 +152,23 @@ public class ContactChooserFragment extends BaseFragment {
 			public void run() {
 				try {
 					List<ContactListItem> contacts = new ArrayList<>();
-					AuthorId localAuthorId = null;
+					AuthorId localAuthorId =
+							identityManager.getLocalAuthor().getId();
 					for (Contact c : contactManager.getActiveContacts()) {
 						if (c.getId().getInt() == contactId) {
 							c1 = c;
-							localAuthorId = c1.getLocalAuthorId();
 						} else {
 							ContactId id = c.getId();
 							GroupId groupId =
-									messagingManager.getConversationId(id);
-							Collection<ConversationItem> messages =
-									getMessages(id);
+									conversationManager.getConversationId(id);
+							GroupCount count =
+									conversationManager.getGroupCount(id);
 							boolean connected =
 									connectionRegistry.isConnected(c.getId());
 							LocalAuthor localAuthor = identityManager
 									.getLocalAuthor(c.getLocalAuthorId());
 							contacts.add(new ContactListItem(c, localAuthor,
-									connected, groupId, messages));
+									connected, groupId, count));
 						}
 					}
 					displayContacts(localAuthorId, contacts);
@@ -220,36 +213,4 @@ public class ContactChooserFragment extends BaseFragment {
 		builder.show();
 	}
 
-	/**
-	 * This needs to be called from the DbThread
-	 */
-	private Collection<ConversationItem> getMessages(ContactId id)
-			throws DbException {
-
-		long now = System.currentTimeMillis();
-
-		Collection<ConversationItem> messages = new ArrayList<>();
-
-		Collection<PrivateMessageHeader> headers =
-				messagingManager.getMessageHeaders(id);
-		for (PrivateMessageHeader h : headers) {
-			messages.add(ConversationItem.from(h));
-		}
-		long duration = System.currentTimeMillis() - now;
-		if (LOG.isLoggable(INFO))
-			LOG.info("Loading message headers took " + duration + " ms");
-
-		now = System.currentTimeMillis();
-		Collection<IntroductionMessage> introductions =
-				introductionManager
-						.getIntroductionMessages(id);
-		for (IntroductionMessage m : introductions) {
-			messages.add(ConversationItem.from(m));
-		}
-		duration = System.currentTimeMillis() - now;
-		if (LOG.isLoggable(INFO))
-			LOG.info("Loading introduction messages took " + duration + " ms");
-
-		return messages;
-	}
 }
diff --git a/briar-android/src/org/briarproject/android/sharing/ContactSelectorFragment.java b/briar-android/src/org/briarproject/android/sharing/ContactSelectorFragment.java
index 951b49c09809d6eced379b3ac61ea5cfe5f1d69b..893ea91262addaa7c1e18b962968a1999172d7f2 100644
--- a/briar-android/src/org/briarproject/android/sharing/ContactSelectorFragment.java
+++ b/briar-android/src/org/briarproject/android/sharing/ContactSelectorFragment.java
@@ -3,6 +3,7 @@ package org.briarproject.android.sharing;
 import android.content.Context;
 import android.os.Build;
 import android.os.Bundle;
+import android.support.annotation.Nullable;
 import android.support.v7.widget.LinearLayoutManager;
 import android.transition.Fade;
 import android.view.LayoutInflater;
@@ -39,6 +40,7 @@ import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
 import static org.briarproject.android.sharing.ShareActivity.CONTACTS;
 import static org.briarproject.android.sharing.ShareActivity.getContactsFromIds;
+import static org.briarproject.android.sharing.ShareActivity.getContactsFromIntegers;
 import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
 
 public class ContactSelectorFragment extends BaseFragment implements
@@ -122,8 +124,9 @@ public class ContactSelectorFragment extends BaseFragment implements
 		if (savedInstanceState != null) {
 			ArrayList<Integer> intContacts =
 					savedInstanceState.getIntegerArrayList(CONTACTS);
-			selectedContacts = ShareActivity.getContactsFromIntegers(
-					intContacts);
+			if (intContacts != null) {
+				selectedContacts = getContactsFromIntegers(intContacts);
+			}
 		}
 
 		return contentView;
@@ -185,7 +188,7 @@ public class ContactSelectorFragment extends BaseFragment implements
 		updateMenuItem();
 	}
 
-	private void loadContacts(final Collection<ContactId> selection) {
+	private void loadContacts(@Nullable final Collection<ContactId> selection) {
 		shareActivity.runOnDbThread(new Runnable() {
 			@Override
 			public void run() {
diff --git a/briar-android/src/org/briarproject/android/sharing/SelectableContactListItem.java b/briar-android/src/org/briarproject/android/sharing/SelectableContactListItem.java
index 0d713fda2f4594b2f6c0be0b5dd4ea943a9655cc..8e76d39e705a562788528b93a0f900ed57940f89 100644
--- a/briar-android/src/org/briarproject/android/sharing/SelectableContactListItem.java
+++ b/briar-android/src/org/briarproject/android/sharing/SelectableContactListItem.java
@@ -1,14 +1,14 @@
 package org.briarproject.android.sharing;
 
+import android.support.annotation.UiThread;
+
 import org.briarproject.android.contact.ContactListItem;
-import org.briarproject.android.contact.ConversationItem;
+import org.briarproject.api.clients.MessageTracker.GroupCount;
 import org.briarproject.api.contact.Contact;
 import org.briarproject.api.identity.LocalAuthor;
 import org.briarproject.api.sync.GroupId;
 
-import java.util.Collections;
-
-// This class is not thread-safe
+// This class is NOT thread-safe
 public class SelectableContactListItem extends ContactListItem {
 
 	private boolean selected, disabled;
@@ -16,8 +16,7 @@ public class SelectableContactListItem extends ContactListItem {
 	public SelectableContactListItem(Contact contact, LocalAuthor localAuthor,
 			GroupId groupId, boolean selected, boolean disabled) {
 
-		super(contact, localAuthor, false, groupId,
-				Collections.<ConversationItem>emptyList());
+		super(contact, localAuthor, false, groupId, new GroupCount(0, 0, 0));
 
 		this.selected = selected;
 		this.disabled = disabled;
diff --git a/briar-android/src/org/briarproject/android/sharing/SharingStatusActivity.java b/briar-android/src/org/briarproject/android/sharing/SharingStatusActivity.java
index 0d69fe6d293dfce17e233b07def8bf030a649ae2..4bc3db43738275172b3e83ffacd9d9a00117914a 100644
--- a/briar-android/src/org/briarproject/android/sharing/SharingStatusActivity.java
+++ b/briar-android/src/org/briarproject/android/sharing/SharingStatusActivity.java
@@ -9,6 +9,8 @@ import org.briarproject.R;
 import org.briarproject.android.BriarActivity;
 import org.briarproject.android.contact.ContactListItem;
 import org.briarproject.android.view.BriarRecyclerView;
+import org.briarproject.api.clients.MessageTracker;
+import org.briarproject.api.clients.MessageTracker.GroupCount;
 import org.briarproject.api.contact.Contact;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.identity.IdentityManager;
@@ -106,7 +108,7 @@ abstract class SharingStatusActivity extends BriarActivity {
 								.getLocalAuthor(c.getLocalAuthorId());
 						ContactListItem item =
 								new ContactListItem(c, localAuthor, false, null,
-										null);
+										new GroupCount(0, 0, 0));
 						contactItems.add(item);
 					}
 				} catch (DbException e) {
@@ -142,7 +144,7 @@ abstract class SharingStatusActivity extends BriarActivity {
 								.getLocalAuthor(c.getLocalAuthorId());
 						ContactListItem item =
 								new ContactListItem(c, localAuthor, false, null,
-										null);
+										new GroupCount(0, 0, 0));
 						contactItems.add(item);
 					}
 				} catch (DbException e) {