public void run() {

    StreamConnection stream = null;
    InputStream input = null;
    MDSPushInputStream pushInputStream = null;

    while (!_stop) {
      try {

        // Synchronize here so that we don't end up creating a connection that is never closed.
        synchronized (this) {
          // Open the connection once (or re-open after an IOException),  so we don't end up
          // in a race condition, where a push is lost if it comes in before the connection
          // is open again. We open the url with a parameter that indicates that we should
          // always use MDS when attempting to connect.
          int port = RhoConf.getInstance().getInt("push_port");
          if (port == 0) port = 100;
          _notify = (StreamConnectionNotifier) Connector.open(URL + port + ";deviceside=false");
        }

        while (!_stop) {

          // NOTE: the following will block until data is received.
          LOG.TRACE("Block push thread until data is recieved");
          stream = _notify.acceptAndOpen();
          LOG.TRACE("Recieved push data");

          try {
            input = stream.openInputStream();
            pushInputStream = new MDSPushInputStream((HttpServerConnection) stream, input);

            // Extract the data from the input stream.

            DataBuffer db = new DataBuffer();
            byte[] data = new byte[CHUNK_SIZE];
            int chunk = 0;

            while (-1 != (chunk = input.read(data))) {
              db.write(data, 0, chunk);
            }

            processPushMessage(data);

            // This method is called to accept the push.
            pushInputStream.accept();

            input.close();
            stream.close();

            data = db.getArray();

          } catch (IOException e1) {
            // A problem occurred with the input stream , however, the original
            // StreamConnectionNotifier is still valid.
            System.err.println(e1.toString());

            if (input != null) {
              try {
                input.close();
              } catch (IOException e2) {
              }
            }

            if (stream != null) {
              try {
                stream.close();
              } catch (IOException e2) {
              }
            }
          }
        }

        _notify.close();
        _notify = null;

      } catch (IOException ioe) {
        LOG.TRACE("Exception thrown by _notify.acceptAndOpen() - exiting push thread");

        // Likely the stream was closed. Catches the exception thrown by
        // _notify.acceptAndOpen() when this program exits.

        _stop = true;

        if (_notify != null) {
          try {
            _notify.close();
            _notify = null;
          } catch (IOException e) {
          }
        }
      }
    }
  }