/// <summary>
        /// Merges the two instances of result items together (joins the values and adjusts TextSpan)
        /// </summary>
        protected override void ConcatenateWithPreviousResult(IList results, CodeStringResultItem previouslyAddedItem, CodeStringResultItem resultItem)
        {
            string textBetween = text.Substring(previouslyAddedItem.AbsoluteCharOffset + previouslyAddedItem.AbsoluteCharLength - OriginalAbsoluteOffset, resultItem.AbsoluteCharOffset - previouslyAddedItem.AbsoluteCharOffset - previouslyAddedItem.AbsoluteCharLength);

            if (Regex.IsMatch(textBetween, CSharpConcateningRegexp))
            {
                results.RemoveAt(results.Count - 1);

                base.ConcatenateWithPreviousResult(results, previouslyAddedItem, resultItem);
            }
        }
        /// <summary>
        /// Merges the two instances of result items together (joins the values and adjusts TextSpan)
        /// </summary>
        protected virtual void ConcatenateWithPreviousResult(IList results, CodeStringResultItem previouslyAddedItem, CodeStringResultItem resultItem)
        {
            string textBetween = text.Substring(previouslyAddedItem.AbsoluteCharOffset + previouslyAddedItem.AbsoluteCharLength - OriginalAbsoluteOffset, resultItem.AbsoluteCharOffset - previouslyAddedItem.AbsoluteCharOffset - previouslyAddedItem.AbsoluteCharLength);

            previouslyAddedItem.Value              += resultItem.Value;
            previouslyAddedItem.WasVerbatim         = previouslyAddedItem.WasVerbatim || resultItem.WasVerbatim;
            previouslyAddedItem.AbsoluteCharLength += textBetween.Length + resultItem.AbsoluteCharLength;
            previouslyAddedItem.IsMarkedWithUnlocalizableComment = previouslyAddedItem.IsMarkedWithUnlocalizableComment || resultItem.IsMarkedWithUnlocalizableComment;

            TextSpan newSpan = new TextSpan();

            newSpan.iStartLine              = previouslyAddedItem.ReplaceSpan.iStartLine;
            newSpan.iStartIndex             = previouslyAddedItem.ReplaceSpan.iStartIndex;
            newSpan.iEndLine                = resultItem.ReplaceSpan.iEndLine;
            newSpan.iEndIndex               = resultItem.ReplaceSpan.iEndIndex;
            previouslyAddedItem.ReplaceSpan = newSpan;
        }
        /// <summary>
        /// Returns criteria displayed in toolwindow's filter, used to calculate localization probability
        /// </summary>
        public static new Dictionary <string, LocalizationCommonCriterion> GetCriteria()
        {
            var localizationCriteriaList = CodeStringResultItem.GetCriteria();

            var comesFromElementPredicate = new LocalizationCommonCriterion("ComesFromElement",
                                                                            "String comes from ASP .NET element attribute",
                                                                            LocalizationCriterionAction.VALUE, 10,
                                                                            (item) => { var i = (item as AspNetStringResultItem); return(i == null ? (bool?)null : i.ComesFromElement); });

            var comesFromInlineExpressionPredicate = new LocalizationCommonCriterion("ComesFromInlineExpression",
                                                                                     "String comes from ASP .NET inline expression",
                                                                                     LocalizationCriterionAction.VALUE, -20,
                                                                                     (item) => { var i = (item as AspNetStringResultItem); return(i == null ? (bool?)null : i.ComesFromInlineExpression); });

            var localizabilityProvedPredicate = new LocalizationCommonCriterion("LocalizabilityProved",
                                                                                "ASP.NET attribute's type is String",
                                                                                LocalizationCriterionAction.VALUE, 40,
                                                                                (item) => { var i = (item as AspNetStringResultItem); return(i == null ? (bool?)null : i.LocalizabilityProved); });

            var comesFromPlainTextPredicate = new LocalizationCommonCriterion("ComesFromPlainText",
                                                                              "String literal comes from ASP .NET plain text",
                                                                              LocalizationCriterionAction.VALUE, 30,
                                                                              (item) => { var i = (item as AspNetStringResultItem); return(i == null ? (bool?)null : i.ComesFromPlainText); });

            var comesFromDirectivePredicate = new LocalizationCommonCriterion("ComesFromDirective",
                                                                              "String literal comes from ASP .NET directive",
                                                                              LocalizationCriterionAction.VALUE, -20,
                                                                              (item) => { var i = (item as AspNetStringResultItem); return(i == null ? (bool?)null : i.ComesFromDirective); });

            var comesFromCodeBlockPredicate = new LocalizationCommonCriterion("ComesFromCodeBlock",
                                                                              "String literal comes from ASP .NET code block",
                                                                              LocalizationCriterionAction.VALUE, -10,
                                                                              (item) => { var i = (item as AspNetStringResultItem); return(i == null ? (bool?)null : i.ComesFromCodeBlock); });

            localizationCriteriaList.Add(comesFromElementPredicate.Name, comesFromElementPredicate);
            localizationCriteriaList.Add(comesFromInlineExpressionPredicate.Name, comesFromInlineExpressionPredicate);
            localizationCriteriaList.Add(localizabilityProvedPredicate.Name, localizabilityProvedPredicate);
            localizationCriteriaList.Add(comesFromPlainTextPredicate.Name, comesFromPlainTextPredicate);
            localizationCriteriaList.Add(comesFromDirectivePredicate.Name, comesFromDirectivePredicate);
            localizationCriteriaList.Add(comesFromCodeBlockPredicate.Name, comesFromCodeBlockPredicate);
            return(localizationCriteriaList);
        }
        /// <summary>
        /// Concatenates two result items based on the content between them. If any control characters are added, they are interpreted and added to the strings.
        /// </summary>
        protected override void ConcatenateWithPreviousResult(IList results, CodeStringResultItem previouslyAddedItem, CodeStringResultItem resultItem)
        {
            string textBetween = text.Substring(previouslyAddedItem.AbsoluteCharOffset + previouslyAddedItem.AbsoluteCharLength - OriginalAbsoluteOffset, resultItem.AbsoluteCharOffset - previouslyAddedItem.AbsoluteCharOffset - previouslyAddedItem.AbsoluteCharLength);
            Match  match       = VBConcateningRegexp.Match(textBetween); // test if the content between is known

            if (match.Success)
            {
                bool ok = match.Groups.Count == 3;
                if (!ok)
                {
                    return;
                }

                // interpret control characters
                StringBuilder addedValues = new StringBuilder();
                for (int i = 0; i < match.Groups[2].Captures.Count; i++)
                {
                    bool matched = false;
                    foreach (AbstractConcatenatingChar m in concatenatingList)
                    {
                        if (m.Matches(match.Groups[2].Captures[i].Value.Trim()))
                        {
                            addedValues.Append(m.ReplaceChar);
                            matched = true;
                            break;
                        }
                    }
                    ok = ok && matched;
                }

                // if all control characters were known, add them to the result item and merge it with the previous one
                if (ok)
                {
                    previouslyAddedItem.Value += addedValues.ToString();
                    results.RemoveAt(results.Count - 1);

                    base.ConcatenateWithPreviousResult(results, previouslyAddedItem, resultItem);
                }
            }
        }
 /// <summary>
 /// Returns criteria displayed in toolwindow's filter, used to calculate localization probability
 /// </summary>
 public static new Dictionary <string, LocalizationCommonCriterion> GetCriteria()
 {
     return(CodeStringResultItem.GetCriteria());
 }