private bool DeflateFast(bool flush, bool finish)
        {
            if (lookahead < MIN_LOOKAHEAD && !flush)
            {
                return(false);
            }

            while (lookahead >= MIN_LOOKAHEAD || flush)
            {
                if (lookahead == 0)
                {
                    /* We are flushing everything */
                    huffman.FlushBlock(window, blockStart, strstart - blockStart, finish);
                    blockStart = strstart;
                    return(false);
                }

                if (strstart > 2 * WSIZE - MIN_LOOKAHEAD)
                {
                    /* slide window, as findLongestMatch needs this.
                     * This should only happen when flushing and the window
                     * is almost full.
                     */
                    SlideWindow();
                }

                int hashHead;
                if (lookahead >= MIN_MATCH &&
                    (hashHead = InsertString()) != 0 &&
                    strategy != DeflateStrategy.HuffmanOnly &&
                    strstart - hashHead <= MAX_DIST &&
                    FindLongestMatch(hashHead))
                {
                    /* longestMatch sets matchStart and matchLen */
                    //					if (DeflaterConstants.DEBUGGING) {
                    //						for (int i = 0 ; i < matchLen; i++) {
                    //							if (window[strstart+i] != window[matchStart + i]) {
                    //								throw new SharpZipBaseException();
                    //							}
                    //						}
                    //					}

                    // -jr- Hak hak hak this stops problems with fast/low compression and index out of range
                    if (huffman.TallyDist(strstart - matchStart, matchLen))
                    {
                        bool lastBlock = finish && lookahead == 0;
                        huffman.FlushBlock(window, blockStart, strstart - blockStart, lastBlock);
                        blockStart = strstart;
                    }

                    lookahead -= matchLen;
                    if (matchLen <= max_lazy && lookahead >= MIN_MATCH)
                    {
                        while (--matchLen > 0)
                        {
                            ++strstart;
                            InsertString();
                        }
                        ++strstart;
                    }
                    else
                    {
                        strstart += matchLen;
                        if (lookahead >= MIN_MATCH - 1)
                        {
                            UpdateHash();
                        }
                    }
                    matchLen = MIN_MATCH - 1;
                    continue;
                }
                else
                {
                    /* No match found */
                    huffman.TallyLit(window[strstart] & 0xff);
                    ++strstart;
                    --lookahead;
                }

                if (huffman.IsFull())
                {
                    bool lastBlock = finish && lookahead == 0;
                    huffman.FlushBlock(window, blockStart, strstart - blockStart, lastBlock);
                    blockStart = strstart;
                    return(!lastBlock);
                }
            }
            return(true);
        }