import java.util.Vector;

/**
 * Thrown by methods in the <code>Queue</code> class to indicate 
 * that the queue is empty. 
 *
 * @author  Andres Santiago Perez-Bergquist
 */
public class EmptyQueueException extends RuntimeException
{
    /**
     * Constructs a new <code>EmptyQueueException</code> with no detail message.
     */
    public EmptyQueueException()
    {
    }
}

public class Queue extends Vector
{
    /**
     * Pushes an item onto the front of this queue. 
     *
     * @param   item   the item to be pushed onto this queue.
     * @return  the <code>item</code> argument.
     */
    public Object enqueue(Object item)
    {
		addElement(item);

		return item;
    }

    /**
     * Removes the object at the front of this queue and returns that 
     * object as the value of this function. 
     *
     * @return     The object at the front of this queue.
     * @exception  EmptyQueueException if this queue is empty.
     */
    public synchronized Object dequeue()
    {
	    if (size() == 0)
			throw new EmptyQueueException();
		else
		{
			Object	obj;

			obj = firstElement();
			removeElementAt(0);

			return obj;
		}
    }
    
    /**
     * Removes the specified object from the queue and returns that 
     * object as the value of this function. 
     *
     * @return     The object removed, or null if it was not in the queue.
     */
    public synchronized Object extract(Object o)
    {
	    int i = lastIndexOf(o);

		if (i >= 0)
			removeElementAt(i);
		else
			return null;

		return o;
    }

    /**
     * Looks at the object at the front of this queue without removing it 
     * from the queue. 
     *
     * @return     the object at the top of this stack. 
     * @exception  EmptyQueueException if this stack is empty.
     */
    public synchronized Object peek()
    {
		if (size() == 0)
			throw new EmptyQueueException();
		else
			return firstElement();
    }

    /**
     * Tests if this queue is empty.
     *
     * @return  <code>true</code> if this queue is empty;
     *          <code>false</code> otherwise.
     */
    public boolean empty()
    {
		return size() == 0;
    }

    /**
     * Returns where an object is on this queue. 
     *
     * @param   o   the desired object.
     * @return  the distance from the front of the queue where the object is]
     *          located; the return value <code>-1</code> indicates that the
     *          object is not on the queue.
     */
    public synchronized int search(Object o)
    {
		int i = lastIndexOf(o);

		if (i >= 0)
		    return i;
		else
			return -1;
    }

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = 1224463164541339165L;
}
