private FieldVariableTransformationResult TransformFieldVariable(
            VariableDeclaratorSyntax variableNode,
            FieldVariableTransformationResult result,
            bool canCopy)
        {
            var variableResult = result.AnalyzationResult;
            var conversion     = variableResult.Conversion;

            if (conversion == FieldVariableConversion.Ignore || !canCopy)
            {
                return(result);
            }

            var startVariableSpan = variableResult.Node.Span.Start;

            variableNode       = variableNode.WithAdditionalAnnotations(new SyntaxAnnotation(result.Annotation));
            startVariableSpan -= variableNode.SpanStart;

            // First we need to annotate nodes that will be modified in order to find them later on.
            // We cannot rely on spans after the first modification as they will change
            var typeReferencesAnnotations = new List <string>();

            foreach (var typeReference in variableResult.TypeReferences.Where(o => o.TypeAnalyzationResult.Conversion == TypeConversion.NewType))
            {
                var reference    = typeReference.ReferenceLocation;
                var refSpanStart = reference.Location.SourceSpan.Start - startVariableSpan;
                var nameNode     = variableNode.GetSimpleName(refSpanStart, reference.Location.SourceSpan.Length, typeReference.IsCref);
                var annotation   = Guid.NewGuid().ToString();
                variableNode = variableNode.ReplaceNode(nameNode, nameNode.WithAdditionalAnnotations(new SyntaxAnnotation(annotation)));
                typeReferencesAnnotations.Add(annotation);
            }

            // Modify references
            foreach (var refAnnotation in typeReferencesAnnotations)
            {
                var nameNode = variableNode.GetAnnotatedNodes(refAnnotation).OfType <SimpleNameSyntax>().First();
                variableNode = variableNode
                               .ReplaceNode(nameNode, nameNode.WithIdentifier(Identifier(nameNode.Identifier.Value + "Async").WithTriviaFrom(nameNode.Identifier)));
            }

            result.Transformed = variableNode;
            return(result);
        }
        internal FieldTransformationResult TransformField(
            BaseFieldDeclarationSyntax fieldNode,
            bool canCopy,
            FieldTransformationResult result,
            ITypeTransformationMetadata typeMetadata,
            INamespaceTransformationMetadata namespaceMetadata)
        {
            var analyzeResult = result.AnalyzationResult;
            var startRootSpan = analyzeResult.Node.SpanStart;

            // Calculate whitespace method trivias
            result.EndOfLineTrivia         = fieldNode.GetEndOfLine();
            result.LeadingWhitespaceTrivia = fieldNode.GetLeadingWhitespace();
            result.IndentTrivia            = fieldNode.GetIndent(result.LeadingWhitespaceTrivia, typeMetadata.LeadingWhitespaceTrivia);

            if (analyzeResult.Variables.All(o => o.Conversion == FieldVariableConversion.Ignore || o.Conversion == FieldVariableConversion.Copy && !canCopy))
            {
                return(result);
            }

            fieldNode      = fieldNode.WithAdditionalAnnotations(new SyntaxAnnotation(result.Annotation));
            startRootSpan -= fieldNode.SpanStart;

            // First we need to annotate nodes that will be modified in order to find them later on.
            // We cannot rely on spans after the first modification as they will change
            var typeReferencesAnnotations = new List <string>();

            foreach (var typeReference in analyzeResult.TypeReferences.Where(o => o.TypeAnalyzationResult.Conversion == TypeConversion.NewType))
            {
                var reference    = typeReference.ReferenceLocation;
                var refSpanStart = reference.Location.SourceSpan.Start - startRootSpan;
                var nameNode     = fieldNode.GetSimpleName(refSpanStart, reference.Location.SourceSpan.Length, typeReference.IsCref);
                var annotation   = Guid.NewGuid().ToString();
                fieldNode = fieldNode.ReplaceNode(nameNode, nameNode.WithAdditionalAnnotations(new SyntaxAnnotation(annotation)));
                typeReferencesAnnotations.Add(annotation);
            }

            foreach (var variableResult in analyzeResult.Variables)
            {
                var spanStart    = variableResult.Node.SpanStart - startRootSpan;
                var spanLength   = variableResult.Node.Span.Length;
                var accessorNode = fieldNode.DescendantNodes()
                                   .First(o => o.SpanStart == spanStart && o.Span.Length == spanLength);
                var transformedNode = new FieldVariableTransformationResult(variableResult);
                result.TransformedVariables.Add(transformedNode);
                fieldNode = fieldNode.ReplaceNode(accessorNode, accessorNode.WithAdditionalAnnotations(new SyntaxAnnotation(transformedNode.Annotation)));
            }

            // Modify references
            foreach (var refAnnotation in typeReferencesAnnotations)
            {
                var nameNode = fieldNode.GetAnnotatedNodes(refAnnotation).OfType <SimpleNameSyntax>().First();
                fieldNode = fieldNode
                            .ReplaceNode(nameNode, nameNode.WithIdentifier(Identifier(nameNode.Identifier.Value + "Async").WithTriviaFrom(nameNode.Identifier)));
            }

            foreach (var fieldVariableResult in result.TransformedVariables.OrderByDescending(o => o.OriginalStartSpan))
            {
                var variableNode = (VariableDeclaratorSyntax)fieldNode.GetAnnotatedNodes(fieldVariableResult.Annotation)
                                   .First();
                var variableTransformResult = TransformFieldVariable(variableNode, fieldVariableResult, canCopy);
                fieldNode = variableTransformResult.Transformed == null
                                        ? fieldNode.RemoveNode(variableNode, SyntaxRemoveOptions.KeepUnbalancedDirectives)
                                        : fieldNode.ReplaceNode(variableNode, variableTransformResult.Transformed);
            }

            result.Transformed = fieldNode;
            return(result);
        }