code: public synchronized List<Message> getFromRange(final int startPosition, final int endPosition) {
          // cache this here, so all parts of the method operate on the same data
          final int firstMessageId = this.getFirstPosition();
          // input validation
          if ((startPosition < MessageStore.INITIAL_MESSAGE_POSITION)
                  || (endPosition < MessageStore.INITIAL_MESSAGE_POSITION)) {
              throw new IllegalArgumentException("Message position cannot be negative.");
          } else if ((firstMessageId >= MessageStore.INITIAL_MESSAGE_POSITION) && (startPosition < firstMessageId)) {
              throw new IllegalArgumentException("Message at position " + startPosition
                      + " had already been discarded. First available message position is " + firstMessageId + ".");
          } else if (endPosition <= startPosition) {
              throw new IllegalArgumentException("Ending position must be larger than starting message position.");
          } else if (endPosition > this.getNextPosition()) {
              throw new IllegalArgumentException("Range end cannot be greater than the next message position.");
          }
          // and properly synchronized range retrieval
          return Collections.unmodifiableList(new LinkedList<>(this.store.subMap(startPosition, endPosition)
                  .values()));
      }
docs: Return all messages on positions in the given range.
  
  @param startPosition
  Least position, inclusive.
  @param endPosition
  Greatest position, exclusive.
  @return Unmodifiable list containing those messages.