/*LUCENE TO-DO Not in use
                internal void PrintSeekState(PrintStream @out)
                {
                  if (CurrentFrame == StaticFrame)
                  {
                    @out.println("  no prior seek");
                  }
                  else
                  {
                    @out.println("  prior seek state:");
                    int ord = 0;
                    bool isSeekFrame = true;
                    while (true)
                    {
                      Frame f = GetFrame(ord);
                      Debug.Assert(f != null);
                      BytesRef prefix = new BytesRef(Term_Renamed.Bytes, 0, f.Prefix);
                      if (f.NextEnt == -1)
                      {
                        @out.println("    frame " + (isSeekFrame ? "(seek)" : "(next)") + " ord=" + ord + " fp=" + f.Fp + (f.IsFloor ? (" (fpOrig=" + f.FpOrig + ")") : "") + " prefixLen=" + f.Prefix + " prefix=" + prefix + (f.NextEnt == -1 ? "" : (" (of " + f.EntCount + ")")) + " hasTerms=" + f.HasTerms + " isFloor=" + f.IsFloor + " code=" + ((f.Fp << BlockTreeTermsWriter.OUTPUT_FLAGS_NUM_BITS) + (f.HasTerms ? BlockTreeTermsWriter.OUTPUT_FLAG_HAS_TERMS:0) + (f.IsFloor ? BlockTreeTermsWriter.OUTPUT_FLAG_IS_FLOOR:0)) + " isLastInFloor=" + f.IsLastInFloor + " mdUpto=" + f.MetaDataUpto + " tbOrd=" + f.TermBlockOrd);
                      }
                      else
                      {
                        @out.println("    frame " + (isSeekFrame ? "(seek, loaded)" : "(next, loaded)") + " ord=" + ord + " fp=" + f.Fp + (f.IsFloor ? (" (fpOrig=" + f.FpOrig + ")") : "") + " prefixLen=" + f.Prefix + " prefix=" + prefix + " nextEnt=" + f.NextEnt + (f.NextEnt == -1 ? "" : (" (of " + f.EntCount + ")")) + " hasTerms=" + f.HasTerms + " isFloor=" + f.IsFloor + " code=" + ((f.Fp << BlockTreeTermsWriter.OUTPUT_FLAGS_NUM_BITS) + (f.HasTerms ? BlockTreeTermsWriter.OUTPUT_FLAG_HAS_TERMS:0) + (f.IsFloor ? BlockTreeTermsWriter.OUTPUT_FLAG_IS_FLOOR:0)) + " lastSubFP=" + f.LastSubFP + " isLastInFloor=" + f.IsLastInFloor + " mdUpto=" + f.MetaDataUpto + " tbOrd=" + f.TermBlockOrd);
                      }
                      if (OuterInstance.Index != null)
                      {
                        Debug.Assert(!isSeekFrame || f.Arc != null, "isSeekFrame=" + isSeekFrame + " f.arc=" + f.Arc);
                        if (f.Prefix > 0 && isSeekFrame && f.Arc.Label != (Term_Renamed.Bytes[f.Prefix - 1] & 0xFF))
                        {
                          @out.println("      broken seek state: arc.label=" + (char) f.Arc.Label + " vs term byte=" + (char)(Term_Renamed.Bytes[f.Prefix - 1] & 0xFF));
                          throw new Exception("seek state is broken");
                        }
                        BytesRef output = Util.Get(OuterInstance.Index, prefix);
                        if (output == null)
                        {
                          @out.println("      broken seek state: prefix is not final in index");
                          throw new Exception("seek state is broken");
                        }
                        else if (isSeekFrame && !f.IsFloor)
                        {
                          ByteArrayDataInput reader = new ByteArrayDataInput(output.Bytes, output.Offset, output.Length);
                          long codeOrig = reader.ReadVLong();
                          long code = (f.Fp << BlockTreeTermsWriter.OUTPUT_FLAGS_NUM_BITS) | (f.HasTerms ? BlockTreeTermsWriter.OUTPUT_FLAG_HAS_TERMS:0) | (f.IsFloor ? BlockTreeTermsWriter.OUTPUT_FLAG_IS_FLOOR:0);
                          if (codeOrig != code)
                          {
                            @out.println("      broken seek state: output code=" + codeOrig + " doesn't match frame code=" + code);
                            throw new Exception("seek state is broken");
                          }
                        }
                      }
                      if (f == CurrentFrame)
                      {
                        break;
                      }
                      if (f.Prefix == ValidIndexPrefix)
                      {
                        isSeekFrame = false;
                      }
                      ord++;
                    }
                  }
                }*/

                /* Decodes only the term bytes of the next term.  If caller then asks for
                   metadata, ie docFreq, totalTermFreq or pulls a D/&PEnum, we then (lazily)
                   decode all metadata up to the current term. */

                public override BytesRef Next()
                {
                    if (@in == null)
                    {
                        // Fresh TermsEnum; seek to first term:
                        FST<BytesRef>.Arc<BytesRef> arc;
                        if (OuterInstance.Index != null)
                        {
                            arc = OuterInstance.Index.GetFirstArc(Arcs[0]);
                            // Empty string prefix must have an output in the index!
                            Debug.Assert(arc.Final);
                        }
                        else
                        {
                            arc = null;
                        }
                        CurrentFrame = PushFrame(arc, OuterInstance.RootCode, 0);
                        CurrentFrame.LoadBlock();
                    }

                    TargetBeforeCurrentLength = CurrentFrame.Ord;

                    Debug.Assert(!Eof);
                    //if (DEBUG) {
                    //System.out.println("\nBTTR.next seg=" + segment + " term=" + brToString(term) + " termExists?=" + termExists + " field=" + fieldInfo.name + " termBlockOrd=" + currentFrame.state.termBlockOrd + " validIndexPrefix=" + validIndexPrefix);
                    //printSeekState();
                    //}

                    if (CurrentFrame == StaticFrame)
                    {
                        // If seek was previously called and the term was
                        // cached, or seek(TermState) was called, usually
                        // caller is just going to pull a D/&PEnum or get
                        // docFreq, etc.  But, if they then call next(),
                        // this method catches up all internal state so next()
                        // works properly:
                        //if (DEBUG) System.out.println("  re-seek to pending term=" + term.utf8ToString() + " " + term);
                        bool result = SeekExact(Term_Renamed);
                        Debug.Assert(result);
                    }

                    // Pop finished blocks
                    while (CurrentFrame.NextEnt == CurrentFrame.EntCount)
                    {
                        if (!CurrentFrame.IsLastInFloor)
                        {
                            CurrentFrame.LoadNextFloorBlock();
                        }
                        else
                        {
                            //if (DEBUG) System.out.println("  pop frame");
                            if (CurrentFrame.Ord == 0)
                            {
                                //if (DEBUG) System.out.println("  return null");
                                Debug.Assert(SetEOF());
                                Term_Renamed.Length = 0;
                                ValidIndexPrefix = 0;
                                CurrentFrame.Rewind();
                                TermExists = false;
                                return null;
                            }
                            long lastFP = CurrentFrame.FpOrig;
                            CurrentFrame = Stack[CurrentFrame.Ord - 1];

                            if (CurrentFrame.NextEnt == -1 || CurrentFrame.LastSubFP != lastFP)
                            {
                                // We popped into a frame that's not loaded
                                // yet or not scan'd to the right entry
                                CurrentFrame.ScanToFloorFrame(Term_Renamed);
                                CurrentFrame.LoadBlock();
                                CurrentFrame.ScanToSubBlock(lastFP);
                            }

                            // Note that the seek state (last seek) has been
                            // invalidated beyond this depth
                            ValidIndexPrefix = Math.Min(ValidIndexPrefix, CurrentFrame.Prefix);
                            //if (DEBUG) {
                            //System.out.println("  reset validIndexPrefix=" + validIndexPrefix);
                            //}
                        }
                    }

                    while (true)
                    {
                        if (CurrentFrame.Next())
                        {
                            // Push to new block:
                            //if (DEBUG) System.out.println("  push frame");
                            CurrentFrame = PushFrame(null, CurrentFrame.LastSubFP, Term_Renamed.Length);
                            // this is a "next" frame -- even if it's
                            // floor'd we must pretend it isn't so we don't
                            // try to scan to the right floor frame:
                            CurrentFrame.IsFloor = false;
                            //currentFrame.hasTerms = true;
                            CurrentFrame.LoadBlock();
                        }
                        else
                        {
                            //if (DEBUG) System.out.println("  return term=" + term.utf8ToString() + " " + term + " currentFrame.ord=" + currentFrame.ord);
                            return Term_Renamed;
                        }
                    }
                }
                /// <summary>
                /// Runs next() through the entire terms dict,
                ///  computing aggregate statistics.
                /// </summary>
                public Stats ComputeBlockStats()
                {
                    Stats stats = new Stats(OuterInstance.OuterInstance.Segment, OuterInstance.fieldInfo.Name);
                    if (OuterInstance.Index != null)
                    {
                        stats.IndexNodeCount = OuterInstance.Index.NodeCount;
                        stats.IndexArcCount = OuterInstance.Index.ArcCount;
                        stats.IndexNumBytes = OuterInstance.Index.SizeInBytes();
                    }

                    CurrentFrame = StaticFrame;
                    FST<BytesRef>.Arc<BytesRef> arc;
                    if (OuterInstance.Index != null)
                    {
                        arc = OuterInstance.Index.GetFirstArc(Arcs[0]);
                        // Empty string prefix must have an output in the index!
                        Debug.Assert(arc.Final);
                    }
                    else
                    {
                        arc = null;
                    }

                    // Empty string prefix must have an output in the
                    // index!
                    CurrentFrame = PushFrame(arc, OuterInstance.RootCode, 0);
                    CurrentFrame.FpOrig = CurrentFrame.Fp;
                    CurrentFrame.LoadBlock();
                    ValidIndexPrefix = 0;

                    stats.StartBlock(CurrentFrame, !(CurrentFrame.IsLastInFloor));

                    while (true)
                    {
                        // Pop finished blocks
                        while (CurrentFrame.NextEnt == CurrentFrame.EntCount)
                        {
                            stats.EndBlock(CurrentFrame);
                            if (!CurrentFrame.IsLastInFloor)
                            {
                                CurrentFrame.LoadNextFloorBlock();
                                stats.StartBlock(CurrentFrame, true);
                            }
                            else
                            {
                                if (CurrentFrame.Ord == 0)
                                {
                                    goto allTermsBreak;
                                }
                                long lastFP = CurrentFrame.FpOrig;
                                CurrentFrame = Stack[CurrentFrame.Ord - 1];
                                Debug.Assert(lastFP == CurrentFrame.LastSubFP);
                                // if (DEBUG) {
                                //   System.out.println("  reset validIndexPrefix=" + validIndexPrefix);
                                // }
                            }
                        }

                        while (true)
                        {
                            if (CurrentFrame.Next())
                            {
                                // Push to new block:
                                CurrentFrame = PushFrame(null, CurrentFrame.LastSubFP, Term_Renamed.Length);
                                CurrentFrame.FpOrig = CurrentFrame.Fp;
                                // this is a "next" frame -- even if it's
                                // floor'd we must pretend it isn't so we don't
                                // try to scan to the right floor frame:
                                CurrentFrame.IsFloor = false;
                                //currentFrame.hasTerms = true;
                                CurrentFrame.LoadBlock();
                                stats.StartBlock(CurrentFrame, !CurrentFrame.IsLastInFloor);
                            }
                            else
                            {
                                stats.Term(Term_Renamed);
                                break;
                            }
                        }
                        //allTermsContinue:;
                    }
                allTermsBreak:

                    stats.Finish();

                    // Put root frame back:
                    CurrentFrame = StaticFrame;
                    if (OuterInstance.Index != null)
                    {
                        arc = OuterInstance.Index.GetFirstArc(Arcs[0]);
                        // Empty string prefix must have an output in the index!
                        Debug.Assert(arc.Final);
                    }
                    else
                    {
                        arc = null;
                    }
                    CurrentFrame = PushFrame(arc, OuterInstance.RootCode, 0);
                    CurrentFrame.Rewind();
                    CurrentFrame.LoadBlock();
                    ValidIndexPrefix = 0;
                    Term_Renamed.Length = 0;

                    return stats;
                }