diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java
index 1967e2cd00711f70a0976388996fe43ff4f649a6..ee82e165b72c986294b07b385d0866a90b24ae9e 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java
@@ -100,7 +100,7 @@ public class ForumActivity extends
 		super.onActivityResult(request, result, data);
 
 		if (request == REQUEST_SHARE_FORUM && result == RESULT_OK) {
-			displaySnackbarShort(R.string.forum_shared_snackbar);
+			displaySnackbar(R.string.forum_shared_snackbar);
 		}
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java
index 8abb679a7b3dc7e59857b5649205144ae3f9098a..feaddbec9cadbc4f9faab0f839e79b04fe29826f 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java
@@ -183,7 +183,7 @@ public class GroupActivity extends
 	@Override
 	protected void onActivityResult(int request, int result, Intent data) {
 		if (request == REQUEST_GROUP_INVITE && result == RESULT_OK) {
-			displaySnackbarShort(R.string.groups_invitation_sent);
+			displaySnackbar(R.string.groups_invitation_sent);
 		} else super.onActivityResult(request, result, data);
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupMessageAdapter.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupMessageAdapter.java
index dbf8c7b96f544f31ab392e486a33e44249dc2a1d..b511804f3cf892c72fbad8d9753ff6ebd7bf8ac5 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupMessageAdapter.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupMessageAdapter.java
@@ -31,9 +31,8 @@ class GroupMessageAdapter extends ThreadItemAdapter<GroupMessageItem> {
 	@LayoutRes
 	@Override
 	public int getItemViewType(int position) {
-		GroupMessageItem item = getVisibleItem(position);
-		if (item != null) return item.getLayout();
-		return R.layout.list_item_thread;
+		GroupMessageItem item = items.get(position);
+		return item.getLayout();
 	}
 
 	@Override
@@ -58,7 +57,7 @@ class GroupMessageAdapter extends ThreadItemAdapter<GroupMessageItem> {
 			GroupMessageItem item = items.get(position);
 			if (item instanceof JoinMessageItem) {
 				((JoinMessageItem) item).setVisibility(v);
-				notifyItemChanged(getVisiblePos(item), item);
+				notifyItemChanged(findItemPosition(item), item);
 			}
 		}
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupMessageItem.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupMessageItem.java
index 79ca011d282455dc4a04f4548a18e4a9075012e2..a64769fdff867379df3bc6ff08917eb4fddbcc74 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupMessageItem.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupMessageItem.java
@@ -1,6 +1,7 @@
 package org.briarproject.briar.android.privategroup.conversation;
 
 import android.support.annotation.LayoutRes;
+import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 
 import org.briarproject.bramble.api.identity.Author;
@@ -20,9 +21,8 @@ class GroupMessageItem extends ThreadItem {
 	private final GroupId groupId;
 
 	private GroupMessageItem(MessageId messageId, GroupId groupId,
-			MessageId parentId,
-			String text, long timestamp, Author author, Status status,
-			boolean isRead) {
+			@Nullable MessageId parentId, String text, long timestamp,
+			Author author, Status status, boolean isRead) {
 		super(messageId, parentId, text, timestamp, author, status, isRead);
 		this.groupId = groupId;
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/JoinMessageItem.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/JoinMessageItem.java
index dfdd9202237dff2bcf8c54c14aaea510648a22c0..405a862d08acde72c82682c1c00d2f8f2262da4c 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/JoinMessageItem.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/JoinMessageItem.java
@@ -27,11 +27,6 @@ class JoinMessageItem extends GroupMessageItem {
 		return 0;
 	}
 
-	@Override
-	public boolean hasDescendants() {
-		return false;
-	}
-
 	@Override
 	@LayoutRes
 	public int getLayout() {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/JoinMessageItemViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/JoinMessageItemViewHolder.java
index 5fe8cf3996b8b4a6d002febbbec1ed0307cfa676..6d6a1f216d22c85bda435444355ca5fe21f729e0 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/JoinMessageItemViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/JoinMessageItemViewHolder.java
@@ -12,7 +12,6 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
 import org.briarproject.briar.R;
 import org.briarproject.briar.android.privategroup.reveal.RevealContactsActivity;
 import org.briarproject.briar.android.threaded.BaseThreadItemViewHolder;
-import org.briarproject.briar.android.threaded.ThreadItemAdapter;
 import org.briarproject.briar.android.threaded.ThreadItemAdapter.ThreadItemListener;
 
 import static org.briarproject.bramble.api.identity.Author.Status.OURSELVES;
@@ -41,10 +40,9 @@ class JoinMessageItemViewHolder
 	}
 
 	@Override
-	public void bind(ThreadItemAdapter<GroupMessageItem> adapter,
-			ThreadItemListener<GroupMessageItem> listener,
-			GroupMessageItem item, int pos) {
-		super.bind(adapter, listener, item, pos);
+	public void bind(GroupMessageItem item,
+			ThreadItemListener<GroupMessageItem> listener) {
+		super.bind(item, listener);
 
 		if (isCreator) bindForCreator((JoinMessageItem) item);
 		else bind((JoinMessageItem) item);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/BaseThreadItemViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/BaseThreadItemViewHolder.java
index a01865237402f20f1b48b630864e05654da8f040..b7fdeff1af4d8b2168c47eb95a63234d7949a4a9 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/BaseThreadItemViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/BaseThreadItemViewHolder.java
@@ -20,9 +20,6 @@ import org.briarproject.briar.R;
 import org.briarproject.briar.android.threaded.ThreadItemAdapter.ThreadItemListener;
 import org.briarproject.briar.android.view.AuthorView;
 
-import static android.view.View.INVISIBLE;
-import static android.view.View.VISIBLE;
-
 @UiThread
 @NotNullByDefault
 public abstract class BaseThreadItemViewHolder<I extends ThreadItem>
@@ -33,7 +30,6 @@ public abstract class BaseThreadItemViewHolder<I extends ThreadItem>
 	protected final TextView textView;
 	private final ViewGroup layout;
 	private final AuthorView author;
-	private final View topDivider;
 
 	public BaseThreadItemViewHolder(View v) {
 		super(v);
@@ -41,43 +37,30 @@ public abstract class BaseThreadItemViewHolder<I extends ThreadItem>
 		layout = (ViewGroup) v.findViewById(R.id.layout);
 		textView = (TextView) v.findViewById(R.id.text);
 		author = (AuthorView) v.findViewById(R.id.author);
-		topDivider = v.findViewById(R.id.top_divider);
 	}
 
-	// TODO improve encapsulation, so we don't need to pass the adapter here
 	@CallSuper
-	public void bind(final ThreadItemAdapter<I> adapter,
-			final ThreadItemListener<I> listener, final I item, int pos) {
-
+	public void bind(final I item, final ThreadItemListener<I> listener) {
 		textView.setText(StringUtils.trim(item.getText()));
 
-		if (pos == 0) {
-			topDivider.setVisibility(INVISIBLE);
-		} else {
-			topDivider.setVisibility(VISIBLE);
-		}
-
 		author.setAuthor(item.getAuthor());
 		author.setDate(item.getTimestamp());
 		author.setAuthorStatus(item.getStatus());
 
-		if (item.equals(adapter.getReplyItem())) {
+		if (item.isHighlighted()) {
 			layout.setActivated(true);
 		} else if (!item.isRead()) {
 			layout.setActivated(true);
-			animateFadeOut(adapter, item);
+			animateFadeOut();
 			listener.onUnreadItemVisible(item);
 		} else {
 			layout.setActivated(false);
 		}
 	}
 
-	private void animateFadeOut(final ThreadItemAdapter<I> adapter,
-			final I addedItem) {
-
+	private void animateFadeOut() {
 		setIsRecyclable(false);
 		ValueAnimator anim = new ValueAnimator();
-		adapter.addAnimatingItem(addedItem, anim);
 		ColorDrawable viewColor = new ColorDrawable(ContextCompat
 				.getColor(getContext(), R.color.forum_cell_highlight));
 		anim.setIntValues(viewColor.getColor(), ContextCompat
@@ -94,7 +77,6 @@ public abstract class BaseThreadItemViewHolder<I extends ThreadItem>
 						R.drawable.list_item_thread_background);
 				layout.setActivated(false);
 				setIsRecyclable(true);
-				adapter.removeAnimatingItem(addedItem);
 			}
 			@Override
 			public void onAnimationCancel(Animator animation) {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItem.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItem.java
index 39d00f98f2085052e45dfe540ddafc7f4dccf0b1..62431da9a16c56870ca2c1634429ffd423a42148 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItem.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItem.java
@@ -23,9 +23,7 @@ public abstract class ThreadItem implements MessageNode {
 	private final Author author;
 	private final Status status;
 	private int level = UNDEFINED;
-	private boolean isShowingDescendants = true;
-	private int descendantCount = 0;
-	private boolean isRead;
+	private boolean isRead, highlighted;
 
 	public ThreadItem(MessageId messageId, @Nullable MessageId parentId,
 			String text, long timestamp, Author author, Status status,
@@ -37,6 +35,7 @@ public abstract class ThreadItem implements MessageNode {
 		this.author = author;
 		this.status = status;
 		this.isRead = isRead;
+		this.highlighted = false;
 	}
 
 	public String getText() {
@@ -71,19 +70,11 @@ public abstract class ThreadItem implements MessageNode {
 		return status;
 	}
 
-	public boolean isShowingDescendants() {
-		return isShowingDescendants;
-	}
-
 	@Override
 	public void setLevel(int level) {
 		this.level = level;
 	}
 
-	public void setShowingDescendants(boolean showingDescendants) {
-		this.isShowingDescendants = showingDescendants;
-	}
-
 	public boolean isRead() {
 		return isRead;
 	}
@@ -92,13 +83,12 @@ public abstract class ThreadItem implements MessageNode {
 		isRead = read;
 	}
 
-	public boolean hasDescendants() {
-		return descendantCount > 0;
+	public void setHighlighted(boolean highlighted) {
+		this.highlighted = highlighted;
 	}
 
-	@Override
-	public void setDescendantCount(int descendantCount) {
-		this.descendantCount = descendantCount;
+	public boolean isHighlighted() {
+		return highlighted;
 	}
 
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemAdapter.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemAdapter.java
index f663a219c23827e2919e2b79a2973f662e36684f..72b03a03fc133340218e0f45ddb801446c9349db 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemAdapter.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadItemAdapter.java
@@ -1,6 +1,5 @@
 package org.briarproject.briar.android.threaded;
 
-import android.animation.ValueAnimator;
 import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 import android.support.v7.widget.LinearLayoutManager;
@@ -13,14 +12,11 @@ import org.briarproject.bramble.api.sync.MessageId;
 import org.briarproject.briar.R;
 import org.briarproject.briar.android.util.VersionedAdapter;
 
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
 import static android.support.v7.widget.RecyclerView.NO_POSITION;
 
+@UiThread
 public class ThreadItemAdapter<I extends ThreadItem>
 		extends RecyclerView.Adapter<BaseThreadItemViewHolder<I>>
 		implements VersionedAdapter {
@@ -28,13 +24,9 @@ public class ThreadItemAdapter<I extends ThreadItem>
 	static final int UNDEFINED = -1;
 
 	protected final NestedTreeList<I> items = new NestedTreeList<>();
-	private final Map<I, ValueAnimator> animatingItems = new HashMap<>();
 	private final ThreadItemListener<I> listener;
 	private final LinearLayoutManager layoutManager;
 
-	@Nullable
-	private I replyItem;
-
 	private volatile int revision = 0;
 
 	public ThreadItemAdapter(ThreadItemListener<I> listener,
@@ -53,24 +45,23 @@ public class ThreadItemAdapter<I extends ThreadItem>
 
 	@Override
 	public void onBindViewHolder(BaseThreadItemViewHolder<I> ui, int position) {
-		I item = getVisibleItem(position);
-		if (item == null) return;
-		ui.bind(this, listener, item, position);
+		I item = items.get(position);
+		ui.bind(item, listener);
 	}
 
-	/**
-	 * Contrary to the super class adapter,
-	 * this returns the number of <b>visible</b> items,
-	 * not all items in the dataset.
-	 */
 	@Override
 	public int getItemCount() {
-		return getVisiblePos(null);
+		return items.size();
 	}
 
-	@Nullable
-	I getReplyItem() {
-		return replyItem;
+	@Override
+	public int getRevision() {
+		return revision;
+	}
+
+	@Override
+	public void incrementRevision() {
+		revision++;
 	}
 
 	public void setItems(Collection<I> items) {
@@ -81,233 +72,51 @@ public class ThreadItemAdapter<I extends ThreadItem>
 
 	public void add(I item) {
 		items.add(item);
-		if (item.getParentId() == null) {
-			notifyItemInserted(getVisiblePos(item));
-		} else {
-			// Try to find the item's parent and perform the proper ui update if
-			// it's present and visible.
-			for (int i = items.indexOf(item) - 1; i >= 0; i--) {
-				I higherItem = items.get(i);
-				if (higherItem.getLevel() < item.getLevel()) {
-					// parent found
-					if (higherItem.isShowingDescendants()) {
-						int parentVisiblePos = getVisiblePos(higherItem);
-						if (parentVisiblePos != NO_POSITION) {
-							// parent is visible, we need to update its ui
-							notifyItemChanged(parentVisiblePos);
-							// new item insert ui
-							int visiblePos = getVisiblePos(item);
-							notifyItemInserted(visiblePos);
-							break;
-						}
-					} else {
-						// do not show the new item if its parent is not showing
-						// descendants (this can be overridden by the user by
-						// pressing the snack bar)
-						break;
-					}
-				}
-			}
-		}
-	}
-
-	void scrollTo(I item) {
-		int visiblePos = getVisiblePos(item);
-		MessageId parentId = item.getParentId();
-		if (visiblePos == NO_POSITION && parentId != null) {
-			// The item is not visible due to being hidden by its parent item.
-			// Find the parent and make it visible and traverse up the parent
-			// chain if necessary to make the item visible
-			for (int i = items.indexOf(item) - 1; i >= 0; i--) {
-				I higherItem = items.get(i);
-				if (higherItem.getId().equals(parentId)) {
-					// parent found
-					showDescendants(higherItem);
-					int parentPos = getVisiblePos(higherItem);
-					if (parentPos != NO_POSITION) {
-						// parent or ancestor is visible, item's visibility
-						// is ensured
-						notifyItemChanged(parentPos);
-						visiblePos = parentPos;
-						break;
-					}
-					// parent or ancestor is hidden, we need to continue up the
-					// dependency chain
-					parentId = higherItem.getParentId();
-					if (parentId == null) throw new AssertionError();
-				}
-			}
-		}
-		if (visiblePos != NO_POSITION)
-			layoutManager.scrollToPositionWithOffset(visiblePos, 0);
+		notifyItemInserted(findItemPosition(item));
 	}
 
-	int getReplyCount(I item) {
-		int counter = 0;
-		int pos = items.indexOf(item);
-		if (pos >= 0) {
-			int ancestorLvl = item.getLevel();
-			for (int i = pos + 1; i < items.size(); i++) {
-				int descendantLvl = items.get(i).getLevel();
-				if (descendantLvl <= ancestorLvl)
-					break;
-				if (descendantLvl == ancestorLvl + 1)
-					counter++;
-			}
-		}
-		return counter;
-	}
-
-	void setReplyItem(@Nullable I item) {
-		if (replyItem != null) {
-			notifyItemChanged(getVisiblePos(replyItem));
-		}
-		replyItem = item;
-		if (replyItem != null) {
-			notifyItemChanged(getVisiblePos(replyItem));
-		}
-	}
-
-	void setReplyItemById(MessageId id) {
-		for (I item : items) {
-			if (item.getId().equals(id)) {
-				setReplyItem(item);
-				break;
-			}
-		}
-	}
-
-	private List<Integer> getSubTreeIndexes(int pos, int levelLimit) {
-		List<Integer> indexList = new ArrayList<>();
-
-		for (int i = pos + 1; i < getItemCount(); i++) {
-			I item = getVisibleItem(i);
-			if (item != null && item.getLevel() > levelLimit) {
-				indexList.add(i);
-			} else {
-				break;
-			}
-		}
-		return indexList;
-	}
-
-	public void showDescendants(I item) {
-		item.setShowingDescendants(true);
-		int visiblePos = getVisiblePos(item);
-		List<Integer> indexList =
-				getSubTreeIndexes(visiblePos, item.getLevel());
-		if (!indexList.isEmpty()) {
-			if (indexList.size() == 1) {
-				notifyItemInserted(indexList.get(0));
-			} else {
-				notifyItemRangeInserted(indexList.get(0),
-						indexList.size());
-			}
+	@Nullable
+	public I getItemAt(int position) {
+		if (position == NO_POSITION || position >= items.size()) {
+			return null;
 		}
+		return items.get(position);
 	}
 
-	public void hideDescendants(I item) {
-		int visiblePos = getVisiblePos(item);
-		List<Integer> indexList =
-				getSubTreeIndexes(visiblePos, item.getLevel());
-		if (!indexList.isEmpty()) {
-			// stop animating children
-			for (int index : indexList) {
-				ValueAnimator anim = animatingItems.get(items.get(index));
-				if (anim != null && anim.isRunning()) {
-					anim.cancel();
-				}
-			}
-			if (indexList.size() == 1) {
-				notifyItemRemoved(indexList.get(0));
-			} else {
-				notifyItemRangeRemoved(indexList.get(0),
-						indexList.size());
-			}
+	protected int findItemPosition(@Nullable I item) {
+		for (int i = 0; i < items.size(); i++) {
+			if (items.get(i).equals(item)) return i;
 		}
-		item.setShowingDescendants(false);
+		return NO_POSITION; // Not found
 	}
 
-
 	/**
-	 * Returns the visible item at the given position
+	 * Highlights the item with the given {@link MessageId}
+	 * and disables the highlight for a previously highlighted item, if any.
 	 *
-	 * @param position is visible item index
-	 * @return the visible item at index 'position' from an ordered list of
-	 * visible items, or null if 'position' is larger than the number of
-	 * visible items.
+	 * Only one item can be highlighted at a time.
 	 */
-	@Nullable
-	public I getVisibleItem(int position) {
-		int levelLimit = UNDEFINED;
-		for (I item : items) {
-			if (levelLimit >= 0) {
-				// skip hidden items that their parent is hiding
-				if (item.getLevel() > levelLimit) {
-					continue;
-				}
-				levelLimit = UNDEFINED;
-			}
-			if (!item.isShowingDescendants()) {
-				levelLimit = item.getLevel();
-			}
-			if (position-- == 0) {
-				return item;
+	void setHighlightedItem(@Nullable MessageId id) {
+		for (int i = 0; i < items.size(); i++) {
+			I item = items.get(i);
+			if (id != null && item.getId().equals(id)) {
+				item.setHighlighted(true);
+				notifyItemChanged(i, item);
+			} else if (item.isHighlighted()) {
+				item.setHighlighted(false);
+				notifyItemChanged(i, item);
 			}
 		}
-		return null;
 	}
 
-	/**
-	 * Returns the visible position of the given item.
-	 *
-	 * @param item the item to find the visible position of, or null to
-	 *             return the total count of visible items.
-	 * @return the visible position of 'item', or the total number of visible
-	 * items if 'item' is null. If 'item' is not visible, NO_POSITION is
-	 * returned.
-	 */
-	protected int getVisiblePos(@Nullable I item) {
-		int visibleCounter = 0;
-		int levelLimit = UNDEFINED;
+	@Nullable
+	I getHighlightedItem() {
 		for (I i : items) {
-			if (levelLimit >= 0) {
-				if (i.getLevel() > levelLimit) {
-					// skip all the items below a non visible branch
-					continue;
-				}
-				levelLimit = UNDEFINED;
-			}
-			if (item != null && item.equals(i)) {
-				return visibleCounter;
-			} else if (!i.isShowingDescendants()) {
-				levelLimit = i.getLevel();
-			}
-			visibleCounter++;
+			if (i.isHighlighted()) return i;
 		}
-		return item == null ? visibleCounter : NO_POSITION;
-	}
-
-	void addAnimatingItem(I item, ValueAnimator anim) {
-		animatingItems.put(item, anim);
-	}
-
-	void removeAnimatingItem(I item) {
-		animatingItems.remove(item);
-	}
-
-	@Override
-	public int getRevision() {
-		return revision;
-	}
-
-	@UiThread
-	@Override
-	public void incrementRevision() {
-		revision++;
+		return null;
 	}
 
-
 	/**
 	 * Gets the number of unread items above and below the current view port.
 	 *
@@ -321,24 +130,13 @@ public class ThreadItemAdapter<I extends ThreadItem>
 			return new UnreadCount(0, 0);
 
 		int unreadCounterTop = 0, unreadCounterBottom = 0;
-		int visibleCounter = 0;
-		int levelLimit = UNDEFINED;
-		for (I i : items) {
-			if (levelLimit >= 0) {
-				if (i.getLevel() > levelLimit) {
-					// skip all the items below a non visible branch
-					continue;
-				}
-				levelLimit = UNDEFINED;
-			}
-			if (visibleCounter > positionBottom && !i.isRead()) {
-				unreadCounterBottom++;
-			} else if (visibleCounter < positionTop && !i.isRead()) {
+		for (int i = 0; i < items.size(); i++) {
+			I item = items.get(i);
+			if (i < positionTop && !item.isRead()) {
 				unreadCounterTop++;
-			} else if (!i.isShowingDescendants()) {
-				levelLimit = i.getLevel();
+			} else if (i > positionBottom && !item.isRead()) {
+				unreadCounterBottom++;
 			}
-			visibleCounter++;
 		}
 		return new UnreadCount(unreadCounterTop, unreadCounterBottom);
 	}
@@ -348,22 +146,9 @@ public class ThreadItemAdapter<I extends ThreadItem>
 	 */
 	public int getVisibleUnreadPosBottom() {
 		final int positionBottom = layoutManager.findLastVisibleItemPosition();
-		int visibleCounter = 0;
-		int levelLimit = UNDEFINED;
-		for (I i : items) {
-			if (levelLimit >= 0) {
-				if (i.getLevel() > levelLimit) {
-					// skip all the items below a non visible branch
-					continue;
-				}
-				levelLimit = UNDEFINED;
-			}
-			if (visibleCounter > positionBottom && !i.isRead()) {
-				return visibleCounter;
-			} else if (!i.isShowingDescendants()) {
-				levelLimit = i.getLevel();
-			}
-			visibleCounter++;
+		if (positionBottom == NO_POSITION) return NO_POSITION;
+		for (int i = positionBottom + 1; i < items.size(); i++) {
+			if (!items.get(i).isRead()) return i;
 		}
 		return NO_POSITION;
 	}
@@ -374,24 +159,12 @@ public class ThreadItemAdapter<I extends ThreadItem>
 	public int getVisibleUnreadPosTop() {
 		final int positionTop = layoutManager.findFirstVisibleItemPosition();
 		int position = NO_POSITION;
-		int visibleCounter = 0;
-		int levelLimit = UNDEFINED;
-		for (I i : items) {
-			if (levelLimit >= 0) {
-				if (i.getLevel() > levelLimit) {
-					// skip all the items below a non visible branch
-					continue;
-				}
-				levelLimit = UNDEFINED;
-			}
-			if (visibleCounter < positionTop && !i.isRead()) {
-				position = visibleCounter;
-			} if (visibleCounter >= positionTop) {
+		for (int i = 0; i < items.size(); i++) {
+			if (i < positionTop && !items.get(i).isRead()) {
+				position = i;
+			} else if (i >= positionTop) {
 				return position;
-			} else if (!i.isShowingDescendants()) {
-				levelLimit = i.getLevel();
 			}
-			visibleCounter++;
 		}
 		return NO_POSITION;
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java
index c43ce66e0265de46decc056db4a2165279ac984e..77ef469716954ba513617fa19bc9fb9d0a75e128 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java
@@ -3,6 +3,7 @@ package org.briarproject.briar.android.threaded;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.annotation.CallSuper;
+import android.support.annotation.Nullable;
 import android.support.annotation.StringRes;
 import android.support.annotation.UiThread;
 import android.support.design.widget.Snackbar;
@@ -32,11 +33,11 @@ import org.briarproject.briar.android.view.TextInputView.TextInputListener;
 import org.briarproject.briar.android.view.UnreadMessageButton;
 import org.briarproject.briar.api.client.NamedGroup;
 import org.briarproject.briar.api.client.PostHeader;
+import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout;
 
 import java.util.Collection;
 import java.util.logging.Logger;
 
-import javax.annotation.Nullable;
 import javax.inject.Inject;
 
 import static android.support.design.widget.Snackbar.make;
@@ -62,9 +63,11 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI
 
 	protected A adapter;
 	protected BriarRecyclerView list;
+	private LinearLayoutManager layoutManager;
 	protected TextInputView textInput;
 	protected GroupId groupId;
 	private UnreadMessageButton upButton, downButton;
+	@Nullable
 	private MessageId replyId;
 
 	protected abstract ThreadListController<G, I, H> getController();
@@ -89,9 +92,9 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI
 		textInput.setVisibility(GONE);
 		textInput.setListener(this);
 		list = (BriarRecyclerView) findViewById(R.id.list);
-		LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
-		list.setLayoutManager(linearLayoutManager);
-		adapter = createAdapter(linearLayoutManager);
+		layoutManager = new LinearLayoutManager(this);
+		list.setLayoutManager(layoutManager);
+		adapter = createAdapter(layoutManager);
 		list.setAdapter(adapter);
 
 		list.getRecyclerView().addOnScrollListener(
@@ -179,7 +182,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI
 								adapter.setItems(items);
 								list.showData();
 								if (replyId != null)
-									adapter.setReplyItemById(replyId);
+									adapter.setHighlightedItem(replyId);
 							}
 						} else {
 							LOG.info("Concurrent update, reloading");
@@ -240,7 +243,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI
 		super.onSaveInstanceState(outState);
 		boolean visible = textInput.getVisibility() == VISIBLE;
 		outState.putBoolean(KEY_INPUT_VISIBILITY, visible);
-		ThreadItem replyItem = adapter.getReplyItem();
+		ThreadItem replyItem = adapter.getHighlightedItem();
 		if (replyItem != null) {
 			outState.putByteArray(KEY_REPLY_ID, replyItem.getId().getBytes());
 		}
@@ -261,7 +264,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI
 	public void onBackPressed() {
 		if (textInput.getVisibility() == VISIBLE) {
 			textInput.setVisibility(GONE);
-			adapter.setReplyItem(null);
+			adapter.setHighlightedItem(null);
 		} else {
 			super.onBackPressed();
 		}
@@ -276,8 +279,21 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI
 	}
 
 	@Override
-	public void onReplyClick(I item) {
+	public void onReplyClick(final I item) {
 		showTextInput(item);
+		if (textInput.isKeyboardOpen()) {
+			scrollToItemAtTop(item);
+		} else {
+			// wait with scrolling until keyboard opened
+			textInput.addOnKeyboardShownListener(
+					new KeyboardAwareLinearLayout.OnKeyboardShownListener() {
+						@Override
+						public void onKeyboardShown() {
+							scrollToItemAtTop(item);
+							textInput.removeOnKeyboardShownListener(this);
+						}
+					});
+		}
 	}
 
 	@Override
@@ -300,7 +316,15 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI
 		}
 	}
 
-	protected void displaySnackbarShort(@StringRes int stringId) {
+	private void scrollToItemAtTop(I item) {
+		int position = adapter.findItemPosition(item);
+		if (position != NO_POSITION) {
+			layoutManager
+					.scrollToPositionWithOffset(position, 0);
+		}
+	}
+
+	protected void displaySnackbar(@StringRes int stringId) {
 		Snackbar snackbar = make(list, stringId, Snackbar.LENGTH_SHORT);
 		snackbar.getView().setBackgroundResource(R.color.briar_primary);
 		snackbar.show();
@@ -318,7 +342,8 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI
 		textInput.showSoftKeyboard();
 		textInput.setHint(replyItem == null ? R.string.forum_new_message_hint :
 				R.string.forum_message_reply_hint);
-		adapter.setReplyItem(replyItem);
+		adapter.setHighlightedItem(
+				replyItem == null ? null : replyItem.getId());
 	}
 
 	@Override
@@ -326,10 +351,10 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI
 		if (text.trim().length() == 0)
 			return;
 		if (StringUtils.utf8IsTooLong(text, getMaxBodyLength())) {
-			displaySnackbarShort(R.string.text_too_long);
+			displaySnackbar(R.string.text_too_long);
 			return;
 		}
-		I replyItem = adapter.getReplyItem();
+		I replyItem = adapter.getHighlightedItem();
 		UiResultExceptionHandler<I, DbException> handler =
 				new UiResultExceptionHandler<I, DbException>(this) {
 					@Override
@@ -346,7 +371,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI
 		textInput.hideSoftKeyboard();
 		textInput.setVisibility(GONE);
 		textInput.setText("");
-		adapter.setReplyItem(null);
+		adapter.setHighlightedItem(null);
 	}
 
 	protected abstract int getMaxBodyLength();
@@ -377,7 +402,8 @@ public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadI
 		adapter.add(item);
 
 		if (isLocal) {
-			displaySnackbarShort(getItemPostedString());
+			displaySnackbar(getItemPostedString());
+			scrollToItemAtTop(item);
 		} else {
 			updateUnreadCount();
 		}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadPostViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadPostViewHolder.java
index 5bdca7ba2f4a754ff5ba77d92b8363adafcaf881..5719f9a0e09ace6d61611e5bd19933b45f69971f 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadPostViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadPostViewHolder.java
@@ -16,32 +16,29 @@ import static android.view.View.VISIBLE;
 public class ThreadPostViewHolder<I extends ThreadItem>
 		extends BaseThreadItemViewHolder<I> {
 
-	private final TextView  lvlText, repliesText;
+	private final TextView  lvlText;
 	private final View[] lvls;
-	private final View chevron, replyButton;
+	private final View replyButton;
+
+	private final static int[] nestedLineIds = {
+			R.id.nested_line_1, R.id.nested_line_2, R.id.nested_line_3,
+			R.id.nested_line_4, R.id.nested_line_5
+	};
 
 	public ThreadPostViewHolder(View v) {
 		super(v);
 
 		lvlText = (TextView) v.findViewById(R.id.nested_line_text);
-		repliesText = (TextView) v.findViewById(R.id.replies);
-		int[] nestedLineIds = {
-				R.id.nested_line_1, R.id.nested_line_2, R.id.nested_line_3,
-				R.id.nested_line_4, R.id.nested_line_5
-		};
 		lvls = new View[nestedLineIds.length];
 		for (int i = 0; i < lvls.length; i++) {
 			lvls[i] = v.findViewById(nestedLineIds[i]);
 		}
-		chevron = v.findViewById(R.id.chevron);
 		replyButton = v.findViewById(R.id.btn_reply);
 	}
 
-	// TODO improve encapsulation, so we don't need to pass the adapter here
 	@Override
-	public void bind(final ThreadItemAdapter<I> adapter,
-			final ThreadItemListener<I> listener, final I item, int pos) {
-		super.bind(adapter, listener, item, pos);
+	public void bind(final I item, final ThreadItemListener<I> listener) {
+		super.bind(item, listener);
 
 		for (int i = 0; i < lvls.length; i++) {
 			lvls[i].setVisibility(i < item.getLevel() ? VISIBLE : GONE);
@@ -53,41 +50,10 @@ public class ThreadPostViewHolder<I extends ThreadItem>
 			lvlText.setVisibility(GONE);
 		}
 
-		int replies = adapter.getReplyCount(item);
-		if (replies == 0) {
-			repliesText.setText("");
-		} else {
-			repliesText.setText(getContext().getResources()
-					.getQuantityString(R.plurals.message_replies, replies,
-							replies));
-		}
-
-		if (item.hasDescendants()) {
-//			chevron.setVisibility(VISIBLE);
-			if (item.isShowingDescendants()) {
-				chevron.setSelected(false);
-			} else {
-				chevron.setSelected(true);
-			}
-			chevron.setOnClickListener(new View.OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					chevron.setSelected(!chevron.isSelected());
-					if (chevron.isSelected()) {
-						adapter.hideDescendants(item);
-					} else {
-						adapter.showDescendants(item);
-					}
-				}
-			});
-		} else {
-//			chevron.setVisibility(INVISIBLE);
-		}
 		replyButton.setOnClickListener(new View.OnClickListener() {
 			@Override
 			public void onClick(View v) {
 				listener.onReplyClick(item);
-				adapter.scrollTo(item);
 			}
 		});
 	}
diff --git a/briar-android/src/main/res/layout/list_item_forum.xml b/briar-android/src/main/res/layout/list_item_forum.xml
index 50bd1a18aff68639e2a03f6f58817f55e81b0243..a3881e9e74c7731f3e45c355ee40320a37c715e2 100644
--- a/briar-android/src/main/res/layout/list_item_forum.xml
+++ b/briar-android/src/main/res/layout/list_item_forum.xml
@@ -60,7 +60,7 @@
 		tools:text="Dec 24"/>
 
 	<View
-		style="@style/Divider.ForumList"
+		style="@style/Divider.ThreadItem"
 		android:layout_alignParentLeft="true"
 		android:layout_alignParentStart="true"
 		android:layout_below="@+id/postCountView"/>
diff --git a/briar-android/src/main/res/layout/list_item_group.xml b/briar-android/src/main/res/layout/list_item_group.xml
index d0b11226487e0d1e4b3866dada0f72ab24fb0794..19ea41eb87ed2792c45c661a91a0df580c9b6b19 100644
--- a/briar-android/src/main/res/layout/list_item_group.xml
+++ b/briar-android/src/main/res/layout/list_item_group.xml
@@ -97,7 +97,7 @@
 
 	<View
 		android:id="@+id/divider"
-		style="@style/Divider.ForumList"
+		style="@style/Divider.ThreadItem"
 		android:layout_alignParentLeft="true"
 		android:layout_alignParentStart="true"
 		android:layout_below="@+id/statusView"
diff --git a/briar-android/src/main/res/layout/list_item_group_join_notice.xml b/briar-android/src/main/res/layout/list_item_group_join_notice.xml
index 23b7fd283ccdfe6975f61f3a94a7b07b4248b6f4..02e0b4b4b2db1bba5642cb39bf7bbddb0e7eb933 100644
--- a/briar-android/src/main/res/layout/list_item_group_join_notice.xml
+++ b/briar-android/src/main/res/layout/list_item_group_join_notice.xml
@@ -6,23 +6,14 @@
 	xmlns:tools="http://schemas.android.com/tools"
 	android:layout_width="match_parent"
 	android:layout_height="wrap_content"
-	android:layout_marginLeft="@dimen/margin_medium"
 	android:baselineAligned="false"
 	android:orientation="vertical">
 
-	<View
-		android:id="@+id/top_divider"
-		style="@style/Divider.ForumList"
-		android:layout_alignParentTop="true"/>
-
 	<org.thoughtcrime.securesms.components.emoji.EmojiTextView
 		android:id="@+id/text"
 		android:layout_width="match_parent"
 		android:layout_height="wrap_content"
-		android:layout_below="@+id/top_divider"
-		android:layout_marginBottom="@dimen/margin_small"
-		android:layout_marginRight="@dimen/margin_medium"
-		android:layout_marginTop="@dimen/margin_medium"
+		android:layout_margin="@dimen/margin_medium"
 		android:textColor="@color/briar_text_secondary"
 		android:textSize="@dimen/text_size_medium"
 		android:textStyle="italic"
@@ -32,9 +23,12 @@
 		android:id="@+id/icon"
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
+		android:layout_alignBottom="@+id/info"
 		android:layout_alignLeft="@+id/text"
+		android:layout_alignTop="@+id/info"
 		android:layout_below="@+id/text"
-		android:layout_marginRight="@dimen/margin_small"
+		android:layout_marginRight="@dimen/margin_medium"
+		android:scaleType="center"
 		tools:ignore="ContentDescription"
 		tools:src="@drawable/ic_visibility"/>
 
@@ -45,6 +39,7 @@
 		android:layout_alignEnd="@+id/text"
 		android:layout_alignRight="@+id/text"
 		android:layout_below="@+id/text"
+		android:layout_marginBottom="@dimen/margin_medium"
 		android:layout_toRightOf="@+id/icon"
 		android:gravity="center_vertical"
 		android:minHeight="24dp"
@@ -57,10 +52,10 @@
 	<org.briarproject.briar.android.view.AuthorView
 		android:id="@+id/author"
 		android:layout_width="wrap_content"
-		android:layout_height="@dimen/button_size"
+		android:layout_height="wrap_content"
 		android:layout_alignLeft="@+id/text"
 		android:layout_below="@+id/info"
-		android:gravity="center"
+		android:layout_toLeftOf="@+id/optionsButton"
 		app:persona="commenter"/>
 
 	<Button
@@ -68,11 +63,16 @@
 		style="@style/BriarButtonFlat.Positive.Tiny"
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
+		android:layout_alignBottom="@+id/author"
 		android:layout_alignEnd="@+id/text"
 		android:layout_alignRight="@+id/text"
-		android:layout_alignTop="@+id/author"
-		android:layout_toRightOf="@+id/author"
+		android:layout_below="@+id/info"
 		android:gravity="right|center_vertical"
 		android:text="@string/options"/>
 
+	<View
+		style="@style/Divider.ThreadItem"
+		android:layout_below="@+id/author"
+		android:layout_marginTop="@dimen/margin_medium"/>
+
 </RelativeLayout>
diff --git a/briar-android/src/main/res/layout/list_item_invitations.xml b/briar-android/src/main/res/layout/list_item_invitations.xml
index ce7afa14770ae968530584d51eb2cadcae59b997..5aab1e59199c53b838ea3bbbfa2882a518525992 100644
--- a/briar-android/src/main/res/layout/list_item_invitations.xml
+++ b/briar-android/src/main/res/layout/list_item_invitations.xml
@@ -81,7 +81,7 @@
 		android:text="@string/decline"/>
 
 	<View
-		style="@style/Divider.ForumList"
+		style="@style/Divider.ThreadItem"
 		android:layout_alignParentLeft="true"
 		android:layout_alignParentStart="true"
 		android:layout_below="@+id/acceptButton"/>
diff --git a/briar-android/src/main/res/layout/list_item_rss_feed.xml b/briar-android/src/main/res/layout/list_item_rss_feed.xml
index 51061a331483abbc8fb676de8ca97dcf98090aae..76e0978a7719b623ca4b55d248eea69d87da8b14 100644
--- a/briar-android/src/main/res/layout/list_item_rss_feed.xml
+++ b/briar-android/src/main/res/layout/list_item_rss_feed.xml
@@ -113,7 +113,7 @@
 		tools:text="This is a description of the RSS feed. It can be several lines long, but it can also not exist at all if it is not present in the feed itself."/>
 
 	<View
-		style="@style/Divider.ForumList"
+		style="@style/Divider.ThreadItem"
 		android:layout_alignParentLeft="true"
 		android:layout_alignParentStart="true"
 		android:layout_below="@+id/descriptionView"
diff --git a/briar-android/src/main/res/layout/list_item_thread.xml b/briar-android/src/main/res/layout/list_item_thread.xml
index b6ec4a14b4da6b504cab1517693b9b410938c79f..c1610883978420ef28eba8c5ab795b40420a19f8 100644
--- a/briar-android/src/main/res/layout/list_item_thread.xml
+++ b/briar-android/src/main/res/layout/list_item_thread.xml
@@ -62,23 +62,20 @@
 			android:background="@drawable/level_indicator_circle"
 			android:gravity="center"
 			android:textSize="@dimen/text_size_small"
-			android:visibility="gone"
-			/>
+			android:visibility="gone"/>
 
 	</RelativeLayout>
 
 	<RelativeLayout
 		android:layout_width="0dp"
 		android:layout_height="wrap_content"
-		android:layout_marginLeft="@dimen/margin_medium"
 		android:layout_weight="1">
 
 		<org.thoughtcrime.securesms.components.emoji.EmojiTextView
 			android:id="@+id/text"
 			android:layout_width="match_parent"
 			android:layout_height="wrap_content"
-			android:paddingRight="@dimen/margin_medium"
-			android:paddingTop="@dimen/margin_medium"
+			android:padding="@dimen/margin_medium"
 			android:textColor="@color/briar_text_primary"
 			android:textIsSelectable="true"
 			android:textSize="@dimen/text_size_medium"
@@ -87,26 +84,12 @@
 		<org.briarproject.briar.android.view.AuthorView
 			android:id="@+id/author"
 			android:layout_width="wrap_content"
-			android:layout_height="@dimen/button_size"
+			android:layout_height="wrap_content"
 			android:layout_alignLeft="@id/text"
 			android:layout_below="@id/text"
-			android:gravity="center"
-			app:persona="commenter"/>
-
-		<TextView
-			android:id="@+id/replies"
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_alignBottom="@+id/author"
-			android:layout_alignTop="@+id/author"
+			android:layout_marginLeft="@dimen/margin_medium"
 			android:layout_toLeftOf="@+id/btn_reply"
-			android:layout_toRightOf="@+id/author"
-			android:ellipsize="end"
-			android:gravity="right|end|center_vertical"
-			android:maxLines="1"
-			android:padding="@dimen/margin_medium"
-			android:textSize="@dimen/text_size_tiny"
-			tools:text="2 replies"/>
+			app:persona="commenter"/>
 
 		<TextView
 			android:id="@+id/btn_reply"
@@ -115,32 +98,17 @@
 			android:layout_height="wrap_content"
 			android:layout_alignBottom="@+id/author"
 			android:layout_alignParentRight="true"
-			android:layout_toLeftOf="@+id/chevron"
+			android:layout_below="@+id/text"
+			android:layout_marginRight="@dimen/margin_medium"
 			android:text="@string/btn_reply"
 			android:textSize="@dimen/text_size_tiny"/>
 
-		<ImageView
-			android:id="@+id/chevron"
-			android:layout_width="@dimen/button_size"
-			android:layout_height="@dimen/button_size"
-			android:layout_alignBottom="@+id/author"
-			android:layout_alignParentRight="true"
-			android:background="?attr/selectableItemBackground"
-			android:clickable="true"
-			android:padding="@dimen/margin_medium"
-			android:scaleType="center"
-			android:src="@drawable/selector_chevron"
-			android:visibility="gone"/>
-
 		<View
-			android:id="@+id/top_divider"
-			style="@style/Divider.ForumList"
-			android:layout_width="match_parent"
-			android:layout_height="@dimen/margin_separator"
+			style="@style/Divider.ThreadItem"
 			android:layout_alignLeft="@id/text"
-			android:layout_alignParentTop="true"/>
+			android:layout_below="@+id/author"
+			android:layout_marginTop="@dimen/margin_medium"/>
 
 	</RelativeLayout>
 
-
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/briar-android/src/main/res/values/styles.xml b/briar-android/src/main/res/values/styles.xml
index 99105713df16ed8960ba4da844601f6756b1af32..f599ac1899d3fcbb2954a3718909de8888bf2927 100644
--- a/briar-android/src/main/res/values/styles.xml
+++ b/briar-android/src/main/res/values/styles.xml
@@ -79,7 +79,7 @@
 		<item name="android:layout_marginLeft">@dimen/margin_large</item>
 	</style>
 
-	<style name="Divider.ForumList" parent="Divider">
+	<style name="Divider.ThreadItem" parent="Divider">
 		<item name="android:layout_width">match_parent</item>
 		<item name="android:layout_height">1dp</item>
 	</style>
@@ -102,7 +102,7 @@
 
 	<style name="DiscussionLevelIndicator">
 		<item name="android:layout_marginLeft">4dp</item>
-		<item name="android:background">?android:attr/listDivider</item>
+		<item name="android:background">@color/divider</item>
 	</style>
 
 	<style name="BriarTabLayout" parent="Widget.Design.TabLayout">
diff --git a/briar-android/src/test/java/org/briarproject/briar/android/forum/ForumActivityTest.java b/briar-android/src/test/java/org/briarproject/briar/android/forum/ForumActivityTest.java
index 5773f0d2aa518bb83525871336c23ece4abba6a0..79867640996af9b5fa2da04f5bd339a863d3cb7f 100644
--- a/briar-android/src/test/java/org/briarproject/briar/android/forum/ForumActivityTest.java
+++ b/briar-android/src/test/java/org/briarproject/briar/android/forum/ForumActivityTest.java
@@ -114,28 +114,15 @@ public class ForumActivityTest {
 		rc.getValue().onResult(dummyData);
 		ThreadItemAdapter<ForumItem> adapter = forumActivity.getAdapter();
 		Assert.assertNotNull(adapter);
-		// Cascade close
 		assertEquals(6, adapter.getItemCount());
-		adapter.hideDescendants(dummyData.get(2));
-		assertEquals(5, adapter.getItemCount());
-		adapter.hideDescendants(dummyData.get(1));
-		assertEquals(4, adapter.getItemCount());
-		adapter.hideDescendants(dummyData.get(0));
-		assertEquals(2, adapter.getItemCount());
 		assertTrue(dummyData.get(0).getText()
-				.equals(adapter.getVisibleItem(0).getText()));
+				.equals(adapter.getItemAt(0).getText()));
 		assertTrue(dummyData.get(5).getText()
-				.equals(adapter.getVisibleItem(1).getText()));
-		// Cascade re-open
-		adapter.showDescendants(dummyData.get(0));
-		assertEquals(4, adapter.getItemCount());
-		adapter.showDescendants(dummyData.get(1));
-		assertEquals(5, adapter.getItemCount());
-		adapter.showDescendants(dummyData.get(2));
-		assertEquals(6, adapter.getItemCount());
+				.equals(adapter.getItemAt(1).getText()));
 		assertTrue(dummyData.get(2).getText()
-				.equals(adapter.getVisibleItem(2).getText()));
+				.equals(adapter.getItemAt(2).getText()));
 		assertTrue(dummyData.get(4).getText()
-				.equals(adapter.getVisibleItem(4).getText()));
+				.equals(adapter.getItemAt(4).getText()));
 	}
+
 }
diff --git a/briar-api/src/main/java/org/briarproject/briar/api/client/MessageTree.java b/briar-api/src/main/java/org/briarproject/briar/api/client/MessageTree.java
index cca70884e3577278b96541fb17ef3049fe5dc79d..8d2ed6cd9ac23eac905d26a478094d5440b4f8fd 100644
--- a/briar-api/src/main/java/org/briarproject/briar/api/client/MessageTree.java
+++ b/briar-api/src/main/java/org/briarproject/briar/api/client/MessageTree.java
@@ -31,8 +31,6 @@ public interface MessageTree<T extends MessageTree.MessageNode> {
 
 		void setLevel(int level);
 
-		void setDescendantCount(int descendantCount);
-
 		long getTimestamp();
 	}
 
diff --git a/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java b/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java
index 982bcd2e765218dbaa1673e959ea70bea2653d63..5636c5f751ba50987cc50ab5074cc4bddd2e2e22 100644
--- a/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java
@@ -83,7 +83,6 @@ public class MessageTreeImpl<T extends MessageTree.MessageNode>
 		list.add(node);
 		List<T> children = nodeMap.get(node.getId());
 		node.setLevel(level);
-		node.setDescendantCount(children.size());
 		for (T child : children) {
 			traverse(list, child, level + 1);
 		}