public override MergeSpecification FindForcedMerges(SegmentInfos infos, int maxSegmentCount, IDictionary <SegmentCommitInfo, bool?> segmentsToMerge)
        {
            if (Verbose())
            {
                Message("findForcedMerges maxSegmentCount=" + maxSegmentCount + " infos=" + Writer.Get().SegString(infos.Segments) + " segmentsToMerge=" + segmentsToMerge);
            }

            List <SegmentCommitInfo> eligible       = new List <SegmentCommitInfo>();
            bool forceMergeRunning                  = false;
            ICollection <SegmentCommitInfo> merging = Writer.Get().MergingSegments;
            bool?segmentIsOriginal                  = false;

            foreach (SegmentCommitInfo info in infos.Segments)
            {
                bool?isOriginal = segmentsToMerge[info];
                if (isOriginal != null)
                {
                    segmentIsOriginal = isOriginal;
                    if (!merging.Contains(info))
                    {
                        eligible.Add(info);
                    }
                    else
                    {
                        forceMergeRunning = true;
                    }
                }
            }

            if (eligible.Count == 0)
            {
                return(null);
            }

            if ((maxSegmentCount > 1 && eligible.Count <= maxSegmentCount) || (maxSegmentCount == 1 && eligible.Count == 1 && (segmentIsOriginal == false || IsMerged(infos, eligible[0]))))
            {
                if (Verbose())
                {
                    Message("already merged");
                }
                return(null);
            }

            eligible.Sort(new SegmentByteSizeDescending(this));

            if (Verbose())
            {
                Message("eligible=" + eligible);
                Message("forceMergeRunning=" + forceMergeRunning);
            }

            int end = eligible.Count;

            MergeSpecification spec = null;

            // Do full merges, first, backwards:
            while (end >= MaxMergeAtOnceExplicit_Renamed + maxSegmentCount - 1)
            {
                if (spec == null)
                {
                    spec = new MergeSpecification();
                }
                OneMerge merge = new OneMerge(eligible.SubList(end - MaxMergeAtOnceExplicit_Renamed, end));
                if (Verbose())
                {
                    Message("add merge=" + Writer.Get().SegString(merge.Segments));
                }
                spec.Add(merge);
                end -= MaxMergeAtOnceExplicit_Renamed;
            }

            if (spec == null && !forceMergeRunning)
            {
                // Do final merge
                int      numToMerge = end - maxSegmentCount + 1;
                OneMerge merge      = new OneMerge(eligible.SubList(end - numToMerge, end));
                if (Verbose())
                {
                    Message("add final merge=" + merge.SegString(Writer.Get().Directory));
                }
                spec = new MergeSpecification();
                spec.Add(merge);
            }

            return(spec);
        }