### Question:
RateLimitedInputStream extends FilterInputStream implements Seekable { @Override public int read() throws IOException { int val = in.read(); if (val >= 0) { rateLimiter.acquire(1); } return val; } <StreamType extends InputStream & Seekable> RateLimitedInputStream(StreamType stream,
      RateLimiter rateLimiter); @Override int read(); @Override int read(byte[] buffer, int offset, int length); @Override void seek(long pos); @Override long getPos(); @Override boolean seekToNewSource(long targetPos);  }### Answer:
@Test public void permitsAreProperlyAcquired() throws Exception { Random randGen = new SecureRandom(); MockRateLimiter rateLimiter = new MockRateLimiter(); long bytesRetrieved = 0; try (InputStream is = new RateLimitedInputStream(new RandomInputStream(), rateLimiter)) { for (int i = 0; i < 100; ++i) { int count = Math.abs(randGen.nextInt()) % 65536; int countRead = is.read(new byte[count]); assertEquals(count, countRead); bytesRetrieved += count; } } assertEquals(bytesRetrieved, rateLimiter.getPermitsAcquired()); }