public async static Task<Solution> MakeAutoPropertyAsync(Document document, SyntaxNode root, PropertyDeclarationSyntax property, CancellationToken cancellationToken)
 {
     var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
     var getterReturn = (ReturnStatementSyntax)property.AccessorList.Accessors.First(a => a.Keyword.ValueText == "get").Body.Statements.First();
     var returnIdentifier = (IdentifierNameSyntax)(getterReturn.Expression is MemberAccessExpressionSyntax ? ((MemberAccessExpressionSyntax)getterReturn.Expression).Name : getterReturn.Expression);
     var returnIdentifierSymbol = semanticModel.GetSymbolInfo(returnIdentifier).Symbol;
     var variableDeclarator = (VariableDeclaratorSyntax)returnIdentifierSymbol.DeclaringSyntaxReferences.First().GetSyntax();
     var fieldDeclaration = variableDeclarator.FirstAncestorOfType<FieldDeclarationSyntax>();
     root = root.TrackNodes(returnIdentifier, fieldDeclaration, property);
     document = document.WithSyntaxRoot(root);
     root = await document.GetSyntaxRootAsync(cancellationToken);
     semanticModel = await document.GetSemanticModelAsync(cancellationToken);
     returnIdentifier = root.GetCurrentNode(returnIdentifier);
     returnIdentifierSymbol = semanticModel.GetSymbolInfo(returnIdentifier).Symbol;
     var newProperty = GetSimpleProperty(property, variableDeclarator)
         .WithTriviaFrom(property)
         .WithAdditionalAnnotations(Formatter.Annotation);
     var newSolution = await Renamer.RenameSymbolAsync(document.Project.Solution, returnIdentifierSymbol, property.Identifier.ValueText, document.Project.Solution.Workspace.Options, cancellationToken);
     document = newSolution.GetDocument(document.Id);
     root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
     root = root.InsertNodesAfter(root.GetCurrentNode(property), new[] { newProperty });
     var multipleVariableDeclaration = fieldDeclaration.Declaration.Variables.Count > 1;
     if (multipleVariableDeclaration)
     {
         var newfieldDeclaration = fieldDeclaration.WithDeclaration(fieldDeclaration.Declaration.RemoveNode(variableDeclarator, SyntaxRemoveOptions.KeepNoTrivia));
         root = root.RemoveNode(root.GetCurrentNode<SyntaxNode>(property), SyntaxRemoveOptions.KeepNoTrivia);
         root = root.ReplaceNode(root.GetCurrentNode(fieldDeclaration), newfieldDeclaration);
     }
     else
     {
         root = root.RemoveNodes(root.GetCurrentNodes<SyntaxNode>(new SyntaxNode[] { fieldDeclaration, property }), SyntaxRemoveOptions.KeepNoTrivia);
     }
     document = document.WithSyntaxRoot(root);
     return document.Project.Solution;
 }
 private static SyntaxNode CreateRootAddingDisposeToEndOfMethod(SyntaxNode root, ExpressionStatementSyntax statement, ILocalSymbol identitySymbol)
 {
     var method = statement.FirstAncestorOrSelf<MethodDeclarationSyntax>();
     var newDispose = ImplementsDisposableExplicitly(identitySymbol.Type)
         ? SyntaxFactory.ExpressionStatement(SyntaxFactory.InvocationExpression(
             SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
             SyntaxFactory.ParenthesizedExpression(SyntaxFactory.CastExpression(SyntaxFactory.ParseName("System.IDisposable").WithAdditionalAnnotations(Simplifier.Annotation), SyntaxFactory.IdentifierName(identitySymbol.Name))),
             SyntaxFactory.IdentifierName("Dispose"))))
         : SyntaxFactory.ParseStatement($"{identitySymbol.Name}.Dispose();");
     newDispose = newDispose.WithAdditionalAnnotations(Formatter.Annotation);
     var last = method.Body.Statements.Last();
     var newRoot = root.InsertNodesAfter(method.Body.Statements.Last(), new[] { newDispose });
     return newRoot;
 }
		private Task<Document> MakePropertiesAsync(Document document, SyntaxNode root, TextSpan span, CancellationToken cancellationToken)
		{
			var field = root.FindNode(span) as FieldDeclarationSyntax;

			var semicolon = SyntaxFactory.Token(SyntaxKind.SemicolonToken);

			// { get; }
			var getAccessor = SyntaxFactory.AccessorList(SyntaxFactory.List(new[] {
				SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(semicolon),
			}));
			// { get; set; }
			var getSetAccessor = getAccessor.AddAccessors(SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithSemicolonToken(semicolon));

			var propertySyntaxes = field.Declaration.Variables.Select(v =>
			{
				var isReadOnly = field.Modifiers.Any(SyntaxKind.ReadOnlyKeyword);
				var accessors = isReadOnly ? getAccessor : getSetAccessor;

				var initializer = v.ChildNodes().OfType<EqualsValueClauseSyntax>().FirstOrDefault();
				var property = SyntaxFactory.PropertyDeclaration(
					attributeLists: field.AttributeLists,
					modifiers: isReadOnly ? field.Modifiers.Remove(field.Modifiers.Where(x => x.IsKind(SyntaxKind.ReadOnlyKeyword)).First()) : field.Modifiers,
					type: field.Declaration.Type,
					explicitInterfaceSpecifier: null,
					identifier: v.Identifier,
					accessorList: accessors,
					expressionBody: null,
					initializer: initializer
				);

				// int Foo { get; set; }\n  or  int Bar { get; set; } = 1;\n
				return (initializer != null ? property.WithSemicolonToken(semicolon) : property)
					.WithTrailingTrivia(SyntaxFactory.SyntaxTrivia(SyntaxKind.EndOfLineTrivia, Environment.NewLine))
					.WithAdditionalAnnotations(Formatter.Annotation);
			});

			var inserted = root.InsertNodesAfter(field, propertySyntaxes);
			var removingNode = inserted.FindNode(span);
			var newRoot = inserted.RemoveNode(removingNode, SyntaxRemoveOptions.KeepNoTrivia);
			return Task.FromResult(document.WithSyntaxRoot(newRoot));
		}
        static CodeAction Handle(Document document, Microsoft.CodeAnalysis.Text.TextSpan span, SyntaxNode root, SyntaxNode node, ExpressionSyntax iterateOver, bool replaceNode)
        {
            return CodeActionFactory.Create(
                span,
                DiagnosticSeverity.Info,
                "Iterate via 'foreach'",
                ct =>
                {
                    ForEachStatementSyntax foreachStmt = BuildForeach(iterateOver);

                    SyntaxNode newRoot;
                    var ancestor = node.GetAncestor<StatementSyntax>();
                    if (replaceNode)
                    {
                        newRoot = root.ReplaceNode(ancestor, new[] { foreachStmt.WithTrailingTrivia(ancestor.GetTrailingTrivia()) });
                    }
                    else
                    {
                        newRoot = root.InsertNodesAfter(ancestor, new[] { foreachStmt.WithTrailingTrivia(ancestor.GetTrailingTrivia()) });
                    }
                    return Task.FromResult(document.WithSyntaxRoot(newRoot));
                }
            );
        }