public boolean hasSeries() {
   synchronized (myBooksByFile) {
     for (Book book : myBooksByFile.values()) {
       if (book.getSeriesInfo() != null) {
         return true;
       }
     }
   }
   return false;
 }
 public List<Book> booksForSeries(String series) {
   final LinkedList<Book> filtered = new LinkedList<Book>();
   for (Book b : books()) {
     final SeriesInfo info = b.getSeriesInfo();
     if (info != null && series.equals(info.Title)) {
       filtered.add(b);
     }
   }
   return filtered;
 }
 public List<String> series() {
   final Set<String> series = new TreeSet<String>();
   synchronized (myBooksByFile) {
     for (Book book : myBooksByFile.values()) {
       final SeriesInfo info = book.getSeriesInfo();
       if (info != null) {
         series.add(info.Title);
       }
     }
   }
   return new ArrayList<String>(series);
 }
 public List<Book> booksForSeriesAndAuthor(String series, Author author) {
   final boolean isNull = Author.NULL.equals(author);
   final LinkedList<Book> filtered = new LinkedList<Book>();
   for (Book b : books()) {
     final List<Author> bookAuthors = b.authors();
     final SeriesInfo info = b.getSeriesInfo();
     if (info != null
         && series.equals(info.Title)
         && (isNull && bookAuthors.isEmpty() || bookAuthors.contains(author))) {
       filtered.add(b);
     }
   }
   return filtered;
 }
 public List<String> titlesForSeries(String series, int limit) {
   if (limit <= 0) {
     return Collections.emptyList();
   }
   final ArrayList<String> titles = new ArrayList<String>(limit);
   synchronized (myBooksByFile) {
     for (Book b : myBooksByFile.values()) {
       final SeriesInfo info = b.getSeriesInfo();
       if (info != null && series.equals(info.Title)) {
         titles.add(b.getTitle());
         if (--limit == 0) {
           break;
         }
       }
     }
   }
   return titles;
 }
 public List<String> titlesForSeriesAndAuthor(String series, Author author, int limit) {
   if (limit <= 0) {
     return Collections.emptyList();
   }
   final boolean isNull = Author.NULL.equals(author);
   final ArrayList<String> titles = new ArrayList<String>(limit);
   synchronized (myBooksByFile) {
     for (Book b : myBooksByFile.values()) {
       final List<Author> bookAuthors = b.authors();
       final SeriesInfo info = b.getSeriesInfo();
       if (info != null
           && series.equals(info.Title)
           && (isNull && bookAuthors.isEmpty() || bookAuthors.contains(author))) {
         titles.add(b.getTitle());
         if (--limit == 0) {
           break;
         }
       }
     }
   }
   return titles;
 }