<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 async def starttls(self, context=None):
 """ Upgrades the connection to the SMTP server into TLS mode. If there has been no previous EHLO or HELO command this session, this method tries ESMTP EHLO first. If the server supports SSL/TLS, this will encrypt the rest of the SMTP session. Raises: SMTPCommandNotSupportedError: If the server does not support STARTTLS. SMTPCommandFailedError: If the STARTTLS command fails BadImplementationError: If the connection does not use aioopenssl. Args: context (:obj:`OpenSSL.SSL.Context`):
 SSL context Returns: (int, message):
 A (code, message) 2-tuple containing the server response. """

        if not self.use_aioopenssl:
            raise BadImplementationError("This connection does not use aioopenssl")

        import aioopenssl
        import OpenSSL

        await self.ehlo_or_helo_if_needed()

        if "starttls" not in self.esmtp_extensions:
            raise SMTPCommandNotSupportedError("STARTTLS")

        code, message = await self.do_cmd("STARTTLS", success=(220,))
        # Don't check for code, do_cmd did it

        if context is None:
            context = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_2_METHOD)

        await self.transport.starttls(ssl_context=context)

        # RFC 3207:
        # The client MUST discard any knowledge obtained from
        # the server, such as the list of SMTP service extensions,
        # which was not obtained from the TLS negotiation itself.

        # FIXME: wouldn't it be better to use reset_state here ?
        # And reset self.reader, self.writer and self.transport just after
        # Maybe also self.ssl_context ?
        self.last_ehlo_response = (None, None)
        self.last_helo_response = (None, None)
        self.supports_esmtp = False
        self.esmtp_extensions = {}
        self.auth_mechanisms = []

        return (code, message)