@Override
  public void rateBooks(Set<BookRating> bookRating) throws BookStoreException {
    // TODO Auto-generated method stub
    // lock update lock, only allow read
    bsLock.updateLock().lock();
    try {
      /* Check if the input is valid */
      if (bookRating == null) throw new BookStoreException(BookStoreConstants.NULL_INPUT);

      int ISBN, rating;
      BookStoreBook book;
      for (BookRating br : bookRating) {
        ISBN = br.getISBN();
        rating = br.getRating();
        if (BookStoreUtility.isInvalidISBN(ISBN))
          throw new BookStoreException(BookStoreConstants.ISBN + ISBN + BookStoreConstants.INVALID);
        if (!bookMap.containsKey(ISBN))
          throw new BookStoreException(
              BookStoreConstants.ISBN + ISBN + BookStoreConstants.NOT_AVAILABLE);
        if (BookStoreUtility.isInvalidRating(rating))
          throw new BookStoreException(
              BookStoreConstants.RATING + rating + BookStoreConstants.INVALID);
      }

      try {
        bsLock.writeLock().lock(); // upgrade to write lock
        /* Inputs are valid so, ready to rate the books change */
        for (BookRating br : bookRating) {
          book = bookMap.get(br.getISBN());
          book.addRating(br.getRating());
        }
      } finally {
        bsLock.writeLock().unlock(); // downgrade to update lock
      }

    } finally {
      bsLock.updateLock().unlock();
    }

    return;
  }