@Override
    public void resourceBound(final Session session) {
        if (!VERSION_QUERY_ENABLED.getValue()) {
            return;
        }

        // Prevent retaining a reference to the session object, while waiting for the right time to execute the query.
        // There's (unproven) concern that this is a factor in issue OF-2367. Better safe than sorry.
        final JID address = session.getAddress();

        // The server should not send requests to the client before the client session
        // has been established (see IQSessionEstablishmentHandler). Sadly, Openfire
        // does not provide a hook for this. For now, the resource bound event is
        // used instead (which should be immediately followed by session establishment).
        TaskEngine.getInstance().schedule( new TimerTask() {
            @Override
            public void run() { try {
                final Session session = SessionManager.getInstance().getSession(address);
                if (session == null || session.isClosed() || !VERSION_QUERY_ENABLED.getValue()){
                    return;
                }

                IQ versionRequest = new IQ(IQ.Type.get);
                versionRequest.setTo(session.getAddress());
                versionRequest.setFrom(session.getServerName());
                versionRequest.setChildElement("query", "jabber:iq:version");
                session.process(versionRequest);
            } catch (Exception e) {
                Log.error("Exception while trying to query a client ({}) for its software version.", session.getAddress(), e);
            }}
        }, VERSION_QUERY_DELAY.getValue()); // Let time pass for the session establishment to have occurred.
    }
A SoftwareVersionManager is the main responsible for sending query to remote entity and 
Obtain software information from the remote entity using XEP-0092 .
@author Manasse Ngudia
xmppserver/src/main/java/org/jivesoftware/openfire/session/SoftwareVersionManager.java