/// <summary>
 /// Creates a default converter where foreach is joined with some children statements but other children statements are kept unmodified.
 /// Example:
 /// foreach(...)
 /// {
 ///     if (condition)
 ///     {
 ///        doSomething();
 ///     }
 /// }
 /// is converted to
 /// foreach(... where condition)
 /// {
 ///        doSomething();
 /// }
 /// </summary>
 protected abstract IConverter <TForEachStatement, TStatement> CreateDefaultConverter(
     ForEachInfo <TForEachStatement, TStatement> forEachInfo);
 /// <summary>
 /// Tries to build a specific converter that covers e.g. Count, ToList, yield return or other similar cases.
 /// </summary>
 protected abstract bool TryBuildSpecificConverter(
     ForEachInfo <TForEachStatement, TStatement> forEachInfo,
     SemanticModel semanticModel,
     TStatement statementCannotBeConverted,
     CancellationToken cancellationToken,
     out IConverter <TForEachStatement, TStatement> converter);