protected virtual async Task <string> InternalTransformAsync(string template, IEnumerable <IToken> tokens, object[] additionalData, Func <IToken, Task <object> > dataProvider) { var builder = new StringBuilder(template); var adjustment = 0; foreach (var token in tokens.OrderBy(t => t.Index)) { var val = await TryGetAndCacheValueAsync(token, dataProvider).ConfigureAwait(false) ?? TryGetAndCacheValue(token, additionalData); if (val == null) { throw new UnResolvedTokenException(token.Token); } var strVal = _formatter.Convert(token, val); builder = builder.Replace(token.Token, strVal, token.Index + adjustment, token.Token.Length); adjustment += strVal.Length - token.Token.Length; } return(builder.ToString()); }