diff --git a/briar-android/src/org/briarproject/android/ActivityComponent.java b/briar-android/src/org/briarproject/android/ActivityComponent.java
index 7f5b272848905c73f66dfc20263bd60d01dc527a..01f39081f52a55dcc041b924a7ea97d134c93da1 100644
--- a/briar-android/src/org/briarproject/android/ActivityComponent.java
+++ b/briar-android/src/org/briarproject/android/ActivityComponent.java
@@ -6,10 +6,8 @@ import org.briarproject.android.blogs.BlogActivity;
 import org.briarproject.android.blogs.BlogFragment;
 import org.briarproject.android.blogs.BlogModule;
 import org.briarproject.android.blogs.BlogPostFragment;
-import org.briarproject.android.blogs.BlogPostPagerFragment;
 import org.briarproject.android.blogs.FeedFragment;
 import org.briarproject.android.blogs.FeedPostFragment;
-import org.briarproject.android.blogs.FeedPostPagerFragment;
 import org.briarproject.android.blogs.ReblogActivity;
 import org.briarproject.android.blogs.ReblogFragment;
 import org.briarproject.android.blogs.RssFeedImportActivity;
@@ -132,10 +130,6 @@ public interface ActivityComponent {
 
 	void inject(FeedPostFragment fragment);
 
-	void inject(BlogPostPagerFragment fragment);
-
-	void inject(FeedPostPagerFragment fragment);
-
 	void inject(ReblogFragment fragment);
 
 	void inject(ReblogActivity activity);
diff --git a/briar-android/src/org/briarproject/android/blogs/BaseController.java b/briar-android/src/org/briarproject/android/blogs/BaseController.java
index 9e94d668de1d3b2fdb8fec4d4ab804552e648f9f..6b81243ec6c1fbdb8dda0d6dcbbf812545107fae 100644
--- a/briar-android/src/org/briarproject/android/blogs/BaseController.java
+++ b/briar-android/src/org/briarproject/android/blogs/BaseController.java
@@ -8,6 +8,7 @@ import org.briarproject.android.controller.handler.ExceptionHandler;
 import org.briarproject.android.controller.handler.ResultExceptionHandler;
 import org.briarproject.api.blogs.BlogPostHeader;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.nullsafety.NotNullByDefault;
 import org.briarproject.api.sync.GroupId;
 import org.briarproject.api.sync.MessageId;
 
@@ -33,9 +34,10 @@ interface BaseController {
 	void repeatPost(BlogPostItem item, @Nullable String comment,
 			ExceptionHandler<DbException> handler);
 
-	void setOnBlogPostAddedListener(OnBlogPostAddedListener listener);
+	void setBlogListener(BlogListener listener);
 
-	interface OnBlogPostAddedListener extends DestroyableContext {
+	@NotNullByDefault
+	interface BlogListener extends DestroyableContext {
 
 		@UiThread
 		void onBlogPostAdded(BlogPostHeader header, boolean local);
diff --git a/briar-android/src/org/briarproject/android/blogs/BaseControllerImpl.java b/briar-android/src/org/briarproject/android/blogs/BaseControllerImpl.java
index ec563fbf37e7572e89183932687fd2ed53e87d04..04d9e2d164bed702e1cbee888a5cac938c953f91 100644
--- a/briar-android/src/org/briarproject/android/blogs/BaseControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/blogs/BaseControllerImpl.java
@@ -46,7 +46,7 @@ abstract class BaseControllerImpl extends DbControllerImpl
 	private final Map<MessageId, BlogPostHeader> headerCache =
 			new ConcurrentHashMap<>();
 
-	private volatile OnBlogPostAddedListener listener;
+	private volatile BlogListener listener;
 
 	BaseControllerImpl(@DatabaseExecutor Executor dbExecutor,
 			LifecycleManager lifecycleManager, EventBus eventBus,
@@ -73,7 +73,7 @@ abstract class BaseControllerImpl extends DbControllerImpl
 	}
 
 	@Override
-	public void setOnBlogPostAddedListener(OnBlogPostAddedListener listener) {
+	public void setBlogListener(BlogListener listener) {
 		this.listener = listener;
 	}
 
diff --git a/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java b/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java
index 9e2db81dc85c5cf54e9831f5902e1ee5fc2b1f15..8717acac1fde806184e03ecc9d92e6f3ac181cae 100644
--- a/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java
@@ -11,7 +11,8 @@ import android.widget.ProgressBar;
 
 import org.briarproject.R;
 import org.briarproject.android.fragment.BaseFragment;
-import org.briarproject.api.db.DbException;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
 
 import java.util.logging.Logger;
 
@@ -19,8 +20,13 @@ import static android.view.View.INVISIBLE;
 import static android.view.View.VISIBLE;
 import static org.briarproject.android.util.AndroidUtils.MIN_RESOLUTION;
 
+@UiThread
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 abstract class BasePostFragment extends BaseFragment {
 
+	static final String POST_ID = "briar.POST_ID";
+
 	private static final Logger LOG =
 			Logger.getLogger(BasePostFragment.class.getName());
 
@@ -33,8 +39,9 @@ abstract class BasePostFragment extends BaseFragment {
 	@CallSuper
 	@Nullable
 	@Override
-	public View onCreateView(LayoutInflater inflater, ViewGroup container,
-			Bundle savedInstanceState) {
+	public View onCreateView(LayoutInflater inflater,
+			@Nullable ViewGroup container,
+			@Nullable Bundle savedInstanceState) {
 		view = inflater.inflate(R.layout.fragment_blog_post, container,
 				false);
 		progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
@@ -64,12 +71,6 @@ abstract class BasePostFragment extends BaseFragment {
 		ui.bindItem(post);
 	}
 
-	@UiThread
-	protected void onBlogPostLoadException(DbException exception) {
-		// TODO: Decide how to handle errors in the UI
-		finish();
-	}
-
 	private void startPeriodicUpdate() {
 		refresher = new Runnable() {
 			@Override
diff --git a/briar-android/src/org/briarproject/android/blogs/BasePostPagerFragment.java b/briar-android/src/org/briarproject/android/blogs/BasePostPagerFragment.java
deleted file mode 100644
index 424fa5d45d725570a20439da8b1d7cf16ccca5be..0000000000000000000000000000000000000000
--- a/briar-android/src/org/briarproject/android/blogs/BasePostPagerFragment.java
+++ /dev/null
@@ -1,183 +0,0 @@
-package org.briarproject.android.blogs;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.annotation.UiThread;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentStatePagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ProgressBar;
-
-import org.briarproject.R;
-import org.briarproject.android.blogs.BaseController.OnBlogPostAddedListener;
-import org.briarproject.android.fragment.BaseFragment;
-import org.briarproject.api.blogs.BlogPostHeader;
-import org.briarproject.api.db.DbException;
-import org.briarproject.api.sync.MessageId;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import static android.view.View.INVISIBLE;
-import static android.view.View.VISIBLE;
-import static org.briarproject.android.blogs.BasePostPagerFragment.BlogPostPagerAdapter.INVALID_POSITION;
-
-abstract class BasePostPagerFragment extends BaseFragment
-		implements OnBlogPostAddedListener {
-
-	static final String POST_ID = "briar.POST_ID";
-
-	private ViewPager pager;
-	private ProgressBar progressBar;
-	private BlogPostPagerAdapter postPagerAdapter;
-	private MessageId postId;
-
-	@Nullable
-	@Override
-	public View onCreateView(LayoutInflater inflater, ViewGroup container,
-			Bundle state) {
-
-		Bundle args;
-		if (state == null) args = getArguments();
-		else args = state;
-		byte[] p = args.getByteArray(POST_ID);
-		if (p == null)
-			throw new IllegalStateException("No post ID in args");
-		postId = new MessageId(p);
-
-		View v = inflater.inflate(R.layout.fragment_blog_post_pager, container,
-				false);
-		progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
-		progressBar.setVisibility(VISIBLE);
-
-		pager = (ViewPager) v.findViewById(R.id.pager);
-		postPagerAdapter = new BlogPostPagerAdapter(getChildFragmentManager());
-
-		return v;
-	}
-
-	@Override
-	public void onStart() {
-		super.onStart();
-		if (postId == null) {
-			MessageId selected = getSelectedPost();
-			if (selected != null) loadBlogPosts(selected);
-		} else {
-			loadBlogPosts(postId);
-		}
-	}
-
-	@Override
-	public void onSaveInstanceState(Bundle outState) {
-		super.onSaveInstanceState(outState);
-		MessageId selected = getSelectedPost();
-		if (selected != null)
-			outState.putByteArray(POST_ID, selected.getBytes());
-	}
-
-	@Override
-	public void onBlogPostAdded(BlogPostHeader header, boolean local) {
-		loadBlogPost(header);
-	}
-
-	abstract void loadBlogPosts(final MessageId select);
-
-	abstract void loadBlogPost(BlogPostHeader header);
-
-	@UiThread
-	protected void onBlogPostsLoaded(MessageId select,
-			Collection<BlogPostItem> posts) {
-
-		postId = null;
-		postPagerAdapter.setPosts(posts);
-		selectPost(select);
-	}
-
-	@UiThread
-	protected void onBlogPostsLoadedException(DbException exception) {
-		// TODO: Decide how to handle errors in the UI
-		finish();
-	}
-
-	@Nullable
-	private MessageId getSelectedPost() {
-		if (postPagerAdapter.getCount() == 0) return null;
-		int position = pager.getCurrentItem();
-		return postPagerAdapter.getPost(position).getId();
-	}
-
-	private void selectPost(MessageId m) {
-		int pos = postPagerAdapter.getPostPosition(m);
-		if (pos != INVALID_POSITION) {
-			progressBar.setVisibility(INVISIBLE);
-			pager.setAdapter(postPagerAdapter);
-			pager.setCurrentItem(pos);
-		}
-	}
-
-	protected void addPost(BlogPostItem post) {
-		MessageId selected = getSelectedPost();
-		postPagerAdapter.addPost(post);
-		if (selected != null) selectPost(selected);
-	}
-
-	@UiThread
-	static class BlogPostPagerAdapter extends FragmentStatePagerAdapter {
-
-		static final int INVALID_POSITION = -1;
-		private final List<BlogPostItem> posts = new ArrayList<>();
-
-		private BlogPostPagerAdapter(FragmentManager fm) {
-			super(fm);
-		}
-
-		@Override
-		public int getCount() {
-			return posts.size();
-		}
-
-		@Override
-		public Fragment getItem(int position) {
-			BlogPostItem post = posts.get(position);
-			return FeedPostFragment.newInstance(post.getGroupId(), post.getId());
-		}
-
-		private BlogPostItem getPost(int position) {
-			return posts.get(position);
-		}
-
-		private void setPosts(Collection<BlogPostItem> posts) {
-			this.posts.clear();
-			this.posts.addAll(posts);
-			Collections.sort(this.posts);
-			notifyDataSetChanged();
-		}
-
-		private void addPost(BlogPostItem post) {
-			posts.add(post);
-			Collections.sort(posts);
-			notifyDataSetChanged();
-		}
-
-		private int getPostPosition(MessageId m) {
-			int count = getCount();
-			for (int i = 0; i < count; i++) {
-				if (getPost(i).getId().equals(m)) {
-					return i;
-				}
-			}
-			return INVALID_POSITION;
-		}
-	}
-
-	@Override
-	public void onBlogRemoved() {
-		finish();
-	}
-}
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogActivity.java b/briar-android/src/org/briarproject/android/blogs/BlogActivity.java
index 116fc8ac8c75679c654a3194a14bfb2e2160486b..a52d4437664e94ac689eb19883fda60fd1641994 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogActivity.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogActivity.java
@@ -49,7 +49,7 @@ public class BlogActivity extends BriarActivity implements
 
 	@Override
 	public void onBlogPostClick(BlogPostItem post) {
-		BlogPostPagerFragment f = BlogPostPagerFragment.newInstance(post.getId());
+		BlogPostFragment f = BlogPostFragment.newInstance(post.getId());
 		getSupportFragmentManager().beginTransaction()
 				.replace(R.id.fragmentContainer, f, f.getUniqueTag())
 				.addToBackStack(f.getUniqueTag())
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogFragment.java b/briar-android/src/org/briarproject/android/blogs/BlogFragment.java
index fb5f43edc7b91c85eedefa7297fb733623129b58..a7273fd61fcd40d1dc476350326e5a9281cb0a6f 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogFragment.java
@@ -4,6 +4,7 @@ import android.content.DialogInterface;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
 import android.support.design.widget.Snackbar;
 import android.support.v4.app.ActivityOptionsCompat;
 import android.support.v4.content.ContextCompat;
@@ -19,7 +20,7 @@ import android.widget.Toast;
 
 import org.briarproject.R;
 import org.briarproject.android.ActivityComponent;
-import org.briarproject.android.blogs.BaseController.OnBlogPostAddedListener;
+import org.briarproject.android.blogs.BaseController.BlogListener;
 import org.briarproject.android.blogs.BlogPostAdapter.OnBlogPostClickListener;
 import org.briarproject.android.controller.handler.UiResultExceptionHandler;
 import org.briarproject.android.fragment.BaseFragment;
@@ -46,10 +47,11 @@ import static org.briarproject.android.BriarActivity.GROUP_ID;
 import static org.briarproject.android.blogs.BlogActivity.REQUEST_SHARE;
 import static org.briarproject.android.blogs.BlogActivity.REQUEST_WRITE_POST;
 
+@UiThread
 @MethodsNotNullByDefault
 @ParametersNotNullByDefault
 public class BlogFragment extends BaseFragment implements
-		OnBlogPostAddedListener {
+		BlogListener {
 
 	private final static String TAG = BlogFragment.class.getName();
 
@@ -99,7 +101,7 @@ public class BlogFragment extends BaseFragment implements
 	@Override
 	public void injectFragment(ActivityComponent component) {
 		component.inject(this);
-		blogController.setOnBlogPostAddedListener(this);
+		blogController.setBlogListener(this);
 	}
 
 	@Override
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostFragment.java b/briar-android/src/org/briarproject/android/blogs/BlogPostFragment.java
index 78b82874fc6e01a664bac2ad229ee2579344c9d0..2a0ecf19297eb2157449bcdd38c77fab45e8fe48 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogPostFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogPostFragment.java
@@ -2,6 +2,7 @@ package org.briarproject.android.blogs;
 
 import android.os.Bundle;
 import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -9,15 +10,18 @@ import android.view.ViewGroup;
 import org.briarproject.android.ActivityComponent;
 import org.briarproject.android.controller.handler.UiResultExceptionHandler;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
 import org.briarproject.api.sync.MessageId;
 
 import javax.inject.Inject;
 
-import static org.briarproject.android.blogs.BasePostPagerFragment.POST_ID;
-
+@UiThread
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 public class BlogPostFragment extends BasePostFragment {
 
-	public final static String TAG = BlogPostFragment.class.getName();
+	private static final String TAG = BlogPostFragment.class.getName();
 
 	private MessageId postId;
 
@@ -36,8 +40,9 @@ public class BlogPostFragment extends BasePostFragment {
 
 	@Nullable
 	@Override
-	public View onCreateView(LayoutInflater inflater, ViewGroup container,
-			Bundle savedInstanceState) {
+	public View onCreateView(LayoutInflater inflater,
+			@Nullable ViewGroup container,
+			@Nullable Bundle savedInstanceState) {
 
 		Bundle args = getArguments();
 		byte[] p = args.getByteArray(POST_ID);
@@ -67,9 +72,11 @@ public class BlogPostFragment extends BasePostFragment {
 					public void onResultUi(BlogPostItem post) {
 						onBlogPostLoaded(post);
 					}
+
 					@Override
 					public void onExceptionUi(DbException exception) {
-						onBlogPostLoadException(exception);
+						// TODO: Decide how to handle errors in the UI
+						finish();
 					}
 				});
 	}
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostItem.java b/briar-android/src/org/briarproject/android/blogs/BlogPostItem.java
index 64295c731713576dad6f891dcab7ca0a46b61e04..debcfd544686a6f2de9818ecba92ac36fb231263 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogPostItem.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogPostItem.java
@@ -9,7 +9,9 @@ import org.briarproject.api.identity.Author.Status;
 import org.briarproject.api.sync.GroupId;
 import org.briarproject.api.sync.MessageId;
 
-// This class is not thread-safe
+import javax.annotation.concurrent.NotThreadSafe;
+
+@NotThreadSafe
 public class BlogPostItem implements Comparable<BlogPostItem> {
 
 	private final BlogPostHeader header;
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java b/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java
deleted file mode 100644
index 7c63d5c7d84a6ced24217e2a310ae8ff4eb49954..0000000000000000000000000000000000000000
--- a/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.briarproject.android.blogs;
-
-import android.os.Bundle;
-
-import org.briarproject.android.ActivityComponent;
-import org.briarproject.android.controller.handler.UiResultExceptionHandler;
-import org.briarproject.api.blogs.BlogPostHeader;
-import org.briarproject.api.db.DbException;
-import org.briarproject.api.sync.MessageId;
-
-import java.util.Collection;
-
-import javax.inject.Inject;
-
-public class BlogPostPagerFragment extends BasePostPagerFragment {
-
-	public final static String TAG = BlogPostPagerFragment.class.getName();
-
-	@Inject
-	BlogController blogController;
-
-	static BlogPostPagerFragment newInstance(MessageId postId) {
-		BlogPostPagerFragment f = new BlogPostPagerFragment();
-
-		Bundle args = new Bundle();
-		args.putByteArray(POST_ID, postId.getBytes());
-		f.setArguments(args);
-
-		return f;
-	}
-
-	@Override
-	public void injectFragment(ActivityComponent component) {
-		component.inject(this);
-		blogController.setOnBlogPostAddedListener(this);
-	}
-
-	@Override
-	public String getUniqueTag() {
-		return TAG;
-	}
-
-
-	@Override
-	void loadBlogPosts(final MessageId select) {
-		blogController.loadBlogPosts(
-				new UiResultExceptionHandler<Collection<BlogPostItem>, DbException>(
-						this) {
-					@Override
-					public void onResultUi(Collection<BlogPostItem> posts) {
-						onBlogPostsLoaded(select, posts);
-					}
-
-					@Override
-					public void onExceptionUi(DbException exception) {
-						onBlogPostsLoadedException(exception);
-					}
-				});
-	}
-
-	@Override
-	void loadBlogPost(BlogPostHeader header) {
-		blogController.loadBlogPost(header,
-				new UiResultExceptionHandler<BlogPostItem, DbException>(
-						this) {
-					@Override
-					public void onResultUi(BlogPostItem post) {
-						addPost(post);
-					}
-
-					@Override
-					public void onExceptionUi(DbException exception) {
-						// TODO: Decide how to handle errors in the UI
-						finish();
-					}
-				});
-	}
-}
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostViewHolder.java b/briar-android/src/org/briarproject/android/blogs/BlogPostViewHolder.java
index aeaa23880ec813e13d639f23cac7ad50088a7be0..784e60b7f3f5b6a869344d03a00abaebd74d786e 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogPostViewHolder.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogPostViewHolder.java
@@ -30,7 +30,7 @@ import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAn
 import static android.view.View.GONE;
 import static android.view.View.VISIBLE;
 import static org.briarproject.android.BriarActivity.GROUP_ID;
-import static org.briarproject.android.blogs.BasePostPagerFragment.POST_ID;
+import static org.briarproject.android.blogs.BasePostFragment.POST_ID;
 import static org.briarproject.android.util.AndroidUtils.TEASER_LENGTH;
 import static org.briarproject.android.util.AndroidUtils.getSpanned;
 import static org.briarproject.android.util.AndroidUtils.getTeaser;
diff --git a/briar-android/src/org/briarproject/android/blogs/FeedController.java b/briar-android/src/org/briarproject/android/blogs/FeedController.java
index 90015b066f6a17f9a79dc76c1d8dd66e6fc04cde..76ab1baa23bf0e351f2fac7997b7c9c9ead97f34 100644
--- a/briar-android/src/org/briarproject/android/blogs/FeedController.java
+++ b/briar-android/src/org/briarproject/android/blogs/FeedController.java
@@ -1,8 +1,11 @@
 package org.briarproject.android.blogs;
 
+import android.support.annotation.UiThread;
+
 import org.briarproject.android.controller.handler.ResultExceptionHandler;
 import org.briarproject.api.blogs.Blog;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.nullsafety.NotNullByDefault;
 
 import java.util.Collection;
 
@@ -13,4 +16,12 @@ public interface FeedController extends BaseController {
 
 	void loadPersonalBlog(ResultExceptionHandler<Blog, DbException> handler);
 
+	void setFeedListener(FeedListener listener);
+
+	@NotNullByDefault
+	interface FeedListener extends BlogListener {
+
+		@UiThread
+		void onBlogAdded();
+	}
 }
diff --git a/briar-android/src/org/briarproject/android/blogs/FeedControllerImpl.java b/briar-android/src/org/briarproject/android/blogs/FeedControllerImpl.java
index a70097b34d2daf1f53d7e6cc66653fbbe7a48663..1c5cee0ca2b359c5e18ebb836e0a6cfff3137879 100644
--- a/briar-android/src/org/briarproject/android/blogs/FeedControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/blogs/FeedControllerImpl.java
@@ -11,6 +11,7 @@ import org.briarproject.api.db.NoSuchMessageException;
 import org.briarproject.api.event.BlogPostAddedEvent;
 import org.briarproject.api.event.Event;
 import org.briarproject.api.event.EventBus;
+import org.briarproject.api.event.GroupAddedEvent;
 import org.briarproject.api.event.GroupRemovedEvent;
 import org.briarproject.api.identity.Author;
 import org.briarproject.api.identity.IdentityManager;
@@ -33,6 +34,8 @@ class FeedControllerImpl extends BaseControllerImpl
 	private static final Logger LOG =
 			Logger.getLogger(FeedControllerImpl.class.getName());
 
+	private volatile FeedListener listener;
+
 	@Inject
 	FeedControllerImpl(@DatabaseExecutor Executor dbExecutor,
 			LifecycleManager lifecycleManager, EventBus eventBus,
@@ -45,6 +48,7 @@ class FeedControllerImpl extends BaseControllerImpl
 	@Override
 	public void onStart() {
 		super.onStart();
+		if (listener == null) throw new IllegalStateException();
 		notificationManager.blockAllBlogPostNotifications();
 		notificationManager.clearAllBlogPostNotifications();
 	}
@@ -55,12 +59,24 @@ class FeedControllerImpl extends BaseControllerImpl
 		notificationManager.unblockAllBlogPostNotifications();
 	}
 
+	@Override
+	public void setFeedListener(FeedListener listener) {
+		super.setBlogListener(listener);
+		this.listener = listener;
+	}
+
 	@Override
 	public void eventOccurred(Event e) {
 		if (e instanceof BlogPostAddedEvent) {
 			BlogPostAddedEvent b = (BlogPostAddedEvent) e;
 			LOG.info("Blog post added");
 			onBlogPostAdded(b.getHeader(), b.isLocal());
+		} else if (e instanceof GroupAddedEvent) {
+			GroupAddedEvent g = (GroupAddedEvent) e;
+			if (g.getGroup().getClientId().equals(CLIENT_ID)) {
+				LOG.info("Blog added");
+				onBlogAdded();
+			}
 		} else if (e instanceof GroupRemovedEvent) {
 			GroupRemovedEvent g = (GroupRemovedEvent) e;
 			if (g.getGroup().getClientId().equals(CLIENT_ID)) {
@@ -70,6 +86,15 @@ class FeedControllerImpl extends BaseControllerImpl
 		}
 	}
 
+	private void onBlogAdded() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
+			@Override
+			public void run() {
+				listener.onBlogAdded();
+			}
+		});
+	}
+
 	@Override
 	public void loadBlogPosts(
 			final ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
diff --git a/briar-android/src/org/briarproject/android/blogs/FeedFragment.java b/briar-android/src/org/briarproject/android/blogs/FeedFragment.java
index 60d8ed7c3ec21827da5ad541edb918d0db8bdc57..e829c08962d5ca0193203f01c3f3dd381b91e946 100644
--- a/briar-android/src/org/briarproject/android/blogs/FeedFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/FeedFragment.java
@@ -3,6 +3,7 @@ package org.briarproject.android.blogs;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
 import android.support.design.widget.Snackbar;
 import android.support.v4.app.ActivityOptionsCompat;
 import android.support.v4.content.ContextCompat;
@@ -17,14 +18,16 @@ import android.view.ViewGroup;
 
 import org.briarproject.R;
 import org.briarproject.android.ActivityComponent;
-import org.briarproject.android.blogs.BaseController.OnBlogPostAddedListener;
 import org.briarproject.android.blogs.BlogPostAdapter.OnBlogPostClickListener;
+import org.briarproject.android.blogs.FeedController.FeedListener;
 import org.briarproject.android.controller.handler.UiResultExceptionHandler;
 import org.briarproject.android.fragment.BaseFragment;
 import org.briarproject.android.view.BriarRecyclerView;
 import org.briarproject.api.blogs.Blog;
 import org.briarproject.api.blogs.BlogPostHeader;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
 
 import java.util.Collection;
 import java.util.logging.Logger;
@@ -37,8 +40,11 @@ import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
 import static org.briarproject.android.BriarActivity.GROUP_ID;
 import static org.briarproject.android.blogs.BlogActivity.REQUEST_WRITE_POST;
 
+@UiThread
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 public class FeedFragment extends BaseFragment implements
-		OnBlogPostClickListener, OnBlogPostAddedListener {
+		OnBlogPostClickListener, FeedListener {
 
 	public final static String TAG = FeedFragment.class.getName();
 	private static final Logger LOG = Logger.getLogger(TAG);
@@ -62,8 +68,9 @@ public class FeedFragment extends BaseFragment implements
 
 	@Nullable
 	@Override
-	public View onCreateView(LayoutInflater inflater, ViewGroup container,
-			Bundle savedInstanceState) {
+	public View onCreateView(LayoutInflater inflater,
+			@Nullable ViewGroup container,
+			@Nullable Bundle savedInstanceState) {
 
 		View v = inflater.inflate(R.layout.fragment_blog, container, false);
 
@@ -81,7 +88,7 @@ public class FeedFragment extends BaseFragment implements
 	@Override
 	public void injectFragment(ActivityComponent component) {
 		component.inject(this);
-		feedController.setOnBlogPostAddedListener(this);
+		feedController.setFeedListener(this);
 	}
 
 	@Override
@@ -216,8 +223,8 @@ public class FeedFragment extends BaseFragment implements
 
 	@Override
 	public void onBlogPostClick(BlogPostItem post) {
-		FeedPostPagerFragment f = FeedPostPagerFragment
-				.newInstance(post.getId());
+		FeedPostFragment f =
+				FeedPostFragment.newInstance(post.getGroupId(), post.getId());
 		getActivity().getSupportFragmentManager().beginTransaction()
 				.replace(R.id.content_fragment, f, f.getUniqueTag())
 				.addToBackStack(f.getUniqueTag())
@@ -253,6 +260,11 @@ public class FeedFragment extends BaseFragment implements
 		s.show();
 	}
 
+	@Override
+	public void onBlogAdded() {
+		loadBlogPosts(false);
+	}
+
 	@Override
 	public void onBlogRemoved() {
 		loadBlogPosts(true);
diff --git a/briar-android/src/org/briarproject/android/blogs/FeedPostFragment.java b/briar-android/src/org/briarproject/android/blogs/FeedPostFragment.java
index 002f69586d875c18c32c08aa584a464bab305a1c..73ec81a3ea0d7784ec97824d00ef206dce4ff0a0 100644
--- a/briar-android/src/org/briarproject/android/blogs/FeedPostFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/FeedPostFragment.java
@@ -2,6 +2,7 @@ package org.briarproject.android.blogs;
 
 import android.os.Bundle;
 import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -9,17 +10,21 @@ import android.view.ViewGroup;
 import org.briarproject.android.ActivityComponent;
 import org.briarproject.android.controller.handler.UiResultExceptionHandler;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
 import org.briarproject.api.sync.GroupId;
 import org.briarproject.api.sync.MessageId;
 
 import javax.inject.Inject;
 
 import static org.briarproject.android.BriarActivity.GROUP_ID;
-import static org.briarproject.android.blogs.BasePostPagerFragment.POST_ID;
 
+@UiThread
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 public class FeedPostFragment extends BasePostFragment {
 
-	public final static String TAG = FeedPostFragment.class.getName();
+	private static final String TAG = FeedPostFragment.class.getName();
 
 	private MessageId postId;
 	private GroupId blogId;
@@ -40,8 +45,9 @@ public class FeedPostFragment extends BasePostFragment {
 
 	@Nullable
 	@Override
-	public View onCreateView(LayoutInflater inflater, ViewGroup container,
-			Bundle savedInstanceState) {
+	public View onCreateView(LayoutInflater inflater,
+			@Nullable ViewGroup container,
+			@Nullable Bundle savedInstanceState) {
 
 		Bundle args = getArguments();
 		byte[] b = args.getByteArray(GROUP_ID);
@@ -55,6 +61,11 @@ public class FeedPostFragment extends BasePostFragment {
 		return super.onCreateView(inflater, container, savedInstanceState);
 	}
 
+	@Override
+	public String getUniqueTag() {
+		return TAG;
+	}
+
 	@Override
 	public void injectFragment(ActivityComponent component) {
 		component.inject(this);
@@ -70,16 +81,12 @@ public class FeedPostFragment extends BasePostFragment {
 					public void onResultUi(BlogPostItem post) {
 						onBlogPostLoaded(post);
 					}
+
 					@Override
 					public void onExceptionUi(DbException exception) {
-						onBlogPostLoadException(exception);
+						// TODO: Decide how to handle errors in the UI
 					}
 				});
 	}
 
-	@Override
-	public String getUniqueTag() {
-		return TAG;
-	}
-
 }
diff --git a/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java b/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java
deleted file mode 100644
index 5dc75709dca8d62c50328fc8995e0ca1bb63750d..0000000000000000000000000000000000000000
--- a/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package org.briarproject.android.blogs;
-
-import android.os.Bundle;
-
-import org.briarproject.android.ActivityComponent;
-import org.briarproject.android.controller.handler.UiResultExceptionHandler;
-import org.briarproject.api.blogs.BlogPostHeader;
-import org.briarproject.api.db.DbException;
-import org.briarproject.api.sync.MessageId;
-
-import java.util.Collection;
-
-import javax.inject.Inject;
-
-public class FeedPostPagerFragment extends BasePostPagerFragment {
-
-	public final static String TAG = FeedPostPagerFragment.class.getName();
-
-	@Inject
-	FeedController feedController;
-
-	static FeedPostPagerFragment newInstance(MessageId postId) {
-		FeedPostPagerFragment f = new FeedPostPagerFragment();
-
-		Bundle args = new Bundle();
-		args.putByteArray(POST_ID, postId.getBytes());
-		f.setArguments(args);
-
-		return f;
-	}
-
-	@Override
-	public void injectFragment(ActivityComponent component) {
-		component.inject(this);
-		feedController.setOnBlogPostAddedListener(this);
-	}
-
-	@Override
-	public String getUniqueTag() {
-		return TAG;
-	}
-
-	@Override
-	public void onStart() {
-		super.onStart();
-		feedController.onStart();
-	}
-
-	@Override
-	public void onStop() {
-		super.onStop();
-		feedController.onStop();
-	}
-
-	@Override
-	void loadBlogPosts(final MessageId select) {
-		feedController.loadBlogPosts(
-				new UiResultExceptionHandler<Collection<BlogPostItem>, DbException>(
-						this) {
-					@Override
-					public void onResultUi(Collection<BlogPostItem> posts) {
-						onBlogPostsLoaded(select, posts);
-					}
-
-					@Override
-					public void onExceptionUi(DbException exception) {
-						onBlogPostsLoadedException(exception);
-					}
-				});
-	}
-
-	@Override
-	void loadBlogPost(BlogPostHeader header) {
-		feedController.loadBlogPost(header,
-				new UiResultExceptionHandler<BlogPostItem, DbException>(
-						this) {
-					@Override
-					public void onResultUi(BlogPostItem post) {
-						addPost(post);
-					}
-
-					@Override
-					public void onExceptionUi(DbException exception) {
-						// TODO: Decide how to handle errors in the UI
-						finish();
-					}
-				});
-	}
-}
diff --git a/briar-android/src/org/briarproject/android/blogs/ReblogActivity.java b/briar-android/src/org/briarproject/android/blogs/ReblogActivity.java
index 4489f5c730f20e4302e31f22fa692a4d1c734865..8f04dc1db2df71ed1a422e5c822e9503721e911d 100644
--- a/briar-android/src/org/briarproject/android/blogs/ReblogActivity.java
+++ b/briar-android/src/org/briarproject/android/blogs/ReblogActivity.java
@@ -15,7 +15,7 @@ import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
 import org.briarproject.api.sync.GroupId;
 import org.briarproject.api.sync.MessageId;
 
-import static org.briarproject.android.blogs.BasePostPagerFragment.POST_ID;
+import static org.briarproject.android.blogs.BasePostFragment.POST_ID;
 
 public class ReblogActivity extends BriarActivity implements
 		BaseFragmentListener {
diff --git a/briar-android/src/org/briarproject/android/blogs/ReblogFragment.java b/briar-android/src/org/briarproject/android/blogs/ReblogFragment.java
index 3f83f380feafc063506f99e3ed40b5f018a0088e..1c9655336a10559d6198294b4f53eb1c769d12b6 100644
--- a/briar-android/src/org/briarproject/android/blogs/ReblogFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/ReblogFragment.java
@@ -28,7 +28,7 @@ import static android.view.View.GONE;
 import static android.view.View.INVISIBLE;
 import static android.view.View.VISIBLE;
 import static org.briarproject.android.BriarActivity.GROUP_ID;
-import static org.briarproject.android.blogs.BasePostPagerFragment.POST_ID;
+import static org.briarproject.android.blogs.BasePostFragment.POST_ID;
 
 @MethodsNotNullByDefault
 @ParametersNotNullByDefault