'signup a user, to either:
- create a new user (no token), or
- create a user for a partner (with token, but no user for partner), or
- change the password of a user (with token, and existing user).
:param values: a dictionary with field values that are written on user
:param token: signup token (optional)
:return: (dbname, login, password) for the signed up user'

@api.model
def signup(self, values, token=None):

    if token:
        partner = self.env['res.partner']._signup_retrieve_partner(token, check_validity=True, raise_exception=True)
        partner.write({'signup_token': False, 'signup_type': False, 'signup_expiration': False})
        partner_user = ((partner.user_ids and partner.user_ids[0]) or False)
        if (partner.country_id or partner.zip or partner.city):
            values.pop('city', None)
            values.pop('country_id', None)
        if partner.lang:
            values.pop('lang', None)
        if partner_user:
            values.pop('login', None)
            values.pop('name', None)
            partner_user.write(values)
            return (self.env.cr.dbname, partner_user.login, values.get('password'))
        else:
            values.update({'name': partner.name, 'partner_id': partner.id, 'email': (values.get('email') or values.get('login'))})
            if partner.company_id:
                values['company_id'] = partner.company_id.id
                values['company_ids'] = [(6, 0, [partner.company_id.id])]
            self._signup_create_user(values)
    else:
        values['email'] = (values.get('email') or values.get('login'))
        self._signup_create_user(values)
    return (self.env.cr.dbname, values.get('login'), values.get('password'))
