
import java.io.PrintWriter;
import javax.naming.OperationNotSupportedException;

public interface Treap {

    /**
     * Retrieves the value associated with a key in this dictionary.
     * If the key is null or the key is not present in this
     * dictionary, this method returns null.
     *
     * @param key   the Comparable key whose associated value
     *              should be retrieved
     * @return	    the Object value associated with the key, or
     *        	    null if the key is null or the key is not in 
     *              this treap
     */
    Object lookup(Comparable key);
    
    /**
     * Adds a key-value pair to this dictionary.  Any old value
     * associated with the key is lost.  If the key or the value is
     * null, the pair is not added to the dictionary.
     *
     * @param key  	the Comparable key to add to this dictionary
     * @param value	the Object value to associate with the key
     */
    void insert(Comparable key, Object value);
    
    /**
     * Removes a key from this dictionary.  If the key is not present
     * in this dictionary, this method does nothing.  Returns the
     * Object associated with the removed key, or null if the key
     * is not present.
     *
     * @param key      the Comparable key to remove
     * @return         the Object associated with the removed key, or null 
     */
    Object remove(Comparable key);

    /**
     * Splits this treap into two treaps.  The left treap should contain
     * values less than the key, while the right treap should contain
     * values greater than or equal to the key.
     *
     * @param key    the Comparable key to split the treap with
     * @return       the left treap in index 0, the right in index 1
     */
    Treap [] split(Comparable key);

    /**
     * Joins this treap with another treap.  If the other treap is not
     * an instance of the implementing class, both treaps are unmodified.
     * At the end of the join, this treap will contain the result.
     * This method may destructively modify both treaps.
     *
     * @param t    the treap to join with
     */
    void join(Treap t);

    /**
     * Melds this treap with another treap.  If the other treap is not
     * an instance of the implementing class, both treaps are unmodified.
     * At the end of the meld, this treap will contain the result.  This
     * method may destructively modify both treaps.
     *
     * @param t    the treap to meld with.  t may be modified.
     */
    void meld(Treap t) throws OperationNotSupportedException;

    /**
     * Removes elements from another treap from this treap.  If the
     * other treap is not an instance of the implementing class,
     * both treaps are unmodified.  At the end of the difference,
     * this treap will contain no keys that were in the other
     * treap.  This method may destructively modify both treaps.
     *
     * @param t   a treap containing elements to remove from this
     *            treap.  t may be destructively modified.
     */
    void difference(Treap t) throws OperationNotSupportedException;


    /**
     * Prints a human-readable version of the treap to the specified
     * PrintWriter.  Each node in the treap will be printed as
     *
     *     [priority] <key, value>
     *
     * Subtreaps are indented one tab over from their parent for
     * printing.  This method prints out the string representations
     * of key and value using the object's toString().
     */
    void printTreap(PrintWriter o);


    /**
     * Resets the internal iterator to the "beginning" of the treap.
     * A treap that has not been iterated over (via nextKey) should
     * not require a call to this method before iteration.
     */
    void resetIterator();

    /**
     * Returns the next key in sorted order, or null if there are none
     * remaining.  If keys are added or removed with a non-reset
     * iterator, the inclusion of affected elements in the iteration
     * order is implementation dependent.
     *
     * @return the next key
     */
    Comparable nextKey();

    /**
     * Returns the balance factor of the treap.  The balance factor
     * is the height of the treap divided by the minimum possible
     * height of a treap of this size.  A perfectly balanced treap
     * has a balance factor of 1.0.  If this treap does not support
     * balance statistics, throw an exception.
     */
    double balanceFactor() throws OperationNotSupportedException;


}
