def find(self, term, value=False, section=None, _expand_derived=True, **kwargs):
import itertools<EOL>if kwargs:  <EOL><INDENT>terms = self.find(term, value, section)<EOL>found_terms = []<EOL>for t in terms:<EOL><INDENT>if all(t.get_value(k) == v for k, v in kwargs.items()):<EOL><INDENT>found_terms.append(t)<EOL><DEDENT><DEDENT>return found_terms<EOL><DEDENT>def in_section(term, section):<EOL><INDENT>if section is None:<EOL><INDENT>return True<EOL><DEDENT>if term.section is None:<EOL><INDENT>return False<EOL><DEDENT>if isinstance(section, (list, tuple)):<EOL><INDENT>return any(in_section(t, e) for e in section)<EOL><DEDENT>else:<EOL><INDENT>return section.lower() == term.section.name.lower()<EOL><DEDENT><DEDENT>if _expand_derived:<EOL><INDENT>try:<EOL><INDENT>try:<EOL><INDENT>term = list(self.derived_terms[term.lower()]) + [term]<EOL><DEDENT>except AttributeError: <EOL><INDENT>terms = []<EOL>for t in term:<EOL><INDENT>terms.append(term)<EOL>for dt in self.derived_terms[t.lower()]:<EOL><INDENT>terms.append(dt)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>except KeyError as e:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>if isinstance(term, (list, tuple)):<EOL><INDENT>return list(itertools.chain(*[self.find(e, value=value, section=section, _expand_derived=False) for e in term]))<EOL><DEDENT>else:<EOL><INDENT>term = term.lower()<EOL>found = []<EOL>if not '<STR_LIT:.>' in term:<EOL><INDENT>term = '<STR_LIT>' + term<EOL><DEDENT>if term.startswith('<STR_LIT>'):<EOL><INDENT>term_gen = self.terms <EOL><DEDENT>else:<EOL><INDENT>term_gen = self.all_terms <EOL><DEDENT>for t in term_gen:<EOL><INDENT>if t.join_lc == '<STR_LIT>':<EOL><INDENT>continue<EOL><DEDENT>assert t.section or t.join_lc == '<STR_LIT>' or t.join_lc == '<STR_LIT>', t<EOL>if (t.term_is(term)<EOL>and in_section(t, section)<EOL>and (value is False or value == t.value)):<EOL><INDENT>found.append(t)<EOL><DEDENT><DEDENT>return found<EOL><DEDENT>
Return a list of terms, possibly in a particular section. Use joined term notation, such as 'Root.Name' The kwargs arg is used to set term properties, all of which match returned terms, so ``name='foobar'`` will match terms that have a ``name`` property of ``foobar``

        :param term: The type of term to find, in fully-qulified notation, or use '*' for wild cards in either the parent or the record parts, such as 'Root.*', '*.Table' or '*.*'
        :param value: Select terms with a given value
        :param section: The name of the section in which to restrict the search
        :param kwargs:  See additional properties on which to match terms.