def word_ladder(self, origin, destination):
        """Constructs a word ladder between the given words using the fetched vocabulary. A word ladder is a sequence of
        words, from origin to destination, where each intermediary word changes exactly one letter in the previous word.
        All intermediate words in the ladder must be real words.
        Constructing a word ladder loosely follows the methodology of A* path finding. A tree data structure is used to
        store a collection of words and the paths between them. The tree is filled first with the destination word and
        is then traversed breadth first adding each word's legal one character substitutions. Traversal ends when any
        path has reached the origin and that path's ancestry is returned.
        The tree is traversed breadth first so that the shortest path is found in all cases. A tree begins at the
        destination and works backwards to the origin so that the chosen path's ancestry is in the correct order.
        :param origin: The starting word to construct a word ladder from.
        :param destination: The word that the ladder traverses to.
        :return: A sequence of words that constitutes a word ladder.
        """
        paths = Tree()                        # tree stores all possible paths
        paths.add_root(destination)           # start at destination so that ancestry path is in the correct order
        visited = set()                       # no need for ANY branch to revisit a word that another branch has been to

        for node in paths.breadth_first():
            if node.data == origin:                     # if node is origin, the word ladder is complete
                path = []
                for ancestor in node.ancestor_data():   # construct a path from this nodes ancestors.
                    path.append(ancestor)
                return path
            else:
                for word in self.similar(node.data):        # add each similar word to this nodes path...
                    if word not in visited:                 # ...only if it hasn't been visited by ANY other tree path
                        node.add(word)
                        visited.add(word)
        return []                                           # no path was found
    def tree_test(self):
        tree = Tree()
        root = tree.add_root(1)
        root_child = root.add(2)
        other_root_child = root.add(3)
        root_child_child = root_child.add(4)

        # test root has correct parent, data, and children
        self.assertEqual(root.parent, None)
        self.assertEqual(root.data, 1)
        self.assertEqual(len(root.children), 2)
        self.assertIn(root_child, root.children)
        self.assertIn(other_root_child, root.children)

        # test child of root has correct parent, data, and children
        self.assertEqual(root_child.parent, root)
        self.assertEqual(root_child.data, 2)
        self.assertEqual(len(root_child.children), 1)
        self.assertIn(root_child_child, root_child.children)

        # test other child of root has correct parent, data, and children
        self.assertEqual(other_root_child.parent, root)
        self.assertEqual(other_root_child.data, 3)
        self.assertEqual(len(other_root_child.children), 0)