public virtual int[] BestSequence(ISequenceModel ts, int size)
        {
            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;
            }

            var newBeam = new Beam<TagSeq>(beamSize, ScoredComparator.ASCENDING_COMPARATOR);
            TagSeq initSeq = new TagSeq();
            newBeam.Add(initSeq);
            for (int pos = 0; pos < padLength; pos++)
            {
                var oldBeam = newBeam;
                if (pos < leftWindow + rightWindow && exhaustiveStart)
                {
                    newBeam = new Beam<TagSeq>(100000, ScoredComparator.ASCENDING_COMPARATOR);
                }
                else
                {
                    newBeam = new Beam<TagSeq>(beamSize, ScoredComparator.ASCENDING_COMPARATOR);
                }

                for (IEnumerator beamI = oldBeam.GetEnumerator(); beamI.MoveNext(); )
                {
                    Console.Out.Write(@"#");
                    Console.Out.Flush();
                    TagSeq tagSeq = (TagSeq)beamI.Current;
                    for (int nextTagNum = 0; nextTagNum < tagNum[pos]; nextTagNum++)
                    {
                        TagSeq nextSeq = tagSeq.Tclone();
                        if (pos >= leftWindow + rightWindow)
                        {
                            nextSeq.ExtendWith(tags[pos][nextTagNum], ts, size);
                        }
                        else
                        {
                            nextSeq.ExtendWith(tags[pos][nextTagNum]);
                        }

                        newBeam.Add(nextSeq);
                    }
                }

                Console.Out.WriteLine(@" done");
                if (recenter)
                {
                    double max = Double.NegativeInfinity;
                    for (IEnumerator beamI = newBeam.GetEnumerator(); beamI.MoveNext(); )
                    {
                        TagSeq tagSeq = (TagSeq)beamI.Current;
                        if (tagSeq.score > max)
                        {
                            max = tagSeq.score;
                        }
                    }

                    for (IEnumerator beamI = newBeam.GetEnumerator(); beamI.MoveNext(); )
                    {
                        TagSeq tagSeq = (TagSeq)beamI.Current;
                        tagSeq.score -= max;
                    }
                }
            }

            try
            {
                var enumerator = newBeam.GetEnumerator();
                if (enumerator.MoveNext())
                {
                    TagSeq bestSeq = enumerator.Current;
                    int[] seq = bestSeq.Tags();
                    return seq;
                }
                else
                    return null;
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(@"Beam empty -- no best sequence.");
                return null;
            }
        }
 public virtual TagSeq Tclone()
 {
     TagSeq o = new TagSeq();
     o.info = info;
     o.size = size;
     o.score = score;
     return o;
 }