private void tryRemoveOccupantFromRoom(@Nonnull final OccupantManager.Occupant occupant, @Nonnull final String reason)
    {
        final Lock lock = getChatRoomLock(occupant.getRoomName());
        if (!lock.tryLock()) { // Don't block on locked rooms, as we're processing many of them. We'll get them in the next round.
            Log.info("Skip removing as a cluster-wide mutex for the room could not immediately be obtained: {}, should have been removed, because: {}", occupant, reason);
            return;
        }
        try {
            final MUCRoom room = getChatRoom(occupant.getRoomName());
            if (room == null) {
                // Room was recently removed? Mismatch between MUCUser#getRooms() and MUCRoom#localMUCRoomManager?
                Log.info("Skip removing {} as the room no longer exists.", occupant);
                return;
            }

            if (!room.hasOccupant(occupant.getRealJID())) {
                // Occupant no longer in room? Mismatch between MUCUser#getRooms() and MUCRoom#localMUCRoomManager?
                Log.debug("Skip removing {} as this occupant no longer is in the room.", occupant);
                return;
            }

            // Kick the user from the room that he/she had previously joined.
            Log.debug("Removing/kicking {}: {}", occupant, reason);
            room.kickOccupant(occupant.getRealJID(), room.getSelfRepresentation().getAffiliation(), room.getSelfRepresentation().getRole(), null, null, reason);

            // Ensure that other cluster nodes see any changes that might have been applied.
            syncChatRoom(room);
        } catch (final ForbiddenException | NotAllowedException e) {
            // Do nothing since we cannot kick owners or admins
            Log.debug("Skip removing {}, because it's not allowed (this user likely is an owner of admin of the room).", occupant, e);
        } finally {
            lock.unlock();
        }
    }
Removes an occupant from a room.

When the system is 'busy', the occupant will not be removed to prevent threads blocking. In such cases, a message
is added to the log files, but the occupant remains in the room.

@param occupant The occupant to be removed
@param reason A human-readable reason for the removal (to be shared with the occupant as well as other occupants of the room).
xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/MultiUserChatServiceImpl.java