public virtual IList <T> ExtractExpressions(ICoreMap annotation)
        {
            // Extract potential expressions
            IList <T>   matchedExpressions = new List <T>();
            IList <int> stageIds           = new List <int>(stages.Keys);

            stageIds.Sort();
            foreach (int stageId in stageIds)
            {
                CoreMapExpressionExtractor.Stage <T>          stage            = stages[stageId];
                SequenceMatchRules.IExtractRule <ICoreMap, T> basicExtractRule = stage.basicExtractRule;
                if (stage.clearMatched)
                {
                    matchedExpressions.Clear();
                }
                if (basicExtractRule != null)
                {
                    basicExtractRule.Extract(annotation, matchedExpressions);
                    if (verbose && matchedExpressions != null)
                    {
                        log.Info("extractExpressions() extracting with " + basicExtractRule + " from " + annotation + " gives " + matchedExpressions);
                    }
                    AnnotateExpressions(annotation, matchedExpressions);
                    matchedExpressions = MatchedExpression.RemoveNullValues(matchedExpressions);
                    matchedExpressions = MatchedExpression.RemoveNested(matchedExpressions);
                    matchedExpressions = MatchedExpression.RemoveOverlapping(matchedExpressions);
                }
                IList <ICoreMap> merged = MatchedExpression.ReplaceMergedUsingTokenOffsets(annotation.Get(tokensAnnotationKey), matchedExpressions);
                SequenceMatchRules.IExtractRule <IList <ICoreMap>, T> compositeExtractRule = stage.compositeExtractRule;
                if (compositeExtractRule != null)
                {
                    Pair <IList <ICoreMap>, IList <T> > p = ApplyCompositeRule(compositeExtractRule, merged, matchedExpressions, stage.limitIters);
                    merged             = p.First();
                    matchedExpressions = p.Second();
                }
                matchedExpressions = FilterInvalidExpressions(stage.filterRule, matchedExpressions);
            }
            matchedExpressions.Sort(MatchedExpression.ExprTokenOffsetsNestedFirstComparator);
            if (!keepTags)
            {
                CleanupTags(annotation);
            }
            return(matchedExpressions);
        }