#![allow(clippy::match_bool)]
use std::collections::VecDeque;
use std::marker::PhantomData;
use std::num::NonZeroUsize;

#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};

use crate::Error;
use crate::iter::*;
use crate::node::Node;
use crate::arena::Arena;

/// A `Token` is a handle to a node in the arena.
#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Token {
    pub (crate) index: NonZeroUsize
}

impl Token {
    /// Checks whether a given node is actually a leaf.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    pub fn is_leaf<T>(self, arena: &Arena<T>) -> bool {
        match arena.get(self) {
            // Dead code: documented panic for invalid token; not reachable without a stale/invalid token
            None => panic!("Invalid token"),
            Some(node) => node.is_leaf()
        }
    }

    /// Creates a new node with the given data and append to the given node.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    /// use atree::iter::TraversalOrder;
    ///
    /// let root_data = "Indo-European";
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// let next_node_token = root_token.append(&mut arena, "Germanic");
    /// next_node_token.append(&mut arena, "Romance");
    /// let mut subtree = root_token.subtree(&arena, TraversalOrder::Pre);
    ///
    /// assert_eq!(subtree.next().unwrap().data, "Indo-European");
    /// assert_eq!(subtree.next().unwrap().data, "Germanic");
    /// assert_eq!(subtree.next().unwrap().data, "Romance");
    /// ```
    pub fn append<T>(self, arena: &mut Arena<T>, data: T) -> Token {
        let new_node_token = arena.allocator.head();
        let previous_sibling = match self.children_mut(arena).last() {
            None => {
                // children_mut will have checked indexability so this will not
                // fail
                arena[self].first_child = Some(new_node_token);
                None
            },
            Some(last_child) => {
                last_child.next_sibling = Some(new_node_token);
                Some(last_child.token)
            }
        };

        let node = Node {
            data,
            token: new_node_token,
            parent: Some(self),
            previous_sibling,
            next_sibling: None,
            first_child: None
        };
        arena.set(new_node_token, node);
        new_node_token
    }

    /// Creates a new node with the given data and sets as the previous sibling
    /// of the current node.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    /// use atree::iter::TraversalOrder;
    ///
    /// let root_data = "Indo-European";
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// let child2 = root_token.append(&mut arena, "Germanic");
    /// let child4 = root_token.append(&mut arena, "Slavic");
    /// child2.append(&mut arena, "English");
    /// // insert in between children 2 and 4
    /// let child3 = child4.insert_before(&mut arena, "Romance");
    /// // insert before child 2
    /// let child1 = child2.insert_before(&mut arena, "Celtic");
    ///
    /// let subtree: Vec<_> = root_token.subtree(&arena, TraversalOrder::Pre)
    ///     .map(|x| x.data)
    ///     .collect();
    /// assert_eq!(&["Indo-European", "Celtic", "Germanic", "English", "Romance", "Slavic"],
    ///            &subtree[..]);
    /// ```
    pub fn insert_before<T>(self, arena: &mut Arena<T>, data: T) -> Token {
        let new_node_token = arena.allocator.head();
        let (self_parent, self_previous_sibling) = match arena.get(self) {
            // Dead code: corrupt-arena sentinel; unreachable via public API
            None => panic!("Invalid token"),
            Some(node) => (node.parent, node.previous_sibling)
        };
        arena[self].previous_sibling = Some(new_node_token);  // already checked
        let previous_sibling = match self_previous_sibling {
            Some(sibling) => match arena.get_mut(sibling) {
                // Dead code: corrupt-arena sentinel; unreachable via public API
                None => panic!("Corrupt arena"),
                Some(ref mut node) => {
                    node.next_sibling = Some(new_node_token);
                    Some(sibling)
                }
            },
            None => match self_parent {
                None => panic!("Cannot insert as the previous sibling of the \
                                root node"),
                Some(p) => match arena.get_mut(p) {
                    // Dead code: corrupt-arena sentinel; unreachable via public API
                    None => panic!("Corrupt arena"),
                    Some(ref mut node) => {
                        node.first_child = Some(new_node_token);
                        None
                    }
                }
            }
        };

        let node = Node {
            data,
            token: new_node_token,
            parent: self_parent,
            previous_sibling,
            next_sibling: Some(self),
            first_child: None
        };
        arena.set(new_node_token, node);
        new_node_token
    }

    /// Set a node in the arena as the next sibling of the given node. Returns
    /// error if the "other node" is not a root node of a tree (as in it already
    /// has a parent and/or siblings).
    ///
    /// **Note**: for performance reasons, this operation does not check whether
    /// the "self" node is in fact a descendant of the other tree. A cyclic
    /// graph may result.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    /// ```
    /// use atree::Arena;
    /// use atree::iter::TraversalOrder;
    ///
    /// // root node that we will attach subtrees to
    /// let root_data = "Indo-European";
    /// let (mut arena, root) = Arena::with_data(root_data);
    ///
    /// let germanic = root.append(&mut arena, "Germanic");
    /// let scots = germanic.append(&mut arena, "German");
    /// let english = germanic.append(&mut arena, "English");
    ///
    /// let romance = arena.new_node("Romance");
    /// let french = romance.append(&mut arena, "French");
    /// let spanish = romance.append(&mut arena, "Spanish");
    ///
    /// germanic.insert_node_after(&mut arena, romance);
    ///
    /// let mut iter = root.subtree(&arena, TraversalOrder::Pre)
    ///     .map(|x| x.data);
    /// assert_eq!(iter.next(), Some("Indo-European"));
    /// assert_eq!(iter.next(), Some("Germanic"));
    /// assert_eq!(iter.next(), Some("German"));
    /// assert_eq!(iter.next(), Some("English"));
    /// assert_eq!(iter.next(), Some("Romance"));
    /// assert_eq!(iter.next(), Some("French"));
    /// assert_eq!(iter.next(), Some("Spanish"));
    /// assert!(iter.next().is_none())
    /// ```
    pub fn insert_node_after<T>(self, arena: &mut Arena<T>, other: Token)
        -> Result<(), Error> {
        // Panics if the arena is corrupt; unreachable via public API
        let self_node = arena.get(self).expect("Invalid token");
        let parent = self_node.parent;
        let next_sibling = self_node.next_sibling;

        let other_node = arena.get_mut(other).expect("Invalid token");

        // check that the other node is really a root node of its own
        match (other_node.previous_sibling,
               other_node.next_sibling,
               other_node.parent) {
            (None, None, None) => (),
            _ => return Err(Error::NotARootNode)
        }

        // Update other's pointers
        other_node.parent = parent;
        other_node.previous_sibling = Some(self);
        other_node.next_sibling = next_sibling;

        // Update self's next_sibling. Indexability has been checked
        arena[self].next_sibling = Some(other);

        // Update the next sibling's previous_sibling
        if let Some(next) = next_sibling {
            let orig_next_node = arena.get_mut(next).expect("Corrupt arena");
            orig_next_node.previous_sibling = Some(other);
        }

        Ok(())
    }

    /// Set a node in the arena as the previous sibling of the given node.
    /// Returns error if the "other node" is not a root node of a tree (as in it
    /// already has a parent and/or siblings).
    ///
    /// **Note**: for performance reasons, this operation does not check whether
    /// the "self" node is in fact a descendant of the other tree. A cyclic
    /// graph may result.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    /// ```
    /// use atree::Arena;
    /// use atree::iter::TraversalOrder;
    ///
    /// // root node that we will attach subtrees to
    /// let root_data = "Indo-European";
    /// let (mut arena, root) = Arena::with_data(root_data);
    ///
    /// let germanic = root.append(&mut arena, "Germanic");
    /// let scots = germanic.append(&mut arena, "German");
    /// let english = germanic.append(&mut arena, "English");
    ///
    /// let romance = arena.new_node("Romance");
    /// let french = romance.append(&mut arena, "French");
    /// let spanish = romance.append(&mut arena, "Spanish");
    ///
    /// germanic.insert_node_before(&mut arena, romance);
    ///
    /// let mut iter = root.subtree(&arena, TraversalOrder::Pre)
    ///     .map(|x| x.data);
    /// assert_eq!(iter.next(), Some("Indo-European"));
    /// assert_eq!(iter.next(), Some("Romance"));
    /// assert_eq!(iter.next(), Some("French"));
    /// assert_eq!(iter.next(), Some("Spanish"));
    /// assert_eq!(iter.next(), Some("Germanic"));
    /// assert_eq!(iter.next(), Some("German"));
    /// assert_eq!(iter.next(), Some("English"));
    /// assert!(iter.next().is_none())
    /// ```
    pub fn insert_node_before<T>(self, arena: &mut Arena<T>, other: Token)
        -> Result<(), Error> {
        // Panics if the arena is corrupt; unreachable via public API
        let self_node = arena.get(self).expect("Invalid token");
        let parent = self_node.parent;
        let previous_sibling = self_node.previous_sibling;

        let other_node = arena.get_mut(other).expect("Invalid token");

        // check that the other node is really a root node of its own
        match (other_node.previous_sibling,
               other_node.next_sibling,
               other_node.parent) {
            (None, None, None) => (),
            _ => return Err(Error::NotARootNode)
        }

        // Update other's pointers
        other_node.parent = parent;
        other_node.previous_sibling = previous_sibling;
        other_node.next_sibling = Some(self);

        // Update self's previous_sibling. Indexability has been checked
        arena[self].previous_sibling = Some(other);

        // Update the previous sibling or parent's first_child
        match previous_sibling {
            Some(prev) => {
                let p = arena.get_mut(prev).expect("Corrupt arena");
                p.next_sibling = Some(other)
            },
            None => if let Some(pt) = parent {
                let p = arena.get_mut(pt).expect("Corrupt arena");
                p.first_child = Some(other);
            }
        }

        Ok(())
    }

    /// Creates a new node with the given data and sets as the next sibling of
    /// the current node.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    /// use atree::iter::TraversalOrder;
    ///
    /// let root_data = "Indo-European";
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// let child1 = root_token.append(&mut arena, "Romance");
    /// let child3 = root_token.append(&mut arena, "Germanic");
    /// child1.append(&mut arena, "French");
    /// // insert betwern children 1 and 4
    /// let child2 = child1.insert_after(&mut arena, "Celtic");
    /// // insert after child 3
    /// child3.insert_after(&mut arena, "Slavic");
    ///
    /// let subtree: Vec<_> = root_token.subtree(&arena, TraversalOrder::Pre)
    ///     .map(|x| x.data)
    ///     .collect();
    /// assert_eq!(&["Indo-European", "Romance", "French", "Celtic", "Germanic", "Slavic"],
    ///            &subtree[..]);
    /// ```
    pub fn insert_after<T>(self, arena: &mut Arena<T>, data: T) -> Token {
        let new_node_token = arena.allocator.head();
        let (self_parent, self_next_sibling) = match arena.get(self) {
            // Dead code: corrupt-arena sentinel; unreachable via public API
            None => panic!("Invalid token"),
            Some(node) => (node.parent, node.next_sibling)
        };
        arena[self].next_sibling = Some(new_node_token);  // already checked
        let next_sibling = match self_next_sibling {
            None => None,
            Some(sibling) => match arena.get_mut(sibling) {
                // Dead code: corrupt-arena sentinel; unreachable via public API
                None => panic!("Corrupt arena"),
                Some(ref mut node) => {
                    node.previous_sibling = Some(new_node_token);
                    Some(sibling)
                }
            },
        };

        let node = Node {
            data,
            token: new_node_token,
            parent: self_parent,
            previous_sibling: Some(self),
            next_sibling,
            first_child: None
        };
        arena.set(new_node_token, node);
        new_node_token
    }

    /// Attaches a different tree in the arena to a node. Returns error if the
    /// "root node" of the other tree is not really a root node (as in it
    /// already has a parent and/or siblings). To attach a tree from a different
    /// arena, use [`copy_and_append_subtree`] instead.
    ///
    /// **Note**: for performance reasons, this operation does not check whether
    /// the "self" node is in fact a descendant of the other tree. A cyclic
    /// graph may result.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    /// ```
    /// use atree::Arena;
    /// use atree::iter::TraversalOrder;
    ///
    /// // root node that we will attach subtrees to
    /// let root_data = "Indo-European";
    /// let (mut arena, root) = Arena::with_data(root_data);
    ///
    /// // the Germanic branch
    /// let germanic = arena.new_node("Germanic");
    /// let west = germanic.append(&mut arena, "West");
    /// let scots = west.append(&mut arena, "Scots");
    /// let english = west.append(&mut arena, "English");
    ///
    /// // the Romance branch
    /// let romance = arena.new_node("Romance");
    /// let french = romance.append(&mut arena, "French");
    /// let italian = romance.append(&mut arena, "Italian");
    ///
    /// // attach subtrees
    /// root.append_node(&mut arena, romance).unwrap();
    /// root.append_node(&mut arena, germanic).unwrap();
    ///
    /// let mut iter = root.subtree(&arena, TraversalOrder::Pre)
    ///     .map(|x| x.data);
    /// assert_eq!(iter.next(), Some("Indo-European"));
    /// assert_eq!(iter.next(), Some("Romance"));
    /// assert_eq!(iter.next(), Some("French"));
    /// assert_eq!(iter.next(), Some("Italian"));
    /// assert_eq!(iter.next(), Some("Germanic"));
    /// assert_eq!(iter.next(), Some("West"));
    /// assert_eq!(iter.next(), Some("Scots"));
    /// assert_eq!(iter.next(), Some("English"));
    /// assert!(iter.next().is_none())
    /// ```
    ///
    /// [`copy_and_append_subtree`]: struct.Arena.html#method.copy_and_append_subtree
    pub fn append_node<T>(self, arena: &mut Arena<T>, other: Self)
        -> Result<(), Error> {
        // Panics if the arena is corrupt; unreachable via public API
        let other_node = arena.get_mut(other).expect("Invalid token");

        // check that the other node is really a root node of its own
        match (other_node.previous_sibling,
               other_node.next_sibling,
               other_node.parent) {
            (None, None, None) => (),
            _ => return Err(Error::NotARootNode)
        }

        // Get self's last child
        let last_child = self.children(arena).last().map(|c| c.token);

        // Update other's pointers
        let other_node = arena.get_mut(other).expect("Invalid token");
        other_node.parent = Some(self);
        other_node.previous_sibling = last_child;

        // Update self's first_child or last child's next_sibling
        match last_child {
            Some(last) => {
                let l = arena.get_mut(last).expect("Corrupt arena");
                l.next_sibling = Some(other);
            }
            None => {
                arena[self].first_child = Some(other);
            }
        }

        Ok(())
    }

    /// Detaches the given node and its descendants into its own tree while
    /// keeping it in the same arena. To detach and allocate the subtree into its
    /// own arena, use [`split_at`] instead.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    /// ```
    /// use atree::Arena;
    /// use atree::iter::TraversalOrder;
    ///
    /// // root node that we will attach subtrees to
    /// let root_data = "Indo-European";
    /// let (mut arena, root) = Arena::with_data(root_data);
    ///
    /// // the Germanic branch
    /// let germanic = root.append(&mut arena, "Germanic");
    /// let west = germanic.append(&mut arena, "West");
    /// let scots = west.append(&mut arena, "Scots");
    /// let english = west.append(&mut arena, "English");
    ///
    /// // detach the west branch from the main tree
    /// west.detach(&mut arena);
    ///
    /// // the west branch is gone from the original tree
    /// let mut iter = root.subtree(&arena, TraversalOrder::Pre)
    ///     .map(|x| x.data);
    /// assert_eq!(iter.next(), Some("Indo-European"));
    /// assert_eq!(iter.next(), Some("Germanic"));
    /// assert!(iter.next().is_none());
    ///
    /// // it exists on its own
    /// let mut iter = west.subtree(&arena, TraversalOrder::Pre)
    ///     .map(|x| x.data);
    /// assert_eq!(iter.next(), Some("West"));
    /// assert_eq!(iter.next(), Some("Scots"));
    /// assert_eq!(iter.next(), Some("English"));
    /// assert!(iter.next().is_none());
    /// ```
    ///
    /// [`split_at`]: struct.Arena.html#method.split_at
    pub fn detach<T>(self, arena: &mut Arena<T>) {
        let (parent, previous_sibling, next_sibling) = match arena.get_mut(self) {
            // Dead code: corrupt-arena sentinel; unreachable via public API
            None => panic!("Invalid token"),
            Some(node) => {
                let parent = node.parent;
                let previous_sibling = node.previous_sibling;
                let next_sibling = node.next_sibling;
                node.parent = None;
                node.previous_sibling = None;
                node.next_sibling = None;
                (parent, previous_sibling, next_sibling)
            }
        };

        match previous_sibling {
            Some(token) => match arena.get_mut(token) {
                // Dead code: corrupt-arena sentinel; unreachable via public API
                None => panic!("Corrupt arena"),
                Some(node) => node.next_sibling = next_sibling
            },
            None => if let Some(token) = parent {
                match arena.get_mut(token) {
                    // Dead code: corrupt-arena sentinel; unreachable via public API
                    None => panic!("Corrupt arena"),
                    Some(n) => n.first_child = next_sibling
                }
            }
        }

        if let Some(token) = next_sibling {
            match arena.get_mut(token) {
                // Dead code: corrupt-arena sentinel; unreachable via public API
                None => panic!("Corrupt arena"),
                Some(node) => node.previous_sibling = previous_sibling
            }
        }
    }

    /// Replace the subtree of self with the subtree of other. Does not remove
    /// self or its descendants but simply makes it a standalone tree within the
    /// arena.
    ///
    /// **Note**: for performance reasons, this operation does not check whether
    /// the "other" node is in fact a descendant of the parent tree of self. A
    /// cyclic graph may result.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    /// ```
    /// use atree::Arena;
    /// use atree::iter::TraversalOrder;
    ///
    /// // root node that we will attach subtrees to
    /// let root_data = "Indo-European";
    /// let (mut arena, root) = Arena::with_data(root_data);
    ///
    /// // the Germanic branch
    /// let germanic = root.append(&mut arena, "Germanic");
    /// let west = germanic.append(&mut arena, "West");
    /// let scots = west.append(&mut arena, "Scots");
    /// let english = west.append(&mut arena, "English");
    ///
    /// // the slavic branch
    /// let slavic = root.append(&mut arena, "Slavic");
    /// let polish = slavic.append(&mut arena, "Polish");
    /// let russian = slavic.append(&mut arena, "Russian");
    ///
    /// // the Romance branch
    /// let romance = arena.new_node("Romance");
    /// let french = romance.append(&mut arena, "French");
    /// let italian = romance.append(&mut arena, "Italian");
    ///
    /// // replace_node germanic with romance
    /// germanic.replace_node(&mut arena, romance).unwrap();
    ///
    /// let mut iter = root.subtree(&arena, TraversalOrder::Pre)
    ///     .map(|x| x.data);
    /// assert_eq!(iter.next(), Some("Indo-European"));
    /// assert_eq!(iter.next(), Some("Romance"));
    /// assert_eq!(iter.next(), Some("French"));
    /// assert_eq!(iter.next(), Some("Italian"));
    /// assert_eq!(iter.next(), Some("Slavic"));
    /// assert_eq!(iter.next(), Some("Polish"));
    /// assert_eq!(iter.next(), Some("Russian"));
    /// assert!(iter.next().is_none());
    ///
    /// // the germanic tree is still around
    /// let mut iter = germanic.subtree(&arena, TraversalOrder::Pre)
    ///     .map(|x| x.data);
    /// assert_eq!(iter.next(), Some("Germanic"));
    /// assert_eq!(iter.next(), Some("West"));
    /// assert_eq!(iter.next(), Some("Scots"));
    /// assert_eq!(iter.next(), Some("English"));
    /// assert!(iter.next().is_none());
    /// ```
    pub fn replace_node<T>(self, arena: &mut Arena<T>, other: Token)
        -> Result<(), Error> {
        let self_node = match arena.get(self) {
            // Dead code: corrupt-arena sentinel; unreachable via public API
            None => panic!("Invalid token"),
            Some(n) => n
        };
        let parent = self_node.parent;
        let previous_sibling = self_node.previous_sibling;
        let next_sibling = self_node.next_sibling;

        let other_node = match arena.get_mut(other) {
            // Dead code: corrupt-arena sentinel; unreachable via public API
            None => panic!("Invalid token"),
            Some(n) => n
        };

        // check that the other node is really a root node of its own
        match (other_node.previous_sibling,
               other_node.next_sibling,
               other_node.parent) {
            (None, None, None) => (),
            _ => return Err(Error::NotARootNode)
        }

        // replace_node the self node with the other node
        other_node.parent = parent;
        other_node.next_sibling = next_sibling;
        other_node.previous_sibling = previous_sibling;

        let self_node = &mut arena[self];  // indexability has been checked
        self_node.parent = None;
        self_node.previous_sibling = None;
        self_node.next_sibling = None;

        // update previous_sibling, next_sibling and parent of the self node
        match previous_sibling {
            Some(sibling) => match arena.get_mut(sibling) {
                // Dead code: corrupt-arena sentinel; unreachable via public API
                None => panic!("Corrupt arena"),
                Some(node) => node.next_sibling = Some(other)
            },
            None => if let Some(p) = parent {
                match arena.get_mut(p) {
                    // Dead code: corrupt-arena sentinel; unreachable via public API
                    None => panic!("Corrupt arena"),
                    Some(node) => node.first_child = Some(other)
                }
            }
        }

        if let Some(sibling) = next_sibling {
            match arena.get_mut(sibling) {
                // Dead code: corrupt-arena sentinel; unreachable via public API
                None => panic!("Corrupt arena"),
                Some(node) => node.previous_sibling = Some(other)
            }
        }

        Ok(())
    }

    /// Returns an iterator of tokens of ancestor nodes.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    ///
    /// let root_data = "Indo-European";
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// let child_token = root_token.append(&mut arena, "Germanic");
    /// let grandchild_token = child_token.append(&mut arena, "English");
    /// let mut ancestors_tokens = grandchild_token.ancestors_tokens(&arena);
    ///
    /// assert_eq!(ancestors_tokens.next(), Some(child_token));
    /// assert_eq!(ancestors_tokens.next(), Some(root_token));
    /// assert!(ancestors_tokens.next().is_none());
    /// ```
    pub fn ancestors_tokens<'a, T>(self, arena: &'a Arena<T>)
        -> AncestorTokens<'a, T> {
        let parent = match arena.get(self) {
            Some(n) => n.parent,
            // Dead code: documented panic for invalid token; not reachable without a stale/invalid token
            None => panic!("Invalid token")
        };
        AncestorTokens { arena, node_token: parent }
    }

    /// Returns an iterator of tokens of siblings preceding the current node.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    ///
    /// let root_data = "Indo-European";
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// let first_child_token = root_token.append(&mut arena, "Germanic");
    /// let second_child_token = root_token.append(&mut arena, "Romance");
    /// let third_child_token = root_token.append(&mut arena, "Slavic");
    /// root_token.append(&mut arena, "Hellenic");
    ///
    /// let mut sibling_tokens = third_child_token.preceding_siblings_tokens(&arena);
    /// assert_eq!(sibling_tokens.next(), Some(second_child_token));
    /// assert_eq!(sibling_tokens.next(), Some(first_child_token));
    /// assert!(sibling_tokens.next().is_none());
    /// ```
    pub fn preceding_siblings_tokens<'a, T>(self, arena: &'a Arena<T>)
        -> PrecedingSiblingTokens<'a, T> {
        let previous_sibling = match arena.get(self) {
            Some(n) => n.previous_sibling,
            // Dead code: documented panic for invalid token; not reachable without a stale/invalid token
            None => panic!("Invalid token")
        };
        PrecedingSiblingTokens { arena, node_token: previous_sibling }
    }

    /// Returns an iterator of tokens of siblings following the current node.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    ///
    /// let root_data = "Indo-European";
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// root_token.append(&mut arena, "Romance");
    /// let second_child_token = root_token.append(&mut arena, "Germanic");
    /// let third_child_token = root_token.append(&mut arena, "Slavic");
    /// let fourth_child_token = root_token.append(&mut arena, "Hellenic");
    ///
    /// let mut sibling_tokens = second_child_token.following_siblings_tokens(&arena);
    /// assert_eq!(sibling_tokens.next(), Some(third_child_token));
    /// assert_eq!(sibling_tokens.next(), Some(fourth_child_token));
    /// assert!(sibling_tokens.next().is_none());
    /// ```
    pub fn following_siblings_tokens<'a, T>(self, arena: &'a Arena<T>)
        -> FollowingSiblingTokens<'a, T> {
        let next_sibling = match arena.get(self) {
            Some(n) => n.next_sibling,
            // Dead code: documented panic for invalid token; not reachable without a stale/invalid token
            None => panic!("Invalid token")
        };
        FollowingSiblingTokens { arena, node_token: next_sibling }
    }

    /// Returns an iterator of tokens of child nodes in the order of insertion.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    ///
    /// let root_data = "Indo-European";
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// let first_child_token = root_token.append(&mut arena, "Romance");
    /// let second_child_token = root_token.append(&mut arena, "Germanic");
    /// let third_child_token = root_token.append(&mut arena, "Slavic");
    /// let fourth_child_token = root_token.append(&mut arena, "Hellenic");
    ///
    /// let mut children_tokens = root_token.children_tokens(&arena);
    /// assert_eq!(children_tokens.next(), Some(first_child_token));
    /// assert_eq!(children_tokens.next(), Some(second_child_token));
    /// assert_eq!(children_tokens.next(), Some(third_child_token));
    /// assert_eq!(children_tokens.next(), Some(fourth_child_token));
    /// assert!(children_tokens.next().is_none());
    /// ```
    pub fn children_tokens<'a, T>(self, arena: &'a Arena<T>)
        -> ChildrenTokens<'a, T> {
        let first_child = match arena.get(self) {
            Some(n) => n.first_child,
            // Dead code: documented panic for invalid token; not reachable without a stale/invalid token
            None => panic!("Invalid token")
        };
        ChildrenTokens { arena, node_token: first_child }
    }

    /// Returns an iterator of references of ancestor nodes.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    ///
    /// let root_data = "Indo-European";
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// let child_token = root_token.append(&mut arena, "Germanic");
    /// let grandchild_token = child_token.append(&mut arena, "Swedish");
    /// let mut ancestors = grandchild_token.ancestors(&arena);
    ///
    /// assert_eq!(ancestors.next().unwrap().data, "Germanic");
    /// assert_eq!(ancestors.next().unwrap().data, "Indo-European");
    /// assert!(ancestors.next().is_none());
    /// ```
    pub fn ancestors<'a, T>(self, arena: &'a Arena<T>) -> Ancestors<'a, T> {
        Ancestors { token_iter: self.ancestors_tokens(arena) }
    }

    /// Returns an iterator of references of sibling nodes preceding the current
    /// node.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    ///
    /// let root_data = "Indo-European";
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// root_token.append(&mut arena, "Romance");
    /// root_token.append(&mut arena, "Germanic");
    /// let third_child_token = root_token.append(&mut arena, "Slavic");
    /// root_token.append(&mut arena, "Celtic");
    ///
    /// let mut siblings = third_child_token.preceding_siblings(&arena);
    /// assert_eq!(siblings.next().unwrap().data, "Germanic");
    /// assert_eq!(siblings.next().unwrap().data, "Romance");
    /// assert!(siblings.next().is_none());
    /// ```
    pub fn preceding_siblings<'a, T>(self, arena: &'a Arena<T>)
        -> PrecedingSiblings<'a, T> {
        PrecedingSiblings { token_iter: self.preceding_siblings_tokens(arena) }
    }

    /// Returns an iterator of references of sibling nodes following the current
    /// node.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    ///
    /// let root_data = "Indo-European";
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// root_token.append(&mut arena, "Romance");
    /// let second_child_token = root_token.append(&mut arena, "Germanic");
    /// root_token.append(&mut arena, "Slavic");
    /// root_token.append(&mut arena, "Hellenic");
    ///
    /// let mut siblings = second_child_token.following_siblings(&arena);
    /// assert_eq!(siblings.next().unwrap().data, "Slavic");
    /// assert_eq!(siblings.next().unwrap().data, "Hellenic");
    /// assert!(siblings.next().is_none());
    /// ```
    pub fn following_siblings<'a, T>(self, arena: &'a Arena<T>)
        -> FollowingSiblings<'a, T> {
        FollowingSiblings { token_iter: self.following_siblings_tokens(arena) }
    }

    /// Returns an iterator of child node references in the order of insertion.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    ///
    /// let root_data = "Indo-European";
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// let first_child_token = root_token.append(&mut arena, "Germanic");
    /// let second_child_token = root_token.append(&mut arena, "Romance");
    /// let third_child_token = root_token.append(&mut arena, "Slavic");
    /// let fourth_child_token = root_token.append(&mut arena, "Celtic");
    ///
    /// let mut children = root_token.children(&arena);
    /// assert_eq!(children.next().unwrap().data, "Germanic");
    /// assert_eq!(children.next().unwrap().data, "Romance");
    /// assert_eq!(children.next().unwrap().data, "Slavic");
    /// assert_eq!(children.next().unwrap().data, "Celtic");
    /// assert!(children.next().is_none());
    /// ```
    pub fn children<'a, T>(self, arena: &'a Arena<T>) -> Children<'a, T> {
        Children { token_iter: self.children_tokens(arena) }
    }

    /// Returns an iterator of mutable ancestor node references.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    ///
    /// let root_data = 1usize;
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// let child_token = root_token.append(&mut arena, 2usize);
    /// let grandchild_token = child_token.append(&mut arena, 3usize);
    /// let great_grandchild_token = grandchild_token.append(&mut arena, 4usize);
    /// let ggreat_grandchild_token = great_grandchild_token.append(&mut arena, 5usize);
    ///
    /// for x in ggreat_grandchild_token.ancestors_mut(&mut arena) {
    ///     x.data += 2;
    /// }
    ///
    /// let mut ancestors = ggreat_grandchild_token.ancestors(&arena);
    /// assert_eq!(ancestors.next().unwrap().data, 6usize);
    /// assert_eq!(ancestors.next().unwrap().data, 5usize);
    /// assert_eq!(ancestors.next().unwrap().data, 4usize);
    /// assert_eq!(ancestors.next().unwrap().data, 3usize);
    /// assert!(ancestors.next().is_none());
    /// ```
    pub fn ancestors_mut<'a, T>(self, arena: &'a mut Arena<T>)
        -> AncestorsMut<'a, T> {
        AncestorsMut {
            arena: arena as *mut Arena<T>,
            node_token: Some(self),
            marker: PhantomData
        }
    }

    /// Returns an iterator of mutable references of sibling nodes that follow
    /// the current node.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    ///
    /// let root_data = 1usize;
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// root_token.append(&mut arena, 2usize);
    /// let second_child_token = root_token.append(&mut arena, 3usize);
    /// root_token.append(&mut arena, 4usize);
    /// root_token.append(&mut arena, 5usize);
    ///
    /// for x in second_child_token.following_siblings_mut(&mut arena) {
    ///     x.data += 2;
    /// }
    ///
    /// let mut children = root_token.children(&arena);
    /// assert_eq!(children.next().unwrap().data, 2usize);
    /// assert_eq!(children.next().unwrap().data, 3usize);
    /// assert_eq!(children.next().unwrap().data, 6usize);
    /// assert_eq!(children.next().unwrap().data, 7usize);
    /// assert!(children.next().is_none());
    /// ```
    pub fn following_siblings_mut<'a, T>(self, arena: &'a mut Arena<T>)
        -> FollowingSiblingsMut<'a, T> {
        let next_sibling = match arena.get(self) {
            Some(n) => n.next_sibling,
            // Dead code: documented panic for invalid token; not reachable without a stale/invalid token
            None => panic!("Invalid token")
        };
        FollowingSiblingsMut {
            arena: arena as *mut Arena<T>,
            node_token: next_sibling,
            marker: PhantomData
        }
    }

    /// Returns an iterator of mutable references of sibling nodes that precede
    /// the current node.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    ///
    /// let root_data = 1usize;
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// root_token.append(&mut arena, 2usize);
    /// root_token.append(&mut arena, 3usize);
    /// root_token.append(&mut arena, 4usize);
    /// let fourth_child_token = root_token.append(&mut arena, 5usize);
    ///
    /// for x in fourth_child_token.preceding_siblings_mut(&mut arena) {
    ///     x.data += 5;
    /// }
    ///
    /// let mut children = root_token.children(&arena);
    /// assert_eq!(children.next().unwrap().data, 7usize);
    /// assert_eq!(children.next().unwrap().data, 8usize);
    /// assert_eq!(children.next().unwrap().data, 9usize);
    /// assert_eq!(children.next().unwrap().data, 5usize);
    /// assert!(children.next().is_none());
    /// ```
    pub fn preceding_siblings_mut<'a, T>(self, arena: &'a mut Arena<T>)
        -> PrecedingSiblingsMut<'a, T> {
        let previous_sibling = match arena.get(self) {
            Some(n) => n.previous_sibling,
            // Dead code: documented panic for invalid token; not reachable without a stale/invalid token
            None => panic!("Invalid token")
        };
        PrecedingSiblingsMut {
            arena: arena as *mut Arena<T>,
            node_token: previous_sibling,
            marker: PhantomData
        }
    }

    /// Returns an iterator of mutable references of child nodes in the order of
    /// insertion.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    ///
    /// let root_data = 1usize;
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// root_token.append(&mut arena, 2usize);
    /// root_token.append(&mut arena, 3usize);
    /// let third_child_token = root_token.append(&mut arena, 4usize);
    /// root_token.append(&mut arena, 5usize);
    /// let grandchild = third_child_token.append(&mut arena, 10usize);
    ///
    /// for x in root_token.children_mut(&mut arena) {
    ///     x.data += 10;
    /// }
    ///
    /// let mut children = root_token.children(&arena);
    /// assert_eq!(children.next().unwrap().data, 12);
    /// assert_eq!(children.next().unwrap().data, 13);
    /// assert_eq!(children.next().unwrap().data, 14);
    /// assert_eq!(children.next().unwrap().data, 15);
    /// assert_eq!(arena.get(grandchild).unwrap().data, 10);
    /// assert!(children.next().is_none());
    /// ```
    pub fn children_mut<'a, T>(self, arena: &'a mut Arena<T>)
        -> ChildrenMut<'a, T> {
        let first_child = match arena.get(self) {
            Some(n) => n.first_child,
            // Dead code: documented panic for invalid token; not reachable without a stale/invalid token
            None => panic!("Invalid token")
        };
        ChildrenMut {
            arena: arena as *mut Arena<T>,
            node_token: first_child,
            marker: PhantomData
        }
    }

    /// Returns an iterator of tokens of subtree nodes of the given node.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    /// use atree::iter::TraversalOrder;
    ///
    /// let root_data = "Indo-European";
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// let first_child = root_token.append(&mut arena, "Romance");
    /// let second_child = root_token.append(&mut arena, "Germanic");
    /// let third_child = root_token.append(&mut arena, "Slavic");
    /// let first_grandchild = second_child.append(&mut arena, "English");
    /// let second_grandchild = second_child.append(&mut arena, "Icelandic");
    /// let fourth_child = root_token.append(&mut arena, "Celtic");
    ///
    /// let mut subtree = root_token.subtree_tokens(&arena, TraversalOrder::Pre);
    /// assert_eq!(subtree.next(), Some(root_token));
    /// assert_eq!(subtree.next(), Some(first_child));
    /// assert_eq!(subtree.next(), Some(second_child));
    /// assert_eq!(subtree.next(), Some(first_grandchild));
    /// assert_eq!(subtree.next(), Some(second_grandchild));
    /// assert_eq!(subtree.next(), Some(third_child));
    /// assert_eq!(subtree.next(), Some(fourth_child));
    /// assert!(subtree.next().is_none());
    ///
    /// let mut subtree = second_grandchild.subtree_tokens(&arena, TraversalOrder::Pre);
    /// assert_eq!(subtree.next(), Some(second_grandchild));
    /// assert!(subtree.next().is_none());
    /// ```
    pub fn subtree_tokens<'a, T>(self, arena: &'a Arena<T>, order: TraversalOrder)
        -> SubtreeTokens<'a, T> {
        let preord_tokens_next = |iter: &mut SubtreeTokens<T>|
            depth_first_tokens_next(iter, preorder_next);
        let postord_tokens_next = |iter: &mut SubtreeTokens<T>|
            depth_first_tokens_next(iter, postorder_next);
        match order {
            TraversalOrder::Pre => SubtreeTokens {
                arena,
                subtree_root: self,
                node_token: Some(self),
                branch: Branch::Child,
                curr_level: VecDeque::new(),  // unused field
                next_level: VecDeque::new(),  // unused field
                next: preord_tokens_next
            },
            TraversalOrder::Post => {
                let (node_token, branch) =
                    postorder_next(self, self, Branch::Child, arena);
                SubtreeTokens {
                    arena,
                    subtree_root: self,
                    node_token,
                    branch,
                    curr_level: VecDeque::new(),  // unused field
                    next_level: VecDeque::new(),  // unused field
                    next: postord_tokens_next
                }
            },
            TraversalOrder::Level => {
                SubtreeTokens {
                    arena,
                    subtree_root: self,  // unused field
                    node_token: None,  // unused field
                    branch: Branch::None,  // unused field
                    curr_level: std::iter::once(self).collect(),
                    next_level: VecDeque::new(),
                    next: breadth_first_tokens_next
                }
            }
        }
    }

    /// Returns an iterator of references of subtree nodes of the given node.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    /// use atree::iter::TraversalOrder;
    ///
    /// let root_data = "Indo-European";
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// root_token.append(&mut arena, "Romance");
    /// root_token.append(&mut arena, "Germanic");
    /// let third_child = root_token.append(&mut arena, "Slavic");
    /// root_token.append(&mut arena, "Celtic");
    /// third_child.append(&mut arena, "Polish");
    /// third_child.append(&mut arena, "Slovakian");
    ///
    /// let mut subtree = root_token.subtree(&arena, TraversalOrder::Pre);
    /// assert_eq!(subtree.next().unwrap().data, "Indo-European");
    /// assert_eq!(subtree.next().unwrap().data, "Romance");
    /// assert_eq!(subtree.next().unwrap().data, "Germanic");
    /// assert_eq!(subtree.next().unwrap().data, "Slavic");
    /// assert_eq!(subtree.next().unwrap().data, "Polish");
    /// assert_eq!(subtree.next().unwrap().data, "Slovakian");
    /// assert_eq!(subtree.next().unwrap().data, "Celtic");
    /// assert!(subtree.next().is_none());
    /// ```
    pub fn subtree<'a, T>(self, arena: &'a Arena<T>, order: TraversalOrder)
        -> Subtree<'a, T> {
        Subtree {
            arena,
            iter: self.subtree_tokens(arena, order)
        }
    }

    /// Returns an iterator of mutable references of subtree nodes of the given
    /// node.
    ///
    /// # Panics:
    ///
    /// Panics if the token does not correspond to a node in the arena.
    ///
    /// # Examples:
    ///
    /// ```
    /// use atree::Arena;
    /// use atree::iter::TraversalOrder;
    ///
    /// let root_data = 1usize;
    /// let (mut arena, root_token) = Arena::with_data(root_data);
    ///
    /// root_token.append(&mut arena, 2usize);
    /// root_token.append(&mut arena, 3usize);
    /// let third_child = root_token.append(&mut arena, 4usize);
    /// root_token.append(&mut arena, 5usize);
    /// third_child.append(&mut arena, 10usize);
    /// third_child.append(&mut arena, 20usize);
    ///
    /// for x in root_token.subtree_mut(&mut arena, TraversalOrder::Pre) {
    ///     x.data += 100;
    /// }
    ///
    /// let mut subtree = root_token.subtree(&arena, TraversalOrder::Pre);
    /// assert_eq!(subtree.next().unwrap().data, 101);
    /// assert_eq!(subtree.next().unwrap().data, 102);
    /// assert_eq!(subtree.next().unwrap().data, 103);
    /// assert_eq!(subtree.next().unwrap().data, 104);
    /// assert_eq!(subtree.next().unwrap().data, 110);
    /// assert_eq!(subtree.next().unwrap().data, 120);
    /// assert_eq!(subtree.next().unwrap().data, 105);
    /// assert!(subtree.next().is_none());
    /// ```
    pub fn subtree_mut<'a, T>(self, arena: &'a mut Arena<T>, order: TraversalOrder)
        -> SubtreeMut<'a, T> {
        SubtreeMut {
            arena: arena as *mut Arena<T>,
            iter: self.subtree_tokens(arena, order),
            marker: PhantomData
        }
    }

    /// Removes all descendants of the current node.
    pub (crate) fn remove_descendants<T>(self, arena: &mut Arena<T>) {
        // This will not silently fail since postorder_next will panic if self
        // isn't valid.  This won't do anything if self has no descendants, but
        // that's the intended behavior.
        if let (Some(mut token), mut branch) =
            postorder_next(self, self, Branch::Child, arena) {
            while branch != Branch::None {
                let (t, b) = postorder_next(token, self, branch, arena);
                arena.allocator.remove(token);  // should not fail (not here anyway)
                token = t.unwrap();
                branch = b;
            }
            arena[self].first_child = None;
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    #[allow(clippy::cognitive_complexity)]
    fn replace_node() {
        // root node that we will attach subtrees to
        let root_data = "Indo-European";
        let (mut arena, root) = Arena::with_data(root_data);

        // the Germanic branch
        let germanic = root.append(&mut arena, "Germanic");
        let west = germanic.append(&mut arena, "West");
        west.append(&mut arena, "Scots");
        west.append(&mut arena, "English");

        // the slavic branch
        let slavic = root.append(&mut arena, "Slavic");
        slavic.append(&mut arena, "Polish");
        slavic.append(&mut arena, "Russian");

        let mut iter = root.subtree(&arena, TraversalOrder::Pre)
            .map(|x| x.data);
        assert_eq!(iter.next(), Some("Indo-European"));
        assert_eq!(iter.next(), Some("Germanic"));
        assert_eq!(iter.next(), Some("West"));
        assert_eq!(iter.next(), Some("Scots"));
        assert_eq!(iter.next(), Some("English"));
        assert_eq!(iter.next(), Some("Slavic"));
        assert_eq!(iter.next(), Some("Polish"));
        assert_eq!(iter.next(), Some("Russian"));
        assert!(iter.next().is_none());

        // the Romance branch
        let romance = arena.new_node("Romance");
        romance.append(&mut arena, "French");
        romance.append(&mut arena, "Italian");

        // replace_node germanic with romance
        germanic.replace_node(&mut arena, romance).unwrap();

        let mut iter = root.subtree(&arena, TraversalOrder::Pre)
            .map(|x| x.data);
        assert_eq!(iter.next(), Some("Indo-European"));
        assert_eq!(iter.next(), Some("Romance"));
        assert_eq!(iter.next(), Some("French"));
        assert_eq!(iter.next(), Some("Italian"));
        assert_eq!(iter.next(), Some("Slavic"));
        assert_eq!(iter.next(), Some("Polish"));
        assert_eq!(iter.next(), Some("Russian"));
        assert!(iter.next().is_none());

        // How about the other way around (replacing the slavic branch instead
        slavic.replace_node(&mut arena, germanic).unwrap();

        let mut iter = root.subtree(&arena, TraversalOrder::Pre)
            .map(|x| x.data);
        assert_eq!(iter.next(), Some("Indo-European"));
        assert_eq!(iter.next(), Some("Romance"));
        assert_eq!(iter.next(), Some("French"));
        assert_eq!(iter.next(), Some("Italian"));
        assert_eq!(iter.next(), Some("Germanic"));
        assert_eq!(iter.next(), Some("West"));
        assert_eq!(iter.next(), Some("Scots"));
        assert_eq!(iter.next(), Some("English"));
        assert!(iter.next().is_none());
    }

    #[test]
    /// Test that NonZeroUsize as T won't be UB
    fn nonzerousize_t_soundness() {
        use core::num::NonZeroUsize;
        let (mut arena, root) = Arena::<NonZeroUsize>::with_data(NonZeroUsize::new(1).unwrap());
        let other = root.append(&mut arena, NonZeroUsize::new(2).unwrap());
        let _ = root.insert_node_after(&mut arena, other);

        let mut iter = root.subtree(&arena, TraversalOrder::Pre)
            .map(|x| x.data);
        assert_eq!(iter.next(), NonZeroUsize::new(1));
        assert_eq!(iter.next(), NonZeroUsize::new(2));
        assert!(iter.next().is_none());
    }

    #[test]
    fn subtree_tokens_postord() {
        let root_data = 1usize;
        let (mut arena, root_token) = Arena::with_data(root_data);

        let first_child = root_token.append(&mut arena, 2usize);
        let second_child = root_token.append(&mut arena, 3usize);
        let third_child = root_token.append(&mut arena, 4usize);
        let first_grandchild = first_child.append(&mut arena, 0usize);
        let fourth_child = root_token.append(&mut arena, 5usize);
        let second_grandchild = second_child.append(&mut arena, 10usize);
        let third_grandchild = second_child.append(&mut arena, 20usize);
        let great_grandchild = third_grandchild.append(&mut arena, 20usize);

        let mut subtree = root_token.subtree_tokens(&arena, TraversalOrder::Post);
        assert_eq!(subtree.next(), Some(first_grandchild));
        assert_eq!(subtree.next(), Some(first_child));
        assert_eq!(subtree.next(), Some(second_grandchild));
        assert_eq!(subtree.next(), Some(great_grandchild));
        assert_eq!(subtree.next(), Some(third_grandchild));
        assert_eq!(subtree.next(), Some(second_child));
        assert_eq!(subtree.next(), Some(third_child));
        assert_eq!(subtree.next(), Some(fourth_child));
        assert_eq!(subtree.next(), Some(root_token));
        assert!(subtree.next().is_none());

        let mut subtree = great_grandchild.subtree_tokens(&arena, TraversalOrder::Post);
        assert_eq!(subtree.next(), Some(great_grandchild));
        assert!(subtree.next().is_none());
    }

    #[test]
    fn subtree_tokens_levelord() {
        let root_data = 1usize;
        let (mut arena, root_token) = Arena::with_data(root_data);

        let first_child = root_token.append(&mut arena, 2usize);
        let second_child = root_token.append(&mut arena, 3usize);
        let third_child = root_token.append(&mut arena, 4usize);
        let first_grandchild = second_child.append(&mut arena, 10usize);
        let second_grandchild = second_child.append(&mut arena, 20usize);
        let fourth_child = root_token.append(&mut arena, 5usize);

        let mut subtree = root_token.subtree_tokens(&arena, TraversalOrder::Level);
        assert_eq!(subtree.next(), Some(root_token));
        assert_eq!(subtree.next(), Some(first_child));
        assert_eq!(subtree.next(), Some(second_child));
        assert_eq!(subtree.next(), Some(third_child));
        assert_eq!(subtree.next(), Some(fourth_child));
        assert_eq!(subtree.next(), Some(first_grandchild));
        assert_eq!(subtree.next(), Some(second_grandchild));
        assert!(subtree.next().is_none());

        let mut subtree = second_grandchild.subtree_tokens(&arena, TraversalOrder::Level);
        assert_eq!(subtree.next(), Some(second_grandchild));
        assert!(subtree.next().is_none());
    }

    #[test]
    fn subtree_postord() {
        let root_data = "Indo-European";
        let (mut arena, root_token) = Arena::with_data(root_data);

        root_token.append(&mut arena, "Romance");
        root_token.append(&mut arena, "Germanic");
        let third_child = root_token.append(&mut arena, "Celtic");
        root_token.append(&mut arena, "Slavic");
        third_child.append(&mut arena, "Ulster");
        third_child.append(&mut arena, "Gaulish");

        let mut subtree = root_token.subtree(&arena, TraversalOrder::Post);
        assert_eq!(subtree.next().unwrap().data, "Romance");
        assert_eq!(subtree.next().unwrap().data, "Germanic");
        assert_eq!(subtree.next().unwrap().data, "Ulster");
        assert_eq!(subtree.next().unwrap().data, "Gaulish");
        assert_eq!(subtree.next().unwrap().data, "Celtic");
        assert_eq!(subtree.next().unwrap().data, "Slavic");
        assert_eq!(subtree.next().unwrap().data, "Indo-European");
        assert!(subtree.next().is_none());
    }

    #[test]
    fn subtree_levelord() {
        let root_data = "Indo-European";
        let (mut arena, root_token) = Arena::with_data(root_data);

        root_token.append(&mut arena, "Romance");
        root_token.append(&mut arena, "Germanic");
        let third_child = root_token.append(&mut arena, "Slavic");
        root_token.append(&mut arena, "Hellenic");
        third_child.append(&mut arena, "Russian");
        third_child.append(&mut arena, "Ukrainian");

        let mut subtree = root_token.subtree(&arena, TraversalOrder::Level);
        assert_eq!(subtree.next().unwrap().data, "Indo-European");
        assert_eq!(subtree.next().unwrap().data, "Romance");
        assert_eq!(subtree.next().unwrap().data, "Germanic");
        assert_eq!(subtree.next().unwrap().data, "Slavic");
        assert_eq!(subtree.next().unwrap().data, "Hellenic");
        assert_eq!(subtree.next().unwrap().data, "Russian");
        assert_eq!(subtree.next().unwrap().data, "Ukrainian");
        assert!(subtree.next().is_none());
    }

    #[test]
    fn subtree_postord_mut() {
        let root_data = 1usize;
        let (mut arena, root_token) = Arena::with_data(root_data);

        root_token.append(&mut arena, 2usize);
        root_token.append(&mut arena, 3usize);
        let third_child = root_token.append(&mut arena, 4usize);
        root_token.append(&mut arena, 5usize);
        third_child.append(&mut arena, 10usize);
        third_child.append(&mut arena, 20usize);

        for x in root_token.subtree_mut(&mut arena, TraversalOrder::Post) {
            x.data += 100;
        }

        let mut subtree = root_token.subtree(&arena, TraversalOrder::Post);
        assert_eq!(subtree.next().unwrap().data, 102);
        assert_eq!(subtree.next().unwrap().data, 103);
        assert_eq!(subtree.next().unwrap().data, 110);
        assert_eq!(subtree.next().unwrap().data, 120);
        assert_eq!(subtree.next().unwrap().data, 104);
        assert_eq!(subtree.next().unwrap().data, 105);
        assert_eq!(subtree.next().unwrap().data, 101);
        assert!(subtree.next().is_none());
    }

    #[test]
    fn subtree_levelord_mut() {
        let root_data = 1usize;
        let (mut arena, root_token) = Arena::with_data(root_data);

        root_token.append(&mut arena, 2usize);
        root_token.append(&mut arena, 3usize);
        let third_child = root_token.append(&mut arena, 4usize);
        root_token.append(&mut arena, 5usize);
        third_child.append(&mut arena, 10usize);
        third_child.append(&mut arena, 20usize);

        for x in root_token.subtree_mut(&mut arena, TraversalOrder::Level) {
            x.data += 100;
        }

        let mut subtree = root_token.subtree(&arena, TraversalOrder::Level);
        assert_eq!(subtree.next().unwrap().data, 101);
        assert_eq!(subtree.next().unwrap().data, 102);
        assert_eq!(subtree.next().unwrap().data, 103);
        assert_eq!(subtree.next().unwrap().data, 104);
        assert_eq!(subtree.next().unwrap().data, 105);
        assert_eq!(subtree.next().unwrap().data, 110);
        assert_eq!(subtree.next().unwrap().data, 120);
        assert!(subtree.next().is_none());
    }

    #[test]
    fn remove_descendants() {
        let root_data = 1usize;
        let (mut arena, root_token) = Arena::with_data(root_data);

        let first_child = root_token.append(&mut arena, 2usize);
        let second_child = root_token.append(&mut arena, 3usize);
        let third_child = root_token.append(&mut arena, 4usize);
        let fourth_child = root_token.append(&mut arena, 5usize);
        let grandchild_1 = third_child.append(&mut arena, 10usize);
        third_child.append(&mut arena, 20usize);
        grandchild_1.append(&mut arena, 100usize);

        assert_eq!(arena.node_count(), 8);

        third_child.remove_descendants(&mut arena);

        let mut subtree = root_token.subtree_tokens(&arena, TraversalOrder::Pre);
        assert_eq!(subtree.next(), Some(root_token));
        assert_eq!(subtree.next(), Some(first_child));
        assert_eq!(subtree.next(), Some(second_child));
        assert_eq!(subtree.next(), Some(third_child));
        assert_eq!(subtree.next(), Some(fourth_child));
        assert!(subtree.next().is_none());

        println!("{:?}", arena.allocator);
        assert_eq!(arena.node_count(), 5);
    }

    #[test]
    fn is_leaf_true() {
        let (mut arena, root) = Arena::with_data(1usize);
        let child = root.append(&mut arena, 2usize);
        assert!(child.is_leaf(&arena));
    }

    #[test]
    fn is_leaf_false() {
        let (mut arena, root) = Arena::with_data(1usize);
        root.append(&mut arena, 2usize);
        assert!(!root.is_leaf(&arena));
    }

    #[test]
    fn replace_node_error_not_a_root_node() {
        let (mut arena, root) = Arena::with_data(1usize);
        let child = root.append(&mut arena, 2usize);
        let sibling = root.append(&mut arena, 3usize);
        // `child` already has a parent, so it's not a root node
        let result = sibling.replace_node(&mut arena, child);
        assert!(matches!(result, Err(Error::NotARootNode)));
    }

    #[test]
    fn insert_node_after_with_next_sibling_updates_sibling_chain() {
        let (mut arena, root) = Arena::with_data(0usize);
        let a = root.append(&mut arena, 1usize);
        let b = root.append(&mut arena, 2usize);
        let c = arena.new_node(3usize);
        // insert c between a and b
        assert!(a.insert_node_after(&mut arena, c).is_ok());
        assert_eq!(arena[a].next_sibling, Some(c));
        assert_eq!(arena[c].next_sibling, Some(b));
        assert_eq!(arena[b].previous_sibling, Some(c));
        assert_eq!(arena[c].previous_sibling, Some(a));
        assert_eq!(arena[c].parent, Some(root));
    }

    #[test]
    fn insert_node_before_inserts_between_siblings() {
        let (mut arena, root) = Arena::with_data(0usize);
        let a = root.append(&mut arena, 1usize);
        let b = root.append(&mut arena, 2usize);
        let c = arena.new_node(3usize);
        // insert c between a and b
        assert!(b.insert_node_before(&mut arena, c).is_ok());
        assert_eq!(arena[a].next_sibling, Some(c));
        assert_eq!(arena[c].previous_sibling, Some(a));
        assert_eq!(arena[c].next_sibling, Some(b));
        assert_eq!(arena[b].previous_sibling, Some(c));
        assert_eq!(arena[c].parent, Some(root));
    }

    #[test]
    fn insert_node_before_returns_not_a_root_node_error() {
        let (mut arena, root) = Arena::with_data(0usize);
        let a = root.append(&mut arena, 1usize);
        // `a` already has a parent, so it's not a root node
        let result = root.insert_node_before(&mut arena, a);
        assert!(matches!(result, Err(Error::NotARootNode)));
    }

    #[test]
    fn append_node_returns_not_a_root_node_error() {
        let (mut arena, root) = Arena::with_data(0usize);
        let a = root.append(&mut arena, 1usize);
        // `a` already has a parent, so it's not a root node
        let result = root.append_node(&mut arena, a);
        assert!(matches!(result, Err(Error::NotARootNode)));
    }

    #[test]
    fn insert_before_first_child_updates_parent_first_child() {
        let (mut arena, root) = Arena::with_data(0usize);
        let a = root.append(&mut arena, 1usize);
        // insert before a, which is the first child
        let new_first = a.insert_before(&mut arena, 99usize);
        // root's first_child should now point to new_first
        assert_eq!(arena[root].first_child, Some(new_first));
        // new_first's next_sibling should be a
        assert_eq!(arena[new_first].next_sibling, Some(a));
        // a's previous_sibling should be new_first
        assert_eq!(arena[a].previous_sibling, Some(new_first));
    }

    #[test]
    fn insert_after_with_next_sibling_updates_sibling_chain() {
        let (mut arena, root) = Arena::with_data(0usize);
        let a = root.append(&mut arena, 1usize);
        let b = root.append(&mut arena, 2usize);
        // insert after a, which already has b as next sibling
        let mid = a.insert_after(&mut arena, 99usize);
        // a -> mid -> b
        assert_eq!(arena[a].next_sibling, Some(mid));
        assert_eq!(arena[mid].next_sibling, Some(b));
        assert_eq!(arena[b].previous_sibling, Some(mid));
    }

    #[test]
    fn detach_middle_child_relinks_neighbors() {
        let (mut arena, root) = Arena::with_data(0usize);
        let a = root.append(&mut arena, 1usize);
        let b = root.append(&mut arena, 2usize);
        let c = root.append(&mut arena, 3usize);

        b.detach(&mut arena);

        assert_eq!(arena[a].next_sibling, Some(c));
        assert_eq!(arena[c].previous_sibling, Some(a));
        assert!(arena[b].parent.is_none());
    }

    #[test]
    fn detach_last_child() {
        let (mut arena, root) = Arena::with_data(0usize);
        let a = root.append(&mut arena, 1usize);
        let b = root.append(&mut arena, 2usize);

        b.detach(&mut arena);

        assert!(arena[a].next_sibling.is_none());
        assert!(arena[b].parent.is_none());
    }

    #[test]
    fn detach_first_child_with_siblings_updates_parent_first_child() {
        let (mut arena, root) = Arena::with_data(0usize);
        let a = root.append(&mut arena, 1usize);
        let b = root.append(&mut arena, 2usize);

        a.detach(&mut arena);

        assert_eq!(arena[root].first_child, Some(b));
        assert!(arena[b].previous_sibling.is_none());
        assert!(arena[a].parent.is_none());
    }
}
