/**
 * A Java interface for the Updatable Priority Queue ADT.  This allows the user
 * to query and change the priority of items in the queue.
<p>
 * The items in an updatable priority queue must be unique; otherwise the
 * operations of getting or setting an item's priority would not be
 * well-defined (which copy of the item would we mean?).
<p>
 * Each implementation of this interface shall define a special "sentinel"
 * priority value that indicates an item is not in the queue.  Setting an
 * item's priority to this value in fact removes it from the queue.  Removing a
 * non-member item is a no-op.
<p>
 * In addition, adding an item may be accomplished, from the user side, simply
 * by setting its priority to a non-sentinel value.
 * 
 * @param <T> the type of the items stored in the queue.
 * @param <P> the type of the priority of each item.
 * @author Jadrian Miles
 */
public interface UpdatablePriorityQueue<T, P extends Comparable<? super P>>
        extends PriorityQueue<PriorityPair<T, P>> {
    /**
     * Adds an item, with the priority given in the pair, to the queue.  This is
     * equivalent to setPriority(itemPair.item(), itemPair.priority()), and
     * therefore may, depending on the priority and the current state of the
     * queue, add, remove, or modify the priority of the item.
     */
    public void add(PriorityPair<T, P> itemPair);
    
    /**
     * Adds an item, with the given priority, to the queue.  This is equivalent
     * to setPriority(item, priority), and therefore may, depending on the
     * priority and the current state of the queue, add, remove, or modify the
     * priority of the item.
     */
    public void add(T item, P priority);
    
    /**
     * Sets the priority of a given item.  The "given item" is, specifically,
     * the element x in the PQ for which x.equals(item) is true.
    <p>
     * The consequences of this operation vary depending on two conditions:
    <ul>
     * <li> NEW: the item is not already in the queue.
     * <li> DEL: "newPriority" is the non-member priority sentinel value.
    </ul>
    <p>
     * The four cases covered by combinations of these conditions are:
    <ul>
     * <li> 1. If !NEW and !DEL, this method changes the item's priority.
     * <li> 2. If  NEW and !DEL, this method adds the item.
     * <li> 3. If !NEW and  DEL, this method removes the item.
     * <li> 4. If  NEW and  DEL, this method is a no-op (removing a non-member).
    </ul>
    <p>
     * The method returns true if the pair (item, newPriority) is in the queue
     * after the call.  (This is !DEL: true in cases 1 and 2; false in 3 and 4.)
     */
    public boolean setPriority(T item, P newPriority);
    
    /**
     * Returns the priority of the given item, or, if that item is not in the
     * queue, an implementation-specific sentinel value.  (As in setPriority(),
     * this queries the element x in the PQ for which x.equals(item) is true.)
     */
    public P getPriority(T item);
    
    /**
     * Returns the sentinel value used by getPriority() to indicate items not
     * currently stored in the queue.
     */
    public P nonMemberPriority();
}
