public List<Presence> kickOccupant(@Nonnull final JID userAddress, @Nonnull final Affiliation actorAffiliation, @Nullable final Role actorRole, @Nullable final JID actorJID, @Nullable final String actorNickname, @Nullable final String reason, final int status) throws ForbiddenException, NotAllowedException
    {
        if (Affiliation.admin != actorAffiliation && Affiliation.owner != actorAffiliation && Role.moderator != actorRole) {
            throw new ForbiddenException();
        }

        // A moderator SHOULD NOT be allowed to revoke moderation privileges from someone with a higher affiliation than
        // themselves (i.e., an unaffiliated moderator SHOULD NOT be allowed to revoke moderation privileges from an
        // admin or an owner, and an admin SHOULD NOT be allowed to revoke moderation privileges from an owner).
        final Affiliation targetAffiliation = getAffiliation(userAddress);
        if (targetAffiliation.getValue() < actorAffiliation.getValue()) { // note that Openfire's values are ordered the other way around.
            throw new NotAllowedException();
        }

        // Update the presence with the new role and inform all occupants
        final List<Presence> updatedPresences = applyRoleChange(userAddress, Role.none);

        // Determine the occupant data of the actor that initiates the kick.
        MUCOccupant sender;
        if ( actorJID == null ) {
            sender = getSelfRepresentation(); // originates from the room itself (eg: through admin console changes).
        } else {
            sender = getOccupantByFullJID(actorJID);
            if ( sender == null ) {
                sender = getSelfRepresentation();
            }
        }

        Log.debug("Kicking '{}' from '{}' by '{}' because of: {} ", userAddress, getJID(), sender, reason);

        for (final Presence updatedPresence : updatedPresences)
        {
            final Element frag = updatedPresence.getChildElement("x", "http://jabber.org/protocol/muc#user");

            // Add the status code that indicates why user was kicked
            frag.addElement("status").addAttribute("code", String.valueOf(status));

            // Effectively kick the occupant from the room
            kickPresence(updatedPresence, actorJID, actorNickname, reason);

            //Inform the other occupants that user has been kicked
            broadcastPresence(updatedPresence, false, sender);
        }
        // TODO should this return presence/should callers distribute this stanza (alternatively: should this stanza be broadcast in this method)?
        return updatedPresences;
    }
Kicks a user from the room. If the user was in the room, the returned updated presence will be sent to the
remaining occupants.

When attempting to remove the <em>affiliation</em> from a user from the room, use
{@link #addNone(JID, Affiliation)} instead. Kicking a user will only cause the
<em>role</em> of the occupant to be changed.

@param userAddress the (real) JID of the occupant to change to visitor
@param actorJID      The JID of the actor that initiated the kick.
@param actorNickname The actor nickname.
@param reason        An optional reason why the user was kicked (can be {@code null}).
@param status        The status code that references the reason for the kick (typically 307).
@return the list of updated presences of all the client resources that the occupant has used to join the room.
@throws ForbiddenException Thrown if trying to ban an owner or an administrator.
xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCRoom.java