private void connectionLost(final Throwable cause) {
        assertUnlocked();

        lock.lock();
        try {
            // If the connection was already lost, don't set it to recoverable.
            if(!isWorking())
                return;

            clearTimeout();

            if(connectionRecoverablyLost)
                return;
            connectionRecoverablyLost = true;

            // All exchanges in the air have failed.
            closeAllExchanges();
        } finally {
            lock.unlock();
        }

        fireConnectionClosedOnError(cause);
    }