docs: def _process_connect_init(self):
          """
          Handles the initial part of the NATS protocol, moving from
          the (RE)CONNECTING to CONNECTED states when establishing
          a connection with the server.
          """
          # INFO {...}
          line = yield self.io.read_until(_CRLF_, max_bytes=None)
          _, args = line.split(INFO_OP + _SPC_, 1)
          self._server_info = tornado.escape.json_decode((args))
  
          if 'max_payload' in self._server_info:
              self._max_payload_size = self._server_info["max_payload"]
  
          # Check whether we need to upgrade to TLS first of all
          if 'tls_required' in self._server_info and self._server_info['tls_required']:
              # Detach and prepare for upgrading the TLS connection.
              self._loop.remove_handler(self._socket.fileno())
  
              tls_opts = {}
              if "tls" in self.options:
                  # Allow customizing the TLS version though default
                  # to one that the server supports at least.
                  tls_opts = self.options["tls"]
  
              # Rewrap using a TLS connection, can't do handshake on connect
              # as the socket is non blocking.
              self._socket = ssl.wrap_socket(
                  self._socket, do_handshake_on_connect=False, **tls_opts)
  
              # Use the TLS stream instead from now
              self.io = tornado.iostream.SSLIOStream(self._socket)
              self.io.set_close_callback(self._process_op_err)
              self.io._do_ssl_handshake()
  
          # Refresh state of the parser upon reconnect.
          if self.is_reconnecting:
              self._ps.reset()
  
          # CONNECT then send a PING expecting a PONG to make a
          # roundtrip to the server and assert that sent commands sent
          # this far have been processed already.
          cmd = self.connect_command()
          yield self.io.write(cmd)
          yield self.io.write(PING_PROTO)
  
          # FIXME: Add readline timeout for these.
          next_op = yield self.io.read_until(
              _CRLF_, max_bytes=MAX_CONTROL_LINE_SIZE)
          if self.options["verbose"] and OK_OP in next_op:
              next_op = yield self.io.read_until(
                  _CRLF_, max_bytes=MAX_CONTROL_LINE_SIZE)
          if ERR_OP in next_op:
              err_line = next_op.decode()
              _, err_msg = err_line.split(_SPC_, 1)
              # FIXME: Maybe handling could be more special here,
              # checking for ErrAuthorization for example.
              # yield from self._process_err(err_msg)
              raise NatsError("nats: " + err_msg.rstrip('\r\n'))
  
          if PONG_PROTO in next_op:
              self._status = Client.CONNECTED
  
          self._loop.spawn_callback(self._read_loop)
          self._pongs = []
          self._pings_outstanding = 0
          self._ping_timer = tornado.ioloop.PeriodicCallback(
              self._ping_interval, self.options["ping_interval"] * 1000)
          self._ping_timer.start()
  
          # Queue and flusher for coalescing writes to the server.
          self._flush_queue = tornado.queues.Queue(maxsize=1024)
          self._loop.spawn_callback(self._flusher_loop)