protected RosterItem provideRosterItem(JID user, String nickname, List<String> groups,
                                           boolean push, boolean persistent)
            throws UserAlreadyExistsException, SharedGroupException {
        if (groups != null && !groups.isEmpty()) {
            // Raise an error if the groups the item belongs to include a shared group
            for (String groupDisplayName : groups) {
                Collection<Group> groupsWithProp = GroupManager
                        .getInstance()
                        .search(Group.SHARED_ROSTER_DISPLAY_NAME_PROPERTY_KEY, groupDisplayName);
                for ( Group group : groupsWithProp )
                {
                    String showInRoster = group.getProperties().get(Group.SHARED_ROSTER_SHOW_IN_ROSTER_PROPERTY_KEY);
                    if ( showInRoster != null && !showInRoster.equals( "nobody" ) )
                    {
                        throw new SharedGroupException( "Cannot add an item to a shared group" );
                    }
                }
            }
        }
        org.xmpp.packet.Roster roster = new org.xmpp.packet.Roster();
        roster.setType(IQ.Type.set);
        org.xmpp.packet.Roster.Item item = roster.addItem(user, nickname, null,
                org.xmpp.packet.Roster.Subscription.none, groups);

        RosterItem rosterItem = new RosterItem(item);
        // Fire event indicating that a roster item is about to be added
        persistent = RosterEventDispatcher.addingContact(this, rosterItem, persistent);

        // Check if we need to make the new roster item persistent
        if (persistent) {
            rosterItem = RosterManager.getRosterItemProvider().createItem(username, rosterItem);
        }

        rosterItems.put(user.toBareJID(), rosterItem);

        if (push) {
            // Broadcast the roster push to the user
            broadcast(roster);
        }

        // Fire event indicating that a roster item has been added
        RosterEventDispatcher.contactAdded(this, rosterItem);

        return rosterItem;
    }
Generate a new RosterItem for use with createRosterItem.

@param user       The roster jid address to create the roster item for.
@param nickname   The nickname to assign the item (or null for none).
@param groups     The groups the item belongs to (or null for none).
@param push       True if the new item must be push to the user.
@param persistent True if the new roster item should be persisted to the DB.
@return The newly created roster items ready to be stored by the Roster item's hash table
@throws UserAlreadyExistsException if the user is already in the roster
@throws SharedGroupException if the group is a shared group
xmppserver/src/main/java/org/jivesoftware/openfire/roster/Roster.java