gt:             if (this.strategy != strategy) {
context: /*
   * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Oracle designates this
   * particular file as subject to the "Classpath" exception as provided
   * by Oracle in the LICENSE file that accompanied this code.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   */
  
  package java.util.zip;
  import org.checkerframework.checker.index.qual.*;
  
  /**
   * This class provides support for general purpose compression using the
   * popular ZLIB compression library. The ZLIB compression library was
   * initially developed as part of the PNG graphics standard and is not
   * protected by patents. It is fully described in the specifications at
   * the <a href="package-summary.html#package_description">java.util.zip
   * package description</a>.
   *
   * <p>The following code fragment demonstrates a trivial compression
   * and decompression of a string using <tt>Deflater</tt> and
   * <tt>Inflater</tt>.
   *
   * <blockquote><pre>
   * try {
   *     // Encode a String into bytes
   *     String inputString = "blahblahblah";
   *     byte[] input = inputString.getBytes("UTF-8");
   *
   *     // Compress the bytes
   *     byte[] output = new byte[100];
   *     Deflater compresser = new Deflater();
   *     compresser.setInput(input);
   *     compresser.finish();
   *     int compressedDataLength = compresser.deflate(output);
   *     compresser.end();
   *
   *     // Decompress the bytes
   *     Inflater decompresser = new Inflater();
   *     decompresser.setInput(output, 0, compressedDataLength);
   *     byte[] result = new byte[100];
   *     int resultLength = decompresser.inflate(result);
   *     decompresser.end();
   *
   *     // Decode the bytes into a String
   *     String outputString = new String(result, 0, resultLength, "UTF-8");
   * } catch(java.io.UnsupportedEncodingException ex) {
   *     // handle
   * } catch (java.util.zip.DataFormatException ex) {
   *     // handle
   * }
   * </pre></blockquote>
   *
   * @see         Inflater
   * @author      David Connelly
   */
  public
  class Deflater {
  
      private final ZStreamRef zsRef;
      private byte[] buf = new byte[0];
      private int off, len;
      private int level, strategy;
      private boolean setParams;
      private boolean finish, finished;
  
      /**
       * Compression method for the deflate algorithm (the only one currently
       * supported).
       */
      public static final int DEFLATED = 8;
  
      /**
       * Compression level for no compression.
       */
      public static final int NO_COMPRESSION = 0;
  
      /**
       * Compression level for fastest compression.
       */
      public static final int BEST_SPEED = 1;
  
      /**
       * Compression level for best compression.
       */
      public static final int BEST_COMPRESSION = 9;
  
      /**
       * Default compression level.
       */
      public static final int DEFAULT_COMPRESSION = -1;
  
      /**
       * Compression strategy best used for data consisting mostly of small
       * values with a somewhat random distribution. Forces more Huffman coding
       * and less string matching.
       */
      public static final int FILTERED = 1;
  
      /**
       * Compression strategy for Huffman coding only.
       */
      public static final int HUFFMAN_ONLY = 2;
  
      /**
       * Default compression strategy.
       */
      public static final int DEFAULT_STRATEGY = 0;
  
      /**
       * Compression flush mode used to achieve best compression result.
       *
       * @see Deflater#deflate(byte[], int, int, int)
       * @since 1.7
       */
      public static final int NO_FLUSH = 0;
  
      /**
       * Compression flush mode used to flush out all pending output; may
       * degrade compression for some compression algorithms.
       *
       * @see Deflater#deflate(byte[], int, int, int)
       * @since 1.7
       */
      public static final int SYNC_FLUSH = 2;
  
      /**
       * Compression flush mode used to flush out all pending output and
       * reset the deflater. Using this mode too often can seriously degrade
       * compression.
       *
       * @see Deflater#deflate(byte[], int, int, int)
       * @since 1.7
       */
      public static final int FULL_FLUSH = 3;
  
      static {
          /* Zip library is loaded from System.initializeSystemClass */
          initIDs();
      }
  
      /**
       * Creates a new compressor using the specified compression level.
       * If 'nowrap' is true then the ZLIB header and checksum fields will
       * not be used in order to support the compression format used in
       * both GZIP and PKZIP.
       * @param level the compression level (0-9)
       * @param nowrap if true then use GZIP compatible compression
       */
      public Deflater(int level, boolean nowrap) {
          this.level = level;
          this.strategy = DEFAULT_STRATEGY;
          this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
      }
  
      /**
       * Creates a new compressor using the specified compression level.
       * Compressed data will be generated in ZLIB format.
       * @param level the compression level (0-9)
       */
      public Deflater(int level) {
          this(level, false);
      }
  
      /**
       * Creates a new compressor with the default compression level.
       * Compressed data will be generated in ZLIB format.
       */
      public Deflater() {
          this(DEFAULT_COMPRESSION, false);
      }
  
      /**
       * Sets input data for compression. This should be called whenever
       * needsInput() returns true indicating that more input data is required.
       * @param b the input data bytes
       * @param off the start offset of the data
       * @param len the length of the data
       * @see Deflater#needsInput
       */
      public void setInput(byte[] b, @IndexFor("#1") int off, @IndexOrHigh("#1") int len) {
          if (b== null) {
              throw new NullPointerException();
          }
          if (off < 0 || len < 0 || off > b.length - len) {
              throw new ArrayIndexOutOfBoundsException();
          }
          synchronized (zsRef) {
              this.buf = b;
              this.off = off;
              this.len = len;
          }
      }
  
      /**
       * Sets input data for compression. This should be called whenever
       * needsInput() returns true indicating that more input data is required.
       * @param b the input data bytes
       * @see Deflater#needsInput
       */
      public void setInput(byte[] b) {
          setInput(b, 0, b.length);
      }
  
      /**
       * Sets preset dictionary for compression. A preset dictionary is used
       * when the history buffer can be predetermined. When the data is later
       * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
       * in order to get the Adler-32 value of the dictionary required for
       * decompression.
       * @param b the dictionary data bytes
       * @param off the start offset of the data
       * @param len the length of the data
       * @see Inflater#inflate
       * @see Inflater#getAdler
       */
      public void setDictionary(byte[] b, @IndexFor("#1") int off, @IndexOrHigh("#1") int len) {
          if (b == null) {
              throw new NullPointerException();
          }
          if (off < 0 || len < 0 || off > b.length - len) {
              throw new ArrayIndexOutOfBoundsException();
          }
          synchronized (zsRef) {
              ensureOpen();
              setDictionary(zsRef.address(), b, off, len);
          }
      }
  
      /**
       * Sets preset dictionary for compression. A preset dictionary is used
       * when the history buffer can be predetermined. When the data is later
       * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
       * in order to get the Adler-32 value of the dictionary required for
       * decompression.
       * @param b the dictionary data bytes
       * @see Inflater#inflate
       * @see Inflater#getAdler
       */
      public void setDictionary(byte[] b) {
          setDictionary(b, 0, b.length);
      }
  
      /**
       * Sets the compression strategy to the specified value.
       * @param strategy the new compression strategy
       * @exception IllegalArgumentException if the compression strategy is
       *                                     invalid
       */
      public void setStrategy(int strategy) {
          switch (strategy) {
            case DEFAULT_STRATEGY:
            case FILTERED:
            case HUFFMAN_ONLY:
              break;
            default:
              throw new IllegalArgumentException();
          }
          synchronized (zsRef) {
  