public virtual IRedactorResult Redact(string input) { IRedactorResult redactorResult = new RedactorResult(); if (string.IsNullOrWhiteSpace(input)) { redactorResult.Result = input; return(redactorResult); } input = BeforeProcess?.Invoke(input) ?? input; ISanitizer sanitizer = CreateSanitizer(input); input = sanitizer?.Update(input)?.Sanitize() ?? input; IEnumerable <IRedactorMatch> mc = Matcher.Match(input); if (mc.Count() > 0) { foreach (IRedactorMatch m in mc) { IRedactorMatch match = BeforeProcessMatch?.Invoke(input, m) ?? m; if (Validator?.Validate(match.Value) ?? true) { input = MatchProcessor.Process(input, match); redactorResult.Logs.Add(new RedactorLogItem() { RangeStart = match.Index, RangeEnd = match.Index + match.Length, RedactorFriendlyName = FriendlyName, SanitizedCharacters = sanitizer?.SanitizedCharacters() ?? Enumerable.Empty <CharacterSnapshot>() }); } input = AfterProcessMatch?.Invoke(input, match) ?? input; } } input = sanitizer?.Update(input)?.Desanitize() ?? input; input = AfterProcess?.Invoke(input) ?? input; redactorResult.Result = input; return(redactorResult); }