public Film recommendFilm(Person person) {
   if (ratings.getPersonalRatings(person).isEmpty()) {
     Map<Film, List<Rating>> filmRatings = ratings.filmRatings();
     List<Film> films = new ArrayList<Film>();
     for (Film f : filmRatings.keySet()) {
       films.add(f);
     }
     Collections.sort(films, new FilmComparator(filmRatings));
     return films.get(0);
   } else {
     Person mostSimilarPerson = findMostSimilarPerson(person);
     Film personalBestFilm = getUnwatchedPersonalBestFilm(mostSimilarPerson, person);
     if (ratings.getRating(mostSimilarPerson, personalBestFilm).getValue() > 1) {
       return personalBestFilm;
     } else {
       return null;
     }
   }
 }
 private int getSimilarity(Person p1, Person p2) {
   Map<Film, Rating> p1Review = ratings.getPersonalRatings(p1);
   Map<Film, Rating> p2Review = ratings.getPersonalRatings(p2);
   int totalSimilarity = 0;
   for (Film f : p1Review.keySet()) {
     if (p2Review.containsKey(f)) {
       totalSimilarity += p1Review.get(f).getValue() * p2Review.get(f).getValue();
     }
   }
   return totalSimilarity;
 }
 private Person findMostSimilarPerson(Person person) {
   List<Person> reviewers = ratings.reviewers();
   reviewers.remove(person);
   Person mostSimilarPerson = reviewers.get(0);
   for (Person p : reviewers) {
     if (getSimilarity(person, p) > getSimilarity(person, mostSimilarPerson)) {
       mostSimilarPerson = p;
     }
   }
   return mostSimilarPerson;
 }
  private List<Film> removeWatchedFilms(List<Film> films, Person person) {
    Map<Film, Rating> reviews = ratings.getPersonalRatings(person);
    Iterator<Film> iterator = films.iterator();

    while (iterator.hasNext()) {
      if (reviews.containsKey(iterator.next())) {
        // delete the object returned by the iterator with its previous method call
        iterator.remove();
      }
    }
    return films;
  }
 private Film getUnwatchedPersonalBestFilm(Person similarPerson, Person personToRecommend) {
   Map<Film, Rating> reviews = ratings.getPersonalRatings(similarPerson);
   List<Film> films = new ArrayList<Film>();
   for (Film f : reviews.keySet()) {
     films.add(f);
   }
   films = removeWatchedFilms(films, personToRecommend);
   if (!films.isEmpty()) {
     Film personalBestfilm = films.get(0);
     for (Film f : films) {
       if (reviews.get(f).getValue() > reviews.get(personalBestfilm).getValue()) {
         personalBestfilm = f;
       }
     }
     return personalBestfilm;
   } else {
     return null;
   }
 }