diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml
index b57845c6b6a82241654d6d9dc0d71ae5588f03e6..5e9dfba96c03d8eeda6b1db194ff7d36035de898 100644
--- a/briar-android/res/values/strings.xml
+++ b/briar-android/res/values/strings.xml
@@ -47,6 +47,7 @@
 	<string name="from">From:</string>
 	<string name="to">To:</string>
 	<string name="anonymous">(Anonymous)</string>
+	<string name="new_contact_item">New contact\u2026</string>
 	<string name="groups_title">Groups</string>
 	<string name="no_posts">(No posts)</string>
 	<string name="create_group_title">New Group</string>
diff --git a/briar-android/src/net/sf/briar/android/blogs/CreateBlogActivity.java b/briar-android/src/net/sf/briar/android/blogs/CreateBlogActivity.java
index 84ec78b6ce8e9c0ce7b53149e279a1fe7fd8dee9..e62dff274a37f50f31a6d4e3d91beb5ec80752aa 100644
--- a/briar-android/src/net/sf/briar/android/blogs/CreateBlogActivity.java
+++ b/briar-android/src/net/sf/briar/android/blogs/CreateBlogActivity.java
@@ -24,7 +24,7 @@ import net.sf.briar.R;
 import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
-import net.sf.briar.android.SelectContactsDialog;
+import net.sf.briar.android.contact.SelectContactsDialog;
 import net.sf.briar.android.invitation.AddContactActivity;
 import net.sf.briar.android.messages.NoContactsDialog;
 import net.sf.briar.api.Contact;
diff --git a/briar-android/src/net/sf/briar/android/blogs/LocalGroupSpinnerAdapter.java b/briar-android/src/net/sf/briar/android/blogs/LocalGroupSpinnerAdapter.java
index c4cf025cb874cdf8218b31ac76008c3a2ea124b7..c0ee80065dcb0c67bd70ecb265249536e9ec4959 100644
--- a/briar-android/src/net/sf/briar/android/blogs/LocalGroupSpinnerAdapter.java
+++ b/briar-android/src/net/sf/briar/android/blogs/LocalGroupSpinnerAdapter.java
@@ -34,7 +34,7 @@ class LocalGroupSpinnerAdapter extends BaseAdapter implements SpinnerAdapter {
 	}
 
 	public int getCount() {
-		return list.size() + 1;
+		return list.isEmpty() ? 0 : list.size() + 1;
 	}
 
 	@Override
@@ -67,7 +67,7 @@ class LocalGroupSpinnerAdapter extends BaseAdapter implements SpinnerAdapter {
 
 	@Override
 	public boolean isEmpty() {
-		return getCount() == 0;
+		return list.isEmpty();
 	}
 
 	public void sort(Comparator<LocalGroupItem> comparator) {
diff --git a/briar-android/src/net/sf/briar/android/blogs/WriteBlogPostActivity.java b/briar-android/src/net/sf/briar/android/blogs/WriteBlogPostActivity.java
index 57dfded067bcfc6221bab347e0c563e4505aa700..cae099277cc28873cd064397475d9febd1ef859d 100644
--- a/briar-android/src/net/sf/briar/android/blogs/WriteBlogPostActivity.java
+++ b/briar-android/src/net/sf/briar/android/blogs/WriteBlogPostActivity.java
@@ -99,7 +99,7 @@ implements OnItemSelectedListener, OnClickListener {
 
 		TextView from = new TextView(this);
 		from.setTextSize(18);
-		from.setPadding(10, 10, 10, 10);
+		from.setPadding(10, 10, 0, 10);
 		from.setText(R.string.from);
 		header.addView(from);
 
diff --git a/briar-android/src/net/sf/briar/android/contact/ContactItem.java b/briar-android/src/net/sf/briar/android/contact/ContactItem.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d6f0dc0201e15369d35c9c6620f5c009a2f4675
--- /dev/null
+++ b/briar-android/src/net/sf/briar/android/contact/ContactItem.java
@@ -0,0 +1,18 @@
+package net.sf.briar.android.contact;
+
+import net.sf.briar.api.Contact;
+
+public class ContactItem {
+
+	public static final ContactItem NEW = new ContactItem(null);
+
+	private final Contact contact;
+
+	public ContactItem(Contact contact) {
+		this.contact = contact;
+	}
+
+	public Contact getContact() {
+		return contact;
+	}
+}
diff --git a/briar-android/src/net/sf/briar/android/contact/ContactNameComparator.java b/briar-android/src/net/sf/briar/android/contact/ContactNameComparator.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb8bb09a62b2b6fd602c51564c07bfa88783862d
--- /dev/null
+++ b/briar-android/src/net/sf/briar/android/contact/ContactNameComparator.java
@@ -0,0 +1,18 @@
+package net.sf.briar.android.contact;
+
+import java.util.Comparator;
+
+public class ContactNameComparator implements Comparator<ContactItem> {
+
+	public static final ContactNameComparator INSTANCE =
+			new ContactNameComparator();
+
+	public int compare(ContactItem a, ContactItem b) {
+		if(a == b) return 0;
+		if(a == ContactItem.NEW) return 1;
+		if(b == ContactItem.NEW) return -1;
+		String aName = a.getContact().getAuthor().getName();
+		String bName = b.getContact().getAuthor().getName();
+		return String.CASE_INSENSITIVE_ORDER.compare(aName, bName);
+	}
+}
diff --git a/briar-android/src/net/sf/briar/android/contact/ContactSpinnerAdapter.java b/briar-android/src/net/sf/briar/android/contact/ContactSpinnerAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..58e17c02d22ec335c6e6649c77334e425c99e40d
--- /dev/null
+++ b/briar-android/src/net/sf/briar/android/contact/ContactSpinnerAdapter.java
@@ -0,0 +1,77 @@
+package net.sf.briar.android.contact;
+
+import static net.sf.briar.android.contact.ContactItem.NEW;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import net.sf.briar.R;
+import android.content.Context;
+import android.content.res.Resources;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.SpinnerAdapter;
+import android.widget.TextView;
+
+public class ContactSpinnerAdapter extends BaseAdapter
+implements SpinnerAdapter {
+
+	private final Context ctx;
+	private final List<ContactItem> list = new ArrayList<ContactItem>();
+
+	public ContactSpinnerAdapter(Context ctx) {
+		this.ctx = ctx;
+	}
+
+	public void add(ContactItem item) {
+		list.add(item);
+	}
+
+	public void clear() {
+		list.clear();
+	}
+
+	public int getCount() {
+		return list.isEmpty() ? 0 : list.size() + 1;
+	}
+
+	@Override
+	public View getDropDownView(int position, View convertView,
+			ViewGroup parent) {
+		return getView(position, convertView, parent);
+	}
+
+	public ContactItem getItem(int position) {
+		if(position == list.size()) return NEW;
+		return list.get(position);
+	}
+
+	public long getItemId(int position) {
+		return android.R.layout.simple_spinner_item;
+	}
+
+	public View getView(int position, View convertView, ViewGroup parent) {
+		TextView name = new TextView(ctx);
+		name.setTextSize(18);
+		name.setMaxLines(1);
+		Resources res = ctx.getResources();
+		int pad = res.getInteger(R.integer.spinner_padding);
+		name.setPadding(pad, pad, pad, pad);
+		ContactItem item = getItem(position);
+		if(item == NEW) name.setText(R.string.new_contact_item);
+		else name.setText(item.getContact().getAuthor().getName());
+		return name;
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return list.isEmpty();
+	}
+
+	public void sort(Comparator<ContactItem> comparator) {
+		Collections.sort(list, comparator);
+	}
+}
diff --git a/briar-android/src/net/sf/briar/android/SelectContactsDialog.java b/briar-android/src/net/sf/briar/android/contact/SelectContactsDialog.java
similarity index 98%
rename from briar-android/src/net/sf/briar/android/SelectContactsDialog.java
rename to briar-android/src/net/sf/briar/android/contact/SelectContactsDialog.java
index 6a07376b22e8875900a810f2198182b050116c2b..ffbd584b60b644f4188e5290cc8d17da9b874996 100644
--- a/briar-android/src/net/sf/briar/android/SelectContactsDialog.java
+++ b/briar-android/src/net/sf/briar/android/contact/SelectContactsDialog.java
@@ -1,4 +1,4 @@
-package net.sf.briar.android;
+package net.sf.briar.android.contact;
 
 import java.util.Collection;
 import java.util.HashSet;
diff --git a/briar-android/src/net/sf/briar/android/groups/CreateGroupActivity.java b/briar-android/src/net/sf/briar/android/groups/CreateGroupActivity.java
index 57b280767b907f1fe916cce022584bd5c582fb22..028d0cccd93f5eb95dd134afbe7fbf1a5694d926 100644
--- a/briar-android/src/net/sf/briar/android/groups/CreateGroupActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/CreateGroupActivity.java
@@ -23,7 +23,7 @@ import net.sf.briar.R;
 import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
-import net.sf.briar.android.SelectContactsDialog;
+import net.sf.briar.android.contact.SelectContactsDialog;
 import net.sf.briar.android.invitation.AddContactActivity;
 import net.sf.briar.android.messages.NoContactsDialog;
 import net.sf.briar.api.Contact;
diff --git a/briar-android/src/net/sf/briar/android/groups/GroupSpinnerAdapter.java b/briar-android/src/net/sf/briar/android/groups/GroupSpinnerAdapter.java
index c4180324b9c977e5d5229b8219c8cfb5414e1d7f..ff027ac971c513e82ee8e548a69342f0bd2089c7 100644
--- a/briar-android/src/net/sf/briar/android/groups/GroupSpinnerAdapter.java
+++ b/briar-android/src/net/sf/briar/android/groups/GroupSpinnerAdapter.java
@@ -34,7 +34,7 @@ class GroupSpinnerAdapter extends BaseAdapter implements SpinnerAdapter {
 	}
 
 	public int getCount() {
-		return list.size() + 1;
+		return list.isEmpty() ? 0 : list.size() + 1;
 	}
 
 	@Override
@@ -67,7 +67,7 @@ class GroupSpinnerAdapter extends BaseAdapter implements SpinnerAdapter {
 
 	@Override
 	public boolean isEmpty() {
-		return getCount() == 0;
+		return list.isEmpty();
 	}
 
 	public void sort(Comparator<GroupItem> comparator) {
diff --git a/briar-android/src/net/sf/briar/android/groups/WriteGroupPostActivity.java b/briar-android/src/net/sf/briar/android/groups/WriteGroupPostActivity.java
index 7fb542d741d8cfc19de3c23387f2b916993a7d38..3254c70c2e38cdd92e4ba685bc9436734f5d1946 100644
--- a/briar-android/src/net/sf/briar/android/groups/WriteGroupPostActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/WriteGroupPostActivity.java
@@ -102,7 +102,7 @@ implements OnItemSelectedListener, OnClickListener {
 
 		TextView from = new TextView(this);
 		from.setTextSize(18);
-		from.setPadding(10, 10, 10, 10);
+		from.setPadding(10, 10, 0, 10);
 		from.setText(R.string.from);
 		header.addView(from);
 
diff --git a/briar-android/src/net/sf/briar/android/identity/LocalAuthorSpinnerAdapter.java b/briar-android/src/net/sf/briar/android/identity/LocalAuthorSpinnerAdapter.java
index 493653d4d4e3defa1bf4028a20819e4bdd124267..0f000a224b6b2c10301bdc0ea868cf41cd23b570 100644
--- a/briar-android/src/net/sf/briar/android/identity/LocalAuthorSpinnerAdapter.java
+++ b/briar-android/src/net/sf/briar/android/identity/LocalAuthorSpinnerAdapter.java
@@ -38,6 +38,7 @@ implements SpinnerAdapter {
 	}
 
 	public int getCount() {
+		if(list.isEmpty()) return 0;
 		return includeAnonymous ? list.size() + 2 : list.size() + 1;
 	}
 
@@ -78,7 +79,7 @@ implements SpinnerAdapter {
 
 	@Override
 	public boolean isEmpty() {
-		return getCount() == 0;
+		return list.isEmpty();
 	}
 
 	public void sort(Comparator<LocalAuthorItem> comparator) {
diff --git a/briar-android/src/net/sf/briar/android/invitation/AddContactActivity.java b/briar-android/src/net/sf/briar/android/invitation/AddContactActivity.java
index 6f59e7413a020bb728e86a5d805356304d5406d5..c4fc69b0ab24568027abf755bab407033a1a6a6d 100644
--- a/briar-android/src/net/sf/briar/android/invitation/AddContactActivity.java
+++ b/briar-android/src/net/sf/briar/android/invitation/AddContactActivity.java
@@ -214,6 +214,7 @@ implements InvitationListener {
 			final Collection<LocalAuthor> localAuthors) {
 		runOnUiThread(new Runnable() {
 			public void run() {
+				if(localAuthors.isEmpty()) throw new IllegalStateException();
 				adapter.clear();
 				for(LocalAuthor a : localAuthors)
 					adapter.add(new LocalAuthorItem(a));
diff --git a/briar-android/src/net/sf/briar/android/messages/ContactSpinnerAdapter.java b/briar-android/src/net/sf/briar/android/messages/ContactSpinnerAdapter.java
deleted file mode 100644
index 79bc800b78d484756aada7ca9d3b128fb4e5f606..0000000000000000000000000000000000000000
--- a/briar-android/src/net/sf/briar/android/messages/ContactSpinnerAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package net.sf.briar.android.messages;
-
-import java.util.ArrayList;
-
-import net.sf.briar.R;
-import net.sf.briar.api.Contact;
-import android.content.Context;
-import android.content.res.Resources;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.SpinnerAdapter;
-import android.widget.TextView;
-
-public class ContactSpinnerAdapter extends ArrayAdapter<Contact>
-implements SpinnerAdapter {
-
-	ContactSpinnerAdapter(Context context) {
-		super(context, android.R.layout.simple_spinner_item,
-				new ArrayList<Contact>());
-	}
-
-	@Override
-	public View getView(int position, View convertView, ViewGroup parent) {
-		TextView name = new TextView(getContext());
-		name.setTextSize(18);
-		name.setMaxLines(1);
-		Resources res = getContext().getResources();
-		int pad = res.getInteger(R.integer.spinner_padding);
-		name.setPadding(pad, pad, pad, pad);
-		name.setText(getItem(position).getAuthor().getName());
-		return name;
-	}
-
-	@Override
-	public View getDropDownView(int position, View convertView,
-			ViewGroup parent) {
-		return getView(position, convertView, parent);
-	}
-}
diff --git a/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java b/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java
index 0ddfced47472ef1f12f999ea2c90c76bc388000a..09a5a263dc5b8882fba0b257a1d846141c92e742 100644
--- a/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java
+++ b/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java
@@ -20,6 +20,10 @@ import net.sf.briar.R;
 import net.sf.briar.android.BriarActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
+import net.sf.briar.android.contact.ContactItem;
+import net.sf.briar.android.contact.ContactNameComparator;
+import net.sf.briar.android.contact.ContactSpinnerAdapter;
+import net.sf.briar.android.invitation.AddContactActivity;
 import net.sf.briar.android.widgets.HorizontalSpace;
 import net.sf.briar.api.AuthorId;
 import net.sf.briar.api.Contact;
@@ -174,12 +178,19 @@ implements OnItemSelectedListener, OnClickListener {
 		runOnUiThread(new Runnable() {
 			public void run() {
 				if(contacts.isEmpty()) finish();
-				int index = -1;
-				for(Contact c : contacts) {
-					if(c.getId().equals(contactId)) index = adapter.getCount();
-					adapter.add(c);
+				adapter.clear();
+				for(Contact c : contacts) adapter.add(new ContactItem(c));
+				adapter.sort(ContactNameComparator.INSTANCE);
+				adapter.notifyDataSetChanged();
+				int count = adapter.getCount();
+				for(int i = 0; i < count; i++) {
+					ContactItem item = adapter.getItem(i);
+					if(item == ContactItem.NEW) continue;
+					if(item.getContact().getId().equals(contactId)) {
+						spinner.setSelection(i);
+						break;
+					}
 				}
-				if(index != -1) spinner.setSelection(index);
 			}
 		});
 	}
@@ -199,9 +210,14 @@ implements OnItemSelectedListener, OnClickListener {
 
 	public void onItemSelected(AdapterView<?> parent, View view, int position,
 			long id) {
-		Contact c = adapter.getItem(position);
-		loadLocalAuthor(c.getLocalAuthorId());
-		contactId = c.getId();
+		ContactItem item = adapter.getItem(position);
+		if(item == ContactItem.NEW) {
+			startActivity(new Intent(this, AddContactActivity.class));
+		} else {
+			Contact c = item.getContact();
+			loadLocalAuthor(c.getLocalAuthorId());
+			contactId = c.getId();
+		}
 	}
 
 	private void loadLocalAuthor(final AuthorId a) {