void deleteSharedUser(Group sharedGroup, JID deletedUser) {
        try {
            // Get the RosterItem for the *local* user to remove
            RosterItem item = getRosterItem(deletedUser);
            int groupSize = item.getSharedGroups().size() + item.getInvisibleSharedGroups().size();
            if (item.isOnlyShared() && groupSize == 1) {
                // Do nothing if the existing shared group is not the sharedGroup to remove
                if (!item.getSharedGroups().contains(sharedGroup) &&
                        !item.getInvisibleSharedGroups().contains(sharedGroup)) {
                    return;
                }
                // Delete the roster item from the roster since it exists only because of this
                // group which is being removed
                deleteRosterItem(deletedUser, false);
            } else {
                // Remove the removed shared group from the list of shared groups
                item.removeSharedGroup(sharedGroup);
                // Update the subscription of the item based on the remaining groups
                if (item.isOnlyShared()) {
                    Collection<Group> userGroups =
                            GroupManager.getInstance().getGroups(getUserJID());
                    Collection<Group> sharedGroups = new ArrayList<>();
                    sharedGroups.addAll(item.getSharedGroups());
                    // Set subscription type to BOTH if the roster user belongs to a shared group
                    // that is mutually visible with a shared group of the new roster item
                    final RosterManager rosterManager = XMPPServer.getInstance().getRosterManager();
                    if (rosterManager.hasMutualVisibility(getUsername(), userGroups, deletedUser,
                            sharedGroups)) {
                        item.setSubStatus(RosterItem.SUB_BOTH);
                    } else if (item.getSharedGroups().isEmpty() &&
                            !item.getInvisibleSharedGroups().isEmpty()) {
                        item.setSubStatus(RosterItem.SUB_FROM);
                    } else {
                        item.setSubStatus(RosterItem.SUB_TO);
                    }
                    // Fire event indicating that a roster item has been updated
                    RosterEventDispatcher.contactUpdated(this, item);
                } else {
                    // Fire event indicating that a roster item has been removed
                    RosterEventDispatcher.contactDeleted(this, item);
                }
                // Brodcast to all the user resources of the updated roster item
                broadcast(item, false);
            }
        } catch (SharedGroupException e) {
            // Do nothing. Checkings are disabled so this exception should never happen.
            Log.error( "Unexpected error while deleting user '{}' from shared group '{}'!", deletedUser, sharedGroup, e );
        } catch (UserNotFoundException e) {
            // Do nothing since the contact does not exist in the user's roster. (strange case!)
            // Log.warn( "Unexpected error while deleting user '{}' from shared group '{}'!", deletedUser, sharedGroup, e );
        }
    }
Update the roster since a group user has been deleted from a shared group. If the RosterItem
(of the deleted contact) exists only because of of the sahred group then the RosterItem will
be deleted physically from the backend store. Otherwise the shared group will be removed from
the shared groups lists. In any case an update broadcast will be sent to all the users
logged resources.

@param sharedGroup the shared group from where the user was deleted.
@param deletedUser the contact to update in the roster.
xmppserver/src/main/java/org/jivesoftware/openfire/roster/Roster.java