diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/ContactManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/ContactManager.java
index f864fa7f371d393139fc4a87353ef6495a8ee5db..e6be9a4d2f61956d238ab6e147761e766b307a33 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/ContactManager.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/ContactManager.java
@@ -43,6 +43,24 @@ public interface ContactManager {
 	 */
 	Contact getContact(ContactId c) throws DbException;
 
+	/**
+	 * Returns the contact with the given remoteAuthorId
+	 * that was added by the LocalAuthor with the given localAuthorId
+	 *
+	 * @throws org.briarproject.bramble.api.db.NoSuchContactException
+	 */
+	Contact getContact(AuthorId remoteAuthorId, AuthorId localAuthorId)
+			throws DbException;
+
+	/**
+	 * Returns the contact with the given remoteAuthorId
+	 * that was added by the LocalAuthor with the given localAuthorId
+	 *
+	 * @throws org.briarproject.bramble.api.db.NoSuchContactException
+	 */
+	Contact getContact(Transaction txn, AuthorId remoteAuthorId,
+			AuthorId localAuthorId) throws DbException;
+
 	/**
 	 * Returns all active contacts.
 	 */
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java
index c4c3152b7a6d65fbc295bdc57e1b5d21c7d48fda..c840321365c62b5617479e9e8e9c547d06a486f0 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java
@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.contact.ContactManager;
 import org.briarproject.bramble.api.crypto.SecretKey;
 import org.briarproject.bramble.api.db.DatabaseComponent;
 import org.briarproject.bramble.api.db.DbException;
+import org.briarproject.bramble.api.db.NoSuchContactException;
 import org.briarproject.bramble.api.db.Transaction;
 import org.briarproject.bramble.api.identity.Author;
 import org.briarproject.bramble.api.identity.AuthorId;
@@ -88,6 +89,32 @@ class ContactManagerImpl implements ContactManager {
 		return contact;
 	}
 
+	@Override
+	public Contact getContact(AuthorId remoteAuthorId, AuthorId localAuthorId)
+			throws DbException {
+		Transaction txn = db.startTransaction(true);
+		try {
+			Contact c = getContact(txn, remoteAuthorId, localAuthorId);
+			db.commitTransaction(txn);
+			return c;
+		} finally {
+			db.endTransaction(txn);
+		}
+	}
+
+	@Override
+	public Contact getContact(Transaction txn, AuthorId remoteAuthorId,
+			AuthorId localAuthorId) throws DbException {
+		Collection<Contact> contacts =
+				db.getContactsByAuthorId(txn, remoteAuthorId);
+		for (Contact c : contacts) {
+			if (c.getLocalAuthorId().equals(localAuthorId)) {
+				return c;
+			}
+		}
+		throw new NoSuchContactException();
+	}
+
 	@Override
 	public Collection<Contact> getActiveContacts() throws DbException {
 		Collection<Contact> contacts;
diff --git a/briar-android-tests/src/test/java/org/briarproject/BlogSharingIntegrationTest.java b/briar-android-tests/src/test/java/org/briarproject/BlogSharingIntegrationTest.java
index 538cf3ccf9b761735469526657603d06bbb62244..4e010620f462050aa88e2b865b54cb09de1ab5bc 100644
--- a/briar-android-tests/src/test/java/org/briarproject/BlogSharingIntegrationTest.java
+++ b/briar-android-tests/src/test/java/org/briarproject/BlogSharingIntegrationTest.java
@@ -4,6 +4,7 @@ import net.jodah.concurrentunit.Waiter;
 
 import org.briarproject.bramble.api.contact.Contact;
 import org.briarproject.bramble.api.db.DbException;
+import org.briarproject.bramble.api.db.NoSuchGroupException;
 import org.briarproject.bramble.api.event.Event;
 import org.briarproject.bramble.api.event.EventListener;
 import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -30,6 +31,7 @@ import static org.briarproject.briar.api.blog.BlogSharingManager.CLIENT_ID;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 public class BlogSharingIntegrationTest
 		extends BriarIntegrationTest<BriarIntegrationTestComponent> {
@@ -266,7 +268,7 @@ public class BlogSharingIntegrationTest
 		assertTrue(blogSharingManager0.getSharedWith(blog2.getId())
 				.contains(contact1From0));
 		// invitee gets blog shared by sharer
-		assertTrue(blogSharingManager1.getSharedBy(blog2.getId())
+		assertTrue(blogSharingManager1.getSharedWith(blog2.getId())
 				.contains(contact0From1));
 
 		// invitee un-subscribes from blog
@@ -282,9 +284,13 @@ public class BlogSharingIntegrationTest
 		// sharer no longer shares blog with invitee
 		assertFalse(blogSharingManager0.getSharedWith(blog2.getId())
 				.contains(contact1From0));
-		// invitee no longer gets blog shared by sharer
-		assertFalse(blogSharingManager1.getSharedBy(blog2.getId())
-				.contains(contact0From1));
+		// invitee no longer has blog shared by sharer
+		try {
+			blogSharingManager1.getSharedWith(blog2.getId());
+			fail();
+		} catch (NoSuchGroupException e) {
+			// expected
+		}
 		// blog can be shared again
 		assertTrue(
 				blogSharingManager0.canBeShared(blog2.getId(), contact1From0));
@@ -310,10 +316,10 @@ public class BlogSharingIntegrationTest
 		eventWaiter.await(TIMEOUT, 1);
 		assertTrue(listener1.requestReceived);
 
-		// make sure blog2 is shared by 0
+		// make sure blog2 is shared by 0 and 2
 		Collection<Contact> contacts =
-				blogSharingManager1.getSharedBy(blog2.getId());
-		assertEquals(1, contacts.size());
+				blogSharingManager1.getSharedWith(blog2.getId());
+		assertEquals(2, contacts.size());
 		assertTrue(contacts.contains(contact0From1));
 
 		// make sure 1 knows that they have blog2 already
@@ -355,10 +361,11 @@ public class BlogSharingIntegrationTest
 		assertEquals(3, blogManager1.getBlogs().size());
 		Collection<Contact> sharedWith =
 				blogSharingManager0.getSharedWith(blog2.getId());
-		assertEquals(1, sharedWith.size());
-		assertEquals(contact1From0, sharedWith.iterator().next());
+		assertEquals(2, sharedWith.size());
+		assertTrue(sharedWith.contains(contact1From0));
+		assertTrue(sharedWith.contains(contact2From0));
 		Collection<Contact> sharedBy =
-				blogSharingManager1.getSharedBy(blog2.getId());
+				blogSharingManager1.getSharedWith(blog2.getId());
 		assertEquals(1, sharedBy.size());
 		assertEquals(contact0From1, sharedBy.iterator().next());
 
@@ -374,7 +381,8 @@ public class BlogSharingIntegrationTest
 		// sharer does not share this blog anymore with invitee
 		sharedWith =
 				blogSharingManager0.getSharedWith(blog2.getId());
-		assertEquals(0, sharedWith.size());
+		assertEquals(1, sharedWith.size());
+		assertTrue(sharedWith.contains(contact2From0));
 	}
 
 	@Test
@@ -396,7 +404,7 @@ public class BlogSharingIntegrationTest
 
 		// make sure blog2 is shared by 0
 		Collection<Contact> contacts =
-				blogSharingManager1.getSharedBy(blog2.getId());
+				blogSharingManager1.getSharedWith(blog2.getId());
 		assertEquals(1, contacts.size());
 		assertTrue(contacts.contains(contact0From1));
 
diff --git a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java
index 40e3f0103f00f63da54b8cb5716a8f0c8eeebbb2..b701f77f821bb72505611f9c96281029c5ea36e5 100644
--- a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java
+++ b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java
@@ -244,7 +244,7 @@ public class ForumSharingIntegrationTest
 				.contains(c1));
 		// invitee gets forum shared by sharer
 		Contact contact0 = contactManager1.getContact(contactId1From0);
-		assertTrue(forumSharingManager1.getSharedBy(forum0.getId())
+		assertTrue(forumSharingManager1.getSharedWith(forum0.getId())
 				.contains(contact0));
 
 		// invitee un-subscribes from forum
@@ -261,7 +261,7 @@ public class ForumSharingIntegrationTest
 		assertFalse(forumSharingManager0.getSharedWith(forum0.getId())
 				.contains(c1));
 		// invitee no longer gets forum shared by sharer
-		assertFalse(forumSharingManager1.getSharedBy(forum0.getId())
+		assertFalse(forumSharingManager1.getSharedWith(forum0.getId())
 				.contains(contact0));
 		// forum can be shared again
 		assertTrue(forumSharingManager0.canBeShared(forum0.getId(), c1));
@@ -299,7 +299,7 @@ public class ForumSharingIntegrationTest
 				.contains(c1));
 		// invitee gets forum shared by sharer
 		Contact contact0 = contactManager1.getContact(contactId1From0);
-		assertTrue(forumSharingManager1.getSharedBy(forum0.getId())
+		assertTrue(forumSharingManager1.getSharedWith(forum0.getId())
 				.contains(contact0));
 
 		// sharer un-subscribes from forum
@@ -317,7 +317,7 @@ public class ForumSharingIntegrationTest
 		assertFalse(forumSharingManager1.getSharedWith(forum0.getId())
 				.contains(c0));
 		// sharer no longer gets forum shared by invitee
-		assertFalse(forumSharingManager1.getSharedBy(forum0.getId())
+		assertFalse(forumSharingManager1.getSharedWith(forum0.getId())
 				.contains(contact0));
 		// forum can be shared again
 		assertTrue(forumSharingManager1.canBeShared(forum0.getId(), c0));
@@ -647,11 +647,11 @@ public class ForumSharingIntegrationTest
 		assertEquals(2, forums.iterator().next().getNewSharers().size());
 		assertEquals(forum0, forums.iterator().next().getShareable());
 		assertEquals(2,
-				forumSharingManager1.getSharedBy(forum0.getId()).size());
+				forumSharingManager1.getSharedWith(forum0.getId()).size());
 
 		// make sure both sharers actually share the forum
 		Collection<Contact> contacts =
-				forumSharingManager1.getSharedBy(forum0.getId());
+				forumSharingManager1.getSharedWith(forum0.getId());
 		assertEquals(2, contacts.size());
 
 		// answer second request
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItem.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItem.java
index 720a9d6df33ddc445b32af1ea2a7121d8a589655..703835a3bcfcaade19eb3d845a6197faf7c32e7e 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItem.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItem.java
@@ -10,13 +10,27 @@ import javax.annotation.concurrent.NotThreadSafe;
 public class ContactItem {
 
 	private final Contact contact;
+	private boolean connected;
 
 	public ContactItem(Contact contact) {
 		this.contact = contact;
 	}
 
+	public ContactItem(Contact contact, boolean connected) {
+		this.contact = contact;
+		this.connected = connected;
+	}
+
 	public Contact getContact() {
 		return contact;
 	}
 
+	boolean isConnected() {
+		return connected;
+	}
+
+	void setConnected(boolean connected) {
+		this.connected = connected;
+	}
+
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java
index 3791c6c34323906fb09e0b8b238374ec78acaeb2..3b543a19eeb6502453de0a523426c5d9b889342b 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java
@@ -1,5 +1,6 @@
 package org.briarproject.briar.android.contact;
 
+import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
@@ -12,8 +13,6 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
 import org.briarproject.briar.R;
 import org.briarproject.briar.android.contact.BaseContactListAdapter.OnContactClickListener;
 
-import javax.annotation.Nullable;
-
 import im.delight.android.identicons.IdenticonDrawable;
 
 @UiThread
@@ -24,6 +23,8 @@ public class ContactItemViewHolder<I extends ContactItem>
 	protected final ViewGroup layout;
 	protected final ImageView avatar;
 	protected final TextView name;
+	@Nullable
+	protected final ImageView bulb;
 
 	public ContactItemViewHolder(View v) {
 		super(v);
@@ -31,6 +32,7 @@ public class ContactItemViewHolder<I extends ContactItem>
 		layout = (ViewGroup) v;
 		avatar = (ImageView) v.findViewById(R.id.avatarView);
 		name = (TextView) v.findViewById(R.id.nameView);
+		bulb = (ImageView) v.findViewById(R.id.bulbView);
 	}
 
 	protected void bind(final I item,
@@ -41,6 +43,15 @@ public class ContactItemViewHolder<I extends ContactItem>
 		String contactName = author.getName();
 		name.setText(contactName);
 
+		if (bulb != null) {
+			// online/offline
+			if (item.isConnected()) {
+				bulb.setImageResource(R.drawable.contact_connected);
+			} else {
+				bulb.setImageResource(R.drawable.contact_disconnected);
+			}
+		}
+
 		layout.setOnClickListener(new View.OnClickListener() {
 			@Override
 			public void onClick(View v) {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItem.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItem.java
index d6e839afa69083571fb92a33e2222e370a3b50b5..c8e47207c949d4e9335dd649283b7f5ba7497b5d 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItem.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItem.java
@@ -10,14 +10,13 @@ import javax.annotation.concurrent.NotThreadSafe;
 @NotNullByDefault
 public class ContactListItem extends ContactItem {
 
-	private boolean connected, empty;
+	private boolean empty;
 	private long timestamp;
 	private int unread;
 
 	public ContactListItem(Contact contact, boolean connected,
 			GroupCount count) {
-		super(contact);
-		this.connected = connected;
+		super(contact, connected);
 		this.empty = count.getMsgCount() == 0;
 		this.unread = count.getUnreadCount();
 		this.timestamp = count.getLatestMsgTime();
@@ -30,14 +29,6 @@ public class ContactListItem extends ContactItem {
 			unread++;
 	}
 
-	boolean isConnected() {
-		return connected;
-	}
-
-	void setConnected(boolean connected) {
-		this.connected = connected;
-	}
-
 	boolean isEmpty() {
 		return empty;
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItemViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItemViewHolder.java
index 649e3782f98474b9ded132d372f11687edd06752..386b2590620ef8a648019525b926d9cd1c4e1037 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItemViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItemViewHolder.java
@@ -2,7 +2,6 @@ package org.briarproject.briar.android.contact;
 
 import android.support.annotation.UiThread;
 import android.view.View;
-import android.widget.ImageView;
 import android.widget.TextView;
 
 import org.briarproject.bramble.api.contact.ContactId;
@@ -20,13 +19,11 @@ import static org.briarproject.briar.android.util.UiUtils.formatDate;
 @NotNullByDefault
 class ContactListItemViewHolder extends ContactItemViewHolder<ContactListItem> {
 
-	protected final ImageView bulb;
 	private final TextView unread;
 	private final TextView date;
 
 	ContactListItemViewHolder(View v) {
 		super(v);
-		bulb = (ImageView) v.findViewById(R.id.bulbView);
 		unread = (TextView) v.findViewById(R.id.unreadCountView);
 		date = (TextView) v.findViewById(R.id.dateView);
 	}
@@ -53,13 +50,6 @@ class ContactListItemViewHolder extends ContactItemViewHolder<ContactListItem> {
 			date.setText(formatDate(date.getContext(), timestamp));
 		}
 
-		// online/offline
-		if (item.isConnected()) {
-			bulb.setImageResource(R.drawable.contact_connected);
-		} else {
-			bulb.setImageResource(R.drawable.contact_disconnected);
-		}
-
 		ContactId c = item.getContact().getId();
 		setTransitionName(avatar, UiUtils.getAvatarTransitionName(c));
 		setTransitionName(bulb, UiUtils.getBulbTransitionName(c));
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/BlogSharingStatusActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/BlogSharingStatusActivity.java
index ab60768c674f3a0b88ada18277aebb87b18768a1..a1adeace5593457397fdd3e1645886a62724cb48 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/BlogSharingStatusActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/BlogSharingStatusActivity.java
@@ -3,6 +3,8 @@ package org.briarproject.briar.android.sharing;
 import org.briarproject.bramble.api.contact.Contact;
 import org.briarproject.bramble.api.db.DatabaseExecutor;
 import org.briarproject.bramble.api.db.DbException;
+import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
 import org.briarproject.briar.android.activity.ActivityComponent;
 import org.briarproject.briar.api.blog.BlogSharingManager;
 
@@ -10,6 +12,8 @@ import java.util.Collection;
 
 import javax.inject.Inject;
 
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 public class BlogSharingStatusActivity extends SharingStatusActivity {
 
 	// Fields that are accessed from background threads must be volatile
@@ -21,16 +25,10 @@ public class BlogSharingStatusActivity extends SharingStatusActivity {
 		component.inject(this);
 	}
 
-	@DatabaseExecutor
 	@Override
+	@DatabaseExecutor
 	protected Collection<Contact> getSharedWith() throws DbException {
 		return blogSharingManager.getSharedWith(getGroupId());
 	}
 
-	@DatabaseExecutor
-	@Override
-	protected Collection<Contact> getSharedBy() throws DbException {
-		return blogSharingManager.getSharedBy(getGroupId());
-	}
-
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ForumSharingStatusActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ForumSharingStatusActivity.java
index fc59fd9cfdea77d7f9de067e605a76157d759c47..e9edf9e839916bb2e935533ec6d111784d99ab47 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ForumSharingStatusActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ForumSharingStatusActivity.java
@@ -3,13 +3,18 @@ package org.briarproject.briar.android.sharing;
 import org.briarproject.bramble.api.contact.Contact;
 import org.briarproject.bramble.api.db.DatabaseExecutor;
 import org.briarproject.bramble.api.db.DbException;
+import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
 import org.briarproject.briar.android.activity.ActivityComponent;
 import org.briarproject.briar.api.forum.ForumSharingManager;
 
 import java.util.Collection;
+import java.util.HashSet;
 
 import javax.inject.Inject;
 
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 public class ForumSharingStatusActivity extends SharingStatusActivity {
 
 	// Fields that are accessed from background threads must be volatile
@@ -21,16 +26,10 @@ public class ForumSharingStatusActivity extends SharingStatusActivity {
 		component.inject(this);
 	}
 
-	@DatabaseExecutor
 	@Override
+	@DatabaseExecutor
 	protected Collection<Contact> getSharedWith() throws DbException {
 		return forumSharingManager.getSharedWith(getGroupId());
 	}
 
-	@DatabaseExecutor
-	@Override
-	protected Collection<Contact> getSharedBy() throws DbException {
-		return forumSharingManager.getSharedBy(getGroupId());
-	}
-
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java
index 543aaf6cd8f27efaae03f092d469e53015a62c8d..db72e8c55cbcb9cf66967e7884a488d6d8f5acfe 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java
@@ -2,11 +2,16 @@ package org.briarproject.briar.android.sharing;
 
 import android.content.Intent;
 import android.os.Bundle;
+import android.support.annotation.Nullable;
 import android.support.v7.widget.LinearLayoutManager;
 import android.view.MenuItem;
 
 import org.briarproject.bramble.api.contact.Contact;
+import org.briarproject.bramble.api.db.DatabaseExecutor;
 import org.briarproject.bramble.api.db.DbException;
+import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
+import org.briarproject.bramble.api.plugin.ConnectionRegistry;
 import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.briar.R;
 import org.briarproject.briar.android.activity.BriarActivity;
@@ -18,55 +23,53 @@ import java.util.Collection;
 import java.util.List;
 import java.util.logging.Logger;
 
+import javax.inject.Inject;
+
 import static java.util.logging.Level.WARNING;
 
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 abstract class SharingStatusActivity extends BriarActivity {
 
+	@Inject
+	ConnectionRegistry connectionRegistry;
+
 	private static final Logger LOG =
 			Logger.getLogger(SharingStatusActivity.class.getName());
 
 	private GroupId groupId;
-	private BriarRecyclerView sharedByList, sharedWithList;
-	private SharingStatusAdapter sharedByAdapter, sharedWithAdapter;
+	private BriarRecyclerView list;
+	private SharingStatusAdapter adapter;
 
 	@Override
-	public void onCreate(Bundle savedInstanceState) {
+	public void onCreate(@Nullable Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 
-		setContentView(R.layout.activity_sharing_status);
+		setContentView(R.layout.list);
 
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra(GROUP_ID);
 		if (b == null) throw new IllegalStateException("No GroupId");
 		groupId = new GroupId(b);
 
-		sharedByList = (BriarRecyclerView) findViewById(R.id.sharedByView);
-		sharedByAdapter = new SharingStatusAdapter(this);
-		sharedByList.setLayoutManager(new LinearLayoutManager(this));
-		sharedByList.setAdapter(sharedByAdapter);
-		sharedByList.setEmptyText(getString(R.string.nobody));
-
-		sharedWithList = (BriarRecyclerView) findViewById(R.id.sharedWithView);
-		sharedWithAdapter = new SharingStatusAdapter(this);
-		sharedWithList.setLayoutManager(new LinearLayoutManager(this));
-		sharedWithList.setAdapter(sharedWithAdapter);
-		sharedWithList.setEmptyText(getString(R.string.nobody));
+		list = (BriarRecyclerView) findViewById(R.id.list);
+		adapter = new SharingStatusAdapter(this);
+		list.setLayoutManager(new LinearLayoutManager(this));
+		list.setAdapter(adapter);
+		list.setEmptyText(getString(R.string.nobody));
 	}
 
 	@Override
 	public void onStart() {
 		super.onStart();
-		loadSharedBy();
 		loadSharedWith();
 	}
 
 	@Override
 	public void onStop() {
 		super.onStop();
-		sharedByAdapter.clear();
-		sharedByList.showProgressBar();
-		sharedWithAdapter.clear();
-		sharedWithList.showProgressBar();
+		adapter.clear();
+		list.showProgressBar();
 	}
 
 	@Override
@@ -81,49 +84,13 @@ abstract class SharingStatusActivity extends BriarActivity {
 		}
 	}
 
-	/**
-	 * This must only be called from the DbThread
-	 */
+	@DatabaseExecutor
 	abstract protected Collection<Contact> getSharedWith() throws DbException;
 
-	/**
-	 * This must only be called from the DbThread
-	 */
-	abstract protected Collection<Contact> getSharedBy() throws DbException;
-
 	protected GroupId getGroupId() {
 		return groupId;
 	}
 
-	private void loadSharedBy() {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					List<ContactItem> contactItems = new ArrayList<>();
-					for (Contact c : getSharedBy()) {
-						ContactItem item = new ContactItem(c);
-						contactItems.add(item);
-					}
-					displaySharedBy(contactItems);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
-			}
-		});
-	}
-
-	private void displaySharedBy(final List<ContactItem> contacts) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (contacts.isEmpty()) sharedByList.showData();
-				else sharedByAdapter.addAll(contacts);
-			}
-		});
-	}
-
 	private void loadSharedWith() {
 		runOnDbThread(new Runnable() {
 			@Override
@@ -131,7 +98,9 @@ abstract class SharingStatusActivity extends BriarActivity {
 				try {
 					List<ContactItem> contactItems = new ArrayList<>();
 					for (Contact c : getSharedWith()) {
-						ContactItem item = new ContactItem(c);
+						boolean online =
+								connectionRegistry.isConnected(c.getId());
+						ContactItem item = new ContactItem(c, online);
 						contactItems.add(item);
 					}
 					displaySharedWith(contactItems);
@@ -147,8 +116,8 @@ abstract class SharingStatusActivity extends BriarActivity {
 		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
-				if (contacts.isEmpty()) sharedWithList.showData();
-				else sharedWithAdapter.addAll(contacts);
+				if (contacts.isEmpty()) list.showData();
+				else adapter.addAll(contacts);
 			}
 		});
 	}
diff --git a/briar-android/src/main/res/layout/activity_sharing_status.xml b/briar-android/src/main/res/layout/activity_sharing_status.xml
deleted file mode 100644
index ee9153f477e454e0e787ea45f5ea9b848f55144d..0000000000000000000000000000000000000000
--- a/briar-android/src/main/res/layout/activity_sharing_status.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ScrollView
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="match_parent"
-	android:layout_height="match_parent">
-
-	<LinearLayout
-		android:layout_width="match_parent"
-		android:layout_height="wrap_content"
-		android:orientation="vertical">
-
-		<TextView
-			android:layout_width="match_parent"
-			android:layout_height="wrap_content"
-			android:background="@color/default_separator_inverted"
-			android:padding="@dimen/margin_medium"
-			android:text="@string/forum_shared_by"
-			android:textSize="@dimen/text_size_large"/>
-
-		<View style="@style/Divider.ForumList"/>
-
-		<org.briarproject.briar.android.view.BriarRecyclerView
-			android:id="@+id/sharedByView"
-			android:layout_width="match_parent"
-			android:layout_height="wrap_content"
-			android:paddingBottom="@dimen/margin_medium"
-			android:paddingTop="@dimen/margin_medium"/>
-
-		<TextView
-			android:layout_width="match_parent"
-			android:layout_height="wrap_content"
-			android:background="@color/default_separator_inverted"
-			android:padding="@dimen/margin_medium"
-			android:text="@string/forum_shared_with"
-			android:textSize="@dimen/text_size_large"/>
-
-		<View style="@style/Divider.ForumList"/>
-
-		<org.briarproject.briar.android.view.BriarRecyclerView
-			android:id="@+id/sharedWithView"
-			android:layout_width="match_parent"
-			android:layout_height="wrap_content"
-			android:paddingBottom="@dimen/margin_medium"
-			android:paddingTop="@dimen/margin_medium"/>
-
-	</LinearLayout>
-
-</ScrollView>
\ No newline at end of file
diff --git a/briar-android/src/main/res/layout/list_item_contact_small.xml b/briar-android/src/main/res/layout/list_item_contact_small.xml
index 66b4c44e38f493469ec224ff39c3363b85af2fb8..742c56c465070f9e18f66151d4a34db3c5fdcd74 100644
--- a/briar-android/src/main/res/layout/list_item_contact_small.xml
+++ b/briar-android/src/main/res/layout/list_item_contact_small.xml
@@ -5,28 +5,38 @@
 	android:layout_width="match_parent"
 	android:layout_height="wrap_content"
 	android:orientation="horizontal"
-	android:paddingBottom="@dimen/margin_small"
-	android:paddingTop="@dimen/margin_small">
+	android:paddingBottom="@dimen/margin_medium"
+	android:paddingTop="@dimen/margin_medium">
 
 	<de.hdodenhof.circleimageview.CircleImageView
 		android:id="@+id/avatarView"
 		style="@style/BriarAvatar"
 		android:layout_width="@dimen/listitem_picture_size_small"
 		android:layout_height="@dimen/listitem_picture_size_small"
+		android:layout_gravity="center_vertical"
 		android:layout_marginLeft="@dimen/listitem_horizontal_margin"
 		android:layout_marginStart="@dimen/listitem_horizontal_margin"
 		tools:src="@drawable/ic_launcher"/>
 
 	<org.thoughtcrime.securesms.components.emoji.EmojiTextView
 		android:id="@+id/nameView"
-		android:layout_width="wrap_content"
+		android:layout_width="0dp"
 		android:layout_height="wrap_content"
 		android:layout_gravity="center_vertical"
-		android:layout_marginLeft="@dimen/listitem_horizontal_margin"
-		android:layout_marginStart="@dimen/listitem_horizontal_margin"
+		android:layout_marginLeft="@dimen/margin_medium"
+		android:layout_marginStart="@dimen/margin_medium"
+		android:layout_weight="1"
 		android:maxLines="2"
 		android:textColor="@color/briar_text_primary"
 		android:textSize="@dimen/text_size_medium"
 		tools:text="This is a name of a contact"/>
 
-</LinearLayout>
\ No newline at end of file
+	<ImageView
+		android:id="@+id/bulbView"
+		android:layout_width="@dimen/listitem_horizontal_margin"
+		android:layout_height="@dimen/listitem_horizontal_margin"
+		android:layout_gravity="center_vertical"
+		android:layout_marginRight="@dimen/listitem_horizontal_margin"
+		tools:src="@drawable/contact_connected"/>
+
+</LinearLayout>
diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml
index e27a3ea9cacd4ed64af3ed35c18b8e7e058c0597..c8e80030db28aab8a0dc9f381c21cf80fbc663b3 100644
--- a/briar-android/src/main/res/values/strings.xml
+++ b/briar-android/src/main/res/values/strings.xml
@@ -262,8 +262,6 @@
 		<item quantity="one">%d forum shared by contacts</item>
 		<item quantity="other">%d forums shared by contacts</item>
 	</plurals>
-	<string name="forum_shared_by">Shared by</string>
-	<string name="forum_shared_with">Shared with</string>
 	<string name="nobody">Nobody</string>
 
 	<!-- Blogs -->
diff --git a/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingManager.java b/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingManager.java
index e4cff4876ead3adfe3448cbd2237d0629bcd4d0b..693c0f8b4204a2e3b59e65f011844f2033c4d4f7 100644
--- a/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingManager.java
+++ b/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingManager.java
@@ -47,11 +47,6 @@ public interface SharingManager<S extends Shareable>
 	 */
 	Collection<SharingInvitationItem> getInvitations() throws DbException;
 
-	/**
-	 * Returns all contacts who are sharing the given group with us.
-	 */
-	Collection<Contact> getSharedBy(GroupId g) throws DbException;
-
 	/**
 	 * Returns all contacts with whom the given group is shared.
 	 */
diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java
index b68187b07831d7ed96bf33fc16506ee675560280..ba160b2b5745393155b078383330b8aaa8126fb2 100644
--- a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java
@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.client.ClientHelper;
 import org.briarproject.bramble.api.client.ContactGroupFactory;
 import org.briarproject.bramble.api.contact.Contact;
 import org.briarproject.bramble.api.contact.ContactId;
+import org.briarproject.bramble.api.contact.ContactManager;
 import org.briarproject.bramble.api.data.BdfDictionary;
 import org.briarproject.bramble.api.data.BdfList;
 import org.briarproject.bramble.api.data.MetadataEncoder;
@@ -37,6 +38,7 @@ import org.briarproject.briar.api.client.SessionId;
 import org.briarproject.briar.api.sharing.InvitationMessage;
 
 import java.security.SecureRandom;
+import java.util.Collection;
 
 import javax.annotation.concurrent.Immutable;
 import javax.inject.Inject;
@@ -52,6 +54,7 @@ class BlogSharingManagerImpl extends
 		SharingManagerImpl<Blog, BlogInvitation, BlogInviteeSessionState, BlogSharerSessionState, BlogInvitationRequestReceivedEvent, BlogInvitationResponseReceivedEvent>
 		implements BlogSharingManager, RemoveBlogHook {
 
+	private final ContactManager contactManager;
 	private final IdentityManager identityManager;
 	private final BlogManager blogManager;
 
@@ -68,13 +71,15 @@ class BlogSharingManagerImpl extends
 			DatabaseComponent db, MessageQueueManager messageQueueManager,
 			MetadataEncoder metadataEncoder, MetadataParser metadataParser,
 			ContactGroupFactory contactGroupFactory, SecureRandom random,
-			IdentityManager identityManager, MessageTracker messageTracker) {
+			ContactManager contactManager, IdentityManager identityManager,
+			MessageTracker messageTracker) {
 
 		super(db, messageQueueManager, clientHelper, metadataParser,
 				metadataEncoder, random, contactGroupFactory, messageTracker,
 				clock);
 
 		this.blogManager = blogManager;
+		this.contactManager = contactManager;
 		this.identityManager = identityManager;
 		sFactory = new SFactory(authorFactory, blogFactory, blogManager);
 		iFactory = new IFactory();
@@ -105,6 +110,27 @@ class BlogSharingManagerImpl extends
 		return super.canBeShared(txn, g, c);
 	}
 
+	@Override
+	public Collection<Contact> getSharedWith(GroupId g) throws DbException {
+		Blog blog = blogManager.getBlog(g);
+		LocalAuthor author = identityManager.getLocalAuthor();
+		if (blog.getAuthor().equals(author)) {
+			// This is our personal blog. It is shared with all our contacts
+			return contactManager.getActiveContacts();
+		} else {
+			// This is someone else's blog. Look up who it is shared with
+			Collection<Contact> shared = super.getSharedWith(g);
+			// If the blog author is our contact, also add her to the list
+			boolean isContact = contactManager
+					.contactExists(blog.getAuthor().getId(), author.getId());
+			if (isContact) {
+				shared.add(contactManager
+						.getContact(blog.getAuthor().getId(), author.getId()));
+			}
+			return shared;
+		}
+	}
+
 	@Override
 	protected InvitationMessage createInvitationRequest(MessageId id,
 			BlogInvitation msg, ContactId contactId, boolean available,
diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java
index 4c99ceb54a5c9742f5e63be0a39619dc0156b37f..c1d54f4f9a9866a74cc568658e7ae0f95af166f8 100644
--- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java
@@ -514,34 +514,6 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
 		return invited;
 	}
 
-	@Override
-	public Collection<Contact> getSharedBy(GroupId g) throws DbException {
-		List<Contact> subscribers;
-		Transaction txn = db.startTransaction(true);
-		try {
-			subscribers = getSharedBy(txn, g);
-			db.commitTransaction(txn);
-		} finally {
-			db.endTransaction(txn);
-		}
-		return subscribers;
-	}
-
-	private List<Contact> getSharedBy(Transaction txn, GroupId g)
-			throws DbException {
-		try {
-			List<Contact> subscribers = new ArrayList<Contact>();
-			for (Contact c : db.getContacts(txn)) {
-				GroupId contactGroup = getContactGroup(c).getId();
-				if (listContains(txn, contactGroup, g, SHARED_WITH_US))
-					subscribers.add(c);
-			}
-			return subscribers;
-		} catch (IOException e) {
-			throw new DbException(e);
-		}
-	}
-
 	@Override
 	public Collection<Contact> getSharedWith(GroupId g) throws DbException {
 		try {
@@ -552,6 +524,8 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
 					GroupId contactGroup = getContactGroup(c).getId();
 					if (listContains(txn, contactGroup, g, SHARED_BY_US))
 						shared.add(c);
+					else if (listContains(txn, contactGroup, g, SHARED_WITH_US))
+						shared.add(c);
 				}
 				db.commitTransaction(txn);
 			} finally {
diff --git a/briar-tests/src/org/briarproject/bramble/contact/ContactManagerImplTest.java b/briar-tests/src/org/briarproject/bramble/contact/ContactManagerImplTest.java
index 99243107e4f47d912114780564ebe050dc273222..d4f6bfc9762cf70bf1982ae094f2d870f1fd2e4b 100644
--- a/briar-tests/src/org/briarproject/bramble/contact/ContactManagerImplTest.java
+++ b/briar-tests/src/org/briarproject/bramble/contact/ContactManagerImplTest.java
@@ -1,11 +1,12 @@
 package org.briarproject.bramble.contact;
 
-import org.briarproject.BriarTestCase;
+import org.briarproject.BriarMockTestCase;
 import org.briarproject.bramble.api.contact.Contact;
 import org.briarproject.bramble.api.contact.ContactId;
 import org.briarproject.bramble.api.contact.ContactManager;
 import org.briarproject.bramble.api.crypto.SecretKey;
 import org.briarproject.bramble.api.db.DatabaseComponent;
+import org.briarproject.bramble.api.db.NoSuchContactException;
 import org.briarproject.bramble.api.db.Transaction;
 import org.briarproject.bramble.api.identity.Author;
 import org.briarproject.bramble.api.identity.AuthorId;
@@ -24,7 +25,7 @@ import static org.briarproject.TestUtils.getSecretKey;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-public class ContactManagerImplTest extends BriarTestCase {
+public class ContactManagerImplTest extends BriarMockTestCase {
 
 	private final Mockery context = new Mockery();
 	private final DatabaseComponent db = context.mock(DatabaseComponent.class);
@@ -66,7 +67,6 @@ public class ContactManagerImplTest extends BriarTestCase {
 		assertEquals(contactId, contactManager
 				.addContact(remote, local, master, timestamp, alice, verified,
 						active));
-		context.assertIsSatisfied();
 	}
 
 	@Test
@@ -82,7 +82,51 @@ public class ContactManagerImplTest extends BriarTestCase {
 		}});
 
 		assertEquals(contact, contactManager.getContact(contactId));
-		context.assertIsSatisfied();
+	}
+
+	@Test
+	public void testGetContactByAuthor() throws Exception {
+		final Transaction txn = new Transaction(null, true);
+		final Collection<Contact> contacts = Collections.singleton(contact);
+		context.checking(new Expectations() {{
+			oneOf(db).startTransaction(true);
+			will(returnValue(txn));
+			oneOf(db).getContactsByAuthorId(txn, remote.getId());
+			will(returnValue(contacts));
+			oneOf(db).commitTransaction(txn);
+			oneOf(db).endTransaction(txn);
+		}});
+
+		assertEquals(contact, contactManager.getContact(remote.getId(), local));
+	}
+
+	@Test(expected = NoSuchContactException.class)
+	public void testGetContactByUnknownAuthor() throws Exception {
+		final Transaction txn = new Transaction(null, true);
+		context.checking(new Expectations() {{
+			oneOf(db).startTransaction(true);
+			will(returnValue(txn));
+			oneOf(db).getContactsByAuthorId(txn, remote.getId());
+			will(returnValue(Collections.emptyList()));
+			oneOf(db).endTransaction(txn);
+		}});
+
+		contactManager.getContact(remote.getId(), local);
+	}
+
+	@Test(expected = NoSuchContactException.class)
+	public void testGetContactByUnknownLocalAuthor() throws Exception {
+		final Transaction txn = new Transaction(null, true);
+		final Collection<Contact> contacts = Collections.singleton(contact);
+		context.checking(new Expectations() {{
+			oneOf(db).startTransaction(true);
+			will(returnValue(txn));
+			oneOf(db).getContactsByAuthorId(txn, remote.getId());
+			will(returnValue(contacts));
+			oneOf(db).endTransaction(txn);
+		}});
+
+		contactManager.getContact(remote.getId(), new AuthorId(getRandomId()));
 	}
 
 	@Test
@@ -101,7 +145,6 @@ public class ContactManagerImplTest extends BriarTestCase {
 		}});
 
 		assertEquals(activeContacts, contactManager.getActiveContacts());
-		context.assertIsSatisfied();
 	}
 
 	@Test
@@ -118,7 +161,6 @@ public class ContactManagerImplTest extends BriarTestCase {
 		}});
 
 		contactManager.removeContact(contactId);
-		context.assertIsSatisfied();
 	}
 
 	@Test
@@ -129,7 +171,6 @@ public class ContactManagerImplTest extends BriarTestCase {
 		}});
 
 		contactManager.setContactActive(txn, contactId, active);
-		context.assertIsSatisfied();
 	}
 
 	@Test
@@ -145,7 +186,6 @@ public class ContactManagerImplTest extends BriarTestCase {
 		}});
 
 		assertTrue(contactManager.contactExists(remote.getId(), local));
-		context.assertIsSatisfied();
 	}
 
 }