private TmMatch RetrieveSimilarMatchWithConcordanceSearch(TmMatch match, SearchSettings settings)
        {
            var segmentText = match.GetSource(settings.IsConcordanceSearch);

            // concordance search don't return any results with too little value of MaxResults
            // That's why it isn't set up to use it's default value 20.
            Trados.Interop.TMAccess.SearchResult tradosSegments = this.TranslationProvider.TradosProvider.ConcordanceSearch(
                segmentText, settings.MinScore);

            return(tradosSegments.TmMatches.Count > 0 ? tradosSegments.TmMatches[1] : match);
        }
        //#region Methods abstract

        ///// <summary>
        ///// Performs a segment search.
        ///// </summary>
        ///// <param name="settings">The settings that define the search parameters.</param>
        ///// <param name="segment">The segment to search for.</param>
        ///// <returns>
        ///// A <see cref="T:Sdl.LanguagePlatform.TranslationMemory.SearchResults"/> object containing the results or an empty object if no results were found.
        ///// </returns>
        //public abstract SearchResults SearchSegment(SearchSettings settings, Segment segment);

        ///// <summary>
        ///// Performs a text search.
        ///// </summary>
        ///// <param name="settings">The settings that define the search parameters.</param>
        ///// <param name="segment">The text to search for.</param>
        ///// <returns>
        ///// A <see cref="T:Sdl.LanguagePlatform.TranslationMemory.SearchResults"/> object containing the results or an empty object if no results were found.
        ///// </returns>
        //public abstract SearchResults SearchText(SearchSettings settings, string segment);

        ///// <summary>
        ///// Performs a translation unit search.
        ///// </summary>
        ///// <param name="settings">The settings that define the search parameters.</param>
        ///// <param name="translationUnit">The translation unit to search for.</param>
        ///// <returns>
        ///// A <see cref="T:Sdl.LanguagePlatform.TranslationMemory.SearchResults"/> object containing the results or an empty object if no results were found.
        ///// </returns>
        //public abstract SearchResults SearchTranslationUnit(SearchSettings settings, TranslationUnit translationUnit);

        //#endregion // Methods abstract

        #region Virtual methods

        #region Methods

        /// <summary>
        /// Performs a segment search.
        /// </summary>
        /// <param name="settings">The settings that define the search parameters.</param>
        /// <param name="segment">The segment to search for.</param>
        /// <returns>
        /// A <see cref="T:Sdl.LanguagePlatform.TranslationMemory.SearchResults"/> object containing the results or an empty object if no results were found.
        /// </returns>
        public virtual SearchResults SearchSegment(SearchSettings settings, Segment segment)
        {
            lock (this.locker)
            {
                string segmentText = SegmentParser.ExtractSegmentText(segment);

                Trados.Interop.TMAccess.SearchResult tradosSegments = GetMatchSegments(settings, segmentText);

                if (tradosSegments == null)
                {
                    return(null);
                }

                var searchResults = new SearchResults
                {
                    SourceSegment = segment.Duplicate(),
                    SourceHash    = segment.GetHashCode(),
                };

                int id = 0;

                foreach (TmMatch match in tradosSegments.TmMatches)
                {
                    // form ScoringResult via applying penalties
                    var scoringResult = new ScoringResult
                    {
                        AppliedPenalties        = new List <AppliedPenalty>(),
                        BaseScore               = match.ScoreValues.GetMatchPercent(),
                        IsStructureContextMatch = false,
                    };
                    this.ApplyPenalties(match, scoringResult, settings);

                    // convert trados 2007 format segments into Studio 2011 ones
                    string translationSource = match.GetSource(settings.IsConcordanceSearch);
                    string translationTarget = match.GetTarget(settings.IsConcordanceSearch);

                    var sourceSegment = SegmentParser.CreateSegment(
                        scoringResult, settings, translationSource, this.SourceLanguage);
                    var targetSegment = SegmentParser.CreateSegment(
                        scoringResult, settings, translationTarget, this.TargetLanguage);

                    // tokenize segments
                    SegmentParser.TokenizeSegment(ref sourceSegment);
                    SegmentParser.TokenizeSegment(ref targetSegment);

                    // create Translation Unit
                    var unit = new TranslationUnit(sourceSegment, targetSegment)
                    {
                        Origin       = TranslationUnitOrigin.TM,
                        Format       = TranslationUnitFormat.TradosTranslatorsWorkbench,
                        SystemFields = new SystemFields(),
                        ResourceId   = new PersistentObjectToken(id++, Guid.NewGuid()),
                    };

                    // set custom attributes
                    this.SetMetaData(match, unit, settings);

                    // form SearchResult
                    var searchResult = new SearchResult(unit)
                    {
                        ScoringResult       = scoringResult,
                        TranslationProposal = unit.Duplicate()
                    };

                    scoringResult.EditDistance = ComputeEditDistance(segment, searchResult, settings);

                    // set "yellow" fileds for concordance
                    if (settings.Mode == SearchMode.ConcordanceSearch || settings.Mode == SearchMode.TargetConcordanceSearch)
                    {
                        this.AnnotateConcordanceHit(segment, searchResult, settings.Mode);
                    }

                    // finally...
                    searchResults.Add(searchResult);
                }


                searchResults.CheckForMultipleTranslations(settings);
                searchResults.RemoveDuplicates();

                //if "Search fo fuzzy matches even if exact match found" is OFF
                //and exact matches are present then also remove fuzzy matches
                //According to LanguagePlatform description for enum SearchMode, exact match should return only exact matches,
                //normal search should return exact matches OR fuzzy matches if no exact matches found
                if (settings.Mode == SearchMode.ExactSearch ||
                    (settings.Mode == SearchMode.NormalSearch && searchResults.Results.Any(i => i.ScoringResult.IsExactMatch)))
                {
                    searchResults.Results.RemoveAll(r => !r.ScoringResult.IsExactMatch);
                }

                //Determine placebles in the searched segment
                if (settings.Mode != SearchMode.TargetConcordanceSearch && !settings.IsConcordanceSearch)
                {
                    searchResults.DocumentPlaceables = PlaceableComputer.ComputePlaceables(searchResults.SourceSegment, null);
                }

                return(searchResults);
            }
        }