'Insert or update a user\'s info.'

@classmethod
def upsert(cls, i):

    if i.avatar_url:
        (scheme, netloc, path, query, fragment) = urlsplit(i.avatar_url)
        fragment = u''
        if (netloc.endswith(u'githubusercontent.com') or netloc.endswith(u'gravatar.com')):
            query = u's=160'
        i.avatar_url = urlunsplit((scheme, netloc, path, query, fragment))
    if isinstance(i.extra_info, ET.Element):
        i.extra_info = xmltodict.parse(ET.tostring(i.extra_info))
    i.extra_info = json.dumps(i.extra_info)
    (cols, vals) = zip(*i.__dict__.items())
    cols = u',    '.join(cols)
    placeholders = u',    '.join(([u'%s'] * len(vals)))
    try:
        with cls.db.get_cursor() as cursor:
            username = safely_reserve_a_username(cursor)
            cursor.execute(u'\n                                                                                INSERT    INTO    elsewhere\n                                                                                                                                (participant,    {0})\n                                                                                                    VALUES    (%s,    {1})\n                                                                '.format(cols, placeholders), ((username,) + vals))
    except IntegrityError:
        username = cls.db.one(u'\n                                                                UPDATE    elsewhere\n                                                                            SET    ({0})    =    ({1})\n                                                                    WHERE    platform=%s    AND    user_id=%s\n                                                    RETURNING    participant\n                                                '.format(cols, placeholders), (vals + (i.platform, i.user_id)))
        if (not username):
            raise
    account = AccountElsewhere.from_user_id(i.platform, i.user_id)
    account.participant.update_avatar()
    return account
