private static long copyStreamContent(@NotNull InputStream inputStream,
                                        @NotNull OutputStream outputStream,
                                        @Nullable JpsLoaderContext loaderContext,
                                        long expectedContentLength) throws IOException {

    CountingGZIPInputStream gzipStream = inputStream instanceof CountingGZIPInputStream ? (CountingGZIPInputStream)inputStream : null;
    byte[] buffer = new byte[StreamUtil.BUFFER_SIZE];
    int count;
    long bytesWritten = 0;
    long bytesRead = 0;
    while ((count = inputStream.read(buffer)) > 0) {
      if (loaderContext != null) loaderContext.checkCanceled();
      outputStream.write(buffer, 0, count);
      bytesWritten += count;
      bytesRead = gzipStream != null ? gzipStream.getCompressedBytesRead() : bytesWritten;

    }
    if (gzipStream != null) {
      // Amount of read bytes may have changed when 'inputStream.read(buffer)' returns -1
      // E.g. reading GZIP trailer doesn't produce inflated stream data.
      bytesRead = gzipStream.getCompressedBytesRead();
    }

    if (bytesRead < expectedContentLength) {
      throw new IOException("Connection closed at byte " + bytesRead + ". Expected " + expectedContentLength + " bytes.");
    }
    return bytesWritten;
  }
private static long copyStreamContent(@NotNull InputStream inputStream,
                                        @NotNull OutputStream outputStream,
                                        @Nullable JpsLoaderContext loaderContext,
                                        long expectedContentLength)