code: def keep_levels(self, level_indices):
          
          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)
docs: 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