/** 
 * Cache represents a web page cache.  A Cache object responds to requests for 
 * a web page (given the URL).  See <tt>requestPage()</tt> for details.
 * 
 * The cache maintains a count of the number of URL requests received.
 * The cache maintains a count of the total number of pages fetched from 
 * the Internet.  
 *
 * @version 2012.11.8
 */
public class Cache
    /** Default cache capacity */
    public final static int kDefaultCapacity = 5;
    /** Construct a Cache with the default capacity. 
     */
    public Cache()
    /** Construct a Cache with the specified capacity. 
     * @param capacity the max number of entries in the cache
     * @pre capacity > 0
     */
    public Cache(int capacity)
    /** Call <code>requestPage()</code> for every url in the input stream available at 
     * the provided Reader.  Each url is on a separate line and may include leading or trailing blanks.
     * Ignore the value returned by <code>requestPage()</code>.
     * @param instream a Reader for the stream of url requests,
     * @post the urls have been counted, the number of page fetches from web have been counted.
     */ 
    public void processUrls(java.io.Reader instream)
    /**  Respond to a request for a web page (given the URL).  
     * If the specified URL is not in the cache, the page is fetched and the content
     * saved in the cache, along with a counter (initially, 1).  
     * On subsequent requests for the same URL, 
     * the cached page will be returned without needing to retrieve the page 
     * from the URL (and its counter incremented).
     * The cache has a finite size, and when the cache fills up any subsequent
     * requests cause the lowest frequency cached item to be removed,
     * and the new request added.  
     * (If multiple entries have the same low
     * frequency, an arbitrary one will be removed.)
     * @param url the URL of the page to be returned
     * @return String contents of the page at the given URL, or an empty string
     *         if the URL is malformed.
     * @see java.net.MalformedURLException
     * @post  If the URL is well-formed, <code>requestCount</code> for this cache 
     * has been incremented.
     */
    public String requestPage(String url)
    /** Return an ordered list of all WebPages in the cache (using the default ordering).
     * @return ArrayList of ordered WebPages.     
     */
    public java.util.ArrayList<WebPage> getPageList()
    /**  Return the number of URL requests received. 
     * @return int number of URL requests received. 
     */
    public int getRequestCount() 
    /** Return the total number of pages fetched from the Internet. 
     * @return int total number of pages fetched from the Internet. 
     */
    public int getUrlFetchCount() 
/**
 * Simulate requesting a bunch of URL's and caching them.
 * Produce a report of the contents of the URL Cache, ordered by decreasing
 * frequency of occurrence. 
 * 
 * @version 2014.2.13
 */
public class CacheSimulator
    /**
     *  Construct a cache simulator.
     */
    public CacheSimulator()
    /** Construct a cache simulator with a specified capacity 
     * @param cacheSize the desired maximum size of the cache
     */
    public CacheSimulator(int cacheSize)
    /** Simulate caching a stream of URL's provided on 
     * the given Reader.
     * @param rdr a Reader from which to read a stream of URL's,
     * one per line (may include leading or trailing blanks)
     */
    public void simulate(Reader rdr)
    /** Produce a report to the specified Writer about the state of the cache
     *  after running the simulation. 
     *  The report will list all the URLs in the cache ordered by decreasing
     *  frequency of number of requests.  Each line of the report consists of
     *  three tab-separated fields:  frequency, url, page content.
     * @param wtr a Writer to which to display the output. 
     * @pre <code>simulate()</code> has been called.
     */
    public void makeReport(Writer wtr)
/**
 * WebPage is a cached web page and its frequency.
 * A WebPage has a URL, content, and a count of the number
 * of times it's been accessed.
 * @version 2012.10.14
 */
public class WebPage implements Comparable<WebPage>
    /** Create a web page with a count of one.
     * @param url the URL of this page.
     * @param pageContent the content of this page
     */
    public WebPage(String url, String pageContent)
    /**
     * Compares this WebPage with the provided WebPage.  
     *
     * @param  other WebPage to which this WebPage is to be compared.
     * @return -1, 0 or 1 as this WebPage's url is alphabetically less than, equal
     *         to, or greater than <tt>other</tt>.
     */    
    public int compareTo(WebPage other)
    /** 
     * Return a string representation of this WebPage, 
     * specifically: <code>frequency + "\t" + url + "\t" + pageContent </code>
     * @return a string representation of this WebPage
     */    
    public String toString()
    /**
     * Increment the frequency by one
     */
    public void increment()
    /**
     * Accessor to page content.
     * @return String page content
     */
    public String getContent()
    /** 
     * Accessor to frequency.
     * @return int number of times this page was requested
     */
    public int getFrequency()
    /**
     * Accessor to url.
     * @return String url value.
     */
    public String getUrl()
/**
 * WebPageComparator represents the comparison of the
 * counts of two WebPages.
 * Provides an ordering of counts in descending order.
 * 
 * @version 2012.10.14
 */
public class WebPageComparator implements Comparator<WebPage>
    /** Compare two WebPages by their count, returning the highest first.
     *  (Note this is the opposite of the standard compare.)
     * @param  one a WebPage to compare.
     * @param  two a WebPage to compare.
     * @return 1, 0 or -1 as <tt>one</tt>'s count is numerically less than, equal
     *         to, or greater than <tt>two</tt>.
     */
    public int compare(WebPage one, WebPage two)