Takes a tree in "By ID" NexSON (v1.2).  provides and iterator over:
        NexsonNodeProxy object
    where the edge of the object is the edge connectin the node to the parent.
    The first node will be the root and will have None as it's edge

def nexson_tree_preorder_iter(tree_proxy, node_id=None, node=None, edge_id=None, edge=None):
    """Takes a tree in "By ID" NexSON (v1.2).  provides and iterator over:
        NexsonNodeProxy object
    where the edge of the object is the edge connectin the node to the parent.
    The first node will be the root and will have None as it's edge
    """
    tree = tree_proxy._nexson_tree
    ebsid = tree['edgeBySourceId']
    nbid = tree['nodeById']
    if edge_id is not None:
        assert edge is not None
        if node_id is None:
            node_id = edge['@target']
        else:
            assert node_id == edge['@target']
        if node is None:
            node = nbid[node_id]
        else:
            assert node == nbid[node_id]
        yield tree_proxy._create_node_proxy_from_edge(edge_id, edge, node_id=node_id, node=node)
        root_id = node_id
    elif node_id is not None:
        if node is None:
            node = nbid[node_id]
        else:
            assert node == nbid[node_id]
        yield tree_proxy._create_node_proxy_from_edge(None, None, node_id=node_id, node=node)
        root_id = node_id
    else:
        root_id = tree['^ot:rootNodeId']
        root = nbid[root_id]
        yield tree_proxy._create_node_proxy_from_edge(None, None, node_id=root_id, node=root)
    stack = []
    new_stack = [(i['@target'], edge_id, i) for edge_id, i in ebsid[root_id].items()]
    stack.extend(new_stack)
    while stack:
        target_node_id, edge_id, edge = stack.pop()
        node = nbid[target_node_id]
        yield tree_proxy._create_node_proxy_from_edge(edge_id=edge_id, edge=edge, node_id=target_node_id)
        daughter_edges = ebsid.get(target_node_id)
        if daughter_edges is not None:
            new_stack = [(i['@target'], edge_id, i) for edge_id, i in daughter_edges.items()]
            stack.extend(new_stack)