A      C    | Subtrees A, B, C and D are the exchangeable nodes
             \    /     | around the edge headed by n
              -->n      | The NNI exchanges either A or B with either C or D
             /    \
            B      D

            A      C                        C      A    | Subtree A is exchanged
             \    /        +NNI(A,C)         \    /     | with subtree C.
              -->n        ==========>         -->n
             /    \                          /    \
            B      D                        B      D

def get_exchangeable_nodes(self, n):
        """
            A      C    | Subtrees A, B, C and D are the exchangeable nodes
             \    /     | around the edge headed by n
              -->n      | The NNI exchanges either A or B with either C or D
             /    \
            B      D

            A      C                        C      A    | Subtree A is exchanged
             \    /        +NNI(A,C)         \    /     | with subtree C.
              -->n        ==========>         -->n
             /    \                          /    \
            B      D                        B      D
        """
        parent = n.parent_node
        a, b = random.sample(n.child_nodes(), 2)
        if parent.parent_node is None:
            if self.tree.rooted:
                c, d = random.sample(n.sister_nodes()[0].child_nodes(), 2)
            else:
                c, d = random.sample(n.sister_nodes(), 2)
        else:
            c = random.choice(n.sister_nodes())
            d = random.choice(parent.sister_nodes())

        return a, b, c, d