internal override Task <Document> GetUpdatedDocumentAsync(Document document, SemanticModel model, SyntaxNode root, SyntaxNode nodeToFix, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var charSetType   = WellKnownTypes.CharSet(model.Compilation);
            var dllImportType = WellKnownTypes.DllImportAttribute(model.Compilation);
            var marshalAsType = WellKnownTypes.MarshalAsAttribute(model.Compilation);
            var unmanagedType = WellKnownTypes.UnmanagedType(model.Compilation);

            if (charSetType == null || dllImportType == null || marshalAsType == null || unmanagedType == null)
            {
                return(Task.FromResult(document));
            }

            var syntaxFactoryService = document.Project.LanguageServices.GetService <SyntaxGenerator>();

            // return the unchanged root if no fix is available
            var newRoot = root;

            if (nodeToFix.Kind() == SyntaxKind.Attribute)
            {
                // could be either a [DllImport] or [MarshalAs] attribute
                var attribute     = (AttributeSyntax)nodeToFix;
                var attributeType = model.GetSymbolInfo(attribute).Symbol;
                var arguments     = attribute.ArgumentList.Arguments;
                if (dllImportType.Equals(attributeType.ContainingType))
                {
                    // [DllImport] attribute, add or replace CharSet named parameter
                    var argumentValue  = CreateCharSetArgument(syntaxFactoryService, charSetType).WithAdditionalAnnotations(Formatter.Annotation);
                    var namedParameter = arguments.FirstOrDefault(arg => arg.NameEquals != null && arg.NameEquals.Name.Identifier.Text == CharSetText);
                    if (namedParameter == null)
                    {
                        // add the parameter
                        namedParameter = SyntaxFactory.AttributeArgument(SyntaxFactory.NameEquals(CharSetText), null, (ExpressionSyntax)argumentValue)
                                         .WithAdditionalAnnotations(Formatter.Annotation);
                        var newArguments    = arguments.Add(namedParameter);
                        var newArgumentList = attribute.ArgumentList.WithArguments(newArguments);
                        newRoot = root.ReplaceNode(attribute.ArgumentList, newArgumentList);
                    }
                    else
                    {
                        // replace the parameter
                        var newNamedParameter = namedParameter.WithExpression((ExpressionSyntax)argumentValue);
                        newRoot = root.ReplaceNode(namedParameter, newNamedParameter);
                    }
                }
                else if (marshalAsType.Equals(attributeType.ContainingType) && arguments.Count == 1)
                {
                    // [MarshalAs] attribute, replace the only argument
                    var newExpression = CreateMarshalAsArgument(syntaxFactoryService, unmanagedType)
                                        .WithLeadingTrivia(arguments[0].GetLeadingTrivia())
                                        .WithTrailingTrivia(arguments[0].GetTrailingTrivia());
                    var newArgument = arguments[0].WithExpression((ExpressionSyntax)newExpression);
                    newRoot = root.ReplaceNode(arguments[0], newArgument);
                }
            }

            return(Task.FromResult(document.WithSyntaxRoot(newRoot)));
        }