def prune(self, nodes, preserve_branch_length=False):
def cmp_nodes(x, y):<EOL><INDENT>if n2depth[x] > n2depth[y]:<EOL><INDENT>return -<NUM_LIT:1><EOL><DEDENT>elif n2depth[x] < n2depth[y]:<EOL><INDENT>return <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>return <NUM_LIT:0><EOL><DEDENT><DEDENT>to_keep = set(_translate_nodes(self, *nodes))<EOL>start, node2path = self.get_common_ancestor(to_keep, get_path=True)<EOL>to_keep.add(self)<EOL>n2count = {}<EOL>n2depth = {}<EOL>for seed, path in six.iteritems(node2path):<EOL><INDENT>for visited_node in path:<EOL><INDENT>if visited_node not in n2depth:<EOL><INDENT>depth = visited_node.get_distance(start, topology_only=True)<EOL>n2depth[visited_node] = depth<EOL><DEDENT>if visited_node is not seed:<EOL><INDENT>n2count.setdefault(visited_node, set()).add(seed)<EOL><DEDENT><DEDENT><DEDENT>visitors2nodes = {}<EOL>for node, visitors in six.iteritems(n2count):<EOL><INDENT>if len(visitors)><NUM_LIT:1>:<EOL><INDENT>visitor_key = frozenset(visitors)<EOL>visitors2nodes.setdefault(visitor_key, set()).add(node)<EOL><DEDENT><DEDENT>for visitors, nodes in six.iteritems(visitors2nodes):<EOL><INDENT>if not (to_keep & nodes):<EOL><INDENT>sorted_nodes = sorted(nodes, key=cmp_to_key(cmp_nodes))<EOL>to_keep.add(sorted_nodes[<NUM_LIT:0>])<EOL><DEDENT><DEDENT>for n in self.get_descendants('<STR_LIT>'):<EOL><INDENT>if n not in to_keep:<EOL><INDENT>if preserve_branch_length:<EOL><INDENT>if len(n.children) == <NUM_LIT:1>:<EOL><INDENT>n.children[<NUM_LIT:0>].dist += n.dist<EOL><DEDENT>elif len(n.children) > <NUM_LIT:1> and n.up:<EOL><INDENT>n.up.dist += n.dist<EOL><DEDENT><DEDENT>n.delete(prevent_nondicotomic=False)<EOL><DEDENT><DEDENT>
Prunes the topology of a node to conserve only a selected list of leaf
internal nodes. The minimum number of nodes that conserve the
topological relationships among the requested nodes will be
retained. Root node is always conserved.

Parameters:
-----------
nodes:
    a list of node names or node objects that should be retained

preserve_branch_length: 
    If True, branch lengths of the deleted nodes are transferred 
    (summed up) to its parent's branch, thus keeping original distances
    among nodes.

**Examples:**
  t1 = Tree('(((((A,B)C)D,E)F,G)H,(I,J)K)root;', format=1)
  t1.prune(['A', 'B'])

  #                /-A
  #          /D /C|
  #       /F|      \-B
  #      |  |
  #    /H|   \-E
  #   |  |                        /-A
  #-root  \-G                 -root
  #   |                           \-B
  #   |   /-I
  #    \K|
  #       \-J

  t1 = Tree('(((((A,B)C)D,E)F,G)H,(I,J)K)root;', format=1)
  t1.prune(['A', 'B', 'C'])

  #                /-A
  #          /D /C|
  #       /F|      \-B
  #      |  |
  #    /H|   \-E
  #   |  |                              /-A
  #-root  \-G                  -root- C|
  #   |                                 \-B
  #   |   /-I
  #    \K|
  #       \-J

  t1 = Tree('(((((A,B)C)D,E)F,G)H,(I,J)K)root;', format=1)
  t1.prune(['A', 'B', 'I'])

  #                /-A
  #          /D /C|
  #       /F|      \-B
  #      |  |
  #    /H|   \-E                    /-I
  #   |  |                      -root
  #-root  \-G                      |   /-A
  #   |                             \C|
  #   |   /-I                          \-B
  #    \K|
  #       \-J

  t1 = Tree('(((((A,B)C)D,E)F,G)H,(I,J)K)root;', format=1)
  t1.prune(['A', 'B', 'F', 'H'])

  #                /-A
  #          /D /C|
  #       /F|      \-B
  #      |  |
  #    /H|   \-E
  #   |  |                              /-A
  #-root  \-G                -root-H /F|
  #   |                                 \-B
  #   |   /-I
  #    \K|
  #       \-J