public override int Advance(int target)
            {
                // TODO: make frq block load lazy/skippable
                // if (DEBUG) {
                //   System.out.println("  FPR.advance target=" + target);
                // }

                // current skip docID < docIDs generated from current buffer <= next skip docID
                // we don't need to skip if target is buffered already
                if (DocFreq > Lucene41PostingsFormat.BLOCK_SIZE && target > NextSkipDoc)
                {
                    // if (DEBUG) {
                    //   System.out.println("load skipper");
                    // }

                    if (Skipper == null)
                    {
                        // Lazy init: first time this enum has ever been used for skipping
                        Skipper = new Lucene41SkipReader((IndexInput)DocIn.Clone(), Lucene41PostingsWriter.MaxSkipLevels, Lucene41PostingsFormat.BLOCK_SIZE, IndexHasPos, IndexHasOffsets, IndexHasPayloads);
                    }

                    if (!Skipped)
                    {
                        Debug.Assert(SkipOffset != -1);
                        // this is the first time this enum has skipped
                        // since reset() was called; load the skip data:
                        Skipper.Init(DocTermStartFP + SkipOffset, DocTermStartFP, 0, 0, DocFreq);
                        Skipped = true;
                    }

                    // always plus one to fix the result, since skip position in Lucene41SkipReader
                    // is a little different from MultiLevelSkipListReader
                    int newDocUpto = Skipper.SkipTo(target) + 1;

                    if (newDocUpto > DocUpto)
                    {
                        // Skipper moved
                        // if (DEBUG) {
                        //   System.out.println("skipper moved to docUpto=" + newDocUpto + " vs current=" + docUpto + "; docID=" + skipper.getDoc() + " fp=" + skipper.getDocPointer());
                        // }
                        Debug.Assert(newDocUpto % Lucene41PostingsFormat.BLOCK_SIZE == 0, "got " + newDocUpto);
                        DocUpto = newDocUpto;

                        // Force to read next block
                        DocBufferUpto = Lucene41PostingsFormat.BLOCK_SIZE;
                        Accum = Skipper.Doc; // actually, this is just lastSkipEntry
                        DocIn.Seek(Skipper.DocPointer); // now point to the block we want to search
                    }
                    // next time we call advance, this is used to
                    // foresee whether skipper is necessary.
                    NextSkipDoc = Skipper.NextSkipDoc;
                }
                if (DocUpto == DocFreq)
                {
                    return Doc = NO_MORE_DOCS;
                }
                if (DocBufferUpto == Lucene41PostingsFormat.BLOCK_SIZE)
                {
                    RefillDocs();
                }

                // Now scan... this is an inlined/pared down version
                // of nextDoc():
                while (true)
                {
                    // if (DEBUG) {
                    //   System.out.println("  scan doc=" + accum + " docBufferUpto=" + docBufferUpto);
                    // }
                    Accum += DocDeltaBuffer[DocBufferUpto];
                    DocUpto++;

                    if (Accum >= target)
                    {
                        break;
                    }
                    DocBufferUpto++;
                    if (DocUpto == DocFreq)
                    {
                        return Doc = NO_MORE_DOCS;
                    }
                }

                if (LiveDocs == null || LiveDocs.Get(Accum))
                {
                    // if (DEBUG) {
                    //   System.out.println("  return doc=" + accum);
                    // }
                    Freq_Renamed = FreqBuffer[DocBufferUpto];
                    DocBufferUpto++;
                    return Doc = Accum;
                }
                else
                {
                    // if (DEBUG) {
                    //   System.out.println("  now do nextDoc()");
                    // }
                    DocBufferUpto++;
                    return NextDoc();
                }
            }
            public override int Advance(int target)
            {
                // TODO: make frq block load lazy/skippable
                // if (DEBUG) {
                //   System.out.println("  FPR.advance target=" + target);
                // }

                if (DocFreq > Lucene41PostingsFormat.BLOCK_SIZE && target > NextSkipDoc)
                {
                    // if (DEBUG) {
                    //   System.out.println("    try skipper");
                    // }
                    if (Skipper == null)
                    {
                        // Lazy init: first time this enum has ever been used for skipping
                        // if (DEBUG) {
                        //   System.out.println("    create skipper");
                        // }
                        Skipper = new Lucene41SkipReader((IndexInput)DocIn.Clone(), Lucene41PostingsWriter.MaxSkipLevels, Lucene41PostingsFormat.BLOCK_SIZE, true, IndexHasOffsets, IndexHasPayloads);
                    }

                    if (!Skipped)
                    {
                        Debug.Assert(SkipOffset != -1);
                        // this is the first time this enum has skipped
                        // since reset() was called; load the skip data:
                        // if (DEBUG) {
                        //   System.out.println("    init skipper");
                        // }
                        Skipper.Init(DocTermStartFP + SkipOffset, DocTermStartFP, PosTermStartFP, PayTermStartFP, DocFreq);
                        Skipped = true;
                    }

                    int newDocUpto = Skipper.SkipTo(target) + 1;

                    if (newDocUpto > DocUpto)
                    {
                        // Skipper moved
                        // if (DEBUG) {
                        //   System.out.println("    skipper moved to docUpto=" + newDocUpto + " vs current=" + docUpto + "; docID=" + skipper.getDoc() + " fp=" + skipper.getDocPointer() + " pos.fp=" + skipper.getPosPointer() + " pos.bufferUpto=" + skipper.getPosBufferUpto());
                        // }

                        Debug.Assert(newDocUpto % Lucene41PostingsFormat.BLOCK_SIZE == 0, "got " + newDocUpto);
                        DocUpto = newDocUpto;

                        // Force to read next block
                        DocBufferUpto = Lucene41PostingsFormat.BLOCK_SIZE;
                        Accum = Skipper.Doc;
                        DocIn.Seek(Skipper.DocPointer);
                        PosPendingFP = Skipper.PosPointer;
                        PosPendingCount = Skipper.PosBufferUpto;
                    }
                    NextSkipDoc = Skipper.NextSkipDoc;
                }
                if (DocUpto == DocFreq)
                {
                    return Doc = NO_MORE_DOCS;
                }
                if (DocBufferUpto == Lucene41PostingsFormat.BLOCK_SIZE)
                {
                    RefillDocs();
                }

                // Now scan... this is an inlined/pared down version
                // of nextDoc():
                while (true)
                {
                    // if (DEBUG) {
                    //   System.out.println("  scan doc=" + accum + " docBufferUpto=" + docBufferUpto);
                    // }
                    Accum += DocDeltaBuffer[DocBufferUpto];
                    Freq_Renamed = FreqBuffer[DocBufferUpto];
                    PosPendingCount += Freq_Renamed;
                    DocBufferUpto++;
                    DocUpto++;

                    if (Accum >= target)
                    {
                        break;
                    }
                    if (DocUpto == DocFreq)
                    {
                        return Doc = NO_MORE_DOCS;
                    }
                }

                if (LiveDocs == null || LiveDocs.Get(Accum))
                {
                    // if (DEBUG) {
                    //   System.out.println("  return doc=" + accum);
                    // }
                    Position = 0;
                    return Doc = Accum;
                }
                else
                {
                    // if (DEBUG) {
                    //   System.out.println("  now do nextDoc()");
                    // }
                    return NextDoc();
                }
            }