//for (int i=0; i<tags.length; i++)
 //System.out.print(tags[i]+" ");
 //System.out.println("\nWith "+tag+" score was "+score);
 public virtual BeamBestSequenceFinder.TagSeq Tclone()
 {
     BeamBestSequenceFinder.TagSeq o = new BeamBestSequenceFinder.TagSeq();
     o.info  = info;
     o.size  = size;
     o.score = score;
     return(o);
 }
        public virtual int[] BestSequence(ISequenceModel ts, int size)
        {
            // Set up tag options
            int length      = ts.Length();
            int leftWindow  = ts.LeftWindow();
            int rightWindow = ts.RightWindow();
            int padLength   = length + leftWindow + rightWindow;

            int[][] tags   = new int[padLength][];
            int[]   tagNum = new int[padLength];
            for (int pos = 0; pos < padLength; pos++)
            {
                tags[pos]   = ts.GetPossibleValues(pos);
                tagNum[pos] = tags[pos].Length;
            }
            Beam newBeam = new Beam(beamSize, ScoredComparator.AscendingComparator);

            BeamBestSequenceFinder.TagSeq initSeq = new BeamBestSequenceFinder.TagSeq();
            newBeam.Add(initSeq);
            for (int pos_1 = 0; pos_1 < padLength; pos_1++)
            {
                if (Thread.Interrupted())
                {
                    // Allow interrupting
                    throw new RuntimeInterruptedException();
                }
                //System.out.println("scoring word " + pos + " / " + (leftWindow + length) + ", tagNum = " + tagNum[pos] + "...");
                //System.out.flush();
                Beam oldBeam = newBeam;
                if (pos_1 < leftWindow + rightWindow && exhaustiveStart)
                {
                    newBeam = new Beam(100000, ScoredComparator.AscendingComparator);
                }
                else
                {
                    newBeam = new Beam(beamSize, ScoredComparator.AscendingComparator);
                }
                // each hypothesis gets extended and beamed
                foreach (object anOldBeam in oldBeam)
                {
                    if (Thread.Interrupted())
                    {
                        // Allow interrupting
                        throw new RuntimeInterruptedException();
                    }
                    // System.out.print("#"); System.out.flush();
                    BeamBestSequenceFinder.TagSeq tagSeq = (BeamBestSequenceFinder.TagSeq)anOldBeam;
                    for (int nextTagNum = 0; nextTagNum < tagNum[pos_1]; nextTagNum++)
                    {
                        BeamBestSequenceFinder.TagSeq nextSeq = tagSeq.Tclone();
                        if (pos_1 >= leftWindow + rightWindow)
                        {
                            nextSeq.ExtendWith(tags[pos_1][nextTagNum], ts, size);
                        }
                        else
                        {
                            nextSeq.ExtendWith(tags[pos_1][nextTagNum]);
                        }
                        //System.out.println("Created: "+nextSeq.score()+" %% "+arrayToString(nextSeq.tags(), nextSeq.size()));
                        newBeam.Add(nextSeq);
                    }
                }
                //		System.out.println("Beam size: "+newBeam.size()+" of "+beamSize);
                //System.out.println("Best is: "+((Scored)newBeam.iterator().next()).score());
                // System.out.println(" done");
                if (recenter)
                {
                    double max = double.NegativeInfinity;
                    foreach (object aNewBeam1 in newBeam)
                    {
                        BeamBestSequenceFinder.TagSeq tagSeq = (BeamBestSequenceFinder.TagSeq)aNewBeam1;
                        if (tagSeq.score > max)
                        {
                            max = tagSeq.score;
                        }
                    }
                    foreach (object aNewBeam in newBeam)
                    {
                        BeamBestSequenceFinder.TagSeq tagSeq = (BeamBestSequenceFinder.TagSeq)aNewBeam;
                        tagSeq.score -= max;
                    }
                }
            }
            try
            {
                BeamBestSequenceFinder.TagSeq bestSeq = (BeamBestSequenceFinder.TagSeq)newBeam.GetEnumerator().Current;
                int[] seq = bestSeq.Tags();
                return(seq);
            }
            catch (NoSuchElementException)
            {
                log.Info("Beam empty -- no best sequence.");
                return(null);
            }
        }