support recursive traversal