def user_groups(self, ldap_user, group_search):
group_info_map = {}  <EOL>member_dn_set = set([ldap_user.dn])  <EOL>handled_dn_set = set()  <EOL>while len(member_dn_set) > <NUM_LIT:0>:<EOL><INDENT>group_infos = self.find_groups_with_any_member(member_dn_set,<EOL>group_search,<EOL>ldap_user.connection)<EOL>new_group_info_map = dict([(info[<NUM_LIT:0>], info) for info in group_infos])<EOL>group_info_map.update(new_group_info_map)<EOL>handled_dn_set.update(member_dn_set)<EOL>member_dn_set = set(new_group_info_map.keys()) - handled_dn_set<EOL><DEDENT>return group_info_map.values()<EOL>
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.