From a33d7d1663da9ae3c30a75e79611873ffb3bcc63 Mon Sep 17 00:00:00 2001
From: Torsten Grote <t@grobox.de>
Date: Mon, 17 Oct 2016 10:35:29 -0200
Subject: [PATCH] Add a stub for a GroupInvitationManager

---
 .../ForumSharingIntegrationTest.java          |   6 +-
 .../api/privategroup/PrivateGroup.java        |   3 +-
 .../invitation/GroupInvitationConstants.java  |   8 +
 .../invitation/GroupInvitationItem.java       |  22 +++
 .../invitation/GroupInvitationManager.java    |  48 ++++++
 .../invitation/GroupInvitationRequest.java    |  38 +++++
 .../invitation/GroupInvitationResponse.java   |  39 +++++
 .../api/sharing/InvitationItem.java           |  26 ++--
 .../briarproject/api/sharing/Shareable.java   |   3 +
 .../api/sharing/SharingInvitationItem.java    |  22 +++
 .../api/sharing/SharingManager.java           |   2 +-
 .../privategroup/PrivateGroupModule.java      |  28 +++-
 .../GroupInvitationManagerImpl.java           | 141 ++++++++++++++++++
 .../sharing/SharingManagerImpl.java           |  10 +-
 14 files changed, 372 insertions(+), 24 deletions(-)
 create mode 100644 briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationConstants.java
 create mode 100644 briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationItem.java
 create mode 100644 briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationManager.java
 create mode 100644 briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationRequest.java
 create mode 100644 briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationResponse.java
 create mode 100644 briar-api/src/org/briarproject/api/sharing/SharingInvitationItem.java
 create mode 100644 briar-core/src/org/briarproject/privategroup/invitation/GroupInvitationManagerImpl.java

diff --git a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java
index ae3e770a4e..306cc25dc1 100644
--- a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java
+++ b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java
@@ -34,7 +34,7 @@ import org.briarproject.api.identity.AuthorFactory;
 import org.briarproject.api.identity.IdentityManager;
 import org.briarproject.api.identity.LocalAuthor;
 import org.briarproject.api.lifecycle.LifecycleManager;
-import org.briarproject.api.sharing.InvitationItem;
+import org.briarproject.api.sharing.SharingInvitationItem;
 import org.briarproject.api.sharing.InvitationMessage;
 import org.briarproject.api.sync.Group;
 import org.briarproject.api.sync.SyncSession;
@@ -762,7 +762,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
 					"Sharer2 to Invitee");
 
 			// make sure we now have two invitations to the same forum available
-			Collection<InvitationItem> forums =
+			Collection<SharingInvitationItem> forums =
 					forumSharingManager1.getInvitations();
 			assertEquals(1, forums.size());
 			assertEquals(2, forums.iterator().next().getNewSharers().size());
@@ -986,7 +986,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
 				try {
 					eventWaiter.assertEquals(1,
 							forumSharingManager1.getInvitations().size());
-					InvitationItem invitation =
+					SharingInvitationItem invitation =
 							forumSharingManager1.getInvitations().iterator()
 									.next();
 					eventWaiter.assertEquals(f, invitation.getShareable());
diff --git a/briar-api/src/org/briarproject/api/privategroup/PrivateGroup.java b/briar-api/src/org/briarproject/api/privategroup/PrivateGroup.java
index 310611361b..9b57d99910 100644
--- a/briar-api/src/org/briarproject/api/privategroup/PrivateGroup.java
+++ b/briar-api/src/org/briarproject/api/privategroup/PrivateGroup.java
@@ -3,6 +3,7 @@ package org.briarproject.api.privategroup;
 import org.briarproject.api.clients.NamedGroup;
 import org.briarproject.api.identity.Author;
 import org.briarproject.api.nullsafety.NotNullByDefault;
+import org.briarproject.api.sharing.Shareable;
 import org.briarproject.api.sync.Group;
 import org.jetbrains.annotations.NotNull;
 
@@ -10,7 +11,7 @@ import javax.annotation.concurrent.Immutable;
 
 @Immutable
 @NotNullByDefault
-public class PrivateGroup extends NamedGroup {
+public class PrivateGroup extends NamedGroup implements Shareable {
 
 	private final Author author;
 
diff --git a/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationConstants.java b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationConstants.java
new file mode 100644
index 0000000000..a22272b22b
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationConstants.java
@@ -0,0 +1,8 @@
+package org.briarproject.api.privategroup.invitation;
+
+public interface GroupInvitationConstants {
+
+	// Group Metadata Keys
+	String CONTACT_ID = "contactId";
+
+}
diff --git a/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationItem.java b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationItem.java
new file mode 100644
index 0000000000..c7f350be45
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationItem.java
@@ -0,0 +1,22 @@
+package org.briarproject.api.privategroup.invitation;
+
+import org.briarproject.api.contact.Contact;
+import org.briarproject.api.sharing.InvitationItem;
+import org.briarproject.api.sharing.Shareable;
+
+public class GroupInvitationItem extends InvitationItem {
+
+	private final Contact creator;
+
+	public GroupInvitationItem(Shareable shareable, boolean subscribed,
+			Contact creator) {
+		super(shareable, subscribed);
+
+		this.creator = creator;
+	}
+
+	public Contact getCreator() {
+		return creator;
+	}
+
+}
diff --git a/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationManager.java b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationManager.java
new file mode 100644
index 0000000000..a5ca33dae1
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationManager.java
@@ -0,0 +1,48 @@
+package org.briarproject.api.privategroup.invitation;
+
+import org.briarproject.api.clients.MessageTracker;
+import org.briarproject.api.clients.SessionId;
+import org.briarproject.api.contact.Contact;
+import org.briarproject.api.contact.ContactId;
+import org.briarproject.api.db.DbException;
+import org.briarproject.api.privategroup.PrivateGroup;
+import org.briarproject.api.sharing.InvitationMessage;
+import org.briarproject.api.sync.ClientId;
+import org.briarproject.api.sync.GroupId;
+
+import java.util.Collection;
+
+public interface GroupInvitationManager extends MessageTracker {
+
+	/** Returns the unique ID of the private group invitation client. */
+	ClientId getClientId();
+
+	/**
+	 * Sends an invitation to share the given forum with the given contact
+	 * and sends an optional message along with it.
+	 */
+	void sendInvitation(GroupId groupId, ContactId contactId,
+			String message)	throws DbException;
+
+	/**
+	 * Responds to a pending private group invitation
+	 */
+	void respondToInvitation(PrivateGroup g, Contact c, boolean accept)
+			throws DbException;
+
+	/**
+	 * Responds to a pending private group invitation
+	 */
+	void respondToInvitation(SessionId id, boolean accept) throws DbException;
+
+	/**
+	 * Returns all private group invitation messages related to the contact
+	 * identified by contactId.
+	 */
+	Collection<InvitationMessage> getInvitationMessages(
+			ContactId contactId) throws DbException;
+
+	/** Returns all private groups to which the user has been invited. */
+	Collection<GroupInvitationItem> getInvitations() throws DbException;
+
+}
diff --git a/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationRequest.java b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationRequest.java
new file mode 100644
index 0000000000..3c9b25760f
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationRequest.java
@@ -0,0 +1,38 @@
+package org.briarproject.api.privategroup.invitation;
+
+import org.briarproject.api.clients.SessionId;
+import org.briarproject.api.contact.ContactId;
+import org.briarproject.api.identity.Author;
+import org.briarproject.api.nullsafety.NotNullByDefault;
+import org.briarproject.api.sharing.InvitationRequest;
+import org.briarproject.api.sync.GroupId;
+import org.briarproject.api.sync.MessageId;
+
+import javax.annotation.concurrent.ThreadSafe;
+
+@ThreadSafe
+@NotNullByDefault
+public class GroupInvitationRequest extends InvitationRequest {
+
+	private final String groupName;
+	private final Author creator;
+
+	public GroupInvitationRequest(MessageId id, SessionId sessionId,
+			GroupId groupId, Author creator, ContactId contactId,
+			String groupName, String message, boolean available, long time,
+			boolean local, boolean sent, boolean seen, boolean read) {
+		super(id, sessionId, groupId, contactId, message, available, time,
+				local, sent, seen, read);
+		this.groupName = groupName;
+		this.creator = creator;
+	}
+
+	public String getGroupName() {
+		return groupName;
+	}
+
+	public Author getCreator() {
+		return creator;
+	}
+
+}
diff --git a/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationResponse.java b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationResponse.java
new file mode 100644
index 0000000000..554e731bcd
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/privategroup/invitation/GroupInvitationResponse.java
@@ -0,0 +1,39 @@
+package org.briarproject.api.privategroup.invitation;
+
+import org.briarproject.api.clients.SessionId;
+import org.briarproject.api.contact.ContactId;
+import org.briarproject.api.identity.Author;
+import org.briarproject.api.nullsafety.NotNullByDefault;
+import org.briarproject.api.sharing.InvitationResponse;
+import org.briarproject.api.sync.GroupId;
+import org.briarproject.api.sync.MessageId;
+import org.jetbrains.annotations.NotNull;
+
+import javax.annotation.concurrent.ThreadSafe;
+
+@ThreadSafe
+@NotNullByDefault
+public class GroupInvitationResponse extends InvitationResponse {
+
+	private final String groupName;
+	private final Author creator;
+
+	public GroupInvitationResponse(MessageId id, SessionId sessionId,
+			GroupId groupId, String groupName, Author creator,
+			ContactId contactId, boolean accept, long time, boolean local,
+			boolean sent, boolean seen, boolean read) {
+		super(id, sessionId, groupId, contactId, accept, time, local, sent,
+				seen, read);
+		this.groupName = groupName;
+		this.creator = creator;
+	}
+
+	public String getGroupName() {
+		return groupName;
+	}
+
+	public Author getCreator() {
+		return creator;
+	}
+
+}
diff --git a/briar-api/src/org/briarproject/api/sharing/InvitationItem.java b/briar-api/src/org/briarproject/api/sharing/InvitationItem.java
index bc180ea13f..a813982b10 100644
--- a/briar-api/src/org/briarproject/api/sharing/InvitationItem.java
+++ b/briar-api/src/org/briarproject/api/sharing/InvitationItem.java
@@ -1,32 +1,36 @@
 package org.briarproject.api.sharing;
 
-import org.briarproject.api.contact.Contact;
+import org.briarproject.api.nullsafety.NotNullByDefault;
+import org.briarproject.api.sync.GroupId;
 
-import java.util.Collection;
+import javax.annotation.concurrent.ThreadSafe;
 
-public class InvitationItem {
+@ThreadSafe
+@NotNullByDefault
+public abstract class InvitationItem {
 
 	private final Shareable shareable;
 	private final boolean subscribed;
-	private final Collection<Contact> newSharers;
-
-	public InvitationItem(Shareable shareable, boolean subscribed,
-			Collection<Contact> newSharers) {
 
+	public InvitationItem(Shareable shareable, boolean subscribed) {
 		this.shareable = shareable;
 		this.subscribed = subscribed;
-		this.newSharers = newSharers;
 	}
 
 	public Shareable getShareable() {
 		return shareable;
 	}
 
+	public GroupId getId() {
+		return shareable.getId();
+	}
+
+	public String getName() {
+		return shareable.getName();
+	}
+
 	public boolean isSubscribed() {
 		return subscribed;
 	}
 
-	public Collection<Contact> getNewSharers() {
-		return newSharers;
-	}
 }
diff --git a/briar-api/src/org/briarproject/api/sharing/Shareable.java b/briar-api/src/org/briarproject/api/sharing/Shareable.java
index 13c11fdeef..144b06dde1 100644
--- a/briar-api/src/org/briarproject/api/sharing/Shareable.java
+++ b/briar-api/src/org/briarproject/api/sharing/Shareable.java
@@ -8,4 +8,7 @@ public interface Shareable {
 	GroupId getId();
 
 	Group getGroup();
+
+	String getName();
+
 }
diff --git a/briar-api/src/org/briarproject/api/sharing/SharingInvitationItem.java b/briar-api/src/org/briarproject/api/sharing/SharingInvitationItem.java
new file mode 100644
index 0000000000..8993f23200
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/sharing/SharingInvitationItem.java
@@ -0,0 +1,22 @@
+package org.briarproject.api.sharing;
+
+import org.briarproject.api.contact.Contact;
+
+import java.util.Collection;
+
+public class SharingInvitationItem extends InvitationItem {
+
+	private final Collection<Contact> newSharers;
+
+	public SharingInvitationItem(Shareable shareable, boolean subscribed,
+			Collection<Contact> newSharers) {
+		super(shareable, subscribed);
+
+		this.newSharers = newSharers;
+	}
+
+	public Collection<Contact> getNewSharers() {
+		return newSharers;
+	}
+
+}
diff --git a/briar-api/src/org/briarproject/api/sharing/SharingManager.java b/briar-api/src/org/briarproject/api/sharing/SharingManager.java
index b4613cd940..3e37191ddd 100644
--- a/briar-api/src/org/briarproject/api/sharing/SharingManager.java
+++ b/briar-api/src/org/briarproject/api/sharing/SharingManager.java
@@ -38,7 +38,7 @@ public interface SharingManager<S extends Shareable> extends MessageTracker {
 	/**
 	 * Returns all invitations to groups.
 	 */
-	Collection<InvitationItem> getInvitations() throws DbException;
+	Collection<SharingInvitationItem> getInvitations() throws DbException;
 
 	/**
 	 * Returns all contacts who are sharing the given group with us.
diff --git a/briar-core/src/org/briarproject/privategroup/PrivateGroupModule.java b/briar-core/src/org/briarproject/privategroup/PrivateGroupModule.java
index 562b95c308..570f697a62 100644
--- a/briar-core/src/org/briarproject/privategroup/PrivateGroupModule.java
+++ b/briar-core/src/org/briarproject/privategroup/PrivateGroupModule.java
@@ -1,17 +1,19 @@
 package org.briarproject.privategroup;
 
 import org.briarproject.api.clients.ClientHelper;
+import org.briarproject.api.contact.ContactManager;
 import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.data.MetadataEncoder;
 import org.briarproject.api.identity.AuthorFactory;
+import org.briarproject.api.lifecycle.LifecycleManager;
+import org.briarproject.api.messaging.ConversationManager;
 import org.briarproject.api.privategroup.GroupMessageFactory;
 import org.briarproject.api.privategroup.PrivateGroupFactory;
 import org.briarproject.api.privategroup.PrivateGroupManager;
-import org.briarproject.api.sync.GroupFactory;
+import org.briarproject.api.privategroup.invitation.GroupInvitationManager;
 import org.briarproject.api.sync.ValidationManager;
 import org.briarproject.api.system.Clock;
-
-import java.security.SecureRandom;
+import org.briarproject.privategroup.invitation.GroupInvitationManagerImpl;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -25,6 +27,8 @@ public class PrivateGroupModule {
 	public static class EagerSingletons {
 		@Inject
 		GroupMessageValidator groupMessageValidator;
+		@Inject
+		GroupInvitationManager groupInvitationManager;
 	}
 
 	@Provides
@@ -65,4 +69,22 @@ public class PrivateGroupModule {
 		return validator;
 	}
 
+	@Provides
+	@Singleton
+	GroupInvitationManager provideGroupInvitationManager(
+			LifecycleManager lifecycleManager, ContactManager contactManager,
+			GroupInvitationManagerImpl groupInvitationManager,
+			ConversationManager conversationManager,
+			ValidationManager validationManager) {
+
+		validationManager.registerIncomingMessageHook(
+				groupInvitationManager.getClientId(), groupInvitationManager);
+		lifecycleManager.registerClient(groupInvitationManager);
+		contactManager.registerAddContactHook(groupInvitationManager);
+		contactManager.registerRemoveContactHook(groupInvitationManager);
+		conversationManager.registerConversationClient(groupInvitationManager);
+
+		return groupInvitationManager;
+	}
+
 }
diff --git a/briar-core/src/org/briarproject/privategroup/invitation/GroupInvitationManagerImpl.java b/briar-core/src/org/briarproject/privategroup/invitation/GroupInvitationManagerImpl.java
new file mode 100644
index 0000000000..12477ab20b
--- /dev/null
+++ b/briar-core/src/org/briarproject/privategroup/invitation/GroupInvitationManagerImpl.java
@@ -0,0 +1,141 @@
+package org.briarproject.privategroup.invitation;
+
+import org.briarproject.api.FormatException;
+import org.briarproject.api.clients.Client;
+import org.briarproject.api.clients.ClientHelper;
+import org.briarproject.api.clients.ContactGroupFactory;
+import org.briarproject.api.clients.SessionId;
+import org.briarproject.api.contact.Contact;
+import org.briarproject.api.contact.ContactId;
+import org.briarproject.api.contact.ContactManager;
+import org.briarproject.api.data.BdfDictionary;
+import org.briarproject.api.data.BdfList;
+import org.briarproject.api.data.MetadataParser;
+import org.briarproject.api.db.DatabaseComponent;
+import org.briarproject.api.db.DbException;
+import org.briarproject.api.db.Transaction;
+import org.briarproject.api.messaging.ConversationManager;
+import org.briarproject.api.privategroup.PrivateGroup;
+import org.briarproject.api.privategroup.invitation.GroupInvitationItem;
+import org.briarproject.api.privategroup.invitation.GroupInvitationManager;
+import org.briarproject.api.sharing.InvitationMessage;
+import org.briarproject.api.sync.ClientId;
+import org.briarproject.api.sync.Group;
+import org.briarproject.api.sync.GroupId;
+import org.briarproject.api.sync.Message;
+import org.briarproject.clients.ConversationClientImpl;
+import org.briarproject.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.inject.Inject;
+
+import static org.briarproject.api.privategroup.invitation.GroupInvitationConstants.CONTACT_ID;
+
+public class GroupInvitationManagerImpl extends ConversationClientImpl
+		implements GroupInvitationManager, Client,
+		ContactManager.AddContactHook, ContactManager.RemoveContactHook,
+		ConversationManager.ConversationClient {
+
+	private static final ClientId CLIENT_ID =
+			new ClientId(StringUtils.fromHexString(
+					"B55231ABFC4A10666CD93D649B1D7F4F"
+							+ "016E65B87BB4C04F4E35613713DBCD13"));
+
+	private final ContactGroupFactory contactGroupFactory;
+	private final Group localGroup;
+
+	@Inject
+	protected GroupInvitationManagerImpl(DatabaseComponent db,
+			ClientHelper clientHelper, MetadataParser metadataParser,
+			ContactGroupFactory contactGroupFactory) {
+		super(db, clientHelper, metadataParser);
+		this.contactGroupFactory = contactGroupFactory;
+		localGroup = contactGroupFactory.createLocalGroup(getClientId());
+	}
+
+	@Override
+	public ClientId getClientId() {
+		return CLIENT_ID;
+	}
+
+	@Override
+	public void createLocalState(Transaction txn) throws DbException {
+		db.addGroup(txn, localGroup);
+		// Ensure we've set things up for any pre-existing contacts
+		for (Contact c : db.getContacts(txn)) addingContact(txn, c);
+	}
+
+	@Override
+	public void addingContact(Transaction txn, Contact c) throws DbException {
+		try {
+			// Create a group to share with the contact
+			Group g = getContactGroup(c);
+			// Return if we've already set things up for this contact
+			if (db.containsGroup(txn, g.getId())) return;
+			// Store the group and share it with the contact
+			db.addGroup(txn, g);
+			db.setVisibleToContact(txn, c.getId(), g.getId(), true);
+			// Attach the contact ID to the group
+			BdfDictionary meta = new BdfDictionary();
+			meta.put(CONTACT_ID, c.getId().getInt());
+			clientHelper.mergeGroupMetadata(txn, g.getId(), meta);
+		} catch (FormatException e) {
+			throw new DbException(e);
+		}
+	}
+
+	@Override
+	public void removingContact(Transaction txn, Contact c) throws DbException {
+		// remove the contact group (all messages will be removed with it)
+		db.removeGroup(txn, getContactGroup(c));
+	}
+
+	@Override
+	protected Group getContactGroup(Contact c) {
+		return contactGroupFactory.createContactGroup(getClientId(), c);
+	}
+
+	@Override
+	protected boolean incomingMessage(Transaction txn, Message m, BdfList body,
+			BdfDictionary meta) throws DbException, FormatException {
+		return false;
+	}
+
+	@Override
+	public void sendInvitation(GroupId groupId, ContactId contactId,
+			String message) throws DbException {
+
+	}
+
+	@Override
+	public void respondToInvitation(PrivateGroup g, Contact c, boolean accept)
+			throws DbException {
+
+	}
+
+	@Override
+	public void respondToInvitation(SessionId id, boolean accept)
+			throws DbException {
+
+	}
+
+	@Override
+	public Collection<InvitationMessage> getInvitationMessages(
+			ContactId contactId) throws DbException {
+		Collection<InvitationMessage> invitations =
+				new ArrayList<InvitationMessage>();
+
+		return invitations;
+	}
+
+	@Override
+	public Collection<GroupInvitationItem> getInvitations() throws DbException {
+		Collection<GroupInvitationItem> invitations =
+				new ArrayList<GroupInvitationItem>();
+
+		return invitations;
+	}
+
+}
diff --git a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java
index a7c90d0a78..dd06fc2c44 100644
--- a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java
+++ b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java
@@ -25,7 +25,7 @@ import org.briarproject.api.event.Event;
 import org.briarproject.api.event.InvitationRequestReceivedEvent;
 import org.briarproject.api.event.InvitationResponseReceivedEvent;
 import org.briarproject.api.identity.LocalAuthor;
-import org.briarproject.api.sharing.InvitationItem;
+import org.briarproject.api.sharing.SharingInvitationItem;
 import org.briarproject.api.sharing.InvitationMessage;
 import org.briarproject.api.sharing.Shareable;
 import org.briarproject.api.sharing.SharingManager;
@@ -418,8 +418,8 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
 	}
 
 	@Override
-	public Collection<InvitationItem> getInvitations() throws DbException {
-		List<InvitationItem> invitations = new ArrayList<InvitationItem>();
+	public Collection<SharingInvitationItem> getInvitations() throws DbException {
+		List<SharingInvitationItem> invitations = new ArrayList<SharingInvitationItem>();
 		Transaction txn = db.startTransaction(true);
 		try {
 			Set<S> shareables = new HashSet<S>();
@@ -445,8 +445,8 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
 			for (S s : shareables) {
 				Collection<Contact> newS = newSharers.get(s.getId());
 				boolean subscribed = db.containsGroup(txn, s.getId());
-				InvitationItem invitation =
-						new InvitationItem(s, subscribed, newS);
+				SharingInvitationItem invitation =
+						new SharingInvitationItem(s, subscribed, newS);
 				invitations.add(invitation);
 			}
 			txn.setComplete();
-- 
GitLab