private static async Task TokenFormatWorkerAsync(TestWorkspace workspace, ITextBuffer buffer, int indentationLine, char ch)
        {
            Document document = buffer.CurrentSnapshot.GetRelatedDocumentsWithChanges().First();
            var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync();

            var line = root.GetText().Lines[indentationLine];

            var index = line.ToString().LastIndexOf(ch);
            Assert.InRange(index, 0, int.MaxValue);

            // get token
            var position = line.Start + index;
            var token = root.FindToken(position);

            var formattingRuleProvider = workspace.Services.GetService<IHostDependentFormattingRuleFactoryService>();

            var rules = formattingRuleProvider.CreateRule(document, position).Concat(Formatter.GetDefaultFormattingRules(document));

            var formatter = new SmartTokenFormatter(document.Options, rules, root);
            var changes = await formatter.FormatTokenAsync(workspace, token, CancellationToken.None);

            ApplyChanges(buffer, changes);
        }
        private async Task<IList<TextChange>> FormatRangeAsync(
            Document document, SyntaxToken endToken, IEnumerable<IFormattingRule> formattingRules,
            CancellationToken cancellationToken)
        {
            if (!IsEndToken(endToken))
            {
                return SpecializedCollections.EmptyList<TextChange>();
            }

            var tokenRange = FormattingRangeHelper.FindAppropriateRange(endToken);
            if (tokenRange == null || tokenRange.Value.Item1.Equals(tokenRange.Value.Item2))
            {
                return SpecializedCollections.EmptyList<TextChange>();
            }

            if (IsInvalidTokenKind(tokenRange.Value.Item1) || IsInvalidTokenKind(tokenRange.Value.Item2))
            {
                return SpecializedCollections.EmptyList<TextChange>();
            }

            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var formatter = new SmartTokenFormatter(document.Project.Solution.Workspace.Options, formattingRules, (CompilationUnitSyntax)root);

            var changes = formatter.FormatRange(document.Project.Solution.Workspace, tokenRange.Value.Item1, tokenRange.Value.Item2, cancellationToken);
            return changes;
        }
        private async Task AutoFormatOnMarkerAsync(string initialMarkup, string expected, SyntaxKind tokenKind, SyntaxKind startTokenKind)
        {
            using (var workspace = await TestWorkspace.CreateCSharpAsync(initialMarkup))
            {
                var tuple = GetService(workspace);
                var testDocument = workspace.Documents.Single();
                var buffer = testDocument.GetTextBuffer();
                var position = testDocument.CursorPosition.Value;

                var document = workspace.CurrentSolution.GetDocument(testDocument.Id);

                var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync();
                var endToken = root.FindToken(position);
                if (position == endToken.SpanStart && !endToken.GetPreviousToken().IsKind(SyntaxKind.None))
                {
                    endToken = endToken.GetPreviousToken();
                }

                Assert.Equal(tokenKind, endToken.Kind());
                var formatter = new SmartTokenFormatter(tuple.Item1, tuple.Item2, root);

                var tokenRange = FormattingRangeHelper.FindAppropriateRange(endToken);
                if (tokenRange == null)
                {
                    Assert.Equal(startTokenKind, SyntaxKind.None);
                    return;
                }

                Assert.Equal(startTokenKind, tokenRange.Value.Item1.Kind());
                if (tokenRange.Value.Item1.Equals(tokenRange.Value.Item2))
                {
                    return;
                }

                var changes = formatter.FormatRange(workspace, tokenRange.Value.Item1, tokenRange.Value.Item2, CancellationToken.None);
                var actual = GetFormattedText(buffer, changes);
                Assert.Equal(expected, actual);
            }
        }