private Pair <IList <ICoreMap>, IList <T> > ApplyCompositeRule <_T0>(SequenceMatchRules.IExtractRule <IList <ICoreMap>, T> compositeExtractRule, IList <_T0> merged, IList <T> matchedExpressions, int limit)
            where _T0 : ICoreMap
        {
            // Apply higher order rules
            bool done = false;
            // Limit of number of times rules are applied just in case
            int maxIters = limit;
            int iters    = 0;

            while (!done)
            {
                IList <T> newExprs  = new List <T>();
                bool      extracted = compositeExtractRule.Extract(merged, newExprs);
                if (verbose && extracted)
                {
                    log.Info("applyCompositeRule() extracting with " + compositeExtractRule + " from " + merged + " gives " + newExprs);
                }
                if (extracted)
                {
                    AnnotateExpressions(merged, newExprs);
                    newExprs = MatchedExpression.RemoveNullValues(newExprs);
                    if (!newExprs.IsEmpty())
                    {
                        newExprs = MatchedExpression.RemoveNested(newExprs);
                        newExprs = MatchedExpression.RemoveOverlapping(newExprs);
                        merged   = MatchedExpression.ReplaceMerged(merged, newExprs);
                        // Favor newly matched expressions over older ones
                        Sharpen.Collections.AddAll(newExprs, matchedExpressions);
                        matchedExpressions = MatchedExpression.RemoveNested(newExprs);
                        matchedExpressions = MatchedExpression.RemoveOverlapping(matchedExpressions);
                    }
                    else
                    {
                        extracted = false;
                    }
                }
                done = !extracted;
                iters++;
                if (maxIters > 0 && iters >= maxIters)
                {
                    if (verbose)
                    {
                        log.Warn("Aborting application of composite rules: Maximum iteration " + maxIters + " reached");
                    }
                    break;
                }
            }
            return(new Pair <IList <ICoreMap>, IList <T> >(merged, matchedExpressions));
        }