private static MatchingProfile EnsureProfileSourceMatchesSourceEntityType(string sourceEntityType,
                                                                                  MatchingProfile profile)
        {
            if (profile.SourceType.Equals(sourceEntityType, StringComparison.InvariantCultureIgnoreCase))
            {
                return(profile);
            }

            return(new MatchingProfile
            {
                Name = profile.Name,
                SourceType = profile.CandidateType,
                CandidateType = profile.SourceType,
                LinkType = profile.LinkType,
                Rules = profile.Rules.Select(ruleset =>
                                             new MatchingProfileRuleset
                {
                    Name = ruleset.Name,
                    Conditions = ruleset.Conditions.Select(c =>
                                                           new MatchingProfileCondition
                    {
                        SourceAttribute = c.CandidateAttribute,
                        CandidateAttribute = c.SourceAttribute,
                    }).ToArray(),
                }).ToArray(),
            });
        }
        private async Task <MatchResultItem[]> FindMatches(
            Entity sourceEntity,
            DateTime pointInTime,
            MatchingProfileRuleset ruleset,
            MatchingProfile profile,
            CancellationToken cancellationToken)
        {
            var searchFilter = ruleset.Conditions
                               .Select(condition => ConvertRulesetConditionToSearchFilter(condition, sourceEntity))
                               .Where(filter => filter != null)
                               .ToArray();

            if (searchFilter.Length == 0)
            {
                _logger.Info($"No conditions could be fulfilled by source entity {sourceEntity} when finding candidates for profile {profile.Name} and ruleset {ruleset.Name}");
                return(new MatchResultItem[0]);
            }

            var searchRequest = new SearchRequest
            {
                Groups = new[]
                {
                    new SearchRequestGroup
                    {
                        Filter = searchFilter,
                        CombinationOperator = "and",
                    },
                },
                CombinationOperator = "and",
                Skip = 0,
                Take = 1000,
            };
            var searchResult = await _repository.SearchAsync(searchRequest, profile.CandidateType, pointInTime, cancellationToken);

            var candidates = searchResult.Results;

            bool CandidateHasMoreEntitiesThanSource(RegisteredEntity candidate)
            {
                var numberOfEntitiesThatAreSourceEntity =
                    candidate.Entities.Count(entity =>
                                             entity.EntityType.Equals(sourceEntity.EntityType, StringComparison.InvariantCultureIgnoreCase) &&
                                             entity.SourceSystemName.Equals(sourceEntity.SourceSystemName, StringComparison.InvariantCultureIgnoreCase) &&
                                             entity.SourceSystemId.Equals(sourceEntity.SourceSystemId, StringComparison.InvariantCultureIgnoreCase));

                return(candidate.Entities.Length - numberOfEntitiesThatAreSourceEntity > 0);
            }

            return(candidates
                   .Where(CandidateHasMoreEntitiesThanSource)
                   .Select(candidate =>
                           new MatchResultItem
            {
                RegisteredEntity = candidate,
                MatchReason = $"Matched using ruleset {ruleset.Name} in profile {profile.Name}",
            })
                   .ToArray());
        }