private void fillOutBuffer() throws IOException {
    if (myInflatorId == -1) {
      return;
    }

    while (myOutBufferLength == 0) {
      if (myInBufferLength == 0) {
        myInBufferOffset = 0;
        final int toRead =
            (myCompressedAvailable < IN_BUFFER_SIZE) ? myCompressedAvailable : IN_BUFFER_SIZE;
        myInBufferLength = myStream.read(myInBuffer, 0, toRead);
        if (myInBufferLength < toRead) {
          myCompressedAvailable = 0;
        } else {
          myCompressedAvailable -= toRead;
        }
      }
      if (myInBufferLength <= 0) {
        break;
      }
      final long result =
          inflate(myInflatorId, myInBuffer, myInBufferOffset, myInBufferLength, myOutBuffer);
      if (result <= 0) {
        final StringBuffer extraInfo =
            new StringBuffer()
                .append(myStream.offset())
                .append(":")
                .append(myInBufferOffset)
                .append(":")
                .append(myInBufferLength)
                .append(":")
                .append(myOutBuffer.length)
                .append(":");
        for (int i = 0; i < Math.min(10, myInBufferLength); ++i) {
          extraInfo.append(myInBuffer[myInBufferOffset + i]).append(",");
        }
        throw new ZipException(
            "Cannot inflate zip-compressed block, code = " + result + ";extra info = " + extraInfo);
      }
      final int in = (int) (result >> 16) & 0xFFFF;
      if (in > myInBufferLength) {
        throw new ZipException(
            "Invalid inflating result, code = " + result + "; buffer length = " + myInBufferLength);
      }
      final int out = (int) result & 0xFFFF;
      myInBufferOffset += in;
      myInBufferLength -= in;
      myOutBufferOffset = 0;
      myOutBufferLength = out;
      if ((result & (1L << 32)) != 0) {
        endInflating(myInflatorId);
        myInflatorId = -1;
        myStream.backSkip(myInBufferLength);
        break;
      }
    }
  }