private void pingOccupant(@Nonnull final OccupantManager.Occupant occupant)
    {
        Log.debug("Pinging {} as the occupant is exceeding the idle time limit.", occupant);
        final IQ pingRequest = new IQ( IQ.Type.get );
        pingRequest.setChildElement( IQPingHandler.ELEMENT_NAME, IQPingHandler.NAMESPACE );
        pingRequest.setFrom( occupant.getRoomName() + "@" + getServiceDomain() );
        pingRequest.setTo( occupant.getRealJID() );
        pingRequest.setID( UUID.randomUUID().toString() ); // Generate unique ID, to prevent duplicate cache entries.
        PINGS_SENT.put(pingRequest.getID(), pingRequest.getTo());

        // Schedule a check to see if the ping was answered, kicking the occupant if it wasn't.
        // The check should be done _before_ the next ping would be sent (to prevent a backlog of ping requests forming)
        Duration timeoutMs = userIdlePing.dividedBy(4);
        final CheckPingResponseTask task = new CheckPingResponseTask(occupant, pingRequest.getID());
        occupant.setPendingPingTask(task);
        TaskEngine.getInstance().schedule(task, timeoutMs);

        XMPPServer.getInstance().getPacketRouter().route(pingRequest);
    }
Sends an IQ Ping request to an occupant, and schedules a check that determines if a response to that request
was received (removing the occupant if it is not).

@param occupant The occupant to ping.
xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/MultiUserChatServiceImpl.java