void testReconnectionBlocking(final boolean testDisconnect) throws Exception {
        logTestStart();
        session.addBOSHClientConnListener(disc);

        // Send a packet to the CM, and receive it at the CM.
        session.send(ComposableBody.builder().build());
        StubConnection conn1 = cm.awaitConnection();
        AbstractBody scr = getSessionCreationResponse(conn1.getRequest().getBody())
            .setAttribute(Attributes.HOLD, "1")
            .setAttribute(Attributes.REQUESTS, "2")
            .build();
        conn1.sendResponse(scr);
        session.drain();

        // Send another request.
        session.send(ComposableBody.builder().build());

        // Close the connection at the CM without sending a response.
        conn1 = cm.awaitConnection();
        conn1.closeConnection();

        // Wait for the client to see the disconnection.
        disc.waitForDisconnection();

        // The disconnection should be recoverable.
        assertTrue(session.isRecoverableConnectionLoss());

        // Start a thread to check for blocking.
        final AtomicBoolean finishedBlocking = new AtomicBoolean(false);
        Thread thread = new Thread() {
            public void run() {
                // Wait 250ms, and make sure that finishedBlocking is still unset.
                try {
                    // Wait 250ms to make sure the below send() call blocks.
                    Thread.sleep(250);

                    // Begin reconnection.
                    session.attemptReconnection();

                    // The send() call should continue to block, because the reconnection
                    // hasn't yet succeeded.  Wait briefly to make sure it continues to block.
                    Thread.sleep(250);

                    finishedBlocking.set(true);

                    if(testDisconnect) {
                        // Permanently disconnecting the session should wake up the blocking read().
                        session.close();
                    } else {
                        // Responding to the request should wake up the blocking send().
                        StubConnection conn = cm.awaitConnection();
                        AbstractBody body = conn.getRequest().getBody();
                        conn.sendResponse(ComposableBody.builder()
                                .setAttribute(Attributes.RID, body.getAttribute(Attributes.RID))
                                .build());
                    }
                } catch(Exception e) {
                    throw new RuntimeException(e);
                }
            }
        };
        thread.setName("Blocking monitor thread");
        thread.start();

        // Attempt to send a packet.  This must block.
        ComposableBody packet = ComposableBody.builder().build();
        BOSHException exceptionThrown = null;
        try {
            session.send(packet);
        } catch(BOSHException e) {
            exceptionThrown = e;
        }

        // If finishedBlocking is false, then we woke up too soon.
        assertTrue("Expected to block", finishedBlocking.get());

        if(testDisconnect) {
            // The thread called disconnect(), which causes send() to throw an exception.
            assertNotNull("Expected an exception to be thrown", exceptionThrown);
        } else {
            // The thread reconnected the connection, so the send() call succeeds.
            assertNull("Unexpected exception", exceptionThrown);
        }
    }