Also, understand that everything that state holds is mutable.  The deflater is the native JVM deflater, and can only be used in a mutable way.  Same with CRC32.  The buffer is mutable too, the way it works is you pass it to the JVM deflater and ask it to give you any bytes that it has, it may only give you a few (because it compressed them), and you don't want to send this to the client immediately, nor do you want to waste the remaining space in the buffer, so you save it, and feed it back in to the deflater next time you get some input with the new offset.  This is the same way that GZIPOutputStream works.  So since everything inside state is and must be mutable, state is inherently a mutable object that the code must not be sure not to ever access concurrently.  Because of that property, using vars seemed also natural.