public IEnumerable <TermMatch> Matches(IMessageActivity input, object defaultValue)
        {
            var inputText = MessageActivityHelper.GetSanitizedTextInput(input);

            // if the user hit enter on an optional prompt, then consider taking the current choice as a low confidence option
            bool userSkippedPrompt = string.IsNullOrWhiteSpace(inputText) && (defaultValue != null || _noPreference != null);

            if (userSkippedPrompt)
            {
                yield return(new TermMatch(0, inputText.Length, 1.0, defaultValue));
            }
            inputText = MessageActivityHelper.RemoveDiacritics(inputText);
            foreach (var expression in _expressions)
            {
                double maxWords = expression.MaxWords;
                foreach (Match match in expression.Expression.Matches(inputText))
                {
                    var    group1 = match.Groups[1];
                    var    group2 = match.Groups[2];
                    object newValue;
                    if (group1.Success)
                    {
                        if (ConvertSpecial(expression.Value, defaultValue, out newValue))
                        {
                            yield return(new TermMatch(group1.Index, group1.Length, 1.0, newValue));
                        }
                    }
                    if (group2.Success)
                    {
                        var words      = group2.Value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Length;
                        var confidence = System.Math.Min(words / maxWords, 1.0);
                        if (ConvertSpecial(expression.Value, defaultValue, out newValue))
                        {
                            yield return(new TermMatch(group2.Index, group2.Length, confidence, newValue));
                        }
                    }
                }
            }
        }
        private int AddExpression(int n, object value, IEnumerable <string> terms, bool allowNumbers)
        {
            var orderedTerms = (from term in terms orderby term.Length descending select MessageActivityHelper.RemoveDiacritics(term)).ToArray();
            var words        = new StringBuilder();
            var first        = true;
            int maxWords     = 0;

            if (orderedTerms.Length > 0)
            {
                maxWords = terms.Max(NumberOfWords);
                foreach (var term in orderedTerms)
                {
                    var nterm = term.Trim().Replace(" ", @"\s+");
                    if (nterm != "")
                    {
                        if (first)
                        {
                            first = false;
                            words.Append('(');
                        }
                        else
                        {
                            words.Append('|');
                        }
                        words.Append("(?:");
                        if (_wordStart.Match(nterm).Success&& _wordEnd.Match(nterm).Success)
                        {
                            words.Append($@"\b{nterm}\b");
                        }
                        else
                        {
                            words.Append(nterm);
                        }
                        words.Append(')');
                    }
                }
            }
            if (first)
            {
                words.Append($@"(\b(?:{NOMATCH})");
            }
            words.Append(')');
            var numbers = allowNumbers ? $"(\\b{n}\\b)" : NOMATCH;
            var expr    = $"{numbers}|{words}";

            _expressions.Add(new ValueAndExpression(value, new Regex(expr.ToString(), RegexOptions.IgnoreCase), maxWords));
            ++n;
            return(n);
        }