'LDAP search helper method for finding groups
:param groupname_pattern: The pattern to match ``search_attr`` against. Defaults to ``search_attr`` if none.
:param search_attr: The ldap attribute to search for ``groupname_pattern``. Defaults to LDAP -> GROUPS -> GROUP_NAME_ATTR config value.
:param group_name_attr: The ldap attribute that is returned by the server to map to ``name`` in the return dictionary.
:param find_by_dn: Search by distinguished name.
:param scope: ldapsearch scope.
:returns: List of dictionaries that take on the following form: {
\'dn\': <distinguished name of entry>,
\'name\': <ldap attribute associated with group_name_attr>
\'first\': <first name>
\'last\': <last name>
\'email\': <email>
\'groups\': <list of DNs of groups that user is a member of>'

def find_groups(self, groupname_pattern, search_attr=None, group_name_attr=None, group_member_attr=None, group_filter=None, find_by_dn=False, scope=ldap.SCOPE_SUBTREE):

    if (not search_attr):
        search_attr = self.ldap_config.GROUPS.GROUP_NAME_ATTR.get()
    if (not group_name_attr):
        group_name_attr = search_attr
    if (not group_member_attr):
        group_member_attr = self.ldap_config.GROUPS.GROUP_MEMBER_ATTR.get()
    if (not group_filter):
        group_filter = self.ldap_config.GROUPS.GROUP_FILTER.get()
    if (not group_filter.startswith('(')):
        group_filter = (('(' + group_filter) + ')')
    sanitized_name = ldap.filter.escape_filter_chars(groupname_pattern).replace('\\2a', '*')
    sanitized_name = sanitized_name.replace('\\5c,', '\\2c')
    (search_dn, group_name_filter) = self._get_search_params(sanitized_name, search_attr, find_by_dn)
    ldap_filter = ((('(&' + group_filter) + group_name_filter) + ')')
    attrlist = ['objectClass', 'dn', 'memberUid', group_member_attr, group_name_attr]
    self._search_dn = search_dn
    self._ldap_filter = ldap_filter
    self._attrlist = attrlist
    ldap_result_id = self.ldap_handle.search(search_dn, scope, ldap_filter, attrlist)
    (result_type, result_data) = self.ldap_handle.result(ldap_result_id)
    if (result_type == ldap.RES_SEARCH_RESULT):
        return self._transform_find_group_results(result_data, group_name_attr, group_member_attr)
    else:
        return []
