From ccc9d53ac75e91acbff9b68d9e5d136b37da522f Mon Sep 17 00:00:00 2001
From: Torsten Grote <t@grobox.de>
Date: Thu, 10 Nov 2016 16:24:29 -0200
Subject: [PATCH] Address review comments

---
 .../android/ActivityComponent.java            | 10 +++-
 .../briarproject/android/BaseActivity.java    |  3 +-
 .../BaseContactSelectorAdapter.java           |  2 +
 .../BaseContactSelectorFragment.java          | 25 ++++++----
 .../ContactSelectorActivity.java              |  7 ++-
 .../ContactSelectorAdapter.java               |  2 +
 .../ContactSelectorController.java            |  6 +--
 .../ContactSelectorControllerImpl.java        | 19 ++++---
 .../ContactSelectorFragment.java              | 34 ++++---------
 .../ContactSelectorListener.java              |  4 +-
 .../creation/BaseGroupInviteActivity.java     |  9 ++--
 .../creation/CreateGroupActivity.java         |  4 +-
 .../creation/CreateGroupControllerImpl.java   |  3 +-
 .../creation/GroupInviteActivity.java         |  4 +-
 .../creation/GroupInviteFragment.java         | 49 +++++++++++++++++++
 .../sharing/BlogInvitationControllerImpl.java |  6 +--
 .../ForumInvitationControllerImpl.java        |  4 --
 .../android/sharing/ShareActivity.java        | 15 +++---
 .../android/sharing/ShareBlogActivity.java    | 19 +++++--
 .../sharing/ShareBlogControllerImpl.java      | 20 +++++++-
 .../android/sharing/ShareBlogFragment.java    | 49 +++++++++++++++++++
 .../android/sharing/ShareForumActivity.java   | 22 ++++++---
 .../sharing/ShareForumControllerImpl.java     | 20 +++++++-
 .../android/sharing/ShareForumFragment.java   | 49 +++++++++++++++++++
 24 files changed, 291 insertions(+), 94 deletions(-)
 create mode 100644 briar-android/src/org/briarproject/android/privategroup/creation/GroupInviteFragment.java
 create mode 100644 briar-android/src/org/briarproject/android/sharing/ShareBlogFragment.java
 create mode 100644 briar-android/src/org/briarproject/android/sharing/ShareForumFragment.java

diff --git a/briar-android/src/org/briarproject/android/ActivityComponent.java b/briar-android/src/org/briarproject/android/ActivityComponent.java
index e350683529..6db54c450a 100644
--- a/briar-android/src/org/briarproject/android/ActivityComponent.java
+++ b/briar-android/src/org/briarproject/android/ActivityComponent.java
@@ -33,17 +33,19 @@ import org.briarproject.android.privategroup.creation.CreateGroupActivity;
 import org.briarproject.android.privategroup.creation.CreateGroupFragment;
 import org.briarproject.android.privategroup.creation.CreateGroupMessageFragment;
 import org.briarproject.android.privategroup.creation.GroupInviteActivity;
+import org.briarproject.android.privategroup.creation.GroupInviteFragment;
 import org.briarproject.android.privategroup.invitation.GroupInvitationActivity;
 import org.briarproject.android.privategroup.list.GroupListFragment;
 import org.briarproject.android.privategroup.memberlist.GroupMemberListActivity;
 import org.briarproject.android.sharing.BlogInvitationActivity;
 import org.briarproject.android.sharing.BlogSharingStatusActivity;
-import org.briarproject.android.contactselection.ContactSelectorFragment;
 import org.briarproject.android.sharing.ForumInvitationActivity;
 import org.briarproject.android.sharing.ForumSharingStatusActivity;
 import org.briarproject.android.sharing.ShareBlogActivity;
+import org.briarproject.android.sharing.ShareBlogFragment;
 import org.briarproject.android.sharing.ShareBlogMessageFragment;
 import org.briarproject.android.sharing.ShareForumActivity;
+import org.briarproject.android.sharing.ShareForumFragment;
 import org.briarproject.android.sharing.ShareForumMessageFragment;
 import org.thoughtcrime.securesms.components.emoji.EmojiProvider;
 import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel;
@@ -142,6 +144,8 @@ public interface ActivityComponent {
 
 	void inject(GroupListFragment fragment);
 
+	void inject(GroupInviteFragment fragment);
+
 	void inject(ForumListFragment fragment);
 
 	void inject(FeedFragment fragment);
@@ -152,10 +156,12 @@ public interface ActivityComponent {
 
 	void inject(ContactChooserFragment fragment);
 
-	void inject(ContactSelectorFragment fragment);
+	void inject(ShareForumFragment fragment);
 
 	void inject(ShareForumMessageFragment fragment);
 
+	void inject(ShareBlogFragment fragment);
+
 	void inject(ShareBlogMessageFragment fragment);
 
 	void inject(IntroductionMessageFragment fragment);
diff --git a/briar-android/src/org/briarproject/android/BaseActivity.java b/briar-android/src/org/briarproject/android/BaseActivity.java
index a144adb9e7..daa5bf4668 100644
--- a/briar-android/src/org/briarproject/android/BaseActivity.java
+++ b/briar-android/src/org/briarproject/android/BaseActivity.java
@@ -2,6 +2,7 @@ package org.briarproject.android;
 
 import android.os.Bundle;
 import android.os.IBinder;
+import android.support.annotation.Nullable;
 import android.support.v7.app.AppCompatActivity;
 import android.view.View;
 import android.view.inputmethod.InputMethodManager;
@@ -31,7 +32,7 @@ public abstract class BaseActivity extends AppCompatActivity
 	}
 
 	@Override
-	public void onCreate(Bundle savedInstanceState) {
+	public void onCreate(@Nullable Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 
 		if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE);
diff --git a/briar-android/src/org/briarproject/android/contactselection/BaseContactSelectorAdapter.java b/briar-android/src/org/briarproject/android/contactselection/BaseContactSelectorAdapter.java
index 8134d5d941..ae3af6cd7d 100644
--- a/briar-android/src/org/briarproject/android/contactselection/BaseContactSelectorAdapter.java
+++ b/briar-android/src/org/briarproject/android/contactselection/BaseContactSelectorAdapter.java
@@ -5,10 +5,12 @@ import android.content.Context;
 import org.briarproject.android.contact.BaseContactListAdapter;
 import org.briarproject.android.contact.ContactItemViewHolder;
 import org.briarproject.api.contact.ContactId;
+import org.briarproject.api.nullsafety.NotNullByDefault;
 
 import java.util.ArrayList;
 import java.util.Collection;
 
+@NotNullByDefault
 public abstract class BaseContactSelectorAdapter<I extends SelectableContactItem, H extends ContactItemViewHolder<I>>
 		extends BaseContactListAdapter<I, H> {
 
diff --git a/briar-android/src/org/briarproject/android/contactselection/BaseContactSelectorFragment.java b/briar-android/src/org/briarproject/android/contactselection/BaseContactSelectorFragment.java
index 2f9c91c6f8..7d093b82ad 100644
--- a/briar-android/src/org/briarproject/android/contactselection/BaseContactSelectorFragment.java
+++ b/briar-android/src/org/briarproject/android/contactselection/BaseContactSelectorFragment.java
@@ -19,6 +19,8 @@ import org.briarproject.android.fragment.BaseFragment;
 import org.briarproject.android.view.BriarRecyclerView;
 import org.briarproject.api.contact.ContactId;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
 import org.briarproject.api.sync.GroupId;
 
 import java.util.ArrayList;
@@ -29,22 +31,22 @@ import static org.briarproject.android.contactselection.ContactSelectorActivity.
 import static org.briarproject.android.contactselection.ContactSelectorActivity.getContactsFromIntegers;
 import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
 
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 public abstract class BaseContactSelectorFragment<I extends SelectableContactItem, H extends ContactItemViewHolder<I>>
 		extends BaseFragment
 		implements OnContactClickListener<I> {
 
 	protected BriarRecyclerView list;
 	protected BaseContactSelectorAdapter<I, H> adapter;
-	protected Collection<ContactId> selectedContacts;
+	protected Collection<ContactId> selectedContacts = new ArrayList<>();
 	protected ContactSelectorListener<I> listener;
 
 	private GroupId groupId;
-	private ContactSelectorController<I> controller;
 
 	@Override
 	public void onAttach(Context context) {
 		super.onAttach(context);
-		//noinspection unchecked
 		listener = (ContactSelectorListener<I>) context;
 	}
 
@@ -60,8 +62,9 @@ public abstract class BaseContactSelectorFragment<I extends SelectableContactIte
 
 	@Override
 	@CallSuper
-	public View onCreateView(LayoutInflater inflater, ViewGroup container,
-			Bundle savedInstanceState) {
+	public View onCreateView(LayoutInflater inflater,
+			@Nullable ViewGroup container,
+			@Nullable Bundle savedInstanceState) {
 
 		View contentView = inflater.inflate(R.layout.list, container, false);
 
@@ -87,7 +90,6 @@ public abstract class BaseContactSelectorFragment<I extends SelectableContactIte
 	@Override
 	public void onStart() {
 		super.onStart();
-		controller = listener.getController();
 		loadContacts(selectedContacts);
 	}
 
@@ -115,10 +117,10 @@ public abstract class BaseContactSelectorFragment<I extends SelectableContactIte
 		onSelectionChanged();
 	}
 
-	private void loadContacts(@Nullable final Collection<ContactId> selection) {
-		controller.loadContacts(groupId, selection,
+	private void loadContacts(final Collection<ContactId> selection) {
+		getController().loadContacts(groupId, selection,
 				new UiResultExceptionHandler<Collection<I>, DbException>(
-						listener) {
+						this) {
 					@Override
 					public void onResultUi(Collection<I> contacts) {
 						if (contacts.isEmpty()) list.showData();
@@ -128,11 +130,14 @@ public abstract class BaseContactSelectorFragment<I extends SelectableContactIte
 
 					@Override
 					public void onExceptionUi(DbException exception) {
-
+						// TODO error handling
+						finish();
 					}
 				});
 	}
 
 	protected abstract void onSelectionChanged();
 
+	protected abstract ContactSelectorController<I> getController();
+
 }
diff --git a/briar-android/src/org/briarproject/android/contactselection/ContactSelectorActivity.java b/briar-android/src/org/briarproject/android/contactselection/ContactSelectorActivity.java
index 1a84cf43fd..48ce9aaf56 100644
--- a/briar-android/src/org/briarproject/android/contactselection/ContactSelectorActivity.java
+++ b/briar-android/src/org/briarproject/android/contactselection/ContactSelectorActivity.java
@@ -2,18 +2,23 @@ package org.briarproject.android.contactselection;
 
 import android.os.Bundle;
 import android.support.annotation.CallSuper;
+import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 
 import org.briarproject.R;
 import org.briarproject.android.BriarActivity;
 import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
 import org.briarproject.api.contact.ContactId;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
 import org.briarproject.api.sync.GroupId;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 public abstract class ContactSelectorActivity<I extends SelectableContactItem>
 		extends BriarActivity
 		implements BaseFragmentListener, ContactSelectorListener<I> {
@@ -25,7 +30,7 @@ public abstract class ContactSelectorActivity<I extends SelectableContactItem>
 	protected Collection<ContactId> contacts;
 
 	@Override
-	public void onCreate(Bundle bundle) {
+	public void onCreate(@Nullable Bundle bundle) {
 		super.onCreate(bundle);
 
 		setContentView(R.layout.activity_fragment_container);
diff --git a/briar-android/src/org/briarproject/android/contactselection/ContactSelectorAdapter.java b/briar-android/src/org/briarproject/android/contactselection/ContactSelectorAdapter.java
index 3605210112..1b681679d1 100644
--- a/briar-android/src/org/briarproject/android/contactselection/ContactSelectorAdapter.java
+++ b/briar-android/src/org/briarproject/android/contactselection/ContactSelectorAdapter.java
@@ -6,7 +6,9 @@ import android.view.View;
 import android.view.ViewGroup;
 
 import org.briarproject.R;
+import org.briarproject.api.nullsafety.NotNullByDefault;
 
+@NotNullByDefault
 public class ContactSelectorAdapter extends
 		BaseContactSelectorAdapter<SelectableContactItem, SelectableContactHolder> {
 
diff --git a/briar-android/src/org/briarproject/android/contactselection/ContactSelectorController.java b/briar-android/src/org/briarproject/android/contactselection/ContactSelectorController.java
index 6ae4465290..e0d9cac7ab 100644
--- a/briar-android/src/org/briarproject/android/contactselection/ContactSelectorController.java
+++ b/briar-android/src/org/briarproject/android/contactselection/ContactSelectorController.java
@@ -1,19 +1,19 @@
 package org.briarproject.android.contactselection;
 
-import android.support.annotation.Nullable;
-
 import org.briarproject.android.controller.DbController;
 import org.briarproject.android.controller.handler.ResultExceptionHandler;
 import org.briarproject.api.contact.ContactId;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.nullsafety.NotNullByDefault;
 import org.briarproject.api.sync.GroupId;
 
 import java.util.Collection;
 
+@NotNullByDefault
 public interface ContactSelectorController<I extends SelectableContactItem>
 		extends DbController {
 
-	void loadContacts(GroupId g, @Nullable Collection<ContactId> selection,
+	void loadContacts(GroupId g, Collection<ContactId> selection,
 			ResultExceptionHandler<Collection<I>, DbException> handler);
 
 }
diff --git a/briar-android/src/org/briarproject/android/contactselection/ContactSelectorControllerImpl.java b/briar-android/src/org/briarproject/android/contactselection/ContactSelectorControllerImpl.java
index ce12b5b992..e9f45bf718 100644
--- a/briar-android/src/org/briarproject/android/contactselection/ContactSelectorControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/contactselection/ContactSelectorControllerImpl.java
@@ -8,22 +8,26 @@ import org.briarproject.api.contact.ContactManager;
 import org.briarproject.api.db.DatabaseExecutor;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.lifecycle.LifecycleManager;
+import org.briarproject.api.nullsafety.NotNullByDefault;
 import org.briarproject.api.sync.GroupId;
-import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
+import javax.annotation.concurrent.Immutable;
+
 import static java.util.logging.Level.WARNING;
 
+@Immutable
+@NotNullByDefault
 public abstract class ContactSelectorControllerImpl<I extends SelectableContactItem>
 		extends DbControllerImpl
 		implements ContactSelectorController<I> {
 
-	protected static final Logger LOG =
-			Logger.getLogger("ContactSelectorController");
+	private static final Logger LOG =
+			Logger.getLogger(ContactSelectorControllerImpl.class.getName());
 
 	private final ContactManager contactManager;
 
@@ -35,7 +39,7 @@ public abstract class ContactSelectorControllerImpl<I extends SelectableContactI
 
 	@Override
 	public void loadContacts(final GroupId g,
-			@Nullable final Collection<ContactId> selection,
+			final Collection<ContactId> selection,
 			final ResultExceptionHandler<Collection<I>, DbException> handler) {
 		runOnDbThread(new Runnable() {
 			@Override
@@ -44,8 +48,8 @@ public abstract class ContactSelectorControllerImpl<I extends SelectableContactI
 					Collection<I> contacts = new ArrayList<>();
 					for (Contact c : contactManager.getActiveContacts()) {
 						// was this contact already selected?
-						boolean selected = isSelected(c, selection != null &&
-								selection.contains(c.getId()));
+						boolean selected =
+								isSelected(c, selection.contains(c.getId()));
 						// can this contact be selected?
 						boolean disabled = isDisabled(g, c);
 						contacts.add(getItem(c, selected, disabled));
@@ -61,7 +65,8 @@ public abstract class ContactSelectorControllerImpl<I extends SelectableContactI
 	}
 
 	@DatabaseExecutor
-	protected abstract boolean isSelected(Contact c, boolean wasSelected);
+	protected abstract boolean isSelected(Contact c, boolean wasSelected)
+			throws DbException;
 
 	@DatabaseExecutor
 	protected abstract boolean isDisabled(GroupId g, Contact c)
diff --git a/briar-android/src/org/briarproject/android/contactselection/ContactSelectorFragment.java b/briar-android/src/org/briarproject/android/contactselection/ContactSelectorFragment.java
index b766b95e7a..7da47a25da 100644
--- a/briar-android/src/org/briarproject/android/contactselection/ContactSelectorFragment.java
+++ b/briar-android/src/org/briarproject/android/contactselection/ContactSelectorFragment.java
@@ -9,13 +9,14 @@ import android.view.View;
 import android.view.ViewGroup;
 
 import org.briarproject.R;
-import org.briarproject.android.ActivityComponent;
 import org.briarproject.android.contact.BaseContactListAdapter.OnContactClickListener;
-import org.briarproject.api.sync.GroupId;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
+import org.jetbrains.annotations.Nullable;
 
-import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
-
-public class ContactSelectorFragment extends
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
+public abstract class ContactSelectorFragment extends
 		BaseContactSelectorFragment<SelectableContactItem, SelectableContactHolder>
 		implements OnContactClickListener<SelectableContactItem> {
 
@@ -23,22 +24,10 @@ public class ContactSelectorFragment extends
 
 	private Menu menu;
 
-	public static ContactSelectorFragment newInstance(GroupId groupId) {
-		Bundle args = new Bundle();
-		args.putByteArray(GROUP_ID, groupId.getBytes());
-		ContactSelectorFragment fragment = new ContactSelectorFragment();
-		fragment.setArguments(args);
-		return fragment;
-	}
-
 	@Override
-	public void injectFragment(ActivityComponent component) {
-		component.inject(this);
-	}
-
-	@Override
-	public View onCreateView(LayoutInflater inflater, ViewGroup container,
-			Bundle savedInstanceState) {
+	public View onCreateView(LayoutInflater inflater,
+			@Nullable ViewGroup container,
+			@Nullable Bundle savedInstanceState) {
 		View contentView =
 				super.onCreateView(inflater, container, savedInstanceState);
 		adapter = new ContactSelectorAdapter(getActivity(), this);
@@ -67,11 +56,6 @@ public class ContactSelectorFragment extends
 		}
 	}
 
-	@Override
-	public String getUniqueTag() {
-		return TAG;
-	}
-
 	@Override
 	protected void onSelectionChanged() {
 		if (menu == null) return;
diff --git a/briar-android/src/org/briarproject/android/contactselection/ContactSelectorListener.java b/briar-android/src/org/briarproject/android/contactselection/ContactSelectorListener.java
index fa8bc3d789..93f91dbc77 100644
--- a/briar-android/src/org/briarproject/android/contactselection/ContactSelectorListener.java
+++ b/briar-android/src/org/briarproject/android/contactselection/ContactSelectorListener.java
@@ -4,14 +4,14 @@ import android.support.annotation.UiThread;
 
 import org.briarproject.android.DestroyableContext;
 import org.briarproject.api.contact.ContactId;
+import org.briarproject.api.nullsafety.NotNullByDefault;
 
 import java.util.Collection;
 
+@NotNullByDefault
 interface ContactSelectorListener<I extends SelectableContactItem>
 		extends DestroyableContext {
 
-	ContactSelectorController<I> getController();
-
 	@UiThread
 	void contactsSelected(Collection<ContactId> contacts);
 
diff --git a/briar-android/src/org/briarproject/android/privategroup/creation/BaseGroupInviteActivity.java b/briar-android/src/org/briarproject/android/privategroup/creation/BaseGroupInviteActivity.java
index 8359cfe917..791866f2ad 100644
--- a/briar-android/src/org/briarproject/android/privategroup/creation/BaseGroupInviteActivity.java
+++ b/briar-android/src/org/briarproject/android/privategroup/creation/BaseGroupInviteActivity.java
@@ -8,6 +8,8 @@ import org.briarproject.android.controller.handler.UiResultExceptionHandler;
 import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
 import org.briarproject.api.contact.ContactId;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Collection;
@@ -16,6 +18,8 @@ import javax.inject.Inject;
 
 import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_INVITATION_MSG_LENGTH;
 
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 public abstract class BaseGroupInviteActivity
 		extends ContactSelectorActivity<SelectableContactItem>
 		implements MessageFragmentListener {
@@ -23,11 +27,6 @@ public abstract class BaseGroupInviteActivity
 	@Inject
 	CreateGroupController controller;
 
-	@Override
-	public ContactSelectorController<SelectableContactItem> getController() {
-		return controller;
-	}
-
 	@Override
 	public void contactsSelected(Collection<ContactId> contacts) {
 		super.contactsSelected(contacts);
diff --git a/briar-android/src/org/briarproject/android/privategroup/creation/CreateGroupActivity.java b/briar-android/src/org/briarproject/android/privategroup/creation/CreateGroupActivity.java
index 5b571fe4a7..c1cffdde04 100644
--- a/briar-android/src/org/briarproject/android/privategroup/creation/CreateGroupActivity.java
+++ b/briar-android/src/org/briarproject/android/privategroup/creation/CreateGroupActivity.java
@@ -67,8 +67,8 @@ public class CreateGroupActivity extends BaseGroupInviteActivity implements
 
 	private void switchToContactSelectorFragment(GroupId g) {
 		setTitle(R.string.groups_invite_members);
-		ContactSelectorFragment fragment =
-				ContactSelectorFragment.newInstance(g);
+		GroupInviteFragment fragment =
+				GroupInviteFragment.newInstance(g);
 		getSupportFragmentManager().beginTransaction()
 				.setCustomAnimations(android.R.anim.fade_in,
 						android.R.anim.fade_out,
diff --git a/briar-android/src/org/briarproject/android/privategroup/creation/CreateGroupControllerImpl.java b/briar-android/src/org/briarproject/android/privategroup/creation/CreateGroupControllerImpl.java
index a0a849c7c0..42a514e96e 100644
--- a/briar-android/src/org/briarproject/android/privategroup/creation/CreateGroupControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/privategroup/creation/CreateGroupControllerImpl.java
@@ -131,7 +131,8 @@ public class CreateGroupControllerImpl
 	}
 
 	@Override
-	protected boolean isSelected(Contact c, boolean wasSelected) {
+	protected boolean isSelected(Contact c, boolean wasSelected)
+			throws DbException {
 		return wasSelected;
 	}
 
diff --git a/briar-android/src/org/briarproject/android/privategroup/creation/GroupInviteActivity.java b/briar-android/src/org/briarproject/android/privategroup/creation/GroupInviteActivity.java
index d4b225cfca..c9614f9cf6 100644
--- a/briar-android/src/org/briarproject/android/privategroup/creation/GroupInviteActivity.java
+++ b/briar-android/src/org/briarproject/android/privategroup/creation/GroupInviteActivity.java
@@ -27,8 +27,8 @@ public class GroupInviteActivity extends BaseGroupInviteActivity
 		groupId = new GroupId(g);
 
 		if (bundle == null) {
-			ContactSelectorFragment fragment =
-					ContactSelectorFragment.newInstance(groupId);
+			GroupInviteFragment fragment =
+					GroupInviteFragment.newInstance(groupId);
 			getSupportFragmentManager().beginTransaction()
 					.replace(R.id.fragmentContainer, fragment)
 					.commit();
diff --git a/briar-android/src/org/briarproject/android/privategroup/creation/GroupInviteFragment.java b/briar-android/src/org/briarproject/android/privategroup/creation/GroupInviteFragment.java
new file mode 100644
index 0000000000..7d97d5fd62
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/privategroup/creation/GroupInviteFragment.java
@@ -0,0 +1,49 @@
+package org.briarproject.android.privategroup.creation;
+
+import android.os.Bundle;
+
+import org.briarproject.android.ActivityComponent;
+import org.briarproject.android.contactselection.ContactSelectorController;
+import org.briarproject.android.contactselection.ContactSelectorFragment;
+import org.briarproject.android.contactselection.SelectableContactItem;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
+import org.briarproject.api.sync.GroupId;
+
+import javax.inject.Inject;
+
+import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
+
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
+public class GroupInviteFragment extends ContactSelectorFragment {
+
+	public static final String TAG = GroupInviteFragment.class.getName();
+
+	@Inject
+	CreateGroupController controller;
+
+	public static GroupInviteFragment newInstance(GroupId groupId) {
+		Bundle args = new Bundle();
+		args.putByteArray(GROUP_ID, groupId.getBytes());
+		GroupInviteFragment fragment = new GroupInviteFragment();
+		fragment.setArguments(args);
+		return fragment;
+	}
+
+	@Override
+	public void injectFragment(ActivityComponent component) {
+		component.inject(this);
+	}
+
+	@Override
+	protected ContactSelectorController<SelectableContactItem> getController() {
+		return controller;
+	}
+
+	@Override
+	public String getUniqueTag() {
+		return TAG;
+	}
+
+}
diff --git a/briar-android/src/org/briarproject/android/sharing/BlogInvitationControllerImpl.java b/briar-android/src/org/briarproject/android/sharing/BlogInvitationControllerImpl.java
index 54227624f4..68fc03bc85 100644
--- a/briar-android/src/org/briarproject/android/sharing/BlogInvitationControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/sharing/BlogInvitationControllerImpl.java
@@ -2,7 +2,6 @@ package org.briarproject.android.sharing;
 
 import org.briarproject.android.controller.handler.ResultExceptionHandler;
 import org.briarproject.api.blogs.Blog;
-import org.briarproject.api.blogs.BlogManager;
 import org.briarproject.api.blogs.BlogSharingManager;
 import org.briarproject.api.contact.Contact;
 import org.briarproject.api.db.DatabaseExecutor;
@@ -22,19 +21,18 @@ import javax.inject.Inject;
 import static java.util.logging.Level.WARNING;
 import static org.briarproject.api.blogs.BlogManager.CLIENT_ID;
 
+
 public class BlogInvitationControllerImpl
 		extends InvitationControllerImpl<SharingInvitationItem>
 		implements BlogInvitationController {
 
-	private final BlogManager blogManager;
 	private final BlogSharingManager blogSharingManager;
 
 	@Inject
 	BlogInvitationControllerImpl(@DatabaseExecutor Executor dbExecutor,
 			LifecycleManager lifecycleManager, EventBus eventBus,
-			BlogManager blogManager, BlogSharingManager blogSharingManager) {
+			BlogSharingManager blogSharingManager) {
 		super(dbExecutor, lifecycleManager, eventBus);
-		this.blogManager = blogManager;
 		this.blogSharingManager = blogSharingManager;
 	}
 
diff --git a/briar-android/src/org/briarproject/android/sharing/ForumInvitationControllerImpl.java b/briar-android/src/org/briarproject/android/sharing/ForumInvitationControllerImpl.java
index ef56349275..5f2d255cdb 100644
--- a/briar-android/src/org/briarproject/android/sharing/ForumInvitationControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/sharing/ForumInvitationControllerImpl.java
@@ -8,7 +8,6 @@ import org.briarproject.api.event.Event;
 import org.briarproject.api.event.EventBus;
 import org.briarproject.api.event.ForumInvitationReceivedEvent;
 import org.briarproject.api.forum.Forum;
-import org.briarproject.api.forum.ForumManager;
 import org.briarproject.api.forum.ForumSharingManager;
 import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.api.sharing.SharingInvitationItem;
@@ -26,16 +25,13 @@ public class ForumInvitationControllerImpl
 		extends InvitationControllerImpl<SharingInvitationItem>
 		implements ForumInvitationController {
 
-	private final ForumManager forumManager;
 	private final ForumSharingManager forumSharingManager;
 
 	@Inject
 	ForumInvitationControllerImpl(@DatabaseExecutor Executor dbExecutor,
 			LifecycleManager lifecycleManager, EventBus eventBus,
-			ForumManager forumManager,
 			ForumSharingManager forumSharingManager) {
 		super(dbExecutor, lifecycleManager, eventBus);
-		this.forumManager = forumManager;
 		this.forumSharingManager = forumSharingManager;
 	}
 
diff --git a/briar-android/src/org/briarproject/android/sharing/ShareActivity.java b/briar-android/src/org/briarproject/android/sharing/ShareActivity.java
index 53d93628eb..8f72fcb83a 100644
--- a/briar-android/src/org/briarproject/android/sharing/ShareActivity.java
+++ b/briar-android/src/org/briarproject/android/sharing/ShareActivity.java
@@ -10,31 +10,28 @@ import org.briarproject.android.contactselection.ContactSelectorFragment;
 import org.briarproject.android.contactselection.SelectableContactItem;
 import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
 import org.briarproject.api.contact.ContactId;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
 import org.briarproject.api.sync.GroupId;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.Collection;
 
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 public abstract class ShareActivity
 		extends ContactSelectorActivity<SelectableContactItem>
 		implements MessageFragmentListener {
 
 	@Override
-	public void onCreate(Bundle bundle) {
+	public void onCreate(@Nullable Bundle bundle) {
 		super.onCreate(bundle);
 
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra(GROUP_ID);
 		if (b == null) throw new IllegalStateException("No GroupId");
 		groupId = new GroupId(b);
-
-		if (bundle == null) {
-			ContactSelectorFragment contactSelectorFragment =
-					ContactSelectorFragment.newInstance(groupId);
-			getSupportFragmentManager().beginTransaction()
-					.add(R.id.fragmentContainer, contactSelectorFragment)
-					.commit();
-		}
 	}
 
 	@UiThread
diff --git a/briar-android/src/org/briarproject/android/sharing/ShareBlogActivity.java b/briar-android/src/org/briarproject/android/sharing/ShareBlogActivity.java
index ffd218a381..7152d9d2b3 100644
--- a/briar-android/src/org/briarproject/android/sharing/ShareBlogActivity.java
+++ b/briar-android/src/org/briarproject/android/sharing/ShareBlogActivity.java
@@ -1,14 +1,16 @@
 package org.briarproject.android.sharing;
 
+import android.os.Bundle;
 import android.widget.Toast;
 
 import org.briarproject.R;
 import org.briarproject.android.ActivityComponent;
-import org.briarproject.android.contactselection.ContactSelectorController;
-import org.briarproject.android.contactselection.SelectableContactItem;
 import org.briarproject.android.controller.handler.UiResultExceptionHandler;
 import org.briarproject.api.contact.ContactId;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.Collection;
 
@@ -17,6 +19,8 @@ import javax.inject.Inject;
 import static android.widget.Toast.LENGTH_SHORT;
 import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
 
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 public class ShareBlogActivity extends ShareActivity {
 
 	@Inject
@@ -33,8 +37,15 @@ public class ShareBlogActivity extends ShareActivity {
 	}
 
 	@Override
-	public ContactSelectorController<SelectableContactItem> getController() {
-		return controller;
+	public void onCreate(@Nullable Bundle bundle) {
+		super.onCreate(bundle);
+
+		if (bundle == null) {
+			ShareBlogFragment fragment = ShareBlogFragment.newInstance(groupId);
+			getSupportFragmentManager().beginTransaction()
+					.add(R.id.fragmentContainer, fragment)
+					.commit();
+		}
 	}
 
 	@Override
diff --git a/briar-android/src/org/briarproject/android/sharing/ShareBlogControllerImpl.java b/briar-android/src/org/briarproject/android/sharing/ShareBlogControllerImpl.java
index 0955989972..35e28da691 100644
--- a/briar-android/src/org/briarproject/android/sharing/ShareBlogControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/sharing/ShareBlogControllerImpl.java
@@ -9,20 +9,30 @@ import org.briarproject.api.contact.ContactId;
 import org.briarproject.api.contact.ContactManager;
 import org.briarproject.api.db.DatabaseExecutor;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.db.NoSuchContactException;
+import org.briarproject.api.db.NoSuchGroupException;
 import org.briarproject.api.lifecycle.LifecycleManager;
+import org.briarproject.api.nullsafety.NotNullByDefault;
 import org.briarproject.api.sync.GroupId;
 
 import java.util.Collection;
 import java.util.concurrent.Executor;
+import java.util.logging.Logger;
 
+import javax.annotation.concurrent.Immutable;
 import javax.inject.Inject;
 
 import static java.util.logging.Level.WARNING;
 
+@Immutable
+@NotNullByDefault
 public class ShareBlogControllerImpl
 		extends ContactSelectorControllerImpl<SelectableContactItem>
 		implements ShareBlogController {
 
+	private final static Logger LOG =
+			Logger.getLogger(ShareBlogControllerImpl.class.getName());
+
 	private final BlogSharingManager blogSharingManager;
 
 	@Inject
@@ -36,7 +46,8 @@ public class ShareBlogControllerImpl
 	}
 
 	@Override
-	protected boolean isSelected(Contact c, boolean wasSelected) {
+	protected boolean isSelected(Contact c, boolean wasSelected)
+			throws DbException {
 		return wasSelected;
 	}
 
@@ -60,7 +71,12 @@ public class ShareBlogControllerImpl
 			public void run() {
 				try {
 					for (ContactId c : contacts) {
-						blogSharingManager.sendInvitation(g, c, msg);
+						try {
+							blogSharingManager.sendInvitation(g, c, msg);
+						} catch (NoSuchContactException | NoSuchGroupException e) {
+							if (LOG.isLoggable(WARNING))
+								LOG.log(WARNING, e.toString(), e);
+						}
 					}
 				} catch (DbException e) {
 					if (LOG.isLoggable(WARNING))
diff --git a/briar-android/src/org/briarproject/android/sharing/ShareBlogFragment.java b/briar-android/src/org/briarproject/android/sharing/ShareBlogFragment.java
new file mode 100644
index 0000000000..f575643f20
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/sharing/ShareBlogFragment.java
@@ -0,0 +1,49 @@
+package org.briarproject.android.sharing;
+
+import android.os.Bundle;
+
+import org.briarproject.android.ActivityComponent;
+import org.briarproject.android.contactselection.ContactSelectorController;
+import org.briarproject.android.contactselection.ContactSelectorFragment;
+import org.briarproject.android.contactselection.SelectableContactItem;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
+import org.briarproject.api.sync.GroupId;
+
+import javax.inject.Inject;
+
+import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
+
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
+public class ShareBlogFragment extends ContactSelectorFragment {
+
+	public static final String TAG = ShareBlogFragment.class.getName();
+
+	@Inject
+	ShareBlogController controller;
+
+	public static ShareBlogFragment newInstance(GroupId groupId) {
+		Bundle args = new Bundle();
+		args.putByteArray(GROUP_ID, groupId.getBytes());
+		ShareBlogFragment fragment = new ShareBlogFragment();
+		fragment.setArguments(args);
+		return fragment;
+	}
+
+	@Override
+	public void injectFragment(ActivityComponent component) {
+		component.inject(this);
+	}
+
+	@Override
+	protected ContactSelectorController<SelectableContactItem> getController() {
+		return controller;
+	}
+
+	@Override
+	public String getUniqueTag() {
+		return TAG;
+	}
+
+}
diff --git a/briar-android/src/org/briarproject/android/sharing/ShareForumActivity.java b/briar-android/src/org/briarproject/android/sharing/ShareForumActivity.java
index 16133e3cfc..7904902d3e 100644
--- a/briar-android/src/org/briarproject/android/sharing/ShareForumActivity.java
+++ b/briar-android/src/org/briarproject/android/sharing/ShareForumActivity.java
@@ -5,11 +5,12 @@ import android.widget.Toast;
 
 import org.briarproject.R;
 import org.briarproject.android.ActivityComponent;
-import org.briarproject.android.contactselection.ContactSelectorController;
-import org.briarproject.android.contactselection.SelectableContactItem;
 import org.briarproject.android.controller.handler.UiResultExceptionHandler;
 import org.briarproject.api.contact.ContactId;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.Collection;
 
@@ -18,6 +19,8 @@ import javax.inject.Inject;
 import static android.widget.Toast.LENGTH_SHORT;
 import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
 
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 public class ShareForumActivity extends ShareActivity {
 
 	@Inject
@@ -34,13 +37,16 @@ public class ShareForumActivity extends ShareActivity {
 	}
 
 	@Override
-	public ContactSelectorController<SelectableContactItem> getController() {
-		return controller;
-	}
-
-	@Override
-	public void onCreate(Bundle bundle) {
+	public void onCreate(@Nullable Bundle bundle) {
 		super.onCreate(bundle);
+
+		if (bundle == null) {
+			ShareForumFragment fragment =
+					ShareForumFragment.newInstance(groupId);
+			getSupportFragmentManager().beginTransaction()
+					.add(R.id.fragmentContainer, fragment)
+					.commit();
+		}
 	}
 
 	@Override
diff --git a/briar-android/src/org/briarproject/android/sharing/ShareForumControllerImpl.java b/briar-android/src/org/briarproject/android/sharing/ShareForumControllerImpl.java
index e4bf4a5559..715250dac7 100644
--- a/briar-android/src/org/briarproject/android/sharing/ShareForumControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/sharing/ShareForumControllerImpl.java
@@ -8,21 +8,31 @@ import org.briarproject.api.contact.ContactId;
 import org.briarproject.api.contact.ContactManager;
 import org.briarproject.api.db.DatabaseExecutor;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.db.NoSuchContactException;
+import org.briarproject.api.db.NoSuchGroupException;
 import org.briarproject.api.forum.ForumSharingManager;
 import org.briarproject.api.lifecycle.LifecycleManager;
+import org.briarproject.api.nullsafety.NotNullByDefault;
 import org.briarproject.api.sync.GroupId;
 
 import java.util.Collection;
 import java.util.concurrent.Executor;
+import java.util.logging.Logger;
 
+import javax.annotation.concurrent.Immutable;
 import javax.inject.Inject;
 
 import static java.util.logging.Level.WARNING;
 
+@Immutable
+@NotNullByDefault
 public class ShareForumControllerImpl
 		extends ContactSelectorControllerImpl<SelectableContactItem>
 		implements ShareForumController {
 
+	private final static Logger LOG =
+			Logger.getLogger(ShareForumControllerImpl.class.getName());
+
 	private final ForumSharingManager forumSharingManager;
 
 	@Inject
@@ -36,7 +46,8 @@ public class ShareForumControllerImpl
 	}
 
 	@Override
-	protected boolean isSelected(Contact c, boolean wasSelected) {
+	protected boolean isSelected(Contact c, boolean wasSelected)
+			throws DbException {
 		return wasSelected;
 	}
 
@@ -60,7 +71,12 @@ public class ShareForumControllerImpl
 			public void run() {
 				try {
 					for (ContactId c : contacts) {
-						forumSharingManager.sendInvitation(g, c, msg);
+						try {
+							forumSharingManager.sendInvitation(g, c, msg);
+						} catch (NoSuchContactException | NoSuchGroupException e) {
+							if (LOG.isLoggable(WARNING))
+								LOG.log(WARNING, e.toString(), e);
+						}
 					}
 				} catch (DbException e) {
 					if (LOG.isLoggable(WARNING))
diff --git a/briar-android/src/org/briarproject/android/sharing/ShareForumFragment.java b/briar-android/src/org/briarproject/android/sharing/ShareForumFragment.java
new file mode 100644
index 0000000000..4133e5ed71
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/sharing/ShareForumFragment.java
@@ -0,0 +1,49 @@
+package org.briarproject.android.sharing;
+
+import android.os.Bundle;
+
+import org.briarproject.android.ActivityComponent;
+import org.briarproject.android.contactselection.ContactSelectorController;
+import org.briarproject.android.contactselection.ContactSelectorFragment;
+import org.briarproject.android.contactselection.SelectableContactItem;
+import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
+import org.briarproject.api.sync.GroupId;
+
+import javax.inject.Inject;
+
+import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
+
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
+public class ShareForumFragment extends ContactSelectorFragment {
+
+	public static final String TAG = ShareForumFragment.class.getName();
+
+	@Inject
+	ShareForumController controller;
+
+	public static ShareForumFragment newInstance(GroupId groupId) {
+		Bundle args = new Bundle();
+		args.putByteArray(GROUP_ID, groupId.getBytes());
+		ShareForumFragment fragment = new ShareForumFragment();
+		fragment.setArguments(args);
+		return fragment;
+	}
+
+	@Override
+	public void injectFragment(ActivityComponent component) {
+		component.inject(this);
+	}
+
+	@Override
+	protected ContactSelectorController<SelectableContactItem> getController() {
+		return controller;
+	}
+
+	@Override
+	public String getUniqueTag() {
+		return TAG;
+	}
+
+}
-- 
GitLab