private void restoreUsersSessionsCache()
    {
        Log.info("Restoring Users Sessions Cache");

        // First remove all elements from users sessions cache that are not present in user caches
        final Set<String> existingUserRoutes = routeOwnersByClusterNode.values().stream().flatMap(Collection::stream).collect(Collectors.toSet());
        existingUserRoutes.addAll(localClientRoutingTable.getRoutes().stream().map(LocalClientSession::getAddress).map(JID::toFullJID).collect(Collectors.toSet()));
        final Set<String> entriesToRemove = usersSessionsCache.values().stream()
            .flatMap(Collection::stream)
            .filter(fullJid -> !existingUserRoutes.contains(fullJid))
            .collect(Collectors.toSet());
        entriesToRemove.forEach(fullJid -> CacheUtil.removeValueFromMultiValuedCache(usersSessionsCache, new JID(fullJid).toBareJID(), fullJid));

        // Add elements from users caches that are not present in users sessions cache
        existingUserRoutes.forEach(fullJid -> {
            CacheUtil.addValueToMultiValuedCache(usersSessionsCache, new JID(fullJid).toBareJID(), fullJid, HashSet::new);
        });
    }
When the users sessions cache is (potentially) inconsistent, it can be rebuilt from routeOwnersByClusterNode and
routingTable.
This method relies on the routeOwnersByClusterNode and routingTable being stable and reflecting the actual
reality. So run this restore method <em>after or at the end of</em> cleanup on a cluster leave.
xmppserver/src/main/java/org/jivesoftware/openfire/spi/RoutingTableImpl.java