<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def user_groups(self, ldap_user, group_search):
 """ This searches for all of a user's groups from the bottom up. In other words, it returns the groups that the user belongs to, the groups that those groups belong to, etc. Circular references will be detected and pruned. """

        group_info_map = {}  # Maps group_dn to group_info of groups we've found
        member_dn_set = {ldap_user.dn}  # Member DNs to search with next
        handled_dn_set = set()  # Member DNs that we've already searched with

        while len(member_dn_set) > 0:
            group_infos = self.find_groups_with_any_member(
                member_dn_set, group_search, ldap_user.connection
            )
            new_group_info_map = {info[0]: info for info in group_infos}
            group_info_map.update(new_group_info_map)
            handled_dn_set.update(member_dn_set)

            # Get ready for the next iteration. To avoid cycles, we make sure
            # never to search with the same member DN twice.
            member_dn_set = set(new_group_info_map.keys()) - handled_dn_set

        return group_info_map.values()