io/src/main/java/com/stanfy/enroscar/io/IoUtils.java
public static void transfer(final InputStream input, final OutputStream output, final BuffersPool buffersPool) throws IOException {
    final InputStream in = buffersPool == null
        ? new BufferedInputStream(input, BUFFER_SIZE_8K)
        : new PoolableBufferedInputStream(input, BUFFER_SIZE_8K, buffersPool);

    final byte[] buffer = buffersPool == null
        ? new byte[BUFFER_SIZE_8K]
        : buffersPool.get(BUFFER_SIZE_8K);

    try {
      int cnt;
      while ((cnt = in.read(buffer)) != EOF) {
        output.write(buffer, 0, cnt);
      }
      output.flush();
    } finally {
      closeQuietly(in);

      if (buffersPool != null) {
        buffersPool.release(buffer);
      }
    }
  }
public static void transfer(final InputStream input, final OutputStream output, final BuffersPool buffersPool) throws IOException {
    final InputStream in = buffersPool == null
        ? new BufferedInputStream(input, BUFFER_SIZE_8K)
        : new PoolableBufferedInputStream(input, BUFFER_SIZE_8K, buffersPool);

    final byte[] buffer = buffersPool == null
        ? new byte[BUFFER_SIZE_8K]
        : buffersPool.get(BUFFER_SIZE_8K);

    try {
      int cnt;
      while ((cnt = in.read(buffer)) != EOF) {
        output.write(buffer, 0, cnt);
      }
      output.flush();
    } finally {
      closeQuietly(in);

      if (buffersPool != null) {
        buffersPool.release(buffer);
      }
    }
  }
Transfers all the bytes from input to output stream.
If read/write operations are successful, output stream will be flushed.
Input stream is always closed after this method invocation.

@param input input stream
@param output output stream
@param buffersPool buffers pool used to obtain a temporal bytes buffer, may be null
@throws IOException if an error happens