diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/QualityGuidelines/RethrowToPreserveStackDetails.Fixer.cs b/src/Microsoft.CodeQuality.Analyzers/Core/QualityGuidelines/RethrowToPreserveStackDetails.Fixer.cs
new file mode 100644
index 0000000000..261ea10081
--- /dev/null
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/QualityGuidelines/RethrowToPreserveStackDetails.Fixer.cs
@@ -0,0 +1,58 @@
+using System.Collections.Immutable;
+using System.Composition;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.Editing;
+using Microsoft.CodeAnalysis.Formatting;
+
+namespace Microsoft.CodeQuality.Analyzers.QualityGuidelines
+{
+ ///
+ /// CA2200: Rethrow to preserve stack details
+ ///
+ [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic, Name = RethrowToPreserveStackDetailsAnalyzer.RuleId), Shared]
+ public sealed class RethrowToPreserveStackDetailsFixer : CodeFixProvider
+ {
+ public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(RethrowToPreserveStackDetailsAnalyzer.RuleId);
+
+ public sealed override FixAllProvider GetFixAllProvider()
+ {
+ // See https://github.com/dotnet/roslyn/blob/master/docs/analyzers/FixAllProvider.md for more information on Fix All Providers'
+ return WellKnownFixAllProviders.BatchFixer;
+ }
+ public async sealed override Task RegisterCodeFixesAsync(CodeFixContext context)
+ {
+ var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
+ var diagnostics = context.Diagnostics;
+
+ var nodeToReplace = root.FindNode(context.Span);
+ if (nodeToReplace == null)
+ {
+ return;
+ }
+ // Register a code action that will invoke the fix.
+ context.RegisterCodeFix(
+ CodeAction.Create(
+ title: MicrosoftCodeQualityAnalyzersResources.RethrowToPreserveStackDetailsTitle,
+ createChangedDocument: c => MakeThrowAsync(context.Document, nodeToReplace, c),
+ equivalenceKey: nameof(RethrowToPreserveStackDetailsFixer)),
+ diagnostics);
+ }
+
+ private async Task MakeThrowAsync(Document document, SyntaxNode nodeToReplace, CancellationToken cancellationToken)
+ {
+ var formattednewLocal = SyntaxGenerator.GetGenerator(document).ThrowStatement()
+ .WithLeadingTrivia(nodeToReplace.GetLeadingTrivia())
+ .WithTrailingTrivia(nodeToReplace.GetTrailingTrivia())
+ .WithAdditionalAnnotations(Formatter.Annotation);
+
+ var oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
+ var newRoot = oldRoot.ReplaceNode(nodeToReplace, formattednewLocal);
+
+ return document.WithSyntaxRoot(newRoot);
+ }
+ }
+}
diff --git a/src/Microsoft.CodeQuality.Analyzers/UnitTests/QualityGuidelines/RethrowToPreserveStackDetailsTests.Fixer.cs b/src/Microsoft.CodeQuality.Analyzers/UnitTests/QualityGuidelines/RethrowToPreserveStackDetailsTests.Fixer.cs
new file mode 100644
index 0000000000..4d075b847e
--- /dev/null
+++ b/src/Microsoft.CodeQuality.Analyzers/UnitTests/QualityGuidelines/RethrowToPreserveStackDetailsTests.Fixer.cs
@@ -0,0 +1,95 @@
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.Testing;
+using Xunit;
+using VerifyCS = Test.Utilities.CSharpCodeFixVerifier<
+ Microsoft.CodeQuality.CSharp.Analyzers.QualityGuidelines.CSharpRethrowToPreserveStackDetailsAnalyzer,
+ Microsoft.CodeQuality.Analyzers.QualityGuidelines.RethrowToPreserveStackDetailsFixer>;
+using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier<
+ Microsoft.CodeQuality.VisualBasic.Analyzers.QualityGuidelines.BasicRethrowToPreserveStackDetailsAnalyzer,
+ Microsoft.CodeQuality.Analyzers.QualityGuidelines.RethrowToPreserveStackDetailsFixer>;
+
+namespace Microsoft.CodeQuality.Analyzers.UnitTests.QualityGuidelines
+{
+ public class RethrowToPreserveStackDetailsTests
+ {
+ [Fact]
+ public async Task TestCSharp_RethrowExplicitlyToThrowImplicitly()
+ {
+ await VerifyCS.VerifyCodeFixAsync(@"
+using System;
+
+class Program
+{
+ void CatchAndRethrowExplicitly()
+ {
+ try
+ {
+ ThrowException();
+ }
+ catch (ArithmeticException e)
+ {
+ throw e; //Some comments
+ }
+ }
+
+ void ThrowException()
+ {
+ throw new ArithmeticException();
+ }
+}", new DiagnosticResult(CSharp.Analyzers.QualityGuidelines.CSharpRethrowToPreserveStackDetailsAnalyzer.Rule).WithLocation(14, 13),
+@"
+using System;
+
+class Program
+{
+ void CatchAndRethrowExplicitly()
+ {
+ try
+ {
+ ThrowException();
+ }
+ catch (ArithmeticException e)
+ {
+ throw; //Some comments
+ }
+ }
+
+ void ThrowException()
+ {
+ throw new ArithmeticException();
+ }
+}");
+ }
+ [Fact]
+ public async Task TestBasic_RethrowExplicitlyToThrowImplicitly()
+ {
+ await VerifyVB.VerifyCodeFixAsync(@"
+Imports System
+Class Program
+ Sub CatchAndRethrowExplicitly()
+ Try
+ Throw New ArithmeticException()
+ Catch e As ArithmeticException
+ Throw e 'Some comment
+ End Try
+ End Sub
+End Class
+", new DiagnosticResult(VisualBasic.Analyzers.QualityGuidelines.BasicRethrowToPreserveStackDetailsAnalyzer.Rule).WithLocation(8, 13),
+ @"
+Imports System
+Class Program
+ Sub CatchAndRethrowExplicitly()
+ Try
+ Throw New ArithmeticException()
+ Catch e As ArithmeticException
+ Throw 'Some comment
+ End Try
+ End Sub
+End Class
+"
+ );
+ }
+ }
+}
+
+