public String generateOccupantId(@Nonnull final JID userJid)
    {
        final String siteKey = MultiUserChatManager.MASTER_KEY.getValue();
        if (siteKey == null || siteKey.isEmpty()) {
            throw new IllegalStateException("Unable to generate an occupant-id: MultiUserChatManager has not been initialized.");
        }

        try {
            // Keep the room's identifier with they key, rather than with the data, which should have slightly improved security properties.
            final byte[] roomKey = ScramUtils.computeHmac(siteKey.getBytes(StandardCharsets.UTF_8), this.getJID().toBareJID());

            return StringUtils.encodeHex(ScramUtils.computeHmac(roomKey, userJid.toBareJID()));
        } catch (SaslException e) {
            throw new RuntimeException("Unable to compute HMAC for user '" + userJid + "' in room '" + this.getJID() + "' while generating an Occupant ID.");
        }
    }
Creates an Occupant ID based on the generation specification defined in XEP-0421.

@param userJid The JID for which to generate an Occupant ID
@return a hexadecimal representation of the Occupant ID
@see <a href="https://xmpp.org/extensions/xep-0421.html#id-generation">XEP-0421: Occupant ID generation</a>
xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCRoom.java