/** Main event loop. */
    public void interruptibleRun() {

      m_outputStreamFilterTee.connectionOpened();

      final byte[] buffer = new byte[BUFFER_SIZE];

      try {
        while (true) {
          final int bytesRead = m_in.read(buffer, 0, BUFFER_SIZE);

          if (bytesRead == -1) {
            break;
          }

          m_outputStreamFilterTee.handle(buffer, bytesRead);
        }
      } catch (SocketException e) {
        // Ignore, assume closed.
      } catch (IOException e) {
        UncheckedInterruptedException.ioException(e);
        logIOException(e);
      } finally {
        m_outputStreamFilterTee.connectionClosed();
      }

      // Tidy up.
      Closer.close(m_in);
    }
    /** Constructor. */
    FilteredStreamThread(InputStream in, OutputStreamFilterTee outputStreamFilterTee) {

      m_in = in;
      m_outputStreamFilterTee = outputStreamFilterTee;

      new StreamThread(
              this, "Filter thread for " + outputStreamFilterTee.getConnectionDetails(), m_in)
          .start();
    }