/// <summary>
        /// Given a sequence, applies our patterns over the sequence and returns
        /// all non overlapping matches.
        /// </summary>
        /// <remarks>
        /// Given a sequence, applies our patterns over the sequence and returns
        /// all non overlapping matches.  When multiple patterns overlaps,
        /// matched patterns are selected by order specified by the comparator
        /// </remarks>
        /// <param name="elements">input sequence to match against</param>
        /// <param name="cmp">comparator indicating order that overlapped sequences should be selected.</param>
        /// <returns>list of match results that are non-overlapping</returns>
        public virtual IList <ISequenceMatchResult <T> > FindNonOverlapping <_T0, _T1>(IList <_T0> elements, IComparator <_T1> cmp)
            where _T0 : T
        {
            ICollection <SequencePattern <T> > triggered = GetTriggeredPatterns(elements);
            IList <ISequenceMatchResult <T> >  all       = new List <ISequenceMatchResult <T> >();
            int i = 0;

            foreach (SequencePattern <T> p in triggered)
            {
                if (Thread.Interrupted())
                {
                    // Allow interrupting
                    throw new RuntimeInterruptedException();
                }
                SequenceMatcher <T> m = p.GetMatcher(elements);
                m.SetMatchWithResult(matchWithResult);
                m.SetOrder(i);
                while (m.Find())
                {
                    all.Add(m.ToBasicSequenceMatchResult());
                }
                i++;
            }
            IList <ISequenceMatchResult <T> > res = IntervalTree.GetNonOverlapping(all, SequenceMatchResultConstants.ToInterval, cmp);

            res.Sort(SequenceMatchResultConstants.OffsetComparator);
            return(res);
        }
        /// <summary>
        /// Given a sequence, applies our patterns over the sequence and returns
        /// all non overlapping matches.
        /// </summary>
        /// <remarks>
        /// Given a sequence, applies our patterns over the sequence and returns
        /// all non overlapping matches.  When multiple patterns overlaps,
        /// matched patterns are selected to give the overall maximum score.
        /// </remarks>
        /// <param name="elements">input sequence to match against</param>
        /// <param name="scorer">scorer for scoring each match</param>
        /// <returns>list of match results that are non-overlapping</returns>
        public virtual IList <ISequenceMatchResult <T> > FindNonOverlappingMaxScore <_T0, _T1>(IList <_T0> elements, IToDoubleFunction <_T1> scorer)
            where _T0 : T
        {
            ICollection <SequencePattern <T> > triggered = GetTriggeredPatterns(elements);
            IList <ISequenceMatchResult <T> >  all       = new List <ISequenceMatchResult <T> >();
            int i = 0;

            foreach (SequencePattern <T> p in triggered)
            {
                SequenceMatcher <T> m = p.GetMatcher(elements);
                m.SetMatchWithResult(matchWithResult);
                m.SetOrder(i);
                while (m.Find())
                {
                    all.Add(m.ToBasicSequenceMatchResult());
                }
                i++;
            }
            IList <ISequenceMatchResult <T> > res = IntervalTree.GetNonOverlappingMaxScore(all, SequenceMatchResultConstants.ToInterval, scorer);

            res.Sort(SequenceMatchResultConstants.OffsetComparator);
            return(res);
        }