        // An Ice Cream Vendor which maintains a queue of waiting
        // customers. The time to serve a customer depends upon the
        // number of ices they require.
class Vendor {
    public Vendor(Scheduler s){
        scheduler = s;
    }

        // Add this customer to the tail of the queue.
    public void arrival(Customer customer){
        Queue q = getQueue();
        q.add(customer);
        if(q.size() == 1){
            // Serve this customer now.
            takeNextInLine();
        }
    }

        // Serve this customer.
    public void serve(Customer customer){
        Scheduler s = getScheduler();
        // How long before this customer leaves?
        long saleTime = timeToSell(customer.getNumIces());
        s.schedule(new FinishServing(s.getTime()+saleTime,this));
    }

        // We have just finished serving the customer at the head
        // of the queue.
    public void departure() throws RuntimeException {
        Queue q = getQueue();
        if(q.size() > 0){
            // Discard head of queue.
            q.next();
            takeNextInLine();
        }
        else{
            throw new RuntimeException(
                "Last customer is missing from the head of the vendor's queue.");
        }
    }

        // Serve the person at the head of the queue, if any.
    protected void takeNextInLine(){
        System.out.println(queue.size()+" customer(s) waiting.");
        Queue q = getQueue();
        if(q.size() > 0){
            Customer customer = (Customer) queue.peek();
            Scheduler s = getScheduler();
            // Serve the customer now.
            s.schedule(new Serve(s.getTime(),customer,this));
        }
    }

        // How long it will take to sell the given number
        // of ice creams.
    protected long timeToSell(int numIceCreams){
        return numIceCreams*timePerIceCream;
    }

    protected Queue getQueue(){
        return queue;
    }

    protected Scheduler getScheduler(){
        return scheduler;
    }

    // How long to serve a single ice cream, in seconds?
    private final long timePerIceCream = 15;
    // The queue of customers.
    private final Queue queue = new Queue();
    private final Scheduler scheduler;
}
