/**
 * Interface for a generic search in a binary tree. A binary tree search is
 * initiated at the root of a tree and maintains the information which node
 * is the current node.
 * 
 * The tree is searched by moving down from the current node to its left or 
 * right child. The tree can be modified at the current node by setting the 
 * data or adding new children with new data.
 *
 * @param <A> The type of the data held in nodes of the tree.
 */
public interface BinaryTreeSearch<A> {

	/**
	 * The data stored at the current node.
	 * 
	 * @return The data at the current node.
	 */
	public A getData();
	
	/**
	 * Checks whether the current node is a leaf node. 
	 * 
	 * @return True if the search arrived at a leaf node.
	 */
	public boolean isLeaf();

	/**
	 * Checks whether the current node has a left child. 
	 * 
	 * @return True if the current node has a left child.
	 */
	public boolean hasLeftChild();
	
	/**
	 * Checks whether the current node has a right child. 
	 * 
	 * @return True if the current node has a right child.
	 */
	public boolean hasRightChild();

	/**
	 * Moves down to the left child.
	 * 
	 * @throws NoSuchElementException if the current node has no left child. 
	 */
	public void nextLeftChild();
	
	/**
	 * Moves down to the right child.
	 * 
	 * @throws NoSuchElementException if the current node has no right child. 
	 */
	public void nextRightChild();
	
	/**
	 * Replaces the current node and creates new children initialized to hold the
	 * provided data. If the data for a child is null, does not create the 
	 * corresponding child.
	 * 
	 * @param data The data for the current node.
	 * @param leftData The data for the new left child.
	 * @param rightData The data for the new right child.
	 */
	public void setNode(A data, A leftData, A rightData);

}
