/*
+-------------+
| Author      |
+-------------+
| String name |
| int year    |
+-------------+
*/

class Author {
  String name;
  int year;
  
  Author(String name, int year){
    this.name = name; 
    this.year = year;
  }

  boolean same(Author that){
    return 
      this.name.equals(that.name)
    && this.year == that.year;
  }
}

/*
           +-----------+                
           | ILoAuthor |<--------------+
           +-----------+               |
                / \                    |
                 |                     |
       - - - - - - - - - -             |
       |                 |             |
 +------------+    +----------------+  |
 | MTLoAuthor |    | ConsLoAuthor   |  |
 +------------+    +----------------+  |
 +------------+  +-| Author first   |  |
                 | | ILoAuthor rest |--+
                 | +----------------+ 
                 |
                 v
        +--------------+
        | Author       |
        +--------------+
        | String name  |
        | int year     |
        +--------------+
*/

interface ILoAuthor{
  // to compute the size of this list
  int size();

  // is the given author in this list?
  boolean contains (Author that);
}

class MTLoAuthor implements ILoAuthor{
  MTLoAuthor() {}

  int size(){ return 0; }

  boolean contains (Author that){
    return false;
  }
}

class ConsLoAuthor implements ILoAuthor{
  Author first;
  ILoAuthor rest;

  ConsLoAuthor(Author first, ILoAuthor rest){
    this.first = first;
    this.rest = rest;
  }

/* TEMPLATE:
... this.first ...                   -- Author
... this.rest ...                    -- ILoAuthor
... this.rest.size() ...             -- int
... this.rest.contains( Author ) ... -- boolean
*/
  int size(){ 
    return 1 + this.rest.size(); 
  }

  boolean contains (Author that){
    return this.first.same(that)
        || this.rest.contains(that);
  }
}

class Examples{
  Examples () {}

  Author a1 = new Author("DB", 1956);
  Author a2 = new Author("StEx", 1900);
  Author a3 = new Author("MF", 1972);
  
  ILoAuthor mtauthors = new MTLoAuthor();
  ILoAuthor authorlist = 
            new ConsLoAuthor(a1,
            new ConsLoAuthor(a2,
                           mtauthors));

  boolean testSize1 = mtauthors.size() == 0;
  boolean testSize2 = authorlist.size() == 2;

  boolean testContains1 = this.mtauthors.contains(this.a1) == false;
  boolean testContains2 = this.authorlist.contains(this.a2) == true;
  boolean testContains3 = this.authorlist.contains(a3) == false;
}
