private CompletableFuture<?> initiateFederationOutbound( @Nonnull MUCOccupant occupantData )
    {
        Log.debug("(room: '{}'): Attempting to establish federation by joining '{}', triggered by user '{}' (as '{}').", room.getJID(), outboundJoinConfiguration.getPeer(), occupantData.getUserAddress(), occupantData.getOccupantJID() );

        final Presence joinStanza = enrichWithFMUCElement( generateJoinStanza( occupantData ), occupantData );
        joinStanza.setFrom( new JID(room.getName(), room.getMUCService().getServiceDomain(), occupantData.getNickname() ) );
        joinStanza.setTo( new JID(outboundJoinConfiguration.getPeer().getNode(), outboundJoinConfiguration.getPeer().getDomain(), occupantData.getNickname() ) );

        Log.trace("(room: '{}'): Registering a callback to be used when the federation request to '{}' has completed.", room.getJID(), outboundJoinConfiguration.getPeer() );
        final CompletableFuture<List<Packet>> result = new CompletableFuture<>();
        final boolean mustBlock = outboundJoinConfiguration.getMode() == FMUCMode.MasterSlave;
        if ( !mustBlock ) {
            Log.trace("(room: '{}'): No need to wait for federation to complete before allowing the local user to join the room.", room.getJID() );
            result.complete( null );
        } else {
            Log.trace("(room: '{}'): Federation needs to have been completed before allowing the local user to join the room.", room.getJID() );
        }

        outboundJoinProgress = new OutboundJoinProgress(outboundJoinConfiguration.getPeer(), result );

        Log.trace( "(room: '{}'): Sending FMUC join request: {}", room.getJID(), joinStanza.toXML() );
        XMPPServer.getInstance().getPacketRouter().route(joinStanza);

        return result;
    }
Attempt to establish a federation with a remote MUC room. In this relation 'our' room will take the role of
'joining FMUC node'.

@param occupantData Occupant that joined the room, triggering the federation to be initiated.
@return A future object that completes when the join can be propagated locally.
xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/FMUCHandler.java