def start_sm(self, request_resumption=True, resumption_timeout=None):
        """
        Start stream management (version 3).

        :param request_resumption: Request that the stream shall be resumable.
        :type request_resumption: :class:`bool`
        :param resumption_timeout: Maximum time in seconds for a stream to be
            resumable.
        :type resumption_timeout: :class:`int`
        :raises aioxmpp.errors.StreamNegotiationFailure: if the server rejects
            the attempt to enable stream management.

        This method attempts to starts stream management on the stream.

        `resumption_timeout` is the ``max`` attribute on
        :class:`.nonza.SMEnabled`; it can be used to set a maximum time for
        which the server shall consider the stream to still be alive after the
        underlying transport (TCP) has failed. The server may impose its own
        maximum or ignore the request, so there are no guarentees that the
        session will stay alive for at most or at least `resumption_timeout`
        seconds. Passing a `resumption_timeout` of 0 is equivalent to passing
        false to `request_resumption` and takes precedence over
        `request_resumption`.

        .. note::

            In addition to server implementation details, it is very well
            possible that the server does not even detect that the underlying
            transport has failed for quite some time for various reasons
            (including high TCP timeouts).

        If the server rejects the attempt to enable stream management, a
        :class:`.errors.StreamNegotiationFailure` is raised. The stream is
        still running in that case.

        .. warning::

           This method cannot and does not check whether the server advertised
           support for stream management. Attempting to negotiate stream
           management without server support might lead to termination of the
           stream.

        If an XML stream error occurs during the negotiation, the result
        depends on a few factors. In any case, the stream is not running
        afterwards. If the :class:`.nonza.SMEnabled` response was not received
        before the XML stream died, SM is also disabled and the exception which
        caused the stream to die is re-raised (this is due to the
        implementation of :func:`~.protocol.send_and_wait_for`). If the
        :class:`.nonza.SMEnabled` response was received and annonuced support
        for resumption, SM is enabled. Otherwise, it is disabled. No exception
        is raised if :class:`.nonza.SMEnabled` was received, as this method has
        no way to determine that the stream failed.

        If negotiation succeeds, this coroutine initializes a new stream
        management session. The stream management state attributes become
        available and :attr:`sm_enabled` becomes :data:`True`.
        """
        if not self.running:
            raise RuntimeError("cannot start Stream Management while"
                               " StanzaStream is not running")
        if self.sm_enabled:
            raise RuntimeError("Stream Management already enabled")

        if resumption_timeout == 0:
            request_resumption = False
            resumption_timeout = None

        # sorry for the callback spaghetti code
        # we have to handle the response synchronously, so we have to use a
        # callback.
        # otherwise, it is possible that an SM related nonza (e.g. <r/>) is
        # received (and attempted to be deserialized) before the handlers are
        # registered
        # see tests/test_highlevel.py:TestProtocoltest_sm_bootstrap_race
        def handle_response(response):
            if isinstance(response, nonza.SMFailed):
                # we handle the error down below
                return

            self._sm_outbound_base = 0
            self._sm_inbound_ctr = 0
            self._sm_unacked_list = []
            self._sm_enabled = True
            self._sm_id = response.id_
            self._sm_resumable = response.resume
            self._sm_max = response.max_
            self._sm_location = response.location

            self._logger.info("SM started: resumable=%s, stream id=%r",
                              self._sm_resumable,
                              self._sm_id)

            # if not self._xmlstream:
            #     # stream died in the meantime...
            #     if self._xmlstream_exception:
            #         raise self._xmlstream_exception

            self._xmlstream.stanza_parser.add_class(
                nonza.SMRequest,
                self.recv_stanza)
            self._xmlstream.stanza_parser.add_class(
                nonza.SMAcknowledgement,
                self.recv_stanza)

        with (yield from self._broker_lock):
            response = yield from protocol.send_and_wait_for(
                self._xmlstream,
                [
                    nonza.SMEnable(resume=bool(request_resumption),
                                   max_=resumption_timeout),
                ],
                [
                    nonza.SMEnabled,
                    nonza.SMFailed
                ],
                cb=handle_response,
            )

            if isinstance(response, nonza.SMFailed):
                raise errors.StreamNegotiationFailure(
                    "Server rejected SM request")
Start stream management (version 3).

        :param request_resumption: Request that the stream shall be resumable.
        :type request_resumption: :class:`bool`
        :param resumption_timeout: Maximum time in seconds for a stream to be
            resumable.
        :type resumption_timeout: :class:`int`
        :raises aioxmpp.errors.StreamNegotiationFailure: if the server rejects
            the attempt to enable stream management.

        This method attempts to starts stream management on the stream.

        `resumption_timeout` is the ``max`` attribute on
        :class:`.nonza.SMEnabled`; it can be used to set a maximum time for
        which the server shall consider the stream to still be alive after the
        underlying transport (TCP) has failed. The server may impose its own
        maximum or ignore the request, so there are no guarentees that the
        session will stay alive for at most or at least `resumption_timeout`
        seconds. Passing a `resumption_timeout` of 0 is equivalent to passing
        false to `request_resumption` and takes precedence over
        `request_resumption`.

        .. note::

            In addition to server implementation details, it is very well
            possible that the server does not even detect that the underlying
            transport has failed for quite some time for various reasons
            (including high TCP timeouts).

        If the server rejects the attempt to enable stream management, a
        :class:`.errors.StreamNegotiationFailure` is raised. The stream is
        still running in that case.

        .. warning::

           This method cannot and does not check whether the server advertised
           support for stream management. Attempting to negotiate stream
           management without server support might lead to termination of the
           stream.

        If an XML stream error occurs during the negotiation, the result
        depends on a few factors. In any case, the stream is not running
        afterwards. If the :class:`.nonza.SMEnabled` response was not received
        before the XML stream died, SM is also disabled and the exception which
        caused the stream to die is re-raised (this is due to the
        implementation of :func:`~.protocol.send_and_wait_for`). If the
        :class:`.nonza.SMEnabled` response was received and annonuced support
        for resumption, SM is enabled. Otherwise, it is disabled. No exception
        is raised if :class:`.nonza.SMEnabled` was received, as this method has
        no way to determine that the stream failed.

        If negotiation succeeds, this coroutine initializes a new stream
        management session. The stream management state attributes become
        available and :attr:`sm_enabled` becomes :data:`True`.