'A helper function for ``trees``.
:param memo: A dictionary used to record the trees that we\'ve
generated for each edge, so that when we see an edge more
than once, we can reuse the same trees.'

def _trees(self, edge, complete, memo, tree_class):

    if (edge in memo):
        return memo[edge]
    if (complete and edge.is_incomplete()):
        return []
    if isinstance(edge, LeafEdge):
        leaf = self._tokens[edge.start()]
        memo[edge] = [leaf]
        return [leaf]
    memo[edge] = []
    trees = []
    lhs = edge.lhs().symbol()
    for cpl in self.child_pointer_lists(edge):
        child_choices = [self._trees(cp, complete, memo, tree_class) for cp in cpl]
        for children in itertools.product(*child_choices):
            trees.append(tree_class(lhs, children))
    if edge.is_incomplete():
        unexpanded = [tree_class(elt, []) for elt in edge.rhs()[edge.dot():]]
        for tree in trees:
            tree.extend(unexpanded)
    memo[edge] = trees
    return trees
