private String bindResourceAndEstablishSession(String resource) throws XMPPException {
        // Wait until server sends response containing the <bind> element
        synchronized (this) {
            if (!resourceBinded) {
                try {
                    wait(30000);
                }
                catch (InterruptedException e) {
                    // Ignore
                }
            }
        }

        if (!resourceBinded) {
            // Server never offered resource binding
            throw new XMPPException("Resource binding not offered by server");
        }

        Bind bindResource = new Bind();
        bindResource.setResource(resource);

        PacketCollector collector = connection
                .createPacketCollector(new PacketIDFilter(bindResource.getPacketID()));
        // Send the packet
        connection.sendPacket(bindResource);
        // Wait up to a certain number of seconds for a response from the server.
        Bind response = (Bind) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
        collector.cancel();
        if (response == null) {
            throw new XMPPException("No response from the server.");
        }
        // If the server replied with an error, throw an exception.
        else if (response.getType() == IQ.Type.ERROR) {
            throw new XMPPException(response.getError());
        }
        String userJID = response.getJid();

        if (sessionSupported) {
            Session session = new Session();
            collector = connection.createPacketCollector(new PacketIDFilter(session.getPacketID()));
            // Send the packet
            connection.sendPacket(session);
            // Wait up to a certain number of seconds for a response from the server.
            IQ ack = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
            collector.cancel();
            if (ack == null) {
                throw new XMPPException("No response from the server.");
            }
            // If the server replied with an error, throw an exception.
            else if (ack.getType() == IQ.Type.ERROR) {
                throw new XMPPException(ack.getError());
            }
        }
        else {
            // Server never offered session establishment
            throw new XMPPException("Session establishment not offered by server");
        }
        return userJID;
    }