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());
        }