<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def log_in(self, username=None, password=None, code=None, redirect_uri="urn:ietf:wg:oauth:2.0:oob", refresh_token=None, scopes=__DEFAULT_SCOPES, to_file=None):
 """ Get the access token for a user. The username is the e-mail used to log in into mastodon. Can persist access token to file `to_file`, to be used in the constructor. Handles password and OAuth-based authorization. Will throw a `MastodonIllegalArgumentError` if the OAuth or the username / password credentials given are incorrect, and `MastodonAPIError` if all of the requested scopes were not granted. For OAuth2, obtain a code via having your user go to the url returned by `auth_request_url()`_ and pass it as the code parameter. In this case, make sure to also pass the same redirect_uri parameter as you used when generating the auth request URL. Returns the access token as a string. """

        if username is not None and password is not None:
            params = self.__generate_params(locals(), ['scopes', 'to_file', 'code', 'refresh_token'])
            params['grant_type'] = 'password'
        elif code is not None:
            params = self.__generate_params(locals(), ['scopes', 'to_file', 'username', 'password', 'refresh_token'])
            params['grant_type'] = 'authorization_code'
        elif refresh_token is not None:
            params = self.__generate_params(locals(), ['scopes', 'to_file', 'username', 'password', 'code'])
            params['grant_type'] = 'refresh_token'
        else:
            raise MastodonIllegalArgumentError('Invalid arguments given. username and password or code are required.')

        params['client_id'] = self.client_id
        params['client_secret'] = self.client_secret
        params['scope'] = " ".join(scopes)

        try:
            response = self.__api_request('POST', '/oauth/token', params, do_ratelimiting=False)
            self.access_token = response['access_token']
            self.__set_refresh_token(response.get('refresh_token'))
            self.__set_token_expired(int(response.get('expires_in', 0)))
        except Exception as e:
            if username is not None or password is not None:
                raise MastodonIllegalArgumentError('Invalid user name, password, or redirect_uris: %s' % e)
            elif code is not None:
                raise MastodonIllegalArgumentError('Invalid access token or redirect_uris: %s' % e)
            else:
                raise MastodonIllegalArgumentError('Invalid request: %s' % e)

        received_scopes = response["scope"].split(" ")
        for scope_set in self.__SCOPE_SETS.keys():
            if scope_set in received_scopes:
                received_scopes += self.__SCOPE_SETS[scope_set]
        
        if not set(scopes) <= set(received_scopes):
            raise MastodonAPIError(
                'Granted scopes "' + " ".join(received_scopes) + '" do not contain all of the requested scopes "' + " ".join(scopes) + '".')

        if to_file is not None:
            with open(to_file, 'w') as token_file:
                token_file.write(response['access_token'] + '\n')
        
        self.__logged_in_id = None
        
        return response['access_token']