def iterdata(self, start, end=None, forward=True, condition=None):
        """
        Perform a depth-first walk of the graph (as ``iterdfs``)
        and yield the item data of every node where condition matches. The 
        condition callback is only called when node_data is not None.
        """

        visited, stack = set([start]), deque([start])

        if forward:
            get_edges = self.out_edges
            get_next = self.tail
        else:
            get_edges = self.inc_edges
            get_next = self.head

        get_data = self.node_data

        while stack:
            curr_node = stack.pop()
            curr_data = get_data(curr_node)
            if curr_data is not None:
                if condition is not None and not condition(curr_data):
                    continue
                yield curr_data
            if curr_node == end:
                break
            for edge in get_edges(curr_node):
                tail = get_next(edge)
                if tail not in visited:
                    visited.add(tail)
                    stack.append(tail)
Perform a depth-first walk of the graph (as ``iterdfs``)
        and yield the item data of every node where condition matches. The 
        condition callback is only called when node_data is not None.