public static byte[] getBytesWithoutClosing(InputStream stream) throws IOException {
    if (stream instanceof ExposedByteArrayInputStream) {
      // Fast path for the exposed version.
      return ((ExposedByteArrayInputStream) stream).readAll();
    } else if (stream instanceof ByteArrayInputStream) {
      // Fast path for ByteArrayInputStream.
      byte[] ret = new byte[stream.available()];
      stream.read(ret);
      return ret;
    }
    // Falls back to normal stream copying.
    SoftReference<byte[]> refBuffer = threadLocalBuffer.get();
    byte[] buffer = refBuffer == null ? null : refBuffer.get();
    if (buffer == null) {
      buffer = new byte[BUF_SIZE];
      threadLocalBuffer.set(new SoftReference<>(buffer));
    }
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    while (true) {
      int r = stream.read(buffer);
      if (r == -1) {
        break;
      }
      outStream.write(buffer, 0, r);
    }
    return outStream.toByteArray();
  }
@Test
  public void testGetBytesFromByteArrayInputStream() throws IOException {
    InputStream stream = new ByteArrayInputStream(testData);
    byte[] bytes = StreamUtils.getBytesWithoutClosing(stream);
    assertArrayEquals(testData, bytes);
    assertEquals(0, stream.available());
  }