<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def keep_levels(self, level_indices):
 """ Rearrange the tree rooted at this node to keep only the given levels. The returned Tree will still be rooted at the current node, i.e. this function implicitly adds ``0`` to ``level_indices``. If ``level_indices`` is an empty list, only this node will be returned, with no children. Elements of ``level_indices`` that do not represent valid level indices (e.g., negative, or too large) will be ignored and no error will be raised. Important: this function modifies the original tree in place! :param list level_indices: the list of int, representing the levels to keep :raises: TypeError if ``level_indices`` is not a list or if it contains an element which is not an int """

        if not isinstance(level_indices, list):
            self.log_exc(u"level_indices is not an instance of list", None, True, TypeError)
        for l in level_indices:
            if not isinstance(l, int):
                self.log_exc(u"level_indices contains an element not int", None, True, TypeError)
        prev_levels = self.levels
        level_indices = set(level_indices)
        if 0 not in level_indices:
            level_indices.add(0)
        level_indices = level_indices & set(range(self.height))
        level_indices = sorted(level_indices)[::-1]
        # first, remove children
        for l in level_indices:
            for node in prev_levels[l]:
                node.remove_children(reset_parent=False)
        # then, connect to the right new parent
        for i in range(len(level_indices) - 1):
            l = level_indices[i]
            for node in prev_levels[l]:
                parent_node = node.ancestor(l - level_indices[i + 1])
                parent_node.add_child(node)