spiceJ/core/src/main/java/at/borkowski/spicej/streams/RateLimitInputStream.java
@Override
   public int read(byte[] b, int off, int len) throws IOException {
      int done = 0;
      while (done < len && (done == 0 || available() > 0 || (boring && real.available() > 0)))
         done += realRead(b, off + done, Math.min(len - done, Math.max(1, rateHelper.getThingsPerTick())));
      return done;
   }
@Override
   public int read(byte[] b, int off, int len) throws IOException {
      int done = 0;
      while (done < len && (done == 0 || available() > 0 || (boring && real.available() > 0)))
         done += realRead(b, off + done, Math.min(len - done, Math.max(1, rateHelper.getThingsPerTick())));
      return done;
   }
This method complies with {@link InputStream#read(byte[], int, int)} and
imposes stronger postconditions.

Reads up to <code>len</code> bytes from the stream. This method blocks for
the first byte reagrdless of the stream's boring flag. For all subsequent
bytes, the behavior depends on the boring flag:

<ul>
<li>In boring mode, the stream blocks until all bytes actually available
from the underlying InputStream (reported by
{@link InputStream#available()}) have been read, even if this means
waiting for the next tick.</li>
<li>In non-boring mode, the stream does not block for the first byte's
subsequent bytes. This means that if a rate limitation is in place (ie.
the rate has been reached for the current tick), this method does not
attempt to read the bytes (the number of actually read bytes is returned
conforming with {@link InputStream#read(byte[], int, int)}.</li>
</ul>