diff --git a/briar-android/res/layout/fragment_forum_list.xml b/briar-android/res/layout/fragment_forum_list.xml
index d078aebb2b4214f905dccb0277747176275721e7..ca4fb452052bd7180b1b4c9dc4e9f63a454e97de 100644
--- a/briar-android/res/layout/fragment_forum_list.xml
+++ b/briar-android/res/layout/fragment_forum_list.xml
@@ -10,6 +10,6 @@
 		xmlns:android="http://schemas.android.com/apk/res/android"
 		android:layout_width="match_parent"
 		android:layout_height="match_parent"
-		app:layout_behavior="org.briarproject.android.util.BriarRecyclerViewBehavior"/>
+		app:layout_behavior="org.briarproject.android.view.BriarRecyclerViewBehavior"/>
 
 </android.support.design.widget.CoordinatorLayout>
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/KeyboardAwareRelativeLayout.java b/briar-android/src/org/thoughtcrime/securesms/components/KeyboardAwareRelativeLayout.java
index f762d1cb69de71774b401d28b80b8cf9a0b13ec3..5217078252324fab5d8e0ce730cbfca0e5ec25f3 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/KeyboardAwareRelativeLayout.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/KeyboardAwareRelativeLayout.java
@@ -1,33 +1,14 @@
-/**
- * Copyright (C) 2014 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
 package org.thoughtcrime.securesms.components;
 
 import android.annotation.TargetApi;
-import android.app.Activity;
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.graphics.Rect;
 import android.os.Build;
-import android.os.Build.VERSION_CODES;
 import android.preference.PreferenceManager;
 import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.RelativeLayout;
@@ -37,15 +18,23 @@ import org.briarproject.R;
 import java.lang.reflect.Field;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.logging.Logger;
+
+import static android.content.Context.WINDOW_SERVICE;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+import static java.util.logging.Level.INFO;
+import static java.util.logging.Level.WARNING;
 
 /**
- * RelativeLayout that, when a view container, will report back when it thinks a soft keyboard
- * has been opened and what its height would be.
+ * RelativeLayout that, when a view container, will report back when it thinks
+ * a soft keyboard has been opened and what its height would be.
  */
 @UiThread
 public class KeyboardAwareRelativeLayout extends RelativeLayout {
-	private static final String TAG =
-			KeyboardAwareRelativeLayout.class.getSimpleName();
+
+	private static final Logger LOG =
+			Logger.getLogger(KeyboardAwareRelativeLayout.class.getName());
 
 	private final Rect rect = new Rect();
 	private final Set<OnKeyboardHiddenListener> hiddenListeners =
@@ -100,7 +89,7 @@ public class KeyboardAwareRelativeLayout extends RelativeLayout {
 		int oldRotation = rotation;
 		rotation = getDeviceRotation();
 		if (oldRotation != rotation) {
-			Log.w(TAG, "rotation changed");
+			LOG.info("Rotation changed");
 			onKeyboardClose();
 		}
 	}
@@ -111,13 +100,13 @@ public class KeyboardAwareRelativeLayout extends RelativeLayout {
 			return;
 		}
 
-		if (viewInset == 0 && Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP)
+		if (viewInset == 0 && Build.VERSION.SDK_INT >= 21)
 			viewInset = getViewInset();
-		final int availableHeight =
-				this.getRootView().getHeight() - statusBarHeight - viewInset;
+		int availableHeight =
+				getRootView().getHeight() - statusBarHeight - viewInset;
 		getWindowVisibleDisplayFrame(rect);
 
-		final int keyboardHeight = availableHeight - (rect.bottom - rect.top);
+		int keyboardHeight = availableHeight - (rect.bottom - rect.top);
 
 		if (keyboardHeight > minKeyboardSize) {
 			if (getKeyboardHeight() != keyboardHeight)
@@ -128,7 +117,7 @@ public class KeyboardAwareRelativeLayout extends RelativeLayout {
 		}
 	}
 
-	@TargetApi(VERSION_CODES.LOLLIPOP)
+	@TargetApi(21)
 	private int getViewInset() {
 		try {
 			Field attachInfoField = View.class.getDeclaredField("mAttachInfo");
@@ -141,25 +130,26 @@ public class KeyboardAwareRelativeLayout extends RelativeLayout {
 				Rect insets = (Rect) stableInsetsField.get(attachInfo);
 				return insets.bottom;
 			}
-		} catch (NoSuchFieldException nsfe) {
-			Log.w(TAG, "field reflection error when measuring view inset",
-					nsfe);
-		} catch (IllegalAccessException iae) {
-			Log.w(TAG, "access reflection error when measuring view inset",
-					iae);
+		} catch (NoSuchFieldException e) {
+			LOG.log(WARNING,
+					"field reflection error when measuring view inset", e);
+		} catch (IllegalAccessException e) {
+			LOG.log(WARNING,
+					"access reflection error when measuring view inset", e);
 		}
 		return 0;
 	}
 
 	protected void onKeyboardOpen(int keyboardHeight) {
-		Log.w(TAG, "onKeyboardOpen(" + keyboardHeight + ")");
+		if (LOG.isLoggable(INFO))
+			LOG.info("onKeyboardOpen(" + keyboardHeight + ")");
 		keyboardOpen = true;
 
 		notifyShownListeners();
 	}
 
 	protected void onKeyboardClose() {
-		Log.w(TAG, "onKeyboardClose()");
+		LOG.info("onKeyboardClose()");
 		keyboardOpen = false;
 		notifyHiddenListeners();
 	}
@@ -175,13 +165,12 @@ public class KeyboardAwareRelativeLayout extends RelativeLayout {
 
 	public boolean isLandscape() {
 		int rotation = getDeviceRotation();
-		return rotation == Surface.ROTATION_90 ||
-				rotation == Surface.ROTATION_270;
+		return rotation == ROTATION_90 || rotation == ROTATION_270;
 	}
 
 	private int getDeviceRotation() {
-		WindowManager windowManager = (WindowManager) getContext()
-				.getSystemService(Activity.WINDOW_SERVICE);
+		WindowManager windowManager =
+				(WindowManager) getContext().getSystemService(WINDOW_SERVICE);
 		return windowManager.getDefaultDisplay().getRotation();
 	}
 
@@ -190,10 +179,10 @@ public class KeyboardAwareRelativeLayout extends RelativeLayout {
 	}
 
 	private int getKeyboardPortraitHeight() {
-		int keyboardHeight =
-				PreferenceManager.getDefaultSharedPreferences(getContext())
-						.getInt("keyboard_height_portrait",
-								defaultCustomKeyboardSize);
+		SharedPreferences prefs =
+				PreferenceManager.getDefaultSharedPreferences(getContext());
+		int keyboardHeight = prefs.getInt("keyboard_height_portrait",
+				defaultCustomKeyboardSize);
 		return clamp(keyboardHeight, minCustomKeyboardSize,
 				getRootView().getHeight() - minCustomKeyboardTopMargin);
 	}
@@ -203,8 +192,9 @@ public class KeyboardAwareRelativeLayout extends RelativeLayout {
 	}
 
 	private void setKeyboardPortraitHeight(int height) {
-		PreferenceManager.getDefaultSharedPreferences(getContext())
-				.edit().putInt("keyboard_height_portrait", height).apply();
+		SharedPreferences prefs =
+				PreferenceManager.getDefaultSharedPreferences(getContext());
+		prefs.edit().putInt("keyboard_height_portrait", height).apply();
 	}
 
 	public void postOnKeyboardClose(final Runnable runnable) {
@@ -254,7 +244,8 @@ public class KeyboardAwareRelativeLayout extends RelativeLayout {
 	}
 
 	private void notifyHiddenListeners() {
-		final Set<OnKeyboardHiddenListener> listeners =
+		// Make a copy as listeners may remove themselves when called
+		Set<OnKeyboardHiddenListener> listeners =
 				new HashSet<>(hiddenListeners);
 		for (OnKeyboardHiddenListener listener : listeners) {
 			listener.onKeyboardHidden();
@@ -262,8 +253,8 @@ public class KeyboardAwareRelativeLayout extends RelativeLayout {
 	}
 
 	private void notifyShownListeners() {
-		final Set<OnKeyboardShownListener> listeners =
-				new HashSet<>(shownListeners);
+		// Make a copy as listeners may remove themselves when called
+		Set<OnKeyboardShownListener> listeners = new HashSet<>(shownListeners);
 		for (OnKeyboardShownListener listener : listeners) {
 			listener.onKeyboardShown();
 		}
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/RepeatableImageKey.java b/briar-android/src/org/thoughtcrime/securesms/components/RepeatableImageKey.java
index f1802bd348c7c292f77111dcd0b54b2edda38d24..453f82f8cf0d79feeca1b74fd27625f30c74ac4c 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/RepeatableImageKey.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/RepeatableImageKey.java
@@ -1,16 +1,18 @@
 package org.thoughtcrime.securesms.components;
 
 import android.content.Context;
-import android.os.Build.VERSION;
-import android.os.Build.VERSION_CODES;
 import android.support.annotation.UiThread;
 import android.util.AttributeSet;
-import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.widget.ImageButton;
 
+import static android.view.HapticFeedbackConstants.KEYBOARD_TAP;
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_UP;
+
 @UiThread
 public class RepeatableImageKey extends ImageButton {
 
@@ -42,7 +44,7 @@ public class RepeatableImageKey extends ImageButton {
 	}
 
 	private void notifyListener() {
-		if (this.listener != null) this.listener.onKeyEvent();
+		if (listener != null) listener.onKeyEvent();
 	}
 
 	private class RepeaterClickListener implements OnClickListener {
@@ -56,31 +58,28 @@ public class RepeatableImageKey extends ImageButton {
 		@Override
 		public void run() {
 			notifyListener();
-			postDelayed(this, VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1
-					? ViewConfiguration.getKeyRepeatDelay()
-					: 50);
+			postDelayed(this, ViewConfiguration.getKeyRepeatDelay());
 		}
 	}
 
 	private class RepeaterTouchListener implements OnTouchListener {
-		private Repeater repeater;
+
+		private final Repeater repeater;
 
 		private RepeaterTouchListener() {
-			this.repeater = new Repeater();
+			repeater = new Repeater();
 		}
 
 		@Override
 		public boolean onTouch(View view, MotionEvent motionEvent) {
 			switch (motionEvent.getAction()) {
-				case MotionEvent.ACTION_DOWN:
+				case ACTION_DOWN:
 					view.postDelayed(repeater,
-							VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1
-									? ViewConfiguration.getKeyRepeatTimeout()
-									: ViewConfiguration.getLongPressTimeout());
-					performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
+							ViewConfiguration.getKeyRepeatTimeout());
+					performHapticFeedback(KEYBOARD_TAP);
 					return false;
-				case MotionEvent.ACTION_CANCEL:
-				case MotionEvent.ACTION_UP:
+				case ACTION_CANCEL:
+				case ACTION_UP:
 					view.removeCallbacks(repeater);
 					return false;
 				default:
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/emoji/AnimatingImageSpan.java b/briar-android/src/org/thoughtcrime/securesms/components/emoji/AnimatingImageSpan.java
index 7f06aff49bdd7e783b9792e9177dab2c632d3ed5..28a71933f274d115dbf4e438a4db2c79ffcc257f 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/emoji/AnimatingImageSpan.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/emoji/AnimatingImageSpan.java
@@ -6,8 +6,9 @@ import android.support.annotation.UiThread;
 import android.text.style.ImageSpan;
 
 @UiThread
-public class AnimatingImageSpan extends ImageSpan {
-	public AnimatingImageSpan(Drawable drawable, Callback callback) {
+class AnimatingImageSpan extends ImageSpan {
+
+	AnimatingImageSpan(Drawable drawable, Callback callback) {
 		super(drawable, ALIGN_BOTTOM);
 		drawable.setCallback(callback);
 	}
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java
index 2b78041d0f79ef073ce218a07b4bef0b0219ee5b..69234600f6b1c5e70799b4cf7b30edf0bc98d791 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java
@@ -12,7 +12,6 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
-import android.widget.ImageView.ScaleType;
 import android.widget.LinearLayout;
 
 import com.astuetz.PagerSlidingTabStrip;
@@ -27,15 +26,18 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.logging.Logger;
 
+import static android.view.KeyEvent.ACTION_DOWN;
+import static android.view.KeyEvent.KEYCODE_DEL;
+import static android.widget.ImageView.ScaleType.CENTER_INSIDE;
 import static java.util.logging.Level.INFO;
 
 @UiThread
 public class EmojiDrawer extends LinearLayout {
 
-	private static final String TAG = EmojiDrawer.class.getName();
-	private static final Logger LOG = Logger.getLogger(TAG);
+	private static final Logger LOG =
+			Logger.getLogger(EmojiDrawer.class.getName());
 	private static final KeyEvent DELETE_KEY_EVENT =
-			new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
+			new KeyEvent(ACTION_DOWN, KEYCODE_DEL);
 
 	private ViewPager pager;
 	private List<EmojiPageModel> models;
@@ -70,7 +72,6 @@ public class EmojiDrawer extends LinearLayout {
 	}
 
 	private void initializeResources(View v) {
-		LOG.info("initializeResources()");
 		this.pager = (ViewPager) v.findViewById(R.id.emoji_pager);
 		this.strip = (PagerSlidingTabStrip) v.findViewById(R.id.tabs);
 
@@ -93,7 +94,7 @@ public class EmojiDrawer extends LinearLayout {
 		ViewGroup.LayoutParams params = getLayoutParams();
 		params.height = height;
 		if (LOG.isLoggable(INFO))
-			LOG.info("showing emoji drawer with height " + params.height);
+			LOG.info("Showing emoji drawer with height " + params.height);
 		setLayoutParams(params);
 		setVisibility(VISIBLE);
 		if (drawerListener != null) drawerListener.onShown();
@@ -102,7 +103,6 @@ public class EmojiDrawer extends LinearLayout {
 	public void hide() {
 		setVisibility(GONE);
 		if (drawerListener != null) drawerListener.onHidden();
-		LOG.info("hide()");
 	}
 
 	private void initializeEmojiGrid() {
@@ -111,7 +111,6 @@ public class EmojiDrawer extends LinearLayout {
 				new EmojiSelectionListener() {
 					@Override
 					public void onEmojiSelected(String emoji) {
-						LOG.info("onEmojiSelected()");
 						recentModel.onCodePointSelected(emoji);
 						if (listener != null) listener.onEmojiSelected(emoji);
 					}
@@ -174,7 +173,7 @@ public class EmojiDrawer extends LinearLayout {
 		@Override
 		public View getCustomTabView(ViewGroup viewGroup, int i) {
 			ImageView image = new ImageView(context);
-			image.setScaleType(ScaleType.CENTER_INSIDE);
+			image.setScaleType(CENTER_INSIDE);
 			image.setImageResource(pages.get(i).getIcon());
 			return image;
 		}
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiFilter.java b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiFilter.java
index 6e9b751cffd514216b95e1540c8f5d761c3152cd..603544869f954448a22f35059f34b61198853e17 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiFilter.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiFilter.java
@@ -9,7 +9,7 @@ import android.text.TextUtils;
 import android.widget.TextView;
 
 @UiThread
-public class EmojiFilter implements InputFilter {
+class EmojiFilter implements InputFilter {
 
 	private final TextView view;
 
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiPageModel.java b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiPageModel.java
index 3b3861b1926c026e00d2687b0ee667305c7697ae..2e0b899d54fddb7cb928a081515a018d482469e5 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiPageModel.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiPageModel.java
@@ -4,7 +4,8 @@ import android.support.annotation.DrawableRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 
-public interface EmojiPageModel {
+interface EmojiPageModel {
+
 	@DrawableRes
 	int getIcon();
 
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java
index d101a9daa18e5642c18715415b4c1f1bce9d9797..fa5e97c8eef6983e1fda830c524c5eb2ee3345ae 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java
@@ -20,6 +20,7 @@ import org.briarproject.R;
 public class EmojiPageView extends FrameLayout {
 
 	private final GridView grid;
+
 	private EmojiSelectionListener listener;
 
 	public EmojiPageView(Context context) {
@@ -60,15 +61,15 @@ public class EmojiPageView extends FrameLayout {
 
 	private static class EmojiGridAdapter extends BaseAdapter {
 
-		protected final Context context;
-		private final int emojiSize;
+		private final Context context;
 		private final EmojiPageModel model;
+		private final int emojiSize;
 
 		private EmojiGridAdapter(Context context, EmojiPageModel model) {
 			this.context = context;
-			this.emojiSize = (int) context.getResources()
-					.getDimension(R.dimen.emoji_drawer_size);
 			this.model = model;
+			emojiSize = (int) context.getResources()
+					.getDimension(R.dimen.emoji_drawer_size);
 		}
 
 		@Override
@@ -88,15 +89,14 @@ public class EmojiPageView extends FrameLayout {
 		}
 
 		@Override
-		public View getView(final int position, final View convertView,
-				final ViewGroup parent) {
-			final EmojiView view;
-			final int pad = context.getResources()
+		public View getView(int position, View convertView, ViewGroup parent) {
+			EmojiView view;
+			int pad = context.getResources()
 					.getDimensionPixelSize(R.dimen.emoji_drawer_item_padding);
 			if (convertView != null && convertView instanceof EmojiView) {
 				view = (EmojiView) convertView;
 			} else {
-				final EmojiView emojiView = new EmojiView(context);
+				EmojiView emojiView = new EmojiView(context);
 				emojiView.setPadding(pad, pad, pad, pad);
 				emojiView.setLayoutParams(
 						new AbsListView.LayoutParams(emojiSize + 2 * pad,
@@ -109,7 +109,7 @@ public class EmojiPageView extends FrameLayout {
 		}
 	}
 
-	public interface EmojiSelectionListener {
+	interface EmojiSelectionListener {
 		void onEmojiSelected(String emoji);
 	}
 }
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiPages.java b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiPages.java
index 9ad5f429b5b203b889179ff06d3e421d5d1dfd3a..0544de13af91fd1374ce81b5e0033bb151b4115f 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiPages.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiPages.java
@@ -8,12 +8,14 @@ import java.util.Arrays;
 import java.util.List;
 
 class EmojiPages {
+
 	static List<EmojiPageModel> getPages(Context ctx) {
 		return Arrays.<EmojiPageModel>asList(
 				new StaticEmojiPageModel(ctx, R.drawable.ic_emoji_smiley_people,
 						R.array.emoji_smiley_people,
 						"emoji_smiley_people.png"),
-				new StaticEmojiPageModel(ctx, R.drawable.ic_emoji_animals_nature,
+				new StaticEmojiPageModel(ctx,
+						R.drawable.ic_emoji_animals_nature,
 						R.array.emoji_animals_nature,
 						"emoji_animals_nature.png"),
 				new StaticEmojiPageModel(ctx, R.drawable.ic_emoji_food_drink,
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
index f53a087d00cf74656162a04623469a82c5e4cc59..2ea99864e9755732f8555d27c481f06fc3436afb 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
@@ -5,7 +5,6 @@ import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.Paint;
-import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
@@ -34,25 +33,30 @@ import java.util.regex.Pattern;
 
 import javax.inject.Inject;
 
+import static android.graphics.PixelFormat.TRANSLUCENT;
+import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
+import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
 
 public class EmojiProvider {
-	private static final String TAG = EmojiProvider.class.getSimpleName();
-	private static volatile EmojiProvider instance = null;
-	private static final Paint paint =
+
+	private static volatile EmojiProvider INSTANCE = null;
+
+	private static final Paint PAINT =
 			new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);
 
 	@Inject
 	AndroidExecutor androidExecutor;
 
-	private static final Logger LOG = Logger.getLogger(TAG);
+	private static final Logger LOG =
+			Logger.getLogger(EmojiProvider.class.getName());
 
 	private final SparseArray<DrawInfo> offsets = new SparseArray<>();
 
 	private static final Pattern EMOJI_RANGE = Pattern.compile(
-	//     0x203c,0x2049  0x20a0-0x32ff          0x1f00-0x1fff              0xfe4e5-0xfe4ee
-	//   |=== !!, ?! ===||==== misc ===||========= emoticons =======||========== flags ==========|
-		"[\\u203c\\u2049\\u20a0-\\u32ff\\ud83c\\udc00-\\ud83f\\udfff\\udbb9\\udce5-\\udbb9\\udcee]");
+			//     0x203c,0x2049  0x20a0-0x32ff          0x1f00-0x1fff              0xfe4e5-0xfe4ee
+			//   |=== !!, ?! ===||==== misc ===||========= emoticons =======||========== flags ==========|
+			"[\\u203c\\u2049\\u20a0-\\u32ff\\ud83c\\udc00-\\ud83f\\udfff\\udbb9\\udce5-\\udbb9\\udcee]");
 
 	private static final int EMOJI_RAW_HEIGHT = 64;
 	private static final int EMOJI_RAW_WIDTH = 64;
@@ -60,30 +64,29 @@ public class EmojiProvider {
 	private static final int EMOJI_PER_ROW = 32;
 
 	private final Context context;
-	private final float decodeScale;
-	private final float verticalPad;
+	private final float decodeScale, verticalPad;
 	private final List<EmojiPageModel> staticPages;
 
-	public static EmojiProvider getInstance(Context context) {
-		if (instance == null) {
+	static EmojiProvider getInstance(Context context) {
+		if (INSTANCE == null) {
 			synchronized (EmojiProvider.class) {
-				if (instance == null) {
+				if (INSTANCE == null) {
 					LOG.info("Creating new instance of EmojiProvider");
-					instance = new EmojiProvider(context);
+					INSTANCE = new EmojiProvider(context);
 					((BaseActivity) context).getActivityComponent()
-							.inject(instance);
+							.inject(INSTANCE);
 				}
 			}
 		}
-		return instance;
+		return INSTANCE;
 	}
 
 	private EmojiProvider(Context context) {
 		this.context = context.getApplicationContext();
-		this.decodeScale = Math.min(1f,
-				context.getResources().getDimension(R.dimen.emoji_drawer_size) /
-						EMOJI_RAW_HEIGHT);
-		this.verticalPad = EMOJI_VERT_PAD * this.decodeScale;
+		float drawerSize =
+				context.getResources().getDimension(R.dimen.emoji_drawer_size);
+		decodeScale = Math.min(1f, drawerSize / EMOJI_RAW_HEIGHT);
+		verticalPad = EMOJI_VERT_PAD * this.decodeScale;
 		staticPages = EmojiPages.getPages(context);
 		for (EmojiPageModel page : staticPages) {
 			if (page.hasSpriteMap()) {
@@ -97,7 +100,8 @@ public class EmojiProvider {
 	}
 
 	@Nullable
-	public Spannable emojify(@Nullable CharSequence text, @NonNull TextView tv) {
+	Spannable emojify(@Nullable CharSequence text,
+			@NonNull TextView tv) {
 		if (text == null) return null;
 		Matcher matches = EMOJI_RANGE.matcher(text);
 		SpannableStringBuilder builder = new SpannableStringBuilder(text);
@@ -107,15 +111,14 @@ public class EmojiProvider {
 			Drawable drawable = getEmojiDrawable(codePoint);
 			if (drawable != null) {
 				builder.setSpan(new EmojiSpan(drawable, tv), matches.start(),
-						matches.end(),
-						Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+						matches.end(), SPAN_EXCLUSIVE_EXCLUSIVE);
 			}
 		}
 		return builder;
 	}
 
 	@Nullable
-	public Drawable getEmojiDrawable(int emojiCode) {
+	Drawable getEmojiDrawable(int emojiCode) {
 		return getEmojiDrawable(offsets.get(emojiCode));
 	}
 
@@ -139,22 +142,30 @@ public class EmojiProvider {
 
 			@Override
 			public void onFailure(Throwable error) {
-				LOG.log(WARNING, error.toString(), error);
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, error.toString(), error);
 			}
 		});
 		return drawable;
 	}
 
-	public List<EmojiPageModel> getStaticPages() {
+	List<EmojiPageModel> getStaticPages() {
 		return staticPages;
 	}
 
 
-	public class EmojiDrawable extends Drawable {
+	class EmojiDrawable extends Drawable {
+
 		private final DrawInfo info;
+		private final float intrinsicWidth, intrinsicHeight;
+
 		private Bitmap bmp;
-		private float intrinsicWidth;
-		private float intrinsicHeight;
+
+		private EmojiDrawable(DrawInfo info, float decodeScale) {
+			this.info = info;
+			intrinsicWidth = EMOJI_RAW_WIDTH * decodeScale;
+			intrinsicHeight = EMOJI_RAW_HEIGHT * decodeScale;
+		}
 
 		@Override
 		public int getIntrinsicWidth() {
@@ -166,32 +177,25 @@ public class EmojiProvider {
 			return (int) intrinsicHeight;
 		}
 
-		private EmojiDrawable(DrawInfo info, float decodeScale) {
-			this.info = info;
-			this.intrinsicWidth = EMOJI_RAW_WIDTH * decodeScale;
-			this.intrinsicHeight = EMOJI_RAW_HEIGHT * decodeScale;
-		}
-
 		@Override
 		public void draw(@NonNull Canvas canvas) {
 			if (bmp == null) {
 				return;
 			}
 
-			final int row = info.index / EMOJI_PER_ROW;
-			final int row_index = info.index % EMOJI_PER_ROW;
-
-			canvas.drawBitmap(bmp,
-					new Rect((int) (row_index * intrinsicWidth),
-							(int) (row * intrinsicHeight + row * verticalPad),
-							(int) ((row_index + 1) * intrinsicWidth),
-							(int) ((row + 1) * intrinsicHeight +
-									row * verticalPad)),
-					getBounds(),
-					paint);
+			int row = info.index / EMOJI_PER_ROW;
+			int rowIndex = info.index % EMOJI_PER_ROW;
+
+			int left = (int) (rowIndex * intrinsicWidth);
+			int top = (int) (row * intrinsicHeight + row * verticalPad);
+			int right = (int) ((rowIndex + 1) * intrinsicWidth);
+			int bottom =
+					(int) ((row + 1) * intrinsicHeight + row * verticalPad);
+			canvas.drawBitmap(bmp, new Rect(left, top, right, bottom),
+					getBounds(), PAINT);
 		}
 
-		public void setBitmap(Bitmap bitmap) {
+		void setBitmap(Bitmap bitmap) {
 			if (bmp == null || !bmp.sameAs(bitmap)) {
 				bmp = bitmap;
 				invalidateSelf();
@@ -200,7 +204,7 @@ public class EmojiProvider {
 
 		@Override
 		public int getOpacity() {
-			return PixelFormat.TRANSLUCENT;
+			return TRANSLUCENT;
 		}
 
 		@Override
@@ -214,26 +218,29 @@ public class EmojiProvider {
 
 
 	private static class DrawInfo {
-		private EmojiPageBitmap page;
-		int index;
 
-		private DrawInfo(final EmojiPageBitmap page, final int index) {
+		private final EmojiPageBitmap page;
+		private final int index;
+
+		private DrawInfo(EmojiPageBitmap page, int index) {
 			this.page = page;
 			this.index = index;
 		}
 
 		@Override
 		public String toString() {
-			return "DrawInfo{ " +"page = " + page +", index = " + index + '}';
+			return "DrawInfo{ " + "page = " + page + ", index = " + index + '}';
 		}
 	}
 
-
 	private class EmojiPageBitmap {
-		private EmojiPageModel model;
-		private SoftReference<Bitmap> bitmapReference;
+
+		private final EmojiPageModel model;
+
 		private ListenableFutureTask<Bitmap> task;
 
+		private volatile SoftReference<Bitmap> bitmapReference;
+
 		private EmojiPageBitmap(EmojiPageModel model) {
 			this.model = model;
 		}
@@ -249,7 +256,8 @@ public class EmojiProvider {
 					@Nullable
 					public Bitmap call() throws Exception {
 						try {
-							LOG.info("loading page " + model.getSprite());
+							if (LOG.isLoggable(INFO))
+								LOG.info("Loading page " + model.getSprite());
 							return loadPage();
 						} catch (IOException ioe) {
 							LOG.log(WARNING, ioe.toString(), ioe);
@@ -283,7 +291,8 @@ public class EmojiProvider {
 						"file:///android_asset/" + model.getSprite(),
 						decodeScale);
 				bitmapReference = new SoftReference<>(bitmap);
-				LOG.info("onPageLoaded(" + model.getSprite() + ")");
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loaded page " + model.getSprite());
 				return bitmap;
 			} catch (BitmapDecodingException e) {
 				LOG.log(WARNING, e.toString(), e);
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiSpan.java b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiSpan.java
index 47269d09549ea78bd0e777e15cca15fdd478a533..6168ee2733501703687499453ff3f0725a8679ff 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiSpan.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiSpan.java
@@ -10,11 +10,12 @@ import android.widget.TextView;
 import org.briarproject.R;
 
 @UiThread
-public class EmojiSpan extends AnimatingImageSpan {
+class EmojiSpan extends AnimatingImageSpan {
+
 	private final int size;
 	private final FontMetricsInt fm;
 
-	public EmojiSpan(@NonNull Drawable drawable, @NonNull TextView tv) {
+	EmojiSpan(@NonNull Drawable drawable, @NonNull TextView tv) {
 		super(drawable, tv);
 		fm = tv.getPaint().getFontMetricsInt();
 		size = fm != null ? Math.abs(fm.descent) + Math.abs(fm.ascent)
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java
index df354c193823d39dc5ed1352b3215e82def6d440..7d10a6393df448b2655151033c635c8e277a7f39 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java
@@ -7,12 +7,16 @@ import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 import android.text.TextUtils;
-import android.text.TextUtils.TruncateAt;
 import android.util.AttributeSet;
 import android.widget.TextView;
 
 import org.thoughtcrime.securesms.components.emoji.EmojiProvider.EmojiDrawable;
 
+import static android.text.TextUtils.TruncateAt.END;
+import static android.view.View.MeasureSpec.AT_MOST;
+import static android.view.View.MeasureSpec.EXACTLY;
+import static android.widget.TextView.BufferType.SPANNABLE;
+
 @UiThread
 public class EmojiTextView extends TextView {
 
@@ -41,9 +45,7 @@ public class EmojiTextView extends TextView {
 	}
 
 	private void setTextEllipsized(final @Nullable CharSequence source) {
-		super.setText(
-				needsEllipsizing ? ellipsize(source) : source,
-				BufferType.SPANNABLE);
+		super.setText(needsEllipsizing ? ellipsize(source) : source, SPANNABLE);
 	}
 
 	@Override
@@ -56,18 +58,16 @@ public class EmojiTextView extends TextView {
 	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 		final int size = MeasureSpec.getSize(widthMeasureSpec);
 		final int mode = MeasureSpec.getMode(widthMeasureSpec);
-		if (getEllipsize() == TruncateAt.END &&
+		if (getEllipsize() == END &&
 				!TextUtils.isEmpty(source) &&
-				(mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) &&
+				(mode == AT_MOST || mode == EXACTLY) &&
 				getPaint().breakText(source, 0, source.length() - 1, true, size,
 						null) != source.length()) {
 			needsEllipsizing = true;
 			FontMetricsInt font = getPaint().getFontMetricsInt();
-			super.onMeasure(
-					MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY),
-					MeasureSpec
-							.makeMeasureSpec(Math.abs(font.top - font.bottom),
-									MeasureSpec.EXACTLY));
+			int height = Math.abs(font.top - font.bottom);
+			super.onMeasure(MeasureSpec.makeMeasureSpec(size, EXACTLY),
+					MeasureSpec.makeMeasureSpec(height, EXACTLY));
 		} else {
 			needsEllipsizing = false;
 			super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -84,13 +84,11 @@ public class EmojiTextView extends TextView {
 	@Nullable
 	public CharSequence ellipsize(@Nullable CharSequence text) {
 		if (TextUtils.isEmpty(text) || getWidth() == 0 ||
-				getEllipsize() != TruncateAt.END) {
+				getEllipsize() != END) {
 			return text;
 		} else {
-			return TextUtils.ellipsize(text,
-					getPaint(),
-					getWidth() - getPaddingRight() - getPaddingLeft(),
-					TruncateAt.END);
+			return TextUtils.ellipsize(text, getPaint(),
+					getWidth() - getPaddingRight() - getPaddingLeft(), END);
 		}
 	}
 
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiView.java b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiView.java
index 1126f034a09ad1aaaf142e06467bf86aa0907994..c4f064d2ad9e5e2300d7730323ceb80934d30202 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiView.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/emoji/EmojiView.java
@@ -13,14 +13,18 @@ import android.view.View;
 
 import org.briarproject.R;
 
+import static android.graphics.Paint.ANTI_ALIAS_FLAG;
+import static android.graphics.Paint.Align.CENTER;
+import static android.graphics.Paint.FILTER_BITMAP_FLAG;
+
 @UiThread
 public class EmojiView extends View implements Drawable.Callback {
+
+	private final Paint paint = new Paint(ANTI_ALIAS_FLAG | FILTER_BITMAP_FLAG);
+
 	private String emoji;
 	private Drawable drawable;
 
-	private final Paint paint =
-			new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-
 	public EmojiView(Context context) {
 		this(context, null);
 	}
@@ -60,7 +64,7 @@ public class EmojiView extends View implements Drawable.Callback {
 			paint.setTextSize(targetFontSize);
 			paint.setColor(ContextCompat
 					.getColor(getContext(), R.color.emoji_text_color));
-			paint.setTextAlign(Paint.Align.CENTER);
+			paint.setTextAlign(CENTER);
 			int xPos = (canvas.getWidth() / 2);
 			int yPos = (int) ((canvas.getHeight() / 2) -
 					((paint.descent() + paint.ascent()) / 2));
@@ -81,9 +85,4 @@ public class EmojiView extends View implements Drawable.Callback {
 		super.invalidateDrawable(drawable);
 		postInvalidate();
 	}
-
-	@Override
-	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-	}
 }
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java b/briar-android/src/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java
index 312d8372919ca38b89ff0c98d4faeeb81f9fe6ab..1c16d9c87732d8b3c1101f375bcba91fdab2d287 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java
@@ -20,16 +20,14 @@ import java.util.logging.Logger;
 
 import javax.inject.Inject;
 
-import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
 import static org.briarproject.android.fragment.SettingsFragment.SETTINGS_NAMESPACE;
 
 @UiThread
 public class RecentEmojiPageModel implements EmojiPageModel {
 
-	private static final String TAG =
-			RecentEmojiPageModel.class.getSimpleName();
-	private static final Logger LOG = Logger.getLogger(TAG);
+	private static final Logger LOG =
+			Logger.getLogger(RecentEmojiPageModel.class.getName());
 
 	private static final String EMOJI_LRU_PREFERENCE = "pref_emoji_recent";
 	private static final int EMOJI_LRU_SIZE = 50;
@@ -38,11 +36,11 @@ public class RecentEmojiPageModel implements EmojiPageModel {
 	private Settings settings;
 
 	@Inject
-	protected SettingsManager settingsManager;
+	SettingsManager settingsManager;
 	@Inject
-	protected DbController dbController;
+	DbController dbController;
 
-	public RecentEmojiPageModel(Context context) {
+	RecentEmojiPageModel(Context context) {
 		if (!(context instanceof BaseActivity)) {
 			throw new IllegalArgumentException(
 					"Needs to be created from BaseActivity");
@@ -85,9 +83,7 @@ public class RecentEmojiPageModel implements EmojiPageModel {
 		return null;
 	}
 
-	public void onCodePointSelected(String emoji) {
-		if (LOG.isLoggable(INFO))
-			LOG.info("onCodePointSelected(" + emoji + ")");
+	void onCodePointSelected(String emoji) {
 		recentlyUsed.remove(emoji);
 		recentlyUsed.add(emoji);
 
@@ -105,7 +101,7 @@ public class RecentEmojiPageModel implements EmojiPageModel {
 			result += emoji + ";";
 		}
 		if (!emojis.isEmpty())
-			result = result.substring(0, result.length()-1);
+			result = result.substring(0, result.length() - 1);
 		return result;
 	}
 
diff --git a/briar-android/src/org/thoughtcrime/securesms/components/emoji/StaticEmojiPageModel.java b/briar-android/src/org/thoughtcrime/securesms/components/emoji/StaticEmojiPageModel.java
index 7c359c8315b66002d46a997f067fc3109215a87d..688ee3ae7a4f778c4c79bd30e3b8616679252082 100644
--- a/briar-android/src/org/thoughtcrime/securesms/components/emoji/StaticEmojiPageModel.java
+++ b/briar-android/src/org/thoughtcrime/securesms/components/emoji/StaticEmojiPageModel.java
@@ -8,7 +8,7 @@ import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 
 @UiThread
-public class StaticEmojiPageModel implements EmojiPageModel {
+class StaticEmojiPageModel implements EmojiPageModel {
 
 	@DrawableRes
 	private final int icon;
@@ -17,14 +17,14 @@ public class StaticEmojiPageModel implements EmojiPageModel {
 	@Nullable
 	private final String sprite;
 
-	public StaticEmojiPageModel(@DrawableRes int icon, @NonNull String[] emoji,
+	StaticEmojiPageModel(@DrawableRes int icon, @NonNull String[] emoji,
 			@Nullable String sprite) {
 		this.icon = icon;
 		this.emoji = emoji;
 		this.sprite = sprite;
 	}
 
-	public StaticEmojiPageModel(Context ctx, @DrawableRes int icon,
+	StaticEmojiPageModel(Context ctx, @DrawableRes int icon,
 			@ArrayRes int res, @Nullable String sprite) {
 		this(icon, getEmoji(ctx, res), sprite);
 	}
@@ -35,6 +35,7 @@ public class StaticEmojiPageModel implements EmojiPageModel {
 		return icon;
 	}
 
+	@Override
 	@NonNull
 	public String[] getEmoji() {
 		return emoji;
diff --git a/briar-android/src/org/thoughtcrime/securesms/util/BitmapDecodingException.java b/briar-android/src/org/thoughtcrime/securesms/util/BitmapDecodingException.java
index 5a4b414623e57dd75ab0f9610d243dcca799ca32..777fdfb2ead9fe8cc8c140432cbc35ff522281c4 100644
--- a/briar-android/src/org/thoughtcrime/securesms/util/BitmapDecodingException.java
+++ b/briar-android/src/org/thoughtcrime/securesms/util/BitmapDecodingException.java
@@ -2,11 +2,11 @@ package org.thoughtcrime.securesms.util;
 
 public class BitmapDecodingException extends Exception {
 
-	public BitmapDecodingException(String s) {
+	BitmapDecodingException(String s) {
 		super(s);
 	}
 
-	public BitmapDecodingException(Exception nested) {
+	BitmapDecodingException(Exception nested) {
 		super(nested);
 	}
 }
diff --git a/briar-android/src/org/thoughtcrime/securesms/util/BitmapUtil.java b/briar-android/src/org/thoughtcrime/securesms/util/BitmapUtil.java
index 92a8425fc8e82bfcdf7199d5406c39cff84c9237..0bc0ed00f95d93721f923863bc475303fb086f01 100644
--- a/briar-android/src/org/thoughtcrime/securesms/util/BitmapUtil.java
+++ b/briar-android/src/org/thoughtcrime/securesms/util/BitmapUtil.java
@@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.util;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.util.Log;
 import android.util.Pair;
 
 import com.bumptech.glide.Glide;
@@ -17,10 +16,14 @@ import com.bumptech.glide.load.resource.bitmap.FitCenter;
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.logging.Logger;
+
+import static java.util.logging.Level.WARNING;
 
 public class BitmapUtil {
 
-	private static final String TAG = BitmapUtil.class.getSimpleName();
+	private static final Logger LOG =
+			Logger.getLogger(BitmapUtil.class.getName());
 
 	private static <T> InputStream getInputStreamForModel(Context context,
 			T model)
@@ -40,8 +43,7 @@ public class BitmapUtil {
 		final Bitmap rough = Downsampler.AT_LEAST
 				.decode(getInputStreamForModel(context, model),
 						Glide.get(context).getBitmapPool(),
-						width, height,
-						DecodeFormat.PREFER_RGB_565);
+						width, height, DecodeFormat.PREFER_RGB_565);
 
 		final Resource<Bitmap> resource = BitmapResource
 				.obtain(rough, Glide.get(context).getBitmapPool());
@@ -55,8 +57,7 @@ public class BitmapUtil {
 	}
 
 	public static <T> Bitmap createScaledBitmap(Context context, T model,
-			float scale)
-			throws BitmapDecodingException {
+			float scale) throws BitmapDecodingException {
 		Pair<Integer, Integer> dimens =
 				getDimensions(getInputStreamForModel(context, model));
 		return createScaledBitmapInto(context, model,
@@ -72,9 +73,8 @@ public class BitmapUtil {
 		BitmapFactory.decodeStream(fis, null, options);
 		try {
 			fis.close();
-		} catch (IOException ioe) {
-			Log.w(TAG,
-					"failed to close the InputStream after reading image dimensions");
+		} catch (IOException e) {
+			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 		}
 
 		if (options.outWidth == -1 || options.outHeight == -1) {
diff --git a/briar-android/test/java/org/briarproject/android/forum/ForumActivityTest.java b/briar-android/test/java/org/briarproject/android/forum/ForumActivityTest.java
index 38f64c5b25241af34913ec05aa92559f324a3add..e61b557beb392dbfedac9dd9620f0fd5ade0417b 100644
--- a/briar-android/test/java/org/briarproject/android/forum/ForumActivityTest.java
+++ b/briar-android/test/java/org/briarproject/android/forum/ForumActivityTest.java
@@ -29,6 +29,8 @@ import java.util.List;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertTrue;
+import static org.briarproject.api.identity.Author.Status.UNKNOWN;
+import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -77,11 +79,12 @@ public class ForumActivityTest {
 	private List<ForumEntry> getDummyData() {
 		ForumEntry[] forumEntries = new ForumEntry[6];
 		for (int i = 0; i < forumEntries.length; i++) {
-			forumEntries[i] =
-					new ForumEntry(new MessageId(TestUtils.getRandomId()),
-							AUTHORS[i], LEVELS[i], System.currentTimeMillis(),
-							AUTHORS[i], new AuthorId(TestUtils.getRandomId()),
-							Author.Status.UNKNOWN);
+			AuthorId authorId = new AuthorId(TestUtils.getRandomId());
+			byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
+			Author author = new Author(authorId, AUTHORS[i], publicKey);
+			forumEntries[i] = new ForumEntry(
+					new MessageId(TestUtils.getRandomId()), AUTHORS[i],
+					LEVELS[i], System.currentTimeMillis(), author, UNKNOWN);
 		}
 		return new ArrayList<>(Arrays.asList(forumEntries));
 	}