public Boolean book(User currentUser, Integer borrowableId,
            Integer quantity, Integer borrowerId, Date start, Date end,
            String reason) {
        // Date verifications

        // Time before the beggining of the booking (reservation)
        DateInterval reservationStartInterval = new DateInterval(new Date(),
                start);
        if (reservationStartInterval.getLength() > currentUser
                .getMaxReservationLength()) {
            return false;
        }

        // Duration of the booking
        DateInterval bookingInterval = new DateInterval(start, end);
        if (bookingInterval.getLength() > currentUser.getMaxBookingLength()) {
            return false;
        }

        BorrowableStock currentStock = this.stock.get(borrowableId);

        // Get the current booking total
        Integer totalItems = currentStock.getCalendar()
                .getCurrentBorrowedTotal(borrowerId);
        
        if (currentStock == null
                || !currentStock.isAvailable(quantity, start, end)
                || !currentStock.getModel().canBook(
                        currentUser.getUserType().toString(),
                        reservationStartInterval.getLength(),
                        bookingInterval.getLength(), totalItems)) {
            return false;
        }
        return currentStock.getCalendar().book(borrowerId, quantity,
                bookingInterval, reason, currentStock.getModel());
    }