void deleteSharedUser(JID deletedUser, Group deletedGroup) {
        try {
            final RosterManager rosterManager = XMPPServer.getInstance().getRosterManager();
            // 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 not delete the item if deletedUser belongs to a public group since the
                    // subcription status will change
                    !(deletedGroup.isUser(deletedUser) &&
                            RosterManager.isPublicSharedGroup(deletedGroup))) {
                // 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 shared group from the item if deletedUser does not belong to a
                // public group
                if (!(deletedGroup.isUser(deletedUser) &&
                        RosterManager.isPublicSharedGroup(deletedGroup))) {
                    item.removeSharedGroup(deletedGroup);
                }
                // Get the groups of the deleted user
                Collection<Group> groups = GroupManager.getInstance().getGroups(deletedUser);
                // Remove all invalid shared groups from the roster item
                for (Group group : groups) {
                    if (!rosterManager.isGroupVisible(group, getUserJID())) {
                        // Remove the shared group from the list of shared groups
                        item.removeSharedGroup(group);
                    }
                }

                // Update the subscription of the item **based on the item groups**
                if (item.isOnlyShared()) {
                    Collection<Group> userGroups =
                            GroupManager.getInstance().getGroups(getUserJID());
                    // 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
                    if (rosterManager
                            .hasMutualVisibility(getUsername(), userGroups, deletedUser, groups)) {
                        item.setSubStatus(RosterItem.SUB_BOTH);
                    } else {
                        // Assume by default that the contact has subscribed from the presence of
                        // this user
                        item.setSubStatus(RosterItem.SUB_FROM);
                        // Check if the user may see the new contact in a shared group
                        for (Group group : groups) {
                            if (rosterManager.isGroupVisible(group, getUserJID())) {
                                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, deletedGroup, 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, deletedGroup, 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