File: EditAndContinue\ActiveStatementTests.cs
Web Access
Project: src\src\Features\CSharpTest\Microsoft.CodeAnalysis.CSharp.Features.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Features.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
#pragma warning disable IDE0055 // Collection expression formatting
 
using System;
using Microsoft.CodeAnalysis.Contracts.EditAndContinue;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.UnitTests;
using Microsoft.CodeAnalysis.EditAndContinue;
using Microsoft.CodeAnalysis.EditAndContinue.UnitTests;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.EditAndContinue.UnitTests;
 
[UseExportProvider]
public class ActiveStatementTests : EditingTestBase
{
    #region Update
 
    [Fact]
    public void Update_Inner()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        while (true)
        {
            <AS:1>Goo(2);</AS:1>
        }
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "Goo(2);"));
    }
 
    [Fact]
    public void Update_Inner_NewCommentAtEndOfActiveStatement()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>//
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    /// <summary>
    /// CreateNewOnMetadataUpdate has no effect in presence of active statements (in break mode).
    /// </summary>
    [Fact]
    public void Update_Inner_Reloadable()
    {
        var src1 = ReloadableAttributeSrc + @"
[CreateNewOnMetadataUpdate]
class C
{
    static void F()
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}";
        var src2 = ReloadableAttributeSrc + @"
[CreateNewOnMetadataUpdate]
class C
{
    static void F()
    {
        while (true)
        {
            <AS:1>Goo(2);</AS:1>
        }
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "Goo(2);"));
    }
 
    [Fact]
    public void Update_Leaf()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        while (true)
        {
            <AS:1>Goo(1);</AS:1>
        }
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a + 1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Update_Leaf_NewCommentAtEndOfActiveStatement()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>//
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    /// <summary>
    /// CreateNewOnMetadataUpdate has no effect in presence of active statements (in break mode).
    /// </summary>
    [Fact]
    public void Update_Leaf_Reloadable()
    {
        var src1 = ReloadableAttributeSrc + @"
[CreateNewOnMetadataUpdate]
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}";
        var src2 = ReloadableAttributeSrc + @"
[CreateNewOnMetadataUpdate]
class C
{
    static void Main(string[] args)
    {
        while (true)
        {
            <AS:1>Goo(1);</AS:1>
        }
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a + 1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemantics(active,
            semanticEdits:
            [
                SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Main"), preserveLocalVariables: true),
                SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Goo"), preserveLocalVariables: true)
            ]);
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/846588")]
    public void Update_Leaf_Block()
    {
        var src1 = @"
class C : System.IDisposable
{
    public void Dispose() {}
 
    static void Main(string[] args)
    {
        using (<AS:0>C x = null</AS:0>) {}
    }
}";
        var src2 = @"
class C : System.IDisposable
{
    public void Dispose() {}
 
    static void Main(string[] args)
    {
        using (<AS:0>C x = new C()</AS:0>) {}
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    #endregion
 
    #region Delete in Method Body
 
    [Fact]
    public void Delete_Inner()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        while (true)
        {
        }
    <AS:1>}</AS:1>
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code));
    }
 
    // TODO (tomat): considering a change
    [Fact]
    public void Delete_Inner_MultipleParents()
    {
        var src1 = @"
class C : IDisposable
{
    unsafe static void Main(string[] args)
    {
        {
            <AS:1>Goo(1);</AS:1>
        }
 
        if (true)
        {
            <AS:2>Goo(2);</AS:2>
        }
        else
        {
            <AS:3>Goo(3);</AS:3>
        }
 
        int x = 1;
        switch (x)
        {
            case 1:
            case 2:
                <AS:4>Goo(4);</AS:4>
                break;
 
            default:
                <AS:5>Goo(5);</AS:5>
                break;
        }
 
        checked
        {
            <AS:6>Goo(4);</AS:6>
        }
 
        unchecked
        {
            <AS:7>Goo(7);</AS:7>
        }
 
        while (true) <AS:8>Goo(8);</AS:8>
    
        do <AS:9>Goo(9);</AS:9> while (true);
 
        for (int i = 0; i < 10; i++) <AS:10>Goo(10);</AS:10>
 
        foreach (var i in new[] { 1, 2}) <AS:11>Goo(11);</AS:11>
 
        using (var z = new C()) <AS:12>Goo(12);</AS:12>
 
        fixed (char* p = ""s"") <AS:13>Goo(13);</AS:13>
 
        label: <AS:14>Goo(14);</AS:14>
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}";
        var src2 = @"
class C : IDisposable
{
    unsafe static void Main(string[] args)
    {
        {
        <AS:1>}</AS:1>
 
        if (true)
        { <AS:2>}</AS:2>
        else
        { <AS:3>}</AS:3>
 
        int x = 1;
        switch (x)
        {
            case 1:
            case 2:
                <AS:4>break;</AS:4>
 
            default:
                <AS:5>break;</AS:5>
        }
 
        checked
        {
        <AS:6>}</AS:6>
 
        unchecked
        {
        <AS:7>}</AS:7>
 
        <AS:8>while (true)</AS:8> { }
    
        do { } <AS:9>while (true);</AS:9>
 
        for (int i = 0; i < 10; <AS:10>i++</AS:10>) { }
 
        foreach (var i <AS:11>in</AS:11> new[] { 1, 2 }) { }
 
        using (<AS:12>var z = new C()</AS:12>) { }
 
        fixed (<AS:13>char* p = ""s""</AS:13>) { }
 
        label: <AS:14>{</AS:14> }
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "case 2:", FeaturesResources.code),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "default:", FeaturesResources.code),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "while (true)", FeaturesResources.code),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "do", FeaturesResources.code),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "for (int i = 0; i < 10;        i++        )", FeaturesResources.code),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "foreach (var i        in         new[] { 1, 2 })", FeaturesResources.code),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "using (       var z = new C()        )", FeaturesResources.code),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "fixed (       char* p = \"s\"        )", FeaturesResources.code),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "label", FeaturesResources.code));
    }
 
    [Fact]
    public void Delete_Leaf1()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
    <AS:0>}</AS:0>
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Delete_Leaf2()
    {
        var src1 = @"
class C
{
    static void Goo(int a)
    {
        Console.WriteLine(1);
        Console.WriteLine(2);
        <AS:0>Console.WriteLine(3);</AS:0>
        Console.WriteLine(4);
    }
}";
        var src2 = @"
class C
{
    static void Goo(int a)
    {
        Console.WriteLine(1);
        Console.WriteLine(2);
 
        <AS:0>Console.WriteLine(4);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Delete_Leaf_InTry()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        try
        {
            <AS:0>Console.WriteLine(a);</AS:0>
        }
        catch
        {
        }
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        try
        {
        <AS:0>}</AS:0>
        catch
        {
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Delete_Leaf_InTry2()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        try
        {
            try
            {
                <AS:0>Console.WriteLine(a);</AS:0>
            }
            catch
            {
            }
        }
        catch
        {
        }
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        try
        {
            try
            {
            <AS:0>}</AS:0>
            catch
            {
            }
        }
        catch
        {
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Delete_Inner_CommentActiveStatement()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        //Goo(1);
    <AS:1>}</AS:1>
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code));
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755959")]
    public void Delete_Leaf_CommentActiveStatement()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        //Console.WriteLine(a);
    <AS:0>}</AS:0>
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Delete_Entire_Namespace()
    {
        var src1 = @"
namespace N
{
    class C
    {
        static void F()
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}";
        var src2 = @"<AS:0/>";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.Delete, "", GetResource("class", "N.C")),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "", GetResource("method", "N.C.F()")));
    }
 
    [Fact]
    public void Delete_Entire_Type()
    {
        var src1 = @"
namespace N
{
    class C
    {
        static void F()
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}";
        var src2 = @"<AS:0>namespace N</AS:0>;";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.Delete, "namespace N", GetResource("class", "C")),
            Diagnostic(RudeEditKind.DeleteActiveStatement, "namespace N", GetResource("method", "N.C.F()")));
    }
 
    [Fact]
    public void Delete_Entire_Method()
    {
        var src1 = @"
namespace N
{
    class C
    {
        static void F()
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}";
        var src2 = @"
namespace N
{
    <AS:0>class C</AS:0>
    {
    }
}
";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteActiveStatement, "class C", GetResource("method", "N.C.F()")));
    }
 
    #endregion
 
    #region Parameters & Returns
 
    [Fact]
    public void Parameter_Rename()
    {
        var src1 = "class C { int F(int a) => <AS:0>1</AS:0>; }";
        var src2 = "class C { int F(int b) => <AS:0>1</AS:0>; }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            active,
            capabilities: EditAndContinueCapabilities.UpdateParameters);
    }
 
    [Theory]
    [InlineData("int")]
    [InlineData("in byte")]
    [InlineData("ref byte")]
    [InlineData("out byte")]
    [InlineData("ref readonly byte")]
    public void Parameter_Update_TypeOrRefKind_RuntimeTypeChanged(string oldType)
    {
        var src1 = "class C { int F(" + oldType + " a) => <AS:0>throw null!</AS:0>; }";
        var src2 = "class C { int F(byte a) => <AS:0>throw null!</AS:0>; }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // Can't remap to the new version of the method.
        // Even if we emitted trampoline we would not be able to remap to the exact instruction the active statement is at in the old version.
 
        edits.VerifySemanticDiagnostics(active,
            diagnostics: [Diagnostic(RudeEditKind.ChangingNameOrSignatureOfActiveMember, "int F(byte a)", GetResource("method"))],
            capabilities: EditAndContinueCapabilities.AddMethodToExistingType);
    }
 
    [Theory, CombinatorialData]
    public void Parameter_Update_RefKind_RuntimeTypeUnchanged(
        [CombinatorialValues("ref", "out", "in", "ref readonly")] string oldModifiers,
        [CombinatorialValues("ref", "out", "in", "ref readonly")] string newModifiers)
    {
        if (oldModifiers == newModifiers)
        {
            return;
        }
 
        var src1 = "class C { int F(" + oldModifiers + " int a) => <AS:0>throw null!</AS:0>; }";
        var src2 = "class C { int F(" + newModifiers + " int a) => <AS:0>throw null!</AS:0>; }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // We don't require a runtime capability to update attributes.
        // All runtimes support changing the attributes in metadata, some just don't reflect the changes in the Reflection model.
        // Having compiler-generated attributes visible via Reflaction API is not that important.
        // The same for [in] and [out] metadata flags.
        edits.VerifySemantics(active,
            [SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F"), preserveLocalVariables: true)],
            capabilities: EditAndContinueCapabilities.Baseline);
    }
 
    [Theory]
    [InlineData("params")]
    [InlineData("this")]
    public void Parameter_Update_Modifiers_RuntimeTypeUnchanged(string newModifiers)
    {
        var src1 = "static class C { static int F(int[] a) => <AS:0>throw null!</AS:0>; }";
        var src2 = "static class C { static int F(" + newModifiers + " int[] a) => <AS:0>throw null!</AS:0>; }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // We don't require a runtime capability to update attributes.
        // All runtimes support changing the attributes in metadata, some just don't reflect the changes in the Reflection model.
        // Having compiler-generated attributes visible via Reflaction API is not that important.
        // The same for [in] and [out] metadata flags.
        edits.VerifySemantics(active,
            [SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F"), preserveLocalVariables: true)],
            capabilities: EditAndContinueCapabilities.Baseline);
    }
 
    [Fact]
    public void Return_TypeChange()
    {
        var src1 = "class C { int F(int a) => <AS:0>1</AS:0>; }";
        var src2 = "class C { byte F(int a) => <AS:0>1</AS:0>; }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // Can't remap to the new version of the method.
        // Even if we emitted trampoline we would not be able to remap to the exact instruction the active statement is at in the old version.
 
        edits.VerifySemanticDiagnostics(active,
            diagnostics: [Diagnostic(RudeEditKind.ChangingNameOrSignatureOfActiveMember, "byte F(int a)", GetResource("method"))],
            capabilities: EditAndContinueCapabilities.AddMethodToExistingType);
    }
 
    [Fact]
    public void Return_TypeChange_Ref()
    {
        var src1 = "class C { int X; int F(int a) => <AS:0>1</AS:0>; }";
        var src2 = "class C { int X; ref int F(int a) => <AS:0>ref X</AS:0>; }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // Can't remap to the new version of the method.
        // Even if we emitted trampoline we would not be able to remap to the exact instruction the active statement is at in the old version.
 
        edits.VerifySemanticDiagnostics(active,
            diagnostics: [Diagnostic(RudeEditKind.ChangingNameOrSignatureOfActiveMember, "ref int F(int a)", GetResource("method"))],
            capabilities: EditAndContinueCapabilities.AddMethodToExistingType);
    }
 
    [Fact]
    public void Return_TypeChange_RefReadonly()
    {
        var src1 = "class C { int X; ref int F(int a) => <AS:0>ref X</AS:0>; }";
        var src2 = "class C { int X; ref readonly int F(int a) => <AS:0>ref X</AS:0>; }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // Can't remap to the new version of the method.
        // Even if we emitted trampoline we would not be able to remap to the exact instruction the active statement is at in the old version.
 
        edits.VerifySemanticDiagnostics(active,
            diagnostics: [Diagnostic(RudeEditKind.ChangingNameOrSignatureOfActiveMember, "ref readonly int F(int a)", GetResource("method"))],
            capabilities: EditAndContinueCapabilities.AddMethodToExistingType);
    }
 
    #endregion
 
    #region Constructors
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/740949")]
    public void Updated_Inner_Constructor()
    {
        var src1 = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        <AS:1>Goo f = new Goo(5);</AS:1>
    }
}
 
class Goo
{
    int value;
    public Goo(int a)
    {
        <AS:0>this.value = a;</AS:0>
    }
}";
        var src2 = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        <AS:1>Goo f = new Goo(5*2);</AS:1>
    }
}
 
class Goo
{
    int value;
    public Goo(int a)
    {
        <AS:0>this.value = a;</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "Goo f = new Goo(5*2);"));
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/741249")]
    public void Updated_Leaf_Constructor()
    {
        var src1 = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        <AS:1>Goo f = new Goo(5);</AS:1>
    }
}
 
class Goo
{
    int value;
    public Goo(int a)
    {
        <AS:0>this.value = a;</AS:0>
    }
}";
        var src2 = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        <AS:1>Goo f = new Goo(5);</AS:1>
    }
}
 
class Goo
{
    int value;
    public Goo(int a)
    {
        <AS:0>this.value = a*2;</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/742334")]
    public void Updated_Leaf_Constructor_Parameter()
    {
        var src1 = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        <AS:1>Goo f = new Goo(5);</AS:1>
    }
}
 
class Goo
{
    int value;
    <AS:0>public Goo(int a)</AS:0>
    {
        this.value = a;
    }
}";
        var src2 = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        <AS:1>Goo f = new Goo(5);</AS:1>
    }
}
 
class Goo
{
    int value;
    <AS:0>public Goo(int b)</AS:0>
    {
        this.value = b;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemantics(
            ActiveStatementsDescription.Empty,
            [
                SemanticEdit(SemanticEditKind.Update, c => c.GetMember("Goo..ctor"), preserveLocalVariables: true)
            ],
            capabilities: EditAndContinueTestVerifier.Net6RuntimeCapabilities);
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/742334")]
    public void Updated_Leaf_Constructor_Parameter_DefaultValue()
    {
        var src1 = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        <AS:1>Goo f = new Goo(5);</AS:1>
    }
}
 
class Goo
{
    int value;
    <AS:0>public Goo(int a = 5)</AS:0>
    {
        this.value = a;
    }
}";
        var src2 = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        <AS:1>Goo f = new Goo(5);</AS:1>
    }
}
 
class Goo
{
    int value;
    <AS:0>public Goo(int a = 42)</AS:0>
    {
        this.value = a;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InitializerUpdate, "int a = 42", FeaturesResources.parameter));
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/742334")]
    public void Updated_Leaf_ConstructorChaining1()
    {
        var src1 = @"
using System;
 
class Test
{
    static void Main(string[] args)
    {
       <AS:1>B b = new B(2, 3);</AS:1>
    }
}
class B : A
{
    public B(int x, int y) : <AS:0>base(x + y, x - y)</AS:0> { }
}
class A
{
    public A(int x, int y) : this(5 + x, y, 0) { }
 
    public A(int x, int y, int z) { }
}";
        var src2 = @"
using System;
 
class Test
{
    static void Main(string[] args)
    {
       <AS:1>B b = new B(2, 3);</AS:1>
    }
}
class B : A
{
    public B(int x, int y) : <AS:0>base(x + y + 5, x - y)</AS:0> { }
}
class A
{
    public A(int x, int y) : this(x, y, 0) { }
 
    public A(int x, int y, int z) { }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/742334")]
    public void Updated_Leaf_ConstructorChaining2()
    {
        var src1 = @"
using System;
 
class Test
{
    static void Main(string[] args)
    {
       <AS:2>B b = new B(2, 3);</AS:2>
    }
}
class B : A
{
    public B(int x, int y) : <AS:1>base(x + y, x - y)</AS:1> { }
}
class A
{
    public A(int x, int y) : <AS:0>this(x, y, 0)</AS:0> { }
 
    public A(int x, int y, int z) { }
}";
        var src2 = @"
using System;
 
class Test
{
    static void Main(string[] args)
    {
       <AS:2>B b = new B(2, 3);</AS:2>
    }
}
class B : A
{
    public B(int x, int y) : <AS:1>base(x + y, x - y)</AS:1> { }
}
class A
{
    public A(int x, int y) : <AS:0>this(5 + x, y, 0)</AS:0> { }
 
    public A(int x, int y, int z) { }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_ImplicitInitializer()
    {
        var src1 = @"
class C
{
    int a = 5;
 
    <AS:0>public C(int a)</AS:0> { }
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C(3);</AS:1>
    }
}";
        var src2 = @"
class C
{
    int a = 42;
 
    <AS:0>public C(int a)</AS:0> { }
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C(3);</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_ExplicitInitializer_Update_Subexpression()
    {
        var src1 = @"
class C
{
    public C(int a) : base(a switch { 1 => <AS:0>1</AS:0>, _ => 2 }) {}
}";
        var src2 = @"
class C
{
    public C(int a) : base(1) <AS:0>{</AS:0>}
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_ExplicitInitializer_Update_Internal()
    {
        var src1 = @"
class D
{
    public D(int d) {}
}
 
class C : D
{
    int a = 5;
 
    public C(int a) : <AS:2>this(true)</AS:2> { }
 
    public C(bool b) : <AS:1>base(F())</AS:1> {}
 
    static int F()
    {
        <AS:0>return 1;</AS:0>
    }
 
    static void Main(string[] args)
    {
        <AS:3>C c = new C(3);</AS:3>
    }
}";
        var src2 = @"
class D
{
    public D(int d) {}
}
 
class C : D
{
    int a = 5;
 
    public C(int a) : <AS:2>this(false)</AS:2> { }
 
    public C(bool b) : <AS:1>base(F())</AS:1> {}
 
    static int F()
    {
        <AS:0>return 1;</AS:0>
    }
 
    static void Main(string[] args)
    {
        <AS:3>C c = new C(3);</AS:3>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "this(false)"));
    }
 
    [Fact]
    public void Constructor_Instance_ExplicitInitializer_Update_Leaf()
    {
        var src1 = @"
class D
{
    public D(int d) { }
}
 
class C : D
{
    public C() : <AS:0>base(1)</AS:0> {}
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var src2 = @"
class D
{
    public D(int d) { }
}
 
class C : D
{
    public C() : <AS:0>base(2)</AS:0> {}
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_ImplicitInitializer_Update_ToExplicit_Leaf()
    {
        var src1 = @"
class D
{
    public D() { }
    public D(int d) { }
}
 
class C : D
{
    <AS:0>public C()</AS:0> {}
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var src2 = @"
class D
{
    public D() { }
    public D(int d) { }
}
 
class C : D
{
    public C() : <AS:0>base(2)</AS:0> {}
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_ImplicitInitializer_Update_ToExplicit_Internal()
    {
        var src1 = @"
class D
{
    public D(int d) <AS:0>{</AS:0> }
}
 
class C : D
{
    <AS:1>public C()</AS:1> {}
}";
        var src2 = @"
class D
{
    public D(int d) <AS:0>{</AS:0> }
}
 
class C : D
{
    public C() : <AS:1>base(1)</AS:1> {}
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "base(1)"));
    }
 
    [Fact]
    public void Constructor_Instance_ExplicitInitializer_Update_ToImplicit_Internal()
    {
        var src1 = @"
class D
{
    public D(int d) {}
}
 
class C : D
{
    public C() : <AS:1>base(F())</AS:1> {}
 
    static int F()
    {
        <AS:0>return 1;</AS:0>
    }
 
    static void Main(string[] args)
    {
        <AS:2>C c = new C();</AS:2>
    }
}";
        var src2 = @"
class D
{
    public D(int d) {}
}
 
class C : D
{
    <AS:1>public C()</AS:1> {}
 
    static int F()
    {
        <AS:0>return 1;</AS:0>
    }
 
    static void Main(string[] args)
    {
        <AS:2>C c = new C();</AS:2>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "public C()"));
    }
 
    [Fact]
    public void Constructor_Instance_ExplicitInitializer_Update_ToImplicit_Leaf()
    {
        var src1 = @"
class D
{
    public D() { }
    public D(int d) { }
}
 
class C : D
{
    public C() : <AS:0>base(2)</AS:0> {}
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var src2 = @"
class D
{
    public D() { }
    public D(int d) { }
}
 
class C : D
{
    <AS:0>public C()</AS:0> {}
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_ExplicitInitializer_WithLambda_Update1()
    {
        var src1 = @"
class C
{
    public C() : this((a, b) => { <AS:0>Console.WriteLine(a + b);</AS:0> }) { }
}";
        var src2 = @"
class C
{
    public C() : base((a, b) => { <AS:0>Console.WriteLine(a - b);</AS:0> }) { }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_ExplicitInitializer_WithLambda_Update2()
    {
        var src1 = @"
class C
{
    public C() : <AS:1>this((a, b) => { <AS:0>Console.WriteLine(a + b);</AS:0> })</AS:1> { Console.WriteLine(1); }
}";
        var src2 = @"
class C
{
    public C() : <AS:1>this((a, b) => { <AS:0>Console.WriteLine(a + b);</AS:0> })</AS:1> { Console.WriteLine(2); }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_ExplicitInitializer_WithLambda_Update3()
    {
        var src1 = @"
class C
{
    public C() : <AS:1>this((a, b) => { <AS:0>Console.WriteLine(a + b);</AS:0> })</AS:1> { Console.WriteLine(1); }
}";
        var src2 = @"
class C
{
    public C() : <AS:1>this((a, b) => { <AS:0>Console.WriteLine(a - b);</AS:0> })</AS:1> { Console.WriteLine(1); }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_ExplicitInitializer_Delete()
    {
        var src1 = @"
class C
{
    public C(int a) : base(a switch { 1 => <AS:0>1</AS:0>, _ => 2 }) {}
}";
        var src2 = @"
class C
{
    public C(int a) <AS:0>{</AS:0>}
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68708")]
    public void Constructor_Instance_ImplicitInitializer_ParameterChange()
    {
        var src1 = "class C { <AS:0>C(int P)</AS:0>  {} }";
        var src2 = "class C { <AS:0>C(byte P)</AS:0> {} }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            active,
            diagnostics: [Diagnostic(RudeEditKind.ChangingNameOrSignatureOfActiveMember, "C(byte P)", GetResource("constructor"))],
            capabilities: EditAndContinueCapabilities.AddMethodToExistingType);
    }
 
    [Theory]
    [InlineData("class")]
    [InlineData("struct")]
    [WorkItem("https://github.com/dotnet/roslyn/issues/68708")]
    public void Constructor_Instance_Primary_ImplicitInitializer_ParameterChange(string keyword)
    {
        var src1 = keyword + " <AS:0>C(int  P)</AS:0>;";
        var src2 = keyword + " <AS:0>C(byte P)</AS:0>;";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            active,
            diagnostics: [Diagnostic(RudeEditKind.ChangingNameOrSignatureOfActiveMember, "(byte P)", GetResource("constructor"))],
            capabilities: EditAndContinueCapabilities.AddMethodToExistingType);
    }
 
    [Theory]
    [InlineData("class")]
    [InlineData("record")]
    public void Constructor_Instance_Primary_ExplicitInitializer(string keyword)
    {
        var src1 = keyword + " C(int P) : <AS:0>B(1)</AS:0>;";
        var src2 = keyword + " C(int P) : <AS:0>B(2)</AS:0>;";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_Primary_Record_Parameter_BaseInitializerChange()
    {
        var src1 = "record C(<AS:0>int P</AS:0>) : B(1);";
        var src2 = "record C(<AS:0>int P</AS:0>) : B(2);";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Theory]
    [InlineData("record")]
    [InlineData("record struct")]
    public void Constructor_Instance_Primary_Record_Parameter_TypeAttributeChange(string keyword)
    {
        var src1 = "class A(int x) : System.Attribute; [A( 1)]" + keyword + " C(<AS:0>int P</AS:0>);";
        var src2 = "class A(int x) : System.Attribute; [A(10)]" + keyword + " C(<AS:0>int P</AS:0>);";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            active,
            capabilities: EditAndContinueCapabilities.ChangeCustomAttributes);
    }
 
    [Theory]
    [InlineData("record")]
    [InlineData("record struct")]
    public void Constructor_Instance_Primary_Record_Parameter_TypeParameterAttributeChange(string keyword)
    {
        var src1 = "class A(int x) : System.Attribute; " + keyword + " C<[A( 1)] T>(<AS:0>int P</AS:0>);";
        var src2 = "class A(int x) : System.Attribute; " + keyword + " C<[A(10)] T>(<AS:0>int P</AS:0>);";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            active,
            diagnostics:
            [
                Diagnostic(RudeEditKind.GenericTypeUpdate, "T")
            ],
            capabilities: EditAndContinueCapabilities.ChangeCustomAttributes);
    }
 
    [Fact]
    public void Constructor_Instance_Copy_BaseInitializerChange()
    {
        var src1 = "record <AS:0>C</AS:0>(int P) : B(1);";
        var src2 = "record <AS:0>C</AS:0>(int P) : B(2);";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Theory]
    [InlineData("record")]
    [InlineData("record struct")]
    public void Constructor_Instance_Copy_TypeAttributeChange(string keyword)
    {
        var src1 = "class A(int x) : System.Attribute; [A( 1)]" + keyword + " <AS:0>C</AS:0>(int P);";
        var src2 = "class A(int x) : System.Attribute; [A(10)]" + keyword + " <AS:0>C</AS:0>(int P);";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            active,
            capabilities: EditAndContinueCapabilities.ChangeCustomAttributes);
    }
 
    [Theory]
    [InlineData("record")]
    [InlineData("record struct")]
    public void Constructor_Instance_Copy_TypeParameterAttributeChange(string keyword)
    {
        var src1 = "class A(int x) : System.Attribute; " + keyword + " <AS:0>C<[A( 1)] T></AS:0>(int P);";
        var src2 = "class A(int x) : System.Attribute; " + keyword + " <AS:0>C<[A(10)] T></AS:0>(int P);";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            active,
            diagnostics:
            [
                Diagnostic(RudeEditKind.GenericTypeUpdate, "T"),
            ],
            capabilities: EditAndContinueCapabilities.ChangeCustomAttributes);
    }
 
    [Fact]
    public void Constructor_Instance_Copy_ReplacingPrimaryWithNonPrimary()
    {
        var src1 = @"
public record <AS:0>C</AS:0>(int P);";
        var src2 = @"
public record C
{
    public int P { get; init; }
    public C(int P) { }
    <AS:0>protected C(C original)</AS:0> { P = original.P; }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_Copy_ReplacingNonPrimaryWithPrimary_Initializer()
    {
        var src1 = @"
public record C
{
    public int P { get; init; }
    public C(int P) { }
    <AS:0>protected C(C original)</AS:0> { P = original.P; }
}
";
        var src2 = @"
public record <AS:0>C</AS:0>(int P);";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_Copy_ReplacingNonPrimaryWithPrimary_Body1()
    {
        var src1 = @"
public record C
{
    public int P { get; init; }
    public C(int P) { }
    protected C(C original) <AS:0>{</AS:0> P = original.P; }
}
";
        var src2 = @"
public record <AS:0>C</AS:0>(int P);";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_Copy_ReplacingNonPrimaryWithPrimary_Body2()
    {
        var src1 = @"
public record C
{
    public int P { get; init; }
    public C(int P) { }
    protected C(C original) { P = original.P; <AS:0>}</AS:0>
}
";
        var src2 = @"
public record <AS:0>C</AS:0>(int P);";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Theory]
    [InlineData("class ")]
    [InlineData("struct")]
    public void Constructor_Instance_Delete_Parameterless(string typeKind)
    {
        var src1 = "partial " + typeKind + " C { public C() { <AS:0>System.Console.WriteLine(1);</AS:0> } }";
        var src2 = "<AS:0>partial " + typeKind + " C</AS:0> { }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // Synthesized constructor is generated and the active statement is remapped into it.
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Theory]
    [InlineData("class")]
    [InlineData("struct")]
    [InlineData("record")]
    [InlineData("record struct")]
    public void Constructor_Instance_Delete_Primary(string typeKind)
    {
        var src1 = typeKind + " <AS:0>C()</AS:0> { }";
        var src2 = "<AS:0>" + typeKind + " C</AS:0> { }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // Synthesized constructor is generated and the active statement is remapped into it.
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Theory]
    [InlineData("class")]
    [InlineData("record")]
    public void Constructor_Instance_Delete_BaseInitializer_Internal(string typeKind)
    {
        var src1 = "<AS:0>var c = new C();</AS:0> " + typeKind + " C() : <AS:1>B()</AS:1> { }";
        var src2 = "<AS:0>var c = new C();</AS:0> " + typeKind + " <AS:1>C()</AS:1> : B { }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "C()"));
    }
 
    [Theory]
    [InlineData("class")]
    [InlineData("record")]
    public void Constructor_Instance_Delete_BaseInitializer_Leaf(string typeKind)
    {
        var src1 = typeKind + " C() : <AS:0>B()</AS:0> { }";
        var src2 = typeKind + " <AS:0>C()</AS:0> : B { }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Theory]
    [InlineData("class")]
    [InlineData("record")]
    public void Constructor_Instance_Insert_BaseInitializer_Internal(string typeKind)
    {
        var src1 = "<AS:0>var c = new C();</AS:0> " + typeKind + " <AS:1>C()</AS:1> : B { }";
        var src2 = "<AS:0>var c = new C();</AS:0> " + typeKind + " C() : <AS:1>B()</AS:1> { }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "B()"));
    }
 
    [Theory]
    [InlineData("class")]
    [InlineData("record")]
    public void Constructor_Instance_Insert_BaseInitializer_Leaf(string typeKind)
    {
        var src1 = typeKind + " <AS:0>C()</AS:0> : B { }";
        var src2 = typeKind + " C() : <AS:0>B()</AS:0> { }";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Theory]
    [InlineData("class")]
    [InlineData("struct")]
    [InlineData("record")]
    [InlineData("record struct")]
    public void Constructor_Instance_Unchanged(string typeKind)
    {
        var src1 = "<AS:0>var c = new C(1);</AS:0> " + typeKind + " <AS:1>C(int a)</AS:1>;";
        var src2 = "<AS:0>var c = new C(2);</AS:0> " + typeKind + " <AS:1>C(int a)</AS:1>;";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_Primary_Record_ReplacingPrimaryWithNonPrimary()
    {
        var src1 = @"
public record <AS:0>C(int P)</AS:0>;";
        var src2 = @"
public record C
{
    public int P { get; init; }
    <AS:0>public C(int P)</AS:0> { }
    protected C(C original) { P = original.P; }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_Primary_Record_ReplacingNonPrimaryWithPrimary_Initializer()
    {
        var src1 = @"
public record C
{
    public int P { get; init; }
    <AS:0>public C(int P)</AS:0> { }
    protected C(C original) { P = original.P; }
}
";
        var src2 = @"
public record <AS:0>C(int P)</AS:0>;";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_Primary_Record_ReplacingNonPrimaryWithPrimary_Body()
    {
        var src1 = @"
public record C
{
    public int P { get; init; }
    public C(int P) { <AS:0>}</AS:0>
    protected C(C original) { P = original.P; }
}
";
        var src2 = @"
public record <AS:0>C(int P)</AS:0>;";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Constructor_Instance_ReplacingNonPrimaryWithPrimary_Record()
    {
        var src1 = @"
public record C
{
    public int P { <AS:0>get;</AS:0> <AS:1>init;</AS:1> }
    <AS:2>public C(int P)</AS:2> { }
    protected C(C original) { <AS:3>P = original.P;</AS:3> }
}";
        var src2 = @"
public record <AS:2,3>C</AS:3>(<AS:0,1>int P</AS:0,1>)</AS:2>;
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "C       (        int P         )"),
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "C"),
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "int P"));
    }
 
    [Fact]
    public void Constructor_Instance_ReplacingPrimaryWithNonPrimary_Record_PrimaryConstructor2()
    {
        var src1 = @"
public record <AS:1,2>C</AS:2>(<AS:0>int P</AS:0>)</AS:1>;";
        var src2 = @"
public record C
{
    public int P { <AS:0>get;</AS:0> init; }
    <AS:1>public C(int P)</AS:1> { }
    <AS:2>protected C(C original)</AS:2> { P = original.P; }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "public C(int P)"),
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "protected C(C original)"));
    }
 
    #endregion
 
    #region Properties
 
    [Fact]
    public void Property_Update_Type_ActiveAccessors()
    {
        // only type is changed, no changes to the accessors (not even whitespace)
        var src1 = @"
class C
{
    public byte P { get => <AS:0>1</AS:0>; set <AS:1>{</AS:1> } }
}
";
        var src2 = @"
class C
{
    public long P { get => <AS:0>1</AS:0>; set <AS:1>{</AS:1> } }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            active,
            diagnostics:
            [
                Diagnostic(RudeEditKind.ChangingNameOrSignatureOfActiveMember, "get", GetResource("property getter")),
                Diagnostic(RudeEditKind.ChangingNameOrSignatureOfActiveMember, "set", GetResource("property setter"))
            ],
            capabilities: EditAndContinueCapabilities.AddMethodToExistingType);
    }
 
    [Fact]
    public void Property_Rename_ActiveAccessors()
    {
        var src1 = @"
class C
{
    public int P { get => <AS:0>1</AS:0>; set <AS:1>{</AS:1> } }
}
";
        var src2 = @"
class C
{
    public int Q { get => <AS:0>1</AS:0>; set <AS:1>{</AS:1> } }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            active,
            diagnostics:
            [
                Diagnostic(RudeEditKind.ChangingNameOrSignatureOfActiveMember, "get", GetResource("property getter")),
                Diagnostic(RudeEditKind.ChangingNameOrSignatureOfActiveMember, "set", GetResource("property setter"))
            ],
            capabilities: EditAndContinueCapabilities.AddMethodToExistingType);
    }
 
    [Fact]
    public void Property_Auto_Record_ReplacingNonPrimaryWithPrimary_Getter()
    {
        var src1 = @"
public record C
{
    public int P { <AS:0>get;</AS:0> init; }
    public C(int P) { }
    protected C(C original) {P = original.P; }
}";
        var src2 = @"
public record C(<AS:0>int P</AS:0>);
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Property_Auto_Record_ReplacingNonPrimaryWithPrimary_Setter()
    {
        var src1 = @"
public record C
{
    public int P { get; <AS:0>init;</AS:0> }
    public C(int P) { }
    protected C(C original) {P = original.P; }
}";
        var src2 = @"
public record C(<AS:0>int P</AS:0>);
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Property_Auto_Record_ReplacingPrimaryWithNonPrimary_Getter()
    {
        // Consider: Just looking at the span we do not know whether the active statement is in the getter of the setter.
        // We could resolve the method token associated with the method to find out and map the statement accordingly.
 
        var src1 = @"
public record C(<AS:0>int P</AS:0>);
";
        var src2 = @"
public record C
{
    public int P { <AS:0>get;</AS:0> init; }
    public C(int P) { }
    protected C(C original) {P = original.P; }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Property_Auto_Record_ReplacingPrimaryWithNonPrimary_Setter()
    {
        // Consider: Just looking at the span we do not know whether the active statement is in the getter of the setter.
        // We could resolve the method token associated with the method to find out and map the statement accordingly.
 
        var src1 = @"
public record C(<AS:0>int P</AS:0>);
";
        var src2 = @"
public record C
{
    public int P { <AS:0>init;</AS:0> get; }
    public C(int P) { }
    protected C(C original) {P = original.P; }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    #endregion
 
    #region Field and Property Initializers
 
    [Theory]
    [InlineData("class ")]
    [InlineData("struct")]
    public void InstancePropertyInitializer_Leaf_Update(string typeKind)
    {
        var src1 = @"
" + typeKind + @" C
{
    int a { get; } = <AS:0>1</AS:0>;
 
    public C() {}
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var src2 = @"
" + typeKind + @" C
{
    int a { get; } = <AS:0>2</AS:0>;
 
    public C() {}
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Theory]
    [InlineData("class ")]
    [InlineData("struct")]
    public void InstancePropertyInitializer_Leaf_Update_SynthesizedConstructor(string typeKind)
    {
        var src1 = @"
" + typeKind + @" C
{
    int a { get; } = <AS:0>1</AS:0>;
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var src2 = @"
" + typeKind + @" C
{
    int a { get; } = <AS:0>2</AS:0>;
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/742334")]
    [InlineData("class ")]
    [InlineData("struct")]
    public void InstanceFieldInitializer_Leaf_Update1(string typeKind)
    {
        var src1 = @"
" + typeKind + @" C
{
    <AS:0>int a = 1</AS:0>, b = 2;
 
    public C() {}
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var src2 = @"
" + typeKind + @" C
{
    <AS:0>int a = 2</AS:0>, b = 2;
 
    public C() {}
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Theory]
    [InlineData("class ")]
    [InlineData("struct")]
    public void InstanceFieldInitializer_Leaf_Update1_SynthesizedConstructor(string typeKind)
    {
        var src1 = @"
" + typeKind + @" C
{
    <AS:0>int a = 1</AS:0>, b = 2;
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var src2 = @"
" + typeKind + @" C
{
    <AS:0>int a = 2</AS:0>, b = 2;
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void InstanceFieldInitializer_Internal_Update1()
    {
        var src1 = @"
class C
{
    <AS:1>int a = F(1)</AS:1>, b = F(2);
 
    public C() {}
 
    public static int F(int a)
    {
        <AS:0>return a;</AS:0> 
    }
 
    static void Main(string[] args)
    {
        <AS:2>C c = new C();</AS:2>
    }
}";
        var src2 = @"
class C
{
    <AS:1>int a = F(2)</AS:1>, b = F(2);
 
    public C() {}
 
    public static int F(int a)
    {
        <AS:0>return a;</AS:0> 
    }
 
    static void Main(string[] args)
    {
        <AS:2>C c = new C();</AS:2>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "int a = F(2)"));
    }
 
    [Fact]
    public void InstanceFieldInitializer_Internal_Update2()
    {
        var src1 = @"
class C
{
    int a = F(1), <AS:1>b = F(2)</AS:1>;
 
    public C() {}
 
    public static int F(int a)
    {
        <AS:0>return a;</AS:0> 
    }
 
    static void Main(string[] args)
    {
        <AS:2>C c = new C();</AS:2>
    }
}";
        var src2 = @"
class C
{
    int a = F(1), <AS:1>b = F(3)</AS:1>;
 
    public C() {}
 
    public static int F(int a)
    {
        <AS:0>return a;</AS:0> 
    }
 
    static void Main(string[] args)
    {
        <AS:2>C c = new C();</AS:2>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "b = F(3)"));
    }
 
    [Fact]
    public void InstancePropertyInitializer_Internal_Delete1()
    {
        var src1 = @"
class C
{
    int a { get; } = <AS:0>1</AS:0>;
    int b { get; } = 2;
}";
        var src2 = @"
class C
{
    int a { get { return 1; } }
    int b { get; } = <AS:0>2</AS:0>;
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void InstancePropertyInitializer_Internal_Delete2()
    {
        var src1 = @"
class C
{
    int a { get; } = <AS:0>1</AS:0>;
    static int s { get; } = 2;
    int b { get; } = 2;
 
    public C() {}
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var src2 = @"
class C
{
    int a { get; }
    static int s { get; } = 2;
    int b { get; } = <AS:0>3</AS:0>;
 
    public C() { }
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void InstanceFieldInitializer_Internal_Delete1()
    {
        var src1 = @"
class C
{
    <AS:1>int a = F(1)</AS:1>, b = F(2);
 
    public C() {}
 
    public static int F(int a)
    {
        <AS:0>return a;</AS:0> 
    }
 
    static void Main(string[] args)
    {
        <AS:2>C c = new C();</AS:2>
    }
}";
        var src2 = @"
class C
{
    int a, <AS:1>b = F(2)</AS:1>;
 
    public C() {}
 
    public static int F(int a)
    {
        <AS:0>return a;</AS:0> 
    }
 
    static void Main(string[] args)
    {
        <AS:2>C c = new C();</AS:2>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69249")]
    public void InstanceFieldInitializer_Internal_Delete2()
    {
        var src1 = @"
class C
{
    int a = F(1), <AS:1>b = F(2)</AS:1>;
 
    public static int F(int a) => <AS:0>1</AS:0>;
}";
        var src2 = @"
class C
{
    <AS:1>int a, b;</AS:1>
 
    public static int F(int a) => <AS:0>1</AS:0>;
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void InstancePropertyAndFieldInitializers_Delete1()
    {
        var src1 = @"
class C
{
    int a { get; } = <AS:0>1</AS:0>;
    static int s { get; } = 2;
    int b = 2;
}";
        var src2 = @"
class C
{
    int a { get; }
    static int s { get; } = 2;
    <AS:0>int b = 3;</AS:0>
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void InstancePropertyAndFieldInitializers_Delete2()
    {
        var src1 = @"
class C
{
    int a = <AS:0>1</AS:0>;
    static int s { get; } = 2;
    int b { get; } = 2;
 
    public C() {}
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var src2 = @"
class C
{
    int a;
    static int s { get; } = 2;
    int b { get; } = <AS:0>3</AS:0>;
 
    public C() { }
 
    static void Main(string[] args)
    {
        <AS:1>C c = new C();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void InstanceFieldInitializer_SingleDeclarator()
    {
        var src1 = @"
class C
{
    <AS:1>public static readonly int a = F(1);</AS:1>
 
    public C() {}
 
    public static int F(int a)
    {
        <AS:0>return a;</AS:0> 
    }
 
    static void Main(string[] args)
    {
        <AS:2>C c = new C();</AS:2>
    }
}";
        var src2 = @"
class C
{
    <AS:1>public static readonly int <TS:1>a = F(1)</TS:1>;</AS:1>
 
    public C() {}
 
    public static int F(int a)
    {
        <TS:0><AS:0>return a + 1;</AS:0></TS:0>
    }
 
    static void Main(string[] args)
    {
        <TS:2><AS:2>C c = new C();</AS:2></TS:2>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void FieldInitializer_Lambda1()
    {
        var src1 = @"
class C
{
    Func<int, int> a = z => <AS:0>z + 1</AS:0>;
 
    static void Main(string[] args)
    {
        <AS:1>new C().a(1);</AS:1>
    }
}";
        var src2 = @"
class C
{
    Func<int, int> a = F(z => <AS:0>z + 1</AS:0>);
 
    static void Main(string[] args)
    {
        <AS:1>new C().a(1);</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void PropertyInitializer_Lambda1()
    {
        var src1 = @"
class C
{
    Func<int, int> a { get; } = z => <AS:0>z + 1</AS:0>;
 
    static void Main(string[] args)
    {
        <AS:1>new C().a(1);</AS:1>
    }
}";
        var src2 = @"
class C
{
    Func<int, int> a { get; } = F(z => <AS:0>z + 1</AS:0>);
 
    static void Main(string[] args)
    {
        <AS:1>new C().a(1);</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void FieldInitializer_Lambda2()
    {
        var src1 = @"
class C
{
    Func<int, Func<int>> a = z => () => <AS:0>z + 1</AS:0>;
 
    static void Main(string[] args)
    {
        <AS:1>new C().a(1)();</AS:1>
    }
}";
        var src2 = @"
class C
{
    Func<int, Func<int>> a = z => () => <AS:0>z + 2</AS:0>;
 
    static void Main(string[] args)
    {
        <AS:1>new C().a(1)();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void PropertyInitializer_Lambda2()
    {
        var src1 = @"
class C
{
    Func<int, Func<int>> a { get; } = z => () => <AS:0>z + 1</AS:0>;
 
    static void Main(string[] args)
    {
        <AS:1>new C().a(1)();</AS:1>
    }
}";
        var src2 = @"
class C
{
    Func<int, Func<int>> a { get; } = z => () => <AS:0>z + 2</AS:0>;
 
    static void Main(string[] args)
    {
        <AS:1>new C().a(1)();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void FieldInitializer_InsertConst1()
    {
        var src1 = @"
class C
{
    <AS:0>int a = 1</AS:0>;
 
    public C() {}
}";
        var src2 = @"
class C
{
    <AS:0>const int a = 1;</AS:0>
 
    public C() {}
}";
        var edits = GetTopEdits(src1, src2);
 
        edits.VerifyEdits(
            "Update [int a = 1       ;]@24 -> [const int a = 1;]@24");
 
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ModifiersUpdate, "const int a = 1", GetResource("field")));
    }
 
    [Fact]
    public void LocalInitializer_InsertConst1()
    {
        var src1 = @"
class C
{
    public void M()
    {
        <AS:0>int a = 1</AS:0>;
    }
}";
        var src2 = @"
class C
{
    public void M()
    {
        const int a = 1;
    <AS:0>}</AS:0>
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void FieldInitializer_InsertConst2()
    {
        var src1 = @"
class C
{
    int <AS:0>a = 1</AS:0>, b = 2;
 
    public C() {}
}";
        var src2 = @"
class C
{
    <AS:0>const int a = 1, b = 2;</AS:0>
 
    public C() {}
}";
        var edits = GetTopEdits(src1, src2);
 
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ModifiersUpdate, "const int a = 1, b = 2", GetResource("field")),
            Diagnostic(RudeEditKind.ModifiersUpdate, "const int a = 1, b = 2", GetResource("field")));
    }
 
    [Fact]
    public void LocalInitializer_InsertConst2()
    {
        var src1 = @"
class C
{
    public void M()
    {
        int <AS:0>a = 1</AS:0>, b = 2;
    }
}";
        var src2 = @"
class C
{
    public void M()
    {
        const int a = 1, b = 2;
    <AS:0>}</AS:0>
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void FieldInitializer_Delete1()
    {
        var src1 = @"
class C
{
    <AS:0>int a = 1;</AS:0>
    int b = 1;
 
    public C() {}
}";
        var src2 = @"
class C
{
    int a;
    <AS:0>int b = 1;</AS:0>
 
    public C() {}
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void LocalInitializer_Delete1()
    {
        var src1 = @"
class C
{
      public void M() { <AS:0>int a = 1</AS:0>; }
}";
        var src2 = @"
class C
{
    public void M() { int a; <AS:0>}</AS:0> 
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void FieldInitializer_Delete2()
    {
        var src1 = @"
class C
{
    int b = 1;
    int c;
    <AS:0>int a = 1;</AS:0>
 
    public C() {}
}";
        var src2 = @"
class C
{
    <AS:0>int b = 1;</AS:0>
    int c;
    int a;
 
    public C() {}
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void LocalInitializer_Delete2()
    {
        var src1 = @"
class C
{
    public void M() 
    {
        int b = 1;
        int c;
        <AS:0>int a = 1;</AS:0>
    }
}";
        var src2 = @"
class C
{
    public void M()
    { 
        int b = 1;
        int c;
        int a;
    <AS:0>}</AS:0>
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void FieldInitializer_Delete3()
    {
        var src1 = @"
class C
{
    int b = 1;
    int c;
    <AS:0>int a = 1;</AS:0>
 
    public C() {}
}";
        var src2 = @"
class C
{
    <AS:0>int b = 1;</AS:0>
    int c;
 
    public C() {}
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteActiveStatement, "class C", GetResource("field", "C.a")),
            Diagnostic(RudeEditKind.Delete, "class C", GetResource("field", "a")));
    }
 
    [Fact]
    public void LocalInitializer_Delete3()
    {
        var src1 = @"
class C
{
    public void M() 
    {
        int b = 1;
        int c;
        <AS:0>int a = 1;</AS:0>
    }
}";
        var src2 = @"
class C
{
    public void M()
    { 
        int b = 1;
        int c;
    <AS:0>}</AS:0>
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void FieldInitializer_DeleteStaticInstance1()
    {
        var src1 = @"
class C
{
    <AS:0>int a = 1;</AS:0>
    static int b = 1;
    int c = 1;
    
    public C() {}
}";
        var src2 = @"
class C
{
    int a;
    static int b = 1;
    <AS:0>int c = 1;</AS:0>
 
    public C() {}
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void FieldInitializer_DeleteStaticInstance2()
    {
        var src1 = @"
class C
{
    static int c = 1;
    <AS:0>static int a = 1;</AS:0>
    int b = 1;
    
    public C() {}
}";
        var src2 = @"
class C
{
    <AS:0>static int c = 1;</AS:0>
    static int a;
    int b = 1;
 
    public C() {}
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void FieldInitializer_DeleteStaticInstance3()
    {
        var src1 = @"
class C
{
    <AS:0>static int a = 1;</AS:0>
    int b = 1;
    
    public C() {}
}";
        var src2 = @"
class C
{
    <AS:0>static int a;</AS:0>
    int b = 1;
 
    public C() {}
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void FieldInitializer_DeleteMove1()
    {
        var src1 = @"
class C
{
    int b = 1;
    int c;
    <AS:0>int a = 1;</AS:0>
 
    public C() {}
}";
        var src2 = @"
class C
{
    int c;
    <AS:0>int b = 1;</AS:0>
 
    public C() {}
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteActiveStatement, "class C", GetResource("field", "C.a")),
            Diagnostic(RudeEditKind.Delete, "class C", GetResource("field", "a")));
    }
 
    [Fact]
    public void LocalInitializer_DeleteReorder1()
    {
        var src1 = @"
class C
{
    public void M() 
    {
        int b = 1;
        <AS:0>int a = 1;</AS:0>
        int c;
    }
}";
        var src2 = @"
class C
{
    public void M()
    { 
        int c;
        <AS:0>int b = 1;</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void FieldToProperty1()
    {
        var src1 = @"
class C
{
    int a = <AS:0>1</AS:0>;
}";
 
        // The placement of the active statement is not ideal, but acceptable.
        var src2 = @"
<AS:0>class C</AS:0>
{
    int a { get; } = 1;
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteActiveStatement, "class C", GetResource("field", "C.a")),
            Diagnostic(RudeEditKind.Delete, "class C", GetResource("field", "a")));
    }
 
    [Fact]
    public void PropertyToField1()
    {
        var src1 = @"
class C
{
    int a { get; } = <AS:0>1</AS:0>;
}";
 
        // The placement of the active statement is not ideal, but acceptable.
        var src2 = @"
<AS:0>class C</AS:0>
{
    int a = 1;
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemantics(
            [
                SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.a")),
                SemanticEdit(SemanticEditKind.Delete, c => c.GetMember("C.get_a"), deletedSymbolContainerProvider: c => c.GetMember("C")),
                SemanticEdit(SemanticEditKind.Delete, c => c.GetMember("C.a"), deletedSymbolContainerProvider: c => c.GetMember("C")),
                SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C..ctor"), preserveLocalVariables: true),
            ],
            capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType);
    }
 
    #endregion
 
    #region Lock Statement
 
    [Fact]
    public void LockBody_Update()
    {
        var src1 = @"
class Test
{
    private static object F() { <AS:0>return new object();</AS:0> }
 
    static void Main(string[] args)
    {
        <AS:1>lock (F())</AS:1>
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static object F() { <AS:0>return new object();</AS:0> }
 
    static void Main(string[] args)
    {
        <AS:1>lock (F())</AS:1>
        {
            System.Console.Write(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755749")]
    public void Lock_Insert_Leaf()
    {
        var src1 = @"
class Test
{
    private static object lockThis = new object();
    static void Main(string[] args)
    {
        <AS:0>System.Console.Write(5);</AS:0>
    }
}";
        var src2 = @"
class Test
{
    private static object lockThis = new object();
    static void Main(string[] args)
    {
        lock (lockThis)
        {
            <AS:0>System.Console.Write(5);</AS:0>
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "lock (lockThis)", CSharpFeaturesResources.lock_statement));
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755749")]
    public void Lock_Insert_Leaf2()
    {
        var src1 = @"
class Test
{
    private static object lockThis = new object();
    static void Main(string[] args)
    {
        {
            System.Console.Write(5);
        <AS:0>}</AS:0>
    }
}";
        var src2 = @"
class Test
{
    private static object lockThis = new object();
    static void Main(string[] args)
    {
        lock (lockThis)
        {
            System.Console.Write(5);
        <AS:0>}</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "lock (lockThis)", CSharpFeaturesResources.lock_statement));
    }
 
    [Fact]
    public void Lock_Insert_Leaf3()
    {
        var src1 = @"
class Test
{
    private static object lockThis = new object();
    static void Main(string[] args)
    {
        {
            System.Console.Write(5);
        }
        <AS:0>System.Console.Write(10);</AS:0>
    }
}";
        var src2 = @"
class Test
{
    private static object lockThis = new object();
    static void Main(string[] args)
    {
        lock (lockThis)
        {
            System.Console.Write(5);
        }
        <AS:0>System.Console.Write(5);</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Lock_Insert_Leaf4()
    {
        var src1 = @"
class Test
{
    public static object a = new object();
    public static object b = new object();
    public static object c = new object();
    public static object d = new object();
    public static object e = new object();
    
    static void Main(string[] args)
    {
        lock (a)
        {
            lock (b)
            {
                lock (c)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var src2 = @"
class Test
{
    public static object a = new object();
    public static object b = new object();
    public static object c = new object();
    public static object d = new object();
    public static object e = new object();
    
    static void Main(string[] args)
    {
        lock (b)
        {
            lock (d)
            {
                lock (a)
                {
                    lock (e)
                    {
                        <AS:0>System.Console.Write();</AS:0>
                    }
                }
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "lock (d)", CSharpFeaturesResources.lock_statement),
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "lock (e)", CSharpFeaturesResources.lock_statement));
    }
 
    [Fact]
    public void Lock_Insert_Leaf5()
    {
        var src1 = @"
class Test
{
    public static object a = new object();
    public static object b = new object();
    public static object c = new object();
    public static object d = new object();
    public static object e = new object();
    
    static void Main(string[] args)
    {
        lock (a)
        {
            lock (c)
            {
                lock (b)
                {
                    lock (e)
                    {
                        <AS:0>System.Console.Write();</AS:0>
                    }
                }
            }
        }
    }
}";
 
        var src2 = @"
class Test
{
    public static object a = new object();
    public static object b = new object();
    public static object c = new object();
    public static object d = new object();
    public static object e = new object();
    
    static void Main(string[] args)
    {
        lock (b)
        {
            lock (d)
            {
                lock (a)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "lock (d)", CSharpFeaturesResources.lock_statement));
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755752")]
    public void Lock_Update_Leaf()
    {
        var src1 = @"
class Test
{
    private static object lockThis = new object();
    static void Main(string[] args)
    {
        lock (lockThis)
        {
            <AS:0>System.Console.Write(5);</AS:0>
        }
    }
}";
        var src2 = @"
class Test
{
    private static object lockThis = new object();
    static void Main(string[] args)
    {
        lock (""test"")
        {
            <AS:0>System.Console.Write(5);</AS:0>
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "lock (\"test\")", CSharpFeaturesResources.lock_statement));
    }
 
    [Fact]
    public void Lock_Update_Leaf2()
    {
        var src1 = @"
class Test
{
    private static object lockThis = new object();
    static void Main(string[] args)
    {
        lock (lockThis)
        {
            System.Console.Write(5);
        }
        <AS:0>System.Console.Write(5);</AS:0>
    }
}";
        var src2 = @"
class Test
{
    private static object lockThis = new object();
    static void Main(string[] args)
    {
        lock (""test"")
        {
            System.Console.Write(5);
        }
        <AS:0>System.Console.Write(5);</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Lock_Delete_Leaf()
    {
        var src1 = @"
class Test
{
    private static object lockThis = new object();
    static void Main(string[] args)
    {
        lock (lockThis)
        {
            <AS:0>System.Console.Write(5);</AS:0>
        }
    }
}";
        var src2 = @"
class Test
{
    private static object lockThis = new object();
    static void Main(string[] args)
    {
        <AS:0>System.Console.Write(5);</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Lock_Update_Lambda1()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        lock (F(a => a))
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        lock (F(a => a + 1))
        {
            <AS:0>Console.WriteLine(2);</AS:0>
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Lock_Update_Lambda2()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        lock (F(a => a))
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        lock (G(a => a))
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "lock (G(a => a))", CSharpFeaturesResources.lock_statement));
    }
 
    [Fact]
    public void Lock_Update_Type()
    {
        var src1 = """
            class C
            {
                static void F()
                {
                    var a = new object();
                    var b = new C();
                    var c = "";
 
                    lock (a)
                    {
                        lock (b)
                        {
                            lock (c)
                            {
                                <AS:0>System.Console.Write();</AS:0>
                            }
                        }
                    }
                }
            }
            """;
 
        var src2 = """
            class C
            {
                static void F()
                {
                    var a = new object();
                    var b = new object(); // type changed
                    var c = "";
 
                    lock (a)
                    {
                        lock (b)
                        {
                            lock (c)
                            {
                                <AS:0>System.Console.Write();</AS:0>
                            }
                        }
                    }
                }
            }
            """;
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.TypeUpdateAroundActiveStatement, "lock (b)", CSharpFeaturesResources.lock_statement, "C", "object"));
    }
 
    [Fact]
    public void Lock_Update_Type_SemanticError()
    {
        var src1 = """
            class C
            {
                static void F()
                {
                    var a = new object();
 
                    lock (a)
                    {
                        <AS:0>System.Console.Write();</AS:0>
                    }
                }
            }
            """;
 
        var src2 = """
            class C
            {
                static void F()
                {
                    lock (a)
                    {
                        <AS:0>System.Console.Write();</AS:0>
                    }
                }
            }
            """;
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.TypeUpdateAroundActiveStatement, "lock (a)", CSharpFeaturesResources.lock_statement, "object", "?"));
    }
 
    #endregion
 
    #region Fixed Statement
 
    [Fact]
    public void FixedBody_Update()
    {
        var src1 = @"
class Test
{
    private static string F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        unsafe
        {
            char* px2;
            fixed (<AS:1>char* pj = &F()</AS:1>)
            {
                System.Console.WriteLine(0);
            }
        }
    }
}";
        var src2 = @"
class Test
{
    private static string F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        unsafe
        {
            char* px2;
            fixed (<AS:1>char* pj = &F()</AS:1>)
            {
                System.Console.WriteLine(1);
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void FixedBody_Update_TypeChange()
    {
        var src1 = """
            class C
            {
                static unsafe void F()
                {
                    var x = new int[1];
                    var y = new int[1];
                    var z = new int[1,1];
                    fixed (int* p = x, q = y, r = z)
                    {
                        <AS:0>System.Console.WriteLine();</AS:0>
                    }
                }
            }
            """;
 
        var src2 = """
            class C
            {
                static unsafe void F()
                {
                    var x = new int[1];
                    var y = new int[1,1];
                    var z = new int[1];
                    fixed (int* p = x, q = y, r = z)
                    {
                        <AS:0>System.Console.WriteLine();</AS:0>
                    }
                }
            }
            """;
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.TypeUpdateAroundActiveStatement, "fixed (int* p = x, q = y, r = z)", CSharpFeaturesResources.fixed_statement, "int[]", "int[*,*]"),
            Diagnostic(RudeEditKind.TypeUpdateAroundActiveStatement, "fixed (int* p = x, q = y, r = z)", CSharpFeaturesResources.fixed_statement, "int[*,*]", "int[]"));
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755742")]
    public void Fixed_Insert_Leaf()
    {
        var src1 = @"
class Test
{
    static int value = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
            <AS:0>px2 = null;</AS:0>
        }
    }
}";
        var src2 = @"
class Test
{
    static int value = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
            fixed (int* pj = &value)
            {
                <AS:0>px2 = null;</AS:0>
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "fixed (int* pj = &value)", CSharpFeaturesResources.fixed_statement));
    }
 
    [Fact]
    public void Fixed_Insert_Leaf2()
    {
        var src1 = @"
class Test
{
    static int value = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
        <AS:0>}</AS:0>
    }
}";
        var src2 = @"
class Test
{
    static int value = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
            fixed (int* pj = &value)
            {
                px2 = null;
            }
        <AS:0>}</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755742")]
    public void Fixed_Insert_Leaf3()
    {
        var src1 = @"
class Test
{
    static int value = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
            <AS:0>px2 = null;</AS:0>
 
            fixed (int* pj = &value)
            {
                
            }
        }
    }
}";
        var src2 = @"
class Test
{
    static int value = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
            fixed (int* pj = &value)
            {
                <AS:0>px2 = null;</AS:0>
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "fixed (int* pj = &value)", CSharpFeaturesResources.fixed_statement));
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755742")]
    public void Fixed_Reorder_Leaf1()
    {
        var src1 = @"
class Test
{
    static int value = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
            fixed (int* a = &value)
            {
                fixed (int* b = &value)
                {
                    <AS:0>px2 = null;</AS:0>
                }
            }
        }
    }
}";
        var src2 = @"
class Test
{
    static int value = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
            fixed (int* b = &value)
            {
                fixed (int* a = &value)
                {
                    <AS:0>px2 = null;</AS:0>
                }
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755746")]
    public void Fixed_Update_Leaf1()
    {
        var src1 = @"
class Test
{
    static int value = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
            fixed (int* pj = &value)
            {
                <AS:0>px2 = null;</AS:0>
            }
        }
    }
}";
        var src2 = @"
class Test
{
    static int value = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
            fixed (int* p = &value)
            {
                <AS:0>px2 = null;</AS:0>
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "fixed (int* p = &value)", CSharpFeaturesResources.fixed_statement));
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755746")]
    public void Fixed_Update_Leaf2()
    {
        var src1 = @"
class Test
{
    public static int value1 = 10;
    public static int value2 = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
            fixed (int* a = &value1)
            {
                fixed (int* b = &value1)
                {
                    fixed (int* c = &value1)
                    {
                        <AS:0>px2 = null;</AS:0>
                    }
                }
            }
        }
    }
}";
        var src2 = @"
class Test
{
    public static int value1 = 10;
    public static int value2 = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
            fixed (int* c = &value1)
            {
                fixed (int* d = &value1)
                {
                    fixed (int* a = &value2)
                    {
                        fixed (int* e = &value1)
                        {
                            <AS:0>px2 = null;</AS:0>
                        }
                    }
                }
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "fixed (int* a = &value2)", CSharpFeaturesResources.fixed_statement),
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "fixed (int* d = &value1)", CSharpFeaturesResources.fixed_statement),
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "fixed (int* e = &value1)", CSharpFeaturesResources.fixed_statement));
    }
 
    [Fact]
    public void Fixed_Delete_Leaf()
    {
        var src1 = @"
class Test
{
    static int value = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
            fixed (int* pj = &value)
            {
                <AS:0>px2 = null;</AS:0>
            }
        }
    }
}";
        var src2 = @"
class Test
{
    static int value = 20;
    static void Main(string[] args)
    {
        unsafe
        {
            int* px2;
            <AS:0>px2 = null;</AS:0>
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Fixed_Update_Lambda1()
    {
        var src1 = @"
class C
{
    static unsafe void Main(string[] args)
    {
        fixed (byte* p = &F(a => a))
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var src2 = @"
class C
{
    static unsafe void Main(string[] args)
    {
        fixed (byte* p = &F(a => a + 1))
        {
            <AS:0>Console.WriteLine(2);</AS:0>
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Fixed_Update_Lambda2()
    {
        var src1 = @"
class C
{
    static unsafe void Main(string[] args)
    {
        fixed (byte* p = &F(a => a))
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var src2 = @"
class C
{
    static unsafe void Main(string[] args)
    {
        fixed (byte* p = &G(a => a))
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "fixed (byte* p = &G(a => a))", CSharpFeaturesResources.fixed_statement));
    }
 
    #endregion
 
    #region ForEach Statement
 
    [Fact]
    public void ForEachBody_Update_ExpressionActive()
    {
        var src1 = @"
class Test
{
    private static string F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach (char c in <AS:1>F()</AS:1>)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static string F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach (char c in <AS:1>F()</AS:1>)
        {
            System.Console.Write(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEachVariableBody_Update_ExpressionActive()
    {
        var src1 = @"
class Test
{
    private static (string, int) F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach ((string s, int i) in <AS:1>F()</AS:1>)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static (string, int) F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach ((string s, int i) in <AS:1>F()</AS:1>)
        {
            System.Console.Write(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEachBody_Update_InKeywordActive()
    {
        var src1 = @"
class Test
{
    private static string F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach (char c <AS:1>in</AS:1> F())
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static string F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach (char c <AS:1>in</AS:1> F())
        {
            System.Console.Write(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEachVariableBody_Update_InKeywordActive()
    {
        var src1 = @"
class Test
{
    private static (string, int) F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach ((string s, int i) <AS:1>in</AS:1> F())
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static (string, int) F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach ((string s, int i) <AS:1>in</AS:1> F())
        {
            System.Console.Write(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEachBody_Update_VariableActive()
    {
        var src1 = @"
class Test
{
    private static string[] F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach (<AS:1>string c</AS:1> in F())
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static string[] F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach (<AS:1>string c</AS:1> in F())
        {
            System.Console.Write(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEachVariableBody_Update_VariableActive()
    {
        var src1 = @"
class Test
{
    private static (string, int) F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach (<AS:1>(string s, int i)</AS:1> in F())
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static (string, int) F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach (<AS:1>(string s, int i)</AS:1> in F())
        {
            System.Console.Write(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEachBody_Update_ForeachKeywordActive()
    {
        var src1 = @"
class Test
{
    private static string F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        <AS:1>foreach</AS:1> (char c in F())
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static string F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        <AS:1>foreach</AS:1> (char c in F())
        {
            System.Console.Write(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEachVariableBody_Update_ForeachKeywordActive()
    {
        var src1 = @"
class Test
{
    private static (string, int) F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        <AS:1>foreach</AS:1> ((string s, int i) in F())
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static (string, int) F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        <AS:1>foreach</AS:1> ((string s, int i) in F())
        {
            System.Console.Write(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEachVariable_Update()
    {
        var src1 = @"
class Test
{
    private static string[] F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach (<AS:1>string c</AS:1> in F())
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static string[] F() { <AS:0>return null;</AS:0> }
 
    static void Main(string[] args)
    {
        foreach (<AS:1>object c</AS:1> in F())
        {
            System.Console.Write(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // not ideal, but good enough:
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "object c"),
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "foreach (      object c        in F())", CSharpFeaturesResources.foreach_statement));
    }
 
    [Fact]
    public void ForEachDeconstructionVariable_Update()
    {
        var src1 = @"
class Test
{
    private static (int, (bool, double))[] F() { <AS:0>return new[] { (1, (true, 2.0)) };</AS:0> }
 
    static void Main(string[] args)
    {
        foreach (<AS:1>(int i, (bool b, double d))</AS:1> in F())
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static (int, (bool, double))[] F() { <AS:0>return new[] { (1, (true, 2.0)) };</AS:0> }
 
    static void Main(string[] args)
    {
        foreach (<AS:1>(int i, (var b, double d))</AS:1> in F())
        {
            System.Console.Write(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "(int i, (var b, double d))"),
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "foreach (      (int i, (var b, double d))        in F())", CSharpFeaturesResources.foreach_statement));
    }
 
    [Fact]
    public void ForEach_Reorder_Leaf()
    {
        var src1 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        foreach (var a in e1)
        {
            foreach (var b in e1)
            {
                foreach (var c in e1)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var src2 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        foreach (var b in e1)
        {
            foreach (var c in e1)
            {
                foreach (var a in e1)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEachVariable_Reorder_Leaf()
    {
        var src1 = @"
class Test
{
    public static (int, bool)[] e1 = new (int, bool)[1];
    public static (int, bool)[] e2 = new (int, bool)[1];
    
    static void Main(string[] args)
    {
        foreach ((var a1, var a2) in e1)
        {
            foreach ((int b1, bool b2) in e1)
            {
                foreach (var c in e1)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var src2 = @"
class Test
{
    public static (int, bool)[] e1 = new (int, bool)[1];
    public static (int, bool)[] e2 = new (int, bool)[1];
    
    static void Main(string[] args)
    {
        foreach ((int b1, bool b2) in e1)
        {
            foreach (var c in e1)
            {
                foreach ((var a1, var a2) in e1)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEach_Update_Leaf()
    {
        var src1 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        <AS:0>System.Console.Write();</AS:0>
    }
}";
        var src2 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        foreach (var b in e1)
        {
            foreach (var c in e1)
            {
                foreach (var a in e1)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach (var b in e1)", CSharpFeaturesResources.foreach_statement),
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach (var c in e1)", CSharpFeaturesResources.foreach_statement),
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach (var a in e1)", CSharpFeaturesResources.foreach_statement));
    }
 
    [Fact]
    public void ForEachVariable_Update_Leaf()
    {
        var src1 = @"
class Test
{
    public static (int, bool)[] e1 = new (int, bool)[1];
    public static (int, bool)[] e2 = new (int, bool)[1];
    
    static void Main(string[] args)
    {
        <AS:0>System.Console.Write();</AS:0>
    }
}";
        var src2 = @"
class Test
{
    public static (int, bool)[] e1 = new (int, bool)[1];
    public static (int, bool)[] e2 = new (int, bool)[1];
    
    static void Main(string[] args)
    {
        foreach ((int b1, bool b2) in e1)
        {
            foreach (var c in e1)
            {
                foreach ((var a1, var a2) in e1)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach (var c in e1)", CSharpFeaturesResources.foreach_statement),
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach ((int b1, bool b2) in e1)", CSharpFeaturesResources.foreach_statement),
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach ((var a1, var a2) in e1)", CSharpFeaturesResources.foreach_statement));
    }
 
    [Fact]
    public void ForEach_Delete_Leaf1()
    {
        var src1 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        foreach (var a in e1)
        {
            foreach (var b in e1)
            {
                foreach (var c in e1)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var src2 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        foreach (var a in e1)
        {
            foreach (var b in e1)
            {
                <AS:0>System.Console.Write();</AS:0>
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEachVariable_Delete_Leaf1()
    {
        var src1 = @"
class Test
{
    public static (int, bool)[] e1 = new (int, bool)[1];
    public static (int, bool)[] e2 = new (int, bool)[1];
    
    static void Main(string[] args)
    {
        foreach ((var a1, var a2) in e1)
        {
            foreach ((int b1, bool b2) in e1)
            {
                foreach (var c in e1)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var src2 = @"
class Test
{
    public static (int, bool)[] e1 = new (int, bool)[1];
    public static (int, bool)[] e2 = new (int, bool)[1];
    
    static void Main(string[] args)
    {
        foreach ((var a1, var a2) in e1)
        {
            foreach ((int b1, bool b2) in e1)
            {
                <AS:0>System.Console.Write();</AS:0>
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEach_Delete_Leaf2()
    {
        var src1 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        foreach (var a in e1)
        {
            foreach (var b in e1)
            {
                foreach (var c in e1)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var src2 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        foreach (var b in e1)
        {
            foreach (var c in e1)
            {
                <AS:0>System.Console.Write();</AS:0>
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEachVariable_Delete_Leaf2()
    {
        var src1 = @"
class Test
{
    public static (int, bool)[] e1 = new (int, bool)[1];
    public static (int, bool)[] e2 = new (int, bool)[1];
    
    static void Main(string[] args)
    {
        foreach ((var a1, var a2) in e1)
        {
            foreach ((int b1, bool b2) in e1)
            {
                foreach (var c in e1)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var src2 = @"
class Test
{
    public static (int, bool)[] e1 = new (int, bool)[1];
    public static (int, bool)[] e2 = new (int, bool)[1];
    
    static void Main(string[] args)
    {
        foreach ((int b1, bool b2) in e1)
        {
            foreach (var c in e1)
            {
                <AS:0>System.Console.Write();</AS:0>
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEach_Delete_Leaf3()
    {
        var src1 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        foreach (var a in e1)
        {
            foreach (var b in e1)
            {
                foreach (var c in e1)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var src2 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        foreach (var a in e1)
        {
            foreach (var c in e1)
            {
                <AS:0>System.Console.Write();</AS:0>
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEachVariable_Delete_Leaf3()
    {
        var src1 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        foreach ((var a1, var a2) in e1)
        {
            foreach ((int b1, bool b2) in e1)
            {
                foreach (var c in e1)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var src2 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        foreach ((var a1, var a2) in e1)
        {
            foreach (var c in e1)
            {
                <AS:0>System.Console.Write();</AS:0>
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEach_Lambda1()
    {
        var src1 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        Action a = () =>
        {
            <AS:0>System.Console.Write();</AS:0>
        };
 
        <AS:1>a();</AS:1>
    }
}";
        var src2 = @"
class Test
{
    public static int[] e1 = new int[1];
    public static int[] e2 = new int[1];
    
    static void Main(string[] args)
    {
        foreach (var b in e1)
        {
            foreach (var c in e1)
            {
                Action a = () =>
                {                
                    foreach (var a in e1)
                    {
                        <AS:0>System.Console.Write();</AS:0>
                    }
                };
            }
 
            <AS:1>a();</AS:1>
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach (var a in e1)", CSharpFeaturesResources.foreach_statement),
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach (var b in e1)", CSharpFeaturesResources.foreach_statement));
    }
 
    [Fact]
    public void ForEach_Update_Lambda1()
    {
        var src1 = @"
class C
{
    static unsafe void Main(string[] args)
    {
        foreach (var a in F(a => a))
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var src2 = @"
class C
{
    static unsafe void Main(string[] args)
    {
        foreach (var a in F(a => a + 1))
        {
            <AS:0>Console.WriteLine(2);</AS:0>
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEach_Update_Lambda2()
    {
        var src1 = @"
class C
{
    static unsafe void Main(string[] args)
    {
        foreach (var a in F(a => a))
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var src2 = @"
class C
{
    static unsafe void Main(string[] args)
    {
        foreach (var a in G(a => a))
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "foreach (var a in G(a => a))", CSharpFeaturesResources.foreach_statement));
    }
 
    [Fact]
    public void ForEach_Update_Collection_01()
    {
        var src1 = @"
class C
{
    static void F()
    {
        var aa = new int[4];
        var bb = new int[4];
        
        foreach (var a in aa)
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        var aa = new int[4];
        var bb = new int[4];
        
        foreach (var a in bb)
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "foreach (var a in bb)", CSharpFeaturesResources.foreach_statement));
    }
 
    [Fact]
    public void ForEach_Update_Collection_02()
    {
        var src1 = @"
class C
{
    static void F()
    {
        Buffer4 aa = default;
        Buffer4 bb = default;
        
        foreach (var a in aa)
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
 
[System.Runtime.CompilerServices.InlineArray(4)]
struct Buffer4
{
    private int _f;
}
";
        var src2 = @"
class C
{
    static void F()
    {
        Buffer4 aa = default;
        Buffer4 bb = default;
        
        foreach (var a in bb)
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
 
[System.Runtime.CompilerServices.InlineArray(4)]
struct Buffer4
{
    private int _f;
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "foreach (var a in bb)", CSharpFeaturesResources.foreach_statement));
    }
 
    [Fact]
    public void ForEach_Update_Collection_03()
    {
        var src1 = @"
class C
{
    public readonly Buffer4 F = default;
}
 
class Program
{
    static System.Collections.Generic.IEnumerable<int> Test(C x, C z)
    {
        foreach (var y in x.F)
        {
            <AS:0>Console.WriteLine(1);</AS:0>
            yield return -1;
        }
    }
}
 
[System.Runtime.CompilerServices.InlineArray(4)]
struct Buffer4
{
    private int _f;
}
";
        var src2 = @"
class C
{
    public readonly Buffer4 F = default;
}
 
class Program
{
    static System.Collections.Generic.IEnumerable<int> Test(C x, C z)
    {
        foreach (var y in z.F)
        {
            <AS:0>Console.WriteLine(1);</AS:0>
            yield return -1;
        }
    }
}
 
[System.Runtime.CompilerServices.InlineArray(4)]
struct Buffer4
{
    private int _f;
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "foreach (var y in z.F)", CSharpFeaturesResources.foreach_statement));
    }
 
    [Fact]
    public void ForEach_Update_Collection_04()
    {
        var src1 = @"
class Program
{
    static System.Collections.Generic.IEnumerable<int> Test()
    {
        foreach (var y in GetBuffer1())
        {
            <AS:0>Console.WriteLine(1);</AS:0>
            yield return -1;
        }
    }
 
    static Buffer4 GetBuffer1() => default;
    static Buffer4 GetBuffer2() => default;
}
 
[System.Runtime.CompilerServices.InlineArray(4)]
struct Buffer4
{
    private int _f;
}
";
        var src2 = @"
class Program
{
    static System.Collections.Generic.IEnumerable<int> Test()
    {
        foreach (var y in GetBuffer2())
        {
            <AS:0>Console.WriteLine(1);</AS:0>
            yield return -1;
        }
    }
 
    static Buffer4 GetBuffer1() => default;
    static Buffer4 GetBuffer2() => default;
}
 
[System.Runtime.CompilerServices.InlineArray(4)]
struct Buffer4
{
    private int _f;
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "foreach (var y in GetBuffer2())", CSharpFeaturesResources.foreach_statement));
    }
 
    [Fact]
    public void ForEach_Update_Nullable_Struct()
    {
        var src1 = @"
class C
{
    static void F()
    {
        var arr = new int?[] { 0 };
        foreach (var s in arr)
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        var arr = new int[] { 0 };
        foreach (var s in arr)
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.TypeUpdateAroundActiveStatement, "foreach (var s in arr)", CSharpFeaturesResources.foreach_statement, "int?[]", "int[]"));
    }
 
    [Fact]
    public void ForEach_Update_Nullable_Class()
    {
        var src1 = @"
class C
{
    static void F()
    {
        var arr = new object?[] { 0 };
        foreach (var s in arr)
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        var arr = new object[] { 0 };
        foreach (var s in arr)
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEach_DeleteBody()
    {
        var src1 = @"
class C
{
    static void F()
    {
        foreach (var s in new[] { 1 }) <AS:0>G();</AS:0>
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        foreach (var s in new[] { 1 }) <AS:0>;</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForEachVariable_DeleteBody()
    {
        var src1 = @"
class C
{
    static void F()
    {
        foreach ((var a1, var a2) in new[] { (1,1) }) <AS:0>G();</AS:0>
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        foreach ((var a1, var a2) in new[] { (1,1) }) <AS:0>;</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    #endregion
 
    #region For Statement
 
    [Fact]
    public void ForStatement_Initializer1()
    {
        var src1 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        int i;
        for (<AS:1>i = F(1)</AS:1>; i < 10; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        int i;
        for (<AS:1>i = F(2)</AS:1>; i < 10; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "i = F(2)"));
    }
 
    [Fact]
    public void ForStatement_Initializer2()
    {
        var src1 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        int i;
        for (<AS:1>i = F(1)</AS:1>, F(1); i < 10; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        int i;
        for (<AS:1>i = F(1)</AS:1>, F(2); i < 10; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForStatement_Initializer_Delete()
    {
        var src1 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        int i;
        for (<AS:1>i = F(1)</AS:1>; i < 10; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        int i;
        for (; <AS:1>i < 10</AS:1>; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteActiveStatement, "for (;       i < 10       ; i++)", FeaturesResources.code));
    }
 
    [Fact]
    public void ForStatement_Declarator1()
    {
        var src1 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (<AS:1>var i = F(1)</AS:1>; i < 10; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (<AS:1>var i = F(2)</AS:1>; i < 10; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "var i = F(2)"));
    }
 
    [Fact]
    public void ForStatement_Declarator2()
    {
        var src1 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (<AS:1>int i = F(1)</AS:1>, j = F(1); i < 10; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (<AS:1>int i = F(1)</AS:1>, j = F(2); i < 10; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForStatement_Declarator3()
    {
        var src1 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (<AS:1>int i = F(1)</AS:1>; i < 10; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (<AS:1>int i = F(1)</AS:1>, j = F(2); i < 10; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForStatement_Condition1()
    {
        var src1 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (int i = 1; <AS:1>i < F(10)</AS:1>; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (int i = 1; <AS:1>i < F(20)</AS:1>; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "i < F(20)"));
    }
 
    [Fact]
    public void ForStatement_Condition_Delete()
    {
        var src1 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (int i = 1; <AS:1>i < F(10)</AS:1>; i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (int i = 1; ; <AS:1>i++</AS:1>)
        {
            System.Console.Write(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteActiveStatement, "for (int i = 1; ;       i++       )", FeaturesResources.code));
    }
 
    [Fact]
    public void ForStatement_Incrementors1()
    {
        var src1 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (int i = 1; i < F(10); <AS:1>F(1)</AS:1>)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (int i = 1; i < F(20); <AS:1>F(1)</AS:1>)
        {
            System.Console.Write(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForStatement_Incrementors2()
    {
        var src1 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (int i = 1; i < F(10); <AS:1>F(1)</AS:1>)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (int i = 1; i < F(10); <AS:1>F(2)</AS:1>)
        {
            System.Console.Write(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "F(2)"));
    }
 
    [Fact]
    public void ForStatement_Incrementors3()
    {
        var src1 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (int i = 1; i < F(10); <AS:1>F(1)</AS:1>)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (int i = 1; i < F(10); <AS:1>F(1)</AS:1>, i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ForStatement_Incrementors4()
    {
        var src1 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (int i = 1; i < F(10); <AS:1>F(1)</AS:1>, i++)
        {
            System.Console.Write(0);
        }
    }
}";
        var src2 = @"
class Test
{
    private static int F(int a) { <AS:0>return a;</AS:0> }
 
    static void Main(string[] args)
    {
        for (int i = 1; i < F(10); i++, <AS:1>F(1)</AS:1>)
        {
            System.Console.Write(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    #endregion
 
    #region Using Statement and Local Declaration
 
    [Fact]
    public void UsingStatement_Expression_Update_Leaf()
    {
        var src1 = @"
class Test
{
    public static System.IDisposable a = null;
    public static System.IDisposable b = null;
    public static System.IDisposable c = null;
    
    static void Main(string[] args)
    {
        using (a)
        {
            using (b)
            {
                <AS:0>System.Console.Write();</AS:0>
            }
        }
    }
}";
        var src2 = @"
class Test
{
    public static System.IDisposable a = null;
    public static System.IDisposable b = null;
    public static System.IDisposable c = null;
    
    static void Main(string[] args)
    {
        using (a)
        {
            using (c)
            {
                using (b)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // Using with an expression generates code that stores the value of the expression in a compiler-generated temp.
        // This temp is not initialized when using is added around an active statement so the disposal is a no-op.
        // The user might expect that the object the field points to is disposed at the end of the using block, but it isn't.
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "using (c)", CSharpFeaturesResources.using_statement));
    }
 
    [Fact]
    public void UsingStatement_Expression_Update_Leaf_TypeChange()
    {
        var src1 = """
            using System;
 
            class C
            {
                static void F()
                {
                    var x = new D1();
                    using (x)
                    {
                        <AS:0>System.Console.Write();</AS:0>
                    }
                }
            }
            
            class D1 : IDisposable { public void Dispose() { } }
            class D2 : IDisposable { public void Dispose() { } }
            """;
 
        var src2 = """
            using System;
 
            class C
            {
                static void F()
                {
                    var x = new D2();
                    using (x)
                    {
                        <AS:0>System.Console.Write();</AS:0>
                    }
                }
            }
            
            class D1 : IDisposable { public void Dispose() { } }
            class D2 : IDisposable { public void Dispose() { } }
            """;
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.TypeUpdateAroundActiveStatement, "using (x)", CSharpFeaturesResources.using_statement, "D1", "D2"));
    }
 
    [Fact]
    public void UsingStatement_Declaration_Update_Leaf()
    {
        var src1 = @"
class Test
{
    static void Main(string[] args)
    {
        using (var a = new Disposable())
        {
            using (var b = new Disposable())
            {
                <AS:0>System.Console.Write();</AS:0>
            }
        }
    }
}";
        var src2 = @"
class Test
{
    static void Main(string[] args)
    {
        using (var a = new Disposable())
        {
            using (var c = new Disposable())
            {
                using (var b = new Disposable())
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            }
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // Unlike using with an expression, using with a declaration does not introduce compiler-generated temps.
        // As with other local declarations that are added but not executed, the variable is not initialized and thus 
        // there should be no expectation (or need) for its disposal. Hence we do not report a rude edit.
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UsingLocalDeclaration_Update_Leaf1()
    {
        var src1 = @"
class Test
{
    static void Main(string[] args)
    {
        using var a = new Disposable(), b = new Disposable();
        <AS:0>System.Console.Write();</AS:0>
    }
}";
        var src2 = @"
class Test
{
    static void Main(string[] args)
    {
        using var a = new Disposable(), c = new Disposable(), b = new Disposable();
        <AS:0>System.Console.Write();</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // Unlike using with an expression, using local declaration does not introduce compiler-generated temps.
        // As with other local declarations that are added but not executed, the variable is not initialized and thus 
        // there should be no expectation (or need) for its disposal. Hence we do not report a rude edit.
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UsingLocalDeclaration_Update_Leaf2()
    {
        var src1 = @"
class Test
{
    static void Main(string[] args)
    {
        using var a = new Disposable();
        using var b = new Disposable();
        <AS:0>System.Console.Write();</AS:0>
    }
}";
        var src2 = @"
class Test
{
    static void Main(string[] args)
    {
        using var a = new Disposable();
        using var c = new Disposable();
        using var b = new Disposable();
        <AS:0>System.Console.Write();</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // Unlike using with an expression, using local declaration does not introduce compiler-generated temps.
        // As with other local declarations that are added but not executed, the variable is not initialized and thus 
        // there should be no expectation (or need) for its disposal. Hence we do not report a rude edit.
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UsingStatement_Update_NonLeaf1()
    {
        var src1 = @"
class Disposable : IDisposable
{
    public void Dispose() <AS:0>{</AS:0>}
}
 
class Test
{
    static void Main(string[] args)
    {
        using (var a = new Disposable(1)) { System.Console.Write(); <AS:1>}</AS:1>
    }
}";
        var src2 = @"
class Disposable : IDisposable
{
    public void Dispose() <AS:0>{</AS:0>}
}
 
class Test
{
    static void Main(string[] args)
    {
        using (var a = new Disposable(2)) { System.Console.Write(); <AS:1>}</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "}"));
    }
 
    [Fact]
    public void UsingStatement_Update_NonLeaf2()
    {
        var src1 = @"
class Disposable : IDisposable
{
    public void Dispose() <AS:0>{</AS:0>}
}
 
class Test
{
    static void Main(string[] args)
    {
        using (Disposable a = new Disposable(1), b = Disposable(2)) { System.Console.Write(); <AS:1>}</AS:1>
    }
}";
        var src2 = @"
class Disposable : IDisposable
{
    public void Dispose() <AS:0>{</AS:0>}
}
 
class Test
{
    static void Main(string[] args)
    {
        using (Disposable a = new Disposable(1)) { System.Console.Write(); <AS:1>}</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "}"));
    }
 
    [Fact]
    public void UsingStatement_Update_NonLeaf_Lambda()
    {
        var src1 = @"
class Disposable : IDisposable
{
    public void Dispose() <AS:0>{</AS:0>}
}
 
class Test
{
    static void Main(string[] args)
    {
        using (var a = new Disposable(() => 1)) { System.Console.Write(); <AS:1>}</AS:1>
    }
}";
        var src2 = @"
class Disposable : IDisposable
{
    public void Dispose() <AS:0>{</AS:0>}
}
 
class Test
{
    static void Main(string[] args)
    {
        using (var a = new Disposable(() => 2)) { System.Console.Write(); <AS:1>}</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UsingLocalDeclaration_Update_NonLeaf1()
    {
        var src1 = @"
class Disposable : IDisposable
{
    public void Dispose() <AS:0>{</AS:0>}
}
 
class Test
{
    static void Main(string[] args)
    {
        if (F())
        {        
            using Disposable a = new Disposable(1);
 
            using Disposable b = new Disposable(2), c = new Disposable(3);
 
  <AS:1>}</AS:1>
    }
}";
        var src2 = @"
class Disposable : IDisposable
{
    public void Dispose() <AS:0>{</AS:0>}
}
 
class Test
{
    static void Main(string[] args)
    {
        if (F())
        {        
            using Disposable a = new Disposable(1);
 
            using Disposable b = new Disposable(20), c = new Disposable(3);
 
  <AS:1>}</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "}"));
    }
 
    [Fact]
    public void UsingLocalDeclaration_Update_NonLeaf_Lambda()
    {
        var src1 = @"
class Disposable : IDisposable
{
    public void Dispose() <AS:0>{</AS:0>}
}
 
class Test
{
    static void Main(string[] args)
    {
        if (F())
        {        
            using Disposable a = new Disposable(() => 1);
 
            {
                using var x = new Disposable(1);
            }
 
            using Disposable b = new Disposable(() => 2), c = new Disposable(() => 3);
 
  <AS:1>}</AS:1>
    }
}";
        var src2 = @"
class Disposable : IDisposable
{
    public void Dispose() <AS:0>{</AS:0>}
}
 
class Test
{
    static void Main(string[] args)
    {
        if (F())
        {        
            using Disposable a = new Disposable(() => 10);
 
            {
                using var x = new Disposable(2);
            }
 
            Console.WriteLine(1);
 
            using Disposable b = new Disposable(() => 20), c = new Disposable(() => 30);
 
  <AS:1>}</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UsingStatement_Expression_InLambdaBody1()
    {
        var src1 = @"
class Test
{
    public static System.IDisposable a = null;
    public static System.IDisposable b = null;
    public static System.IDisposable c = null;
    public static System.IDisposable d = null;
    
    static void Main(string[] args)
    {
        using (a)
        {
            Action a = () =>
            {
                using (b)
                {
                    <AS:0>System.Console.Write();</AS:0>
                }
            };
        }
 
        <AS:1>a();</AS:1>
    }
}";
        var src2 = @"
class Test
{
    public static System.IDisposable a = null;
    public static System.IDisposable b = null;
    public static System.IDisposable c = null;
    public static System.IDisposable d = null;
    
    static void Main(string[] args)
    {
        using (d)
        {
            Action a = () =>
            {
                using (c)
                {
                    using (b)
                    {
                        <AS:0>System.Console.Write();</AS:0>
                    }
                }
            };
        }
 
        <AS:1>a();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "using (c)", CSharpFeaturesResources.using_statement));
    }
 
    [Fact]
    public void UsingStatement_Expression_Update_Lambda1()
    {
        var src1 = @"
class C
{
    static unsafe void Main(string[] args)
    {
        using (F(a => a))
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var src2 = @"
class C
{
    static unsafe void Main(string[] args)
    {
        using (F(a => a + 1))
        {
            <AS:0>Console.WriteLine(2);</AS:0>
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UsingStatement_Expression_Update_Lambda2()
    {
        var src1 = @"
class C
{
    static unsafe void Main(string[] args)
    {
        using (F(a => a))
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var src2 = @"
class C
{
    static unsafe void Main(string[] args)
    {
        using (G(a => a))
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "using (G(a => a))", CSharpFeaturesResources.using_statement));
    }
 
    #endregion
 
    #region Conditional Block Statements (If, Switch, While, Do)
 
    [Fact]
    public void IfBody_Update1()
    {
        var src1 = @"
class C
{
    public static bool B() <AS:0>{</AS:0> return false; }
    
    public static void F()
    {
        <AS:1>if (B())</AS:1>
        {
            System.Console.WriteLine(0);
        }
    }
}";
        var src2 = @"
class C
{
    public static bool B() <AS:0>{</AS:0> return false; }
    
    public static void F()
    {
        <AS:1>if (B())</AS:1>
        {
            System.Console.WriteLine(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void IfBody_Update2()
    {
        var src1 = @"
class C
{
    public static bool B() <AS:0>{</AS:0> return false; }
    
    public static void F()
    {
        <AS:1>if (B())</AS:1>
        {
            System.Console.WriteLine(0);
        }
    }
}";
        var src2 = @"
class C
{
    public static bool B() <AS:0>{</AS:0> return false; }
    
    public static void F()
    {
        <AS:1>if (!B())</AS:1>
        {
            System.Console.WriteLine(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "if (!B())"));
    }
 
    [Fact]
    public void IfBody_Update_Lambda()
    {
        var src1 = @"
class C
{
    public static bool B(Func<int> a) => <AS:0>false</AS:0>;
    
    public static void F()
    {
        <AS:1>if (B(() => 1))</AS:1>
        {
            System.Console.WriteLine(0);
        }
    }
}";
        var src2 = @"
class C
{
    public static bool B(Func<int> a) => <AS:0>false</AS:0>;
    
    public static void F()
    {
        <AS:1>if (B(() => 2))</AS:1>
        {
            System.Console.WriteLine(0);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void WhileBody_Update1()
    {
        var src1 = @"
class C
{
    public static bool B() <AS:0>{</AS:0> return false; }
    
    public static void F()
    {
        <AS:1>while (B())</AS:1>
        {
            System.Console.WriteLine(0);
        }
    }
}";
        var src2 = @"
class C
{
    public static bool B() <AS:0>{</AS:0> return false; }
    
    public static void F()
    {
        <AS:1>while (B())</AS:1>
        {
            System.Console.WriteLine(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void WhileBody_Update2()
    {
        var src1 = @"
class C
{
    public static bool B() <AS:0>{</AS:0> return false; }
    
    public static void F()
    {
        <AS:1>while (B())</AS:1>
        {
            System.Console.WriteLine(0);
        }
    }
}";
        var src2 = @"
class C
{
    public static bool B() <AS:0>{</AS:0> return false; }
    
    public static void F()
    {
        <AS:1>while (!B())</AS:1>
        {
            System.Console.WriteLine(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "while (!B())"));
    }
 
    [Fact]
    public void WhileBody_Update_Lambda()
    {
        var src1 = @"
class C
{
    public static bool B(Func<int> a) => <AS:0>false</AS:0>;
    
    public static void F()
    {
        <AS:1>while (B(() => 1))</AS:1>
        {
            System.Console.WriteLine(0);
        }
    }
}";
        var src2 = @"
class C
{
    public static bool B(Func<int> a) => <AS:0>false</AS:0>;
    
    public static void F()
    {
        <AS:1>while (B(() => 2))</AS:1>
        {
            System.Console.WriteLine(1);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void DoWhileBody_Update1()
    {
        var src1 = @"
class C
{
    public static bool B() <AS:0>{</AS:0> return false; }
    
    public static void F()
    {
        do
        {
            System.Console.WriteLine(0);
        }
        <AS:1>while (B());</AS:1>
    }
}";
        var src2 = @"
class C
{
    public static bool B() <AS:0>{</AS:0> return false; }
    
    public static void F()
    {
        do
        {
            System.Console.WriteLine(1);
        }
        <AS:1>while (B());</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void DoWhileBody_Update2()
    {
        var src1 = @"
class C
{
    public static bool B() <AS:0>{</AS:0> return false; }
    
    public static void F()
    {
        do
        {
            System.Console.WriteLine(0);
        }
        <AS:1>while (B());</AS:1>
    }
}";
        var src2 = @"
class C
{
    public static bool B() <AS:0>{</AS:0> return false; }
    
    public static void F()
    {
        do
        {
            System.Console.WriteLine(1);
        }
        <AS:1>while (!B());</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "while (!B());"));
    }
 
    [Fact]
    public void DoWhileBody_Update_Lambda()
    {
        var src1 = @"
class C
{
    public static bool B(Func<int> a) => <AS:0>false</AS:0>;
    
    public static void F()
    {
        do
        {
            System.Console.WriteLine(0);
        }
        <AS:1>while (B(() => 1));</AS:1>
    }
}";
        var src2 = @"
class C
{
    public static bool B(Func<int> a) => <AS:0>false</AS:0>;
    
    public static void F()
    {
        do
        {
            System.Console.WriteLine(1);
        }
        <AS:1>while (B(() => 2));</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void DoWhileBody_Delete()
    {
        var src1 = @"
class C
{
    static void F()
    {
        do <AS:0>G();</AS:0> while (true);
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        do <AS:0>;</AS:0> while (true);
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void SwitchCase_Update1()
    {
        var src1 = @"
class C
{
    public static string F() <AS:0>{</AS:0> return null; }
    
    public static void G()
    {
        <AS:1>switch (F())</AS:1>
        {
            case ""a"": System.Console.WriteLine(0); break;
            case ""b"": System.Console.WriteLine(1); break;
        }
    }
}";
        var src2 = @"
class C
{
    public static string F() <AS:0>{</AS:0> return null; }
    
    public static void G()
    {
        <AS:1>switch (F())</AS:1>
        {
            case ""a"": System.Console.WriteLine(0); break;
            case ""b"": System.Console.WriteLine(2); break;
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void SwitchCase_Update_Lambda()
    {
        var src1 = @"
class C
{
    public static bool B(Func<int> a) => <AS:0>false</AS:0>;
    
    public static void F()
    {
        <AS:1>switch (B(() => 1))</AS:1>
        {
            case ""a"": System.Console.WriteLine(0); break;
            case ""b"": System.Console.WriteLine(1); break;
        }
    }
}";
        var src2 = @"
class C
{
    public static bool B(Func<int> a) => <AS:0>false</AS:0>;
    
    public static void F()
    {
        <AS:1>switch (B(() => 2))</AS:1>
        {
            case ""a"": System.Console.WriteLine(0); break;
            case ""b"": System.Console.WriteLine(2); break;
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    #endregion
 
    #region Switch Statement When Clauses, Patterns
 
    [Fact]
    public void SwitchWhenClause_PatternUpdate1()
    {
        var src1 = @"
class C
{
    public static int Main()
    {
        switch (F())
        {
            case int a1 when G1(a1):
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
                
            case byte a when G5(a):
                return 10;
                
            case double b when G2(b):
                return 20;
                
            case C { X: 2 } when G4(9):
                return 30;
                
            case C { X: 2, Y: C { X: 1 } } c1 when G3(c1):
                return 40;
        }
 
        return 0;
    }
}";
        var src2 = @"
class C
{
    public static int Main()
    {
        switch (F())
        {
            case int a1 when G1(a1):
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
                
            case byte a when G5(a):
                return 10;
                
            case double b when G2(b):
                return 20;
                
            case C { X: 2 } when G4(9):
                return 30;
                
            case C { X: 2, Y: C { X: 2 } } c1 when G3(c1):
                return 40;
        }
 
        return 0;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "switch (F())", CSharpFeaturesResources.switch_statement_case_clause));
    }
 
    [Fact]
    public void SwitchWhenClause_PatternInsert()
    {
        var src1 = @"
class C
{
    public static int Main()
    {
        switch (F())
        {
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
        }
 
        return 0;
    }
}";
        var src2 = @"
class C
{
    public static int Main()
    {
        switch (F())
        {
            case int a1 when G1(a1):
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
        }
 
        return 0;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "switch (F())", CSharpFeaturesResources.switch_statement_case_clause));
    }
 
    [Fact]
    public void SwitchWhenClause_PatternDelete()
    {
        var src1 = @"
class C
{
    public static int Main()
    {
        switch (F())
        {
            case int a1 when G1(a1):
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
        }
 
        return 0;
    }
}";
        var src2 = @"
class C
{
    public static int Main()
    {
        switch (F())
        {
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
        }
 
        return 0;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "switch (F())", CSharpFeaturesResources.switch_statement_case_clause));
    }
 
    [Fact]
    public void SwitchWhenClause_WhenDelete()
    {
        var src1 = @"
class C
{
    public static int Main()
    {
        switch (F())
        {
            case byte a1 when G1(a1):
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
        }
 
        return 0;
    }
}";
        var src2 = @"
class C
{
    public static int Main()
    {
        switch (F())
        {
            case byte a1:
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
        }
 
        return 0;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "switch (F())", CSharpFeaturesResources.switch_statement_case_clause));
    }
 
    [Fact]
    public void SwitchWhenClause_WhenAdd()
    {
        var src1 = @"
class C
{
    public static int Main()
    {
        switch (F())
        {
            case byte a1:
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
        }
 
        return 0;
    }
}";
        var src2 = @"
class C
{
    public static int Main()
    {
        switch (F())
        {
            case byte a1 when G1(a1):
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
        }
 
        return 0;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "switch (F())", CSharpFeaturesResources.switch_statement_case_clause));
    }
 
    [Fact]
    public void SwitchWhenClause_WhenUpdate()
    {
        var src1 = @"
class C
{
    public static int Main()
    {
        switch (F())
        {
            case byte a1 when G1(a1):
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
        }
 
        return 0;
    }
}";
        var src2 = @"
class C
{
    public static int Main()
    {
        switch (F())
        {
            case byte a1 when G1(a1 * 2):
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
        }
 
        return 0;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void SwitchWhenClause_UpdateGoverningExpression()
    {
        var src1 = @"
class C
{
    public static int Main()
    {
        switch (F(1))
        {
            case int a1 when G1(a1):
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
        }
 
        return 0;
    }
}";
        var src2 = @"
class C
{
    public static int Main()
    {
        switch (F(2))
        {
            case int a1 when G1(a1):
            case int a2 <AS:0>when G1(a2)</AS:0>:
                return 10;
        }
 
        return 0;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "switch (F(2))", CSharpFeaturesResources.switch_statement));
    }
 
    [Fact]
    public void Switch_PropertyPattern_Update_NonLeaf()
    {
        var src1 = @"
class C
{
    public int X { get => <AS:0>1</AS:0>; }
 
    public static int F(object obj)
    {
        <AS:1>switch (obj)</AS:1>
        {
            case C { X: 1 }:
                return 1;
        }
 
        return 0;
    }
}";
        var src2 = @"
class C
{
    public int X { get => <AS:0>1</AS:0>; }
 
    public static int F(object obj)
    {
        <AS:1>switch (obj)</AS:1>
        {
            case C { X: 2 }:
                return 1;
        }
 
        return 0;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "switch (obj)"));
    }
 
    [Fact]
    public void Switch_PositionalPattern_Update_NonLeaf()
    {
        var src1 = @"
class C
{
    public void Deconstruct(out int x) => <AS:0>x = X</AS:0>;
 
    public static int F(object obj)
    {
        <AS:1>switch (obj)</AS:1>
        {
            case C ( x: 1 ):
                return 1;
        }
 
        return 0;
    }
}";
        var src2 = @"
class C
{
    public void Deconstruct(out int x) => <AS:0>x = X</AS:0>;
 
    public static int F(object obj)
    {
        <AS:1>switch (obj)</AS:1>
        {
            case C ( x: 2 ):
                return 1;
        }
 
        return 0;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "switch (obj)"));
    }
 
    [Fact]
    public void Switch_VarPattern_Update_NonLeaf()
    {
        var src1 = @"
class C
{
    public static object G() => <AS:0>null</AS:0>;
    
    public static int F(object obj)
    {
        <AS:1>switch (G())</AS:1>
        {
            case var (x, y):
                return 1;
 
            case 2:
                return 2;
        }
 
        return 0;
    }
}";
        var src2 = @"
class C
{
    public static object G() => <AS:0>null</AS:0>;
 
    public static int F(object obj)
    {
        <AS:1>switch (G())</AS:1>
        {
            case var (x, y):
                return 1;
 
            case 3:
                return 2;
        }
 
        return 0;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "switch (G())"));
    }
 
    [Fact]
    public void Switch_DiscardPattern_Update_NonLeaf()
    {
        var src1 = @"
class C
{
    public static object G() => <AS:0>null</AS:0>;
    
    public static int F(object obj)
    {
        <AS:1>switch (G())</AS:1>
        {
            case bool _:
                return 1;
        }
 
        return 0;
    }
}";
        var src2 = @"
class C
{
    public static object G() => <AS:0>null</AS:0>;
 
    public static int F(object obj)
    {
        <AS:1>switch (G())</AS:1>
        {
            case int _:
                return 1;
        }
 
        return 0;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "switch (G())"));
    }
 
    [Fact]
    public void Switch_NoPatterns_Update_NonLeaf()
    {
        var src1 = @"
class C
{
    public static object G() => <AS:0>null</AS:0>;
 
    public static int F(object obj)
    {
        <AS:1>switch (G())</AS:1>
        {
            case 1:
                return 1;
        }
 
        return 0;
    }
}";
        var src2 = @"
class C
{
    public static object G() => <AS:0>null</AS:0>;
 
    public static int F(object obj)
    {
        <AS:1>switch (G())</AS:1>
        {
            case 2:
                return 1;
        }
 
        return 0;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    #endregion
 
    #region Switch Expression
 
    [Fact]
    public void SwitchExpression()
    {
        var src1 = @"
class C
{
    public static int Main()
    {
        Console.WriteLine(1);
 
        <AS:4>return F() switch
        {
            int a <AS:0>when F1()</AS:0> => <AS:1>F2()</AS:1>,
            bool b => <AS:2>F3()</AS:2>,
            _ => <AS:3>F4()</AS:3>
        };</AS:4>
    }
}";
        var src2 = @"
class C
{
    public static int Main()
    {
        Console.WriteLine(2);
 
        <AS:4>return F() switch
        {
            int a <AS:0>when F1()</AS:0> => <AS:1>F2()</AS:1>,
            bool b => <AS:2>F3()</AS:2>,
            _ => <AS:3>F4()</AS:3>
        };</AS:4>
    }
}";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void SwitchExpression_Lambda1()
    {
        var src1 = @"
class C
{
	public static int Main() => <AS:1>F() switch { 0 => new Func<int>(() => <AS:0>1</AS:0>)(), _ => 2}</AS:1>;
}";
        var src2 = @"
class C
{
	public static int Main() => <AS:1>F() switch { 0 => new Func<int>(() => <AS:0>3</AS:0>)(), _ => 2}</AS:1>;
}";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void SwitchExpression_Lambda2()
    {
        var src1 = @"
class C
{
	public static int Main() => <AS:1>F() switch { i => new Func<int>(() => <AS:0>i + 1</AS:0>)(), _ => 2}</AS:1>;
}";
        var src2 = @"
class C
{
	public static int Main() => <AS:1>F() switch { i => new Func<int>(() => <AS:0>i + 3</AS:0>)(), _ => 2}</AS:1>;
}";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43099")]
    public void SwitchExpression_MemberExpressionBody()
    {
        var src1 = @"
class C
{
    public static int Main() => <AS:0>F() switch { 0 => 1, _ => 2}</AS:0>;
}";
        var src2 = @"
class C
{
    public static int Main() => <AS:0>G() switch { 0 => 10, _ => 20}</AS:0>;
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43099")]
    public void SwitchExpression_LambdaBody()
    {
        var src1 = @"
class C
{
    public static Func<int> M() => () => <AS:0>F() switch { 0 => 1, _ => 2}</AS:0>;
}";
        var src2 = @"
class C
{
    public static Func<int> M() => () => <AS:0>G() switch { 0 => 10, _ => 20}</AS:0>;
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43099")]
    public void SwitchExpression_QueryLambdaBody()
    {
        var src1 = @"
class C
{
    public static IEnumerable<int> M()
    {
        return 
           from a in new[] { 1 }
           where <AS:0>F() <AS:1>switch { 0 => true, _ => false}</AS:0,1>
           select a;
    }
}";
        var src2 = @"
class C
{
    public static IEnumerable<int> M()
    {
        return 
           from a in new[] { 2 }
           where <AS:0>F() <AS:1>switch { 0 => true, _ => false}</AS:0,1>
           select a;
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43099")]
    public void SwitchExpression_NestedInGoverningExpression()
    {
        var src1 = @"
class C
{
    public static int Main() => <AS:1>(F() switch { 0 => 1, _ => 2 }) switch { 1 => <AS:0>10</AS:0>, _ => 20 }</AS:1>;
}";
        var src2 = @"
class C
{
    public static int Main() => <AS:1>(G() switch { 0 => 10, _ => 20 }) switch { 10 => <AS:0>100</AS:0>, _ => 200 }</AS:1>;
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "(G() switch { 0 => 10, _ => 20 }) switch { 10 =>       100       , _ => 200 }"));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43099")]
    public void SwitchExpression_NestedInArm()
    {
        var src1 = @"
class C
{
    public static int Main() => F1() switch
    {
        1 when F2() <AS:0>switch { 0 => true, _ => false }</AS:0> => F3() <AS:1>switch { 0 => 1, _ => 2 }</AS:1>, 
        _ => 20
    };
}";
        var src2 = @"
class C
{
    public static int Main() => F1() switch
    {
        1 when F2() <AS:0>switch { 0 => true, _ => false }</AS:0> => F3() <AS:1>switch { 0 => 1, _ => 2 }</AS:1>,
        _ => 20
    };
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43099")]
    public void SwitchExpression_Delete1()
    {
        var src1 = @"
class C
{
    public static int Main()
    {
        return Method() switch { true => G(), _ => F2() switch { 1 => <AS:0>0</AS:0>, _ => 2 } };
    }
}";
        var src2 = @"
class C
{
    public static int Main()
    {
        return Method() switch { true => G(), _ => <AS:0>1</AS:0> };
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43099")]
    public void SwitchExpression_Delete2()
    {
        var src1 = @"
class C
{
    public static int Main()
    {
        return F1() switch { 1 => 0, _ => F2() switch { 1 => <AS:0>0</AS:0>, _ => 2 } };
    }
}";
        var src2 = @"
class C
{
    public static int Main()
    {
        return F1() switch { 1 => <AS:0>0</AS:0>, _ => 1 };
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43099")]
    public void SwitchExpression_Delete3()
    {
        var src1 = @"
class C
{
    public static int Main()
    {
        return F1() switch { 1 when F2() switch { 1 => <AS:0>true</AS:0>, _ => false } => 0, _ => 2 };
    }
}";
        var src2 = @"
class C
{
    public static int Main()
    {
        return F1() switch { 1 <AS:0>when F3()</AS:0> => 0, _ => 1 };
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    #endregion
 
    #region Try
 
    [Fact]
    public void Try_Add_Inner()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
            <AS:1>Goo();</AS:1>
        }
        catch 
        {
        }
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "try", CSharpFeaturesResources.try_block));
    }
 
    [Fact]
    public void Try_Add_Leaf()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        try
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
        catch
        {
        }
    } 
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Try_Delete_Inner()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
            <AS:1>Goo();</AS:1>
        }
        <ER:1.0>catch 
        {
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "Goo();", CSharpFeaturesResources.try_block));
    }
 
    [Fact]
    public void Try_Delete_Leaf()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>        
    }
 
    static void Goo()
    {
        try
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
        catch
        {
        }
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Try_Update_Inner()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
            <AS:1>Goo();</AS:1>
        }
        <ER:1.0>catch
        {
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
            <AS:1>Goo();</AS:1>
        }
        <ER:1.0>catch (IOException)
        {
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "try", CSharpFeaturesResources.try_block));
    }
 
    [Fact]
    public void Try_Update_Inner2()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
            <AS:1>Goo();</AS:1>
        }
        <ER:1.0>catch
        {
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
            <AS:1>Goo();</AS:1>
        }
        <ER:1.0>catch
        {
        }</ER:1.0>
        Console.WriteLine(2);
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void TryFinally_Update_Inner()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
            <AS:1>Goo();</AS:1>
        }
        <ER:1.0>finally
        {
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
            <AS:1>Goo();</AS:1>
        }
        <ER:1.0>finally
        {
        }</ER:1.0>
        Console.WriteLine(2);
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Try_Update_Leaf()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        try
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
        catch
        {
        }
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        try
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
        catch (IOException)
        {
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void TryFinally_DeleteStatement_Inner()
    {
        var src1 = @"
class C
{
    static void F()
    {
        <AS:0>Console.WriteLine(0);</AS:0>
 
        try
        {
            <AS:1>Console.WriteLine(1);</AS:1>
        }
        <ER:1.0>finally
        {
            Console.WriteLine(2);
        }</ER:1.0>
    }
}";
        var src2 = @"
class C
{
    static void F()
    {
        <AS:0>Console.WriteLine(0);</AS:0>
     
        try
        {
        <AS:1>}</AS:1>
        finally
        {
            Console.WriteLine(2);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code));
    }
 
    [Fact]
    public void TryFinally_DeleteStatement_Leaf()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <ER:0.0>try
        {
            Console.WriteLine(0);
        }
        finally
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }</ER:0.0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
            Console.WriteLine(0);
        }
        finally
        {
        <AS:0>}</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "finally", CSharpFeaturesResources.finally_clause));
    }
 
    [Fact]
    public void Try_DeleteStatement_Inner()
    {
        var src1 = @"
class C
{
    static void F()
    {
        <AS:0>Console.WriteLine(0);</AS:0>
        
        try
        {
            <AS:1>Console.WriteLine(1);</AS:1>
        }
        <ER:1.0>finally
        {
            Console.WriteLine(2);
        }</ER:1.0>
    }
}";
        var src2 = @"
class C
{
    static void F()
    {
        <AS:0>Console.WriteLine(0);</AS:0>
        
        try
        {
        <AS:1>}</AS:1>
        <ER:1.0>finally
        {
            Console.WriteLine(2);
        }</ER:1.0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code));
    }
 
    [Fact]
    public void Try_DeleteStatement_Leaf()
    {
        var src1 = @"
class C
{
    static void F()
    {
        try
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
        finally
        {
            Console.WriteLine(2);
        }
    }
}";
        var src2 = @"
class C
{
    static void F()
    {
        try
        {
        <AS:0>}</AS:0>
        finally
        {
            Console.WriteLine(2);
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    #endregion
 
    #region Catch
 
    [Fact]
    public void Catch_Add_Inner()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
        }
        catch 
        {
            <AS:1>Goo();</AS:1>
        }
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause));
    }
 
    [Fact]
    public void Catch_Add_Leaf()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        try
        {
        }
        catch 
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause));
    }
 
    [Fact]
    public void Catch_Delete_Inner()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
        }
        <ER:1.0>catch 
        {
            <AS:1>Goo();</AS:1>
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "Goo();", CSharpFeaturesResources.catch_clause));
    }
 
    [Fact]
    public void Catch_Delete_Leaf()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>        
    }
 
    static void Goo()
    {
        try
        {
        }
        <ER:0.0>catch
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }</ER:0.0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "Console.WriteLine(1);", CSharpFeaturesResources.catch_clause));
    }
 
    [Fact]
    public void Catch_Update_Inner()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
        }
        <ER:1.0>catch
        {
            <AS:1>Goo();</AS:1>
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
        }
        <ER:1.0>catch (IOException)
        {
            <AS:1>Goo();</AS:1>
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause));
    }
 
    [Fact]
    public void Catch_Update_InFilter_Inner()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:1.0>catch (IOException) <AS:1>when (Goo(1))</AS:1>
        {
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:1.0>catch (Exception) <AS:1>when (Goo(1))</AS:1>
        {
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause));
    }
 
    [Fact]
    public void Catch_Update_Leaf()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        try
        {
        }
        <ER:0.0>catch
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }</ER:0.0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        try
        {
        }
        <ER:0.0>catch (IOException)
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }</ER:0.0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause));
    }
 
    [Fact]
    public void CatchFilter_Update_Inner()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:1.0>catch (IOException) <AS:1>when (Goo(1))</AS:1>
        {
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:1.0>catch (IOException) <AS:1>when (Goo(2))</AS:1>
        {
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "when (Goo(2))"),
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause));
    }
 
    [Fact]
    public void CatchFilter_Update_Leaf1()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:0.0>catch (IOException) <AS:0>when (Goo(1))</AS:0>
        {
        }</ER:0.0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:0.0>catch (IOException) <AS:0>when (Goo(2))</AS:0>
        {
        }</ER:0.0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause));
    }
 
    [Fact]
    public void CatchFilter_Update_Leaf2()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:0.0>catch (IOException) <AS:0>when (Goo(1))</AS:0>
        {
        }</ER:0.0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:0.0>catch (Exception) <AS:0>when (Goo(1))</AS:0>
        {
        }<ER:0.0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause));
    }
 
    #endregion
 
    #region Finally
 
    [Fact]
    public void Finally_Add_Inner()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
        }
        finally 
        {
            <AS:1>Goo();</AS:1>
        }
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "finally", CSharpFeaturesResources.finally_clause));
    }
 
    [Fact]
    public void Finally_Add_Leaf()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        try
        {
        }
        finally 
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "finally", CSharpFeaturesResources.finally_clause));
    }
 
    [Fact]
    public void Finally_Delete_Inner()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <ER:1.0>try
        {
        }
        finally 
        {
            <AS:1>Goo();</AS:1>
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "Goo();", CSharpFeaturesResources.finally_clause));
    }
 
    [Fact]
    public void Finally_Delete_Leaf()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>        
    }
 
    static void Goo()
    {
        <ER:0.0>try
        {
        }
        finally
        {
            <AS:0>Console.WriteLine(1);</AS:0>
        }</ER:0.0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo();</AS:1>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "Console.WriteLine(1);", CSharpFeaturesResources.finally_clause));
    }
 
    #endregion
 
    #region Try-Catch-Finally
 
    [Fact]
    public void TryCatchFinally()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:1.0>catch (IOException)
        {
            try
            {
                try
                {
                    try
                    {
                        <AS:1>Goo();</AS:1>
                    }
                    catch 
                    {
                    }
                }
                catch (Exception)
                {
                }
            }
            finally
            {
            }
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {
        }
        <ER:1.0>catch (Exception)
        {
            try
            {
                try
                {
                }
                finally
                {
                    try
                    {
                        <AS:1>Goo();</AS:1>
                    }
                    catch 
                    {
                    }
                }   
            }
            catch (Exception)
            {
            }
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause),
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "try", CSharpFeaturesResources.try_block),
            Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "Goo();", CSharpFeaturesResources.try_block),
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "finally", CSharpFeaturesResources.finally_clause));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23865")]
    public void TryCatchFinally_Regions()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:1.0>catch (IOException)
        {
            try
            {
                try
                {
                    try
                    {
                        <AS:1>Goo();</AS:1>
                    }
                    catch 
                    {
                    }
                }
                catch (Exception)
                {
                }
            }
            finally
            {
            }
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:1.0>catch (IOException)
        {
            try { try { try { <AS:1>Goo();</AS:1> } catch { } } catch (Exception) { } } finally { }
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // TODO: this is incorrect, we need to report a rude edit:
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23865")]
    public void TryCatchFinally2_Regions()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {    
            try
            {
                try
                {
                    try
                    {
                        <AS:1>Goo();</AS:1>
                    }
                    <ER:1.3>catch 
                    {
                    }</ER:1.3>
                }
                <ER:1.2>catch (Exception)
                {
                }</ER:1.2>
            }
            <ER:1.1>finally
            {
            }</ER:1.1>
        }
        <ER:1.0>catch (IOException)
        {
            
        }
        finally
        {
            
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {    
            try
            {
                try
                {
                    try
                    {
                        <AS:1>Goo();</AS:1>
                    }
                    <ER:1.3>catch 
                    {
 
                    }</ER:1.3>
                }
                <ER:1.2>catch (Exception)
                {
                }</ER:1.2>
            }
            <ER:1.1>finally
            {
            }</ER:1.1>
        }
        <ER:1.0>catch (IOException)
        {
            
        }
        finally
        {
            
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // TODO: this is incorrect, we need to report a rude edit since an ER span has been changed (empty line added):
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void TryFilter_Regions1()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:1.0>catch (IOException e) when (e == null)
        {
            <AS:1>Goo();</AS:1>
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:1.0>catch (IOException e) when (e == null) { <AS:1>Goo();</AS:1> }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void TryFilter_Regions2()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:1.0>catch (IOException e) <AS:1>when (e == null)</AS:1>
        {
            Goo();
        }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        try
        {            
        }
        <ER:1.0>catch (IOException e) <AS:1>when (e == null)</AS:1> { Goo(); }</ER:1.0>
    }
 
    static void Goo()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Try_Lambda1()
    {
        var src1 = @"
using System;
using System.Linq;
class C
{
    static int Goo(int x)
    {
        <AS:0>return 1;</AS:0>
    }
 
    static void F()
    {
        Func<int, int> f = null;
        try
        {
            f = x => <AS:1>1 + Goo(x)</AS:1>;
        }
        catch
        {
        }
 
        <AS:2>Console.Write(f(2));</AS:2>
    }
}";
        var src2 = @"
using System;
using System.Linq;
class C
{
    static int Goo(int x)
    {
        <AS:0>return 1;</AS:0>
    }
 
    static void F()
    {
        Func<int, int> f = null;
 
        f = x => <AS:1>1 + Goo(x)</AS:1>;
 
        <AS:2>Console.Write(f(2));</AS:2>
    }
}";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Try_Lambda2()
    {
        var src1 = @"
using System;
using System.Linq;
class C
{
    static int Goo(int x)
    {
        <AS:0>return 1;</AS:0>
    }
 
    static void F()
    {
        Func<int, int> f = x => 
        {
            try
            {
                <AS:1>return 1 + Goo(x);</AS:1>
            }
            <ER:1.0>catch
            {
            }</ER:1.0>
        };
 
        <AS:2>Console.Write(f(2));</AS:2>
    }
}";
        var src2 = @"
using System;
using System.Linq;
class C
{
    static int Goo(int x)
    {
        <AS:0>return 1;</AS:0>
    }
 
    static void F()
    {
        Func<int, int> f = x => 
        {
            <AS:1>return 1 + Goo(x);</AS:1>
        };
 
        <AS:2>Console.Write(f(2));</AS:2>
    }
}";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "return 1 + Goo(x);", CSharpFeaturesResources.try_block));
    }
 
    [Fact]
    public void Try_Query_Join1()
    {
        var src1 = @"
class C
{
    static int Goo(int x)
    {
        <AS:0>return 1;</AS:0>
    }
 
    static void F()
    {
        try
        {
            q = from x in xs
                join y in ys on <AS:1>F()</AS:1> equals G()
                select 1;
        }
        catch
        {
        }
 
        <AS:2>q.ToArray();</AS:2>
    }
}";
        var src2 = @"
class C
{
    static int Goo(int x)
    {
        <AS:0>return 1;</AS:0>
    }
 
    static void F()
    {
        q = from x in xs
            join y in ys on <AS:1>F()</AS:1> equals G()
            select 1;
 
        <AS:2>q.ToArray();</AS:2>
    }
}";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    #endregion
 
    #region Checked/Unchecked
 
    [Fact]
    public void CheckedUnchecked_Insert_Leaf()
    {
        var src1 = @"
class Test
{
    static void Main(string[] args)
    {
        int a = 1, b = 2;
        <AS:0>Console.WriteLine(a*b);</AS:0>
    }
}";
        var src2 = @"
class Test
{
    static void Main(string[] args)
    {
        int a = 1, b = 2;
        checked
        {
            <AS:0>Console.WriteLine(a*b);</AS:0>
        }
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void CheckedUnchecked_Insert_Internal()
    {
        var src1 = @"
class Test
{
    static void Main(string[] args)
    {
        <AS:1>System.Console.WriteLine(5 * M(1, 2));</AS:1>
    }
 
    private static int M(int a, int b) 
    {
        <AS:0>return a * b;</AS:0>
    }
}";
        var src2 = @"
class Test
{
    static void Main(string[] args)
    {
        checked
        {
            <AS:1>System.Console.WriteLine(5 * M(1, 2));</AS:1>
        }
    }
 
    private static int M(int a, int b) 
    {
        <AS:0>return a * b;</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.InsertAroundActiveStatement, "checked", CSharpFeaturesResources.checked_statement));
    }
 
    [Fact]
    public void CheckedUnchecked_Delete_Internal()
    {
        var src1 = @"
class Test
{
    static void Main(string[] args)
    {
        checked
        {
            <AS:1>System.Console.WriteLine(5 * M(1, 2));</AS:1>
        }
    }
 
    private static int M(int a, int b) 
    {
        <AS:0>return a * b;</AS:0>
    }
}";
        var src2 = @"
class Test
{
    static void Main(string[] args)
    {
        <AS:1>System.Console.WriteLine(5 * M(1, 2));</AS:1>
    }
 
    private static int M(int a, int b) 
    {
        <AS:0>return a * b;</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "System.Console.WriteLine(5 * M(1, 2));", CSharpFeaturesResources.checked_statement));
    }
 
    [Fact]
    public void CheckedUnchecked_Update_Internal()
    {
        var src1 = @"
class Test
{
    static void Main(string[] args)
    {
        unchecked
        {   
            <AS:1>System.Console.WriteLine(5 * M(1, 2));</AS:1>
        }
    }
 
    private static int M(int a, int b) 
    {
        <AS:0>return a * b;</AS:0>
    }
}";
        var src2 = @"
class Test
{
    static void Main(string[] args)
    {
        checked
        {
            <AS:1>System.Console.WriteLine(5 * M(1, 2));</AS:1>
        }
    }
 
    private static int M(int a, int b) 
    {
        <AS:0>return a * b;</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "checked", CSharpFeaturesResources.checked_statement));
    }
 
    [Fact]
    public void CheckedUnchecked_Lambda1()
    {
        var src1 = @"
class Test
{
    static void Main(string[] args)
    {
        unchecked
        {   
            Action f = () => <AS:1>5 * M(1, 2)</AS:1>;
        }
 
        <AS:2>f();</AS:2>
    }
 
    private static int M(int a, int b) 
    {
        <AS:0>return a * b;</AS:0>
    }
}";
        var src2 = @"
class Test
{
    static void Main(string[] args)
    {
        checked
        {   
            Action f = () => <AS:1>5 * M(1, 2)</AS:1>;
        }
 
        <AS:2>f();</AS:2>
    }
 
    private static int M(int a, int b) 
    {
        <AS:0>return a * b;</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "checked", CSharpFeaturesResources.checked_statement));
    }
 
    [Fact]
    public void CheckedUnchecked_Query1()
    {
        var src1 = @"
using System.Collections.Generic;
using System.Linq;
 
class Test
{
    static void F()
    {
        IEnumerable<int> f;
        unchecked
        {
            f = from a in new[] { 5 } select <AS:1>M(a, int.MaxValue)</AS:1>;
        }
 
        <AS:2>f.ToArray();</AS:2>
    }
 
    private static int M(int a, int b) 
    {
        <AS:0>return a * b;</AS:0>
    }
}";
        var src2 = @"
using System.Collections.Generic;
using System.Linq;
 
class Test
{
    static void F()
    {
        IEnumerable<int> f;
        checked
        {
            f = from a in new[] { 5 } select <AS:1>M(a, int.MaxValue)</AS:1>;
        }
 
        <AS:2>f.ToArray();</AS:2>
    }
 
    private static int M(int a, int b) 
    {
        <AS:0>return a * b;</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "checked", CSharpFeaturesResources.checked_statement));
    }
 
    #endregion
 
    #region Lambdas
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1359")]
    public void Lambdas_LeafEdits_GeneralStatement()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>F(a => <AS:0>1</AS:0>);</AS:1>
    }
}
";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>F(a => <AS:0>2</AS:0>);</AS:1>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1359")]
    public void Lambdas_LeafEdits_Nested1()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:2>F(b => <AS:1>F(a => <AS:0>1</AS:0>)</AS:1>);</AS:2>
    }
}
";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:2>F(b => <AS:1>F(a => <AS:0>2</AS:0>)</AS:1>);</AS:2>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1359")]
    public void Lambdas_LeafEdits_Nested2()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:2>F(b => <AS:1>F(a => <AS:0>1</AS:0>)</AS:1>);</AS:2>
    }
}
";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:2>F(b => <AS:1>G(a => <AS:0>2</AS:0>)</AS:1>);</AS:2>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "G(a =>       2       )"));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1359")]
    public void Lambdas_LeafEdits_IfStatement()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>if (F(a => <AS:0>1</AS:0>))</AS:1> { }
    }
}
";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>if (F(a => <AS:0>2</AS:0>))</AS:1> { }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1359")]
    public void Lambdas_LeafEdits_WhileStatement()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>while (F(a => <AS:0>1</AS:0>))</AS:1> { }
    }
}
";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>while (F(a => <AS:0>2</AS:0>))</AS:1> { }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1359")]
    public void Lambdas_LeafEdits_DoStatement()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        do {} <AS:1>while (F(a => <AS:0>1</AS:0>));</AS:1>
    }
}
";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        do {} <AS:1>while (F(a => <AS:0>2</AS:0>));</AS:1>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1359")]
    public void Lambdas_LeafEdits_SwitchStatement()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>switch (F(a => <AS:0>1</AS:0>))</AS:1>
        {
            case 0: break;
            case 1: break;
        }
    }
}
";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>switch (F(a => <AS:0>2</AS:0>))</AS:1>
        {
            case 0: break;
            case 1: break;
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1359")]
    public void Lambdas_LeafEdits_LockStatement()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>lock (F(a => <AS:0>1</AS:0>))</AS:1> {}
    }
}
";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>lock (F(a => <AS:0>2</AS:0>))</AS:1> {}
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1359")]
    public void Lambdas_LeafEdits_UsingStatement1()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>using (F(a => <AS:0>1</AS:0>))</AS:1> {}
    }
}
";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>using (F(a => <AS:0>2</AS:0>))</AS:1> {}
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    [WorkItem("https://github.com/dotnet/roslyn/issues/22696")]
    public void Lambdas_ExpressionToStatements()
    {
        // TODO: The active statement should be mapped to the return statement.
 
        var src1 = @"
class C
{
    static void Main()
    {
              Func<int, int> f = a => <AS:0>1</AS:0>;
    }
}
";
        var src2 = @"
class C
{
    static void Main()
    {
        <AS:0>Func<int, int> f = a => { return 1; };</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    [WorkItem("https://github.com/dotnet/roslyn/issues/22696")]
    public void Lambdas_ExpressionToStatements_WithSignatureChange()
    {
        // TODO: The active statement should be mapped to the return statement.
 
        var src1 = @"
class C
{
    static void Main()
    {
              Func<int, int> f = a => <AS:0>1</AS:0>;
    }
}
";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:0>Func<int, int> f = a => { return 1; };</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            active,
            capabilities: EditAndContinueCapabilities.AddMethodToExistingType);
    }
 
    [Fact]
    public void Lambdas_ExpressionToDelegate()
    {
        var src1 = @"
using System;
class C
{
    static void F()
    {
        Func<int, int> f = a => <AS:0>1</AS:0>;
    }
}
";
        var src2 = @"
using System;
class C
{
    static void F()
    {
        <AS:0>Func<int, int> f = delegate(int a) { return 1; };</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61415")]
    public void Lambdas_EditAroundTry_WithActiveStatement()
    {
        var src1 =
            """
            Action F = () =>
            {
                try
                {
                    <AS:1>G();</AS:1>
                }
                <ER:1.0>catch
                {
                }</ER:1.0>
            };
 
            <AS:0>F();</AS:0>
 
            void G()
            <AS:2>{</AS:2>
            }
            """;
        var src2 =
            """
            Action F = () =>
            {
                System.Console.WriteLine(1);
                try
                {
                    <AS:1>G();</AS:1>
                }
                <ER:1.0>catch
                {
                }</ER:1.0>
            };
            
            <AS:0>F();</AS:0>
            
            void G()
            <AS:2>{</AS:2>
            }
            """;
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Lambdas_StatementsToExpression()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        Func<int, int> f = a => { <AS:0>return 1;</AS:0> };
    }
}
";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:0>Func<int, int> f = a => 1;</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Lambdas_DelegateToExpression()
    {
        var src1 = @"
using System;
class C
{
    static void F()
    {
        Func<int, int> f = delegate(int a) { <AS:0>return 1;</AS:0> };
    }
}
";
        var src2 = @"
using System;
class C
{
    static void F()
    {
        <AS:0>Func<int, int> f = a => 1;</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Lambdas_StatementsToDelegate()
    {
        var src1 = @"
using System;
class C
{
    static void F()
    {
        Func<int, int> f = a => { <AS:0>return 1;</AS:0> };
    }
}
";
        var src2 = @"
using System;
class C
{
    static void F()
    {
        Func<int, int> f = delegate(int a) { <AS:0>return 2;</AS:0> };
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Lambdas_ActiveStatementUpdate()
    {
        var src1 = @"
using System;
class C
{
    static void Main(string[] args)
    {
        Func<int, int, int> f = (int a, int b) => <AS:0>a + b + 1</AS:0>;
        <AS:1>f(2);</AS:1>
    }
}";
        var src2 = @"
using System;
class C
{
    static void Main(string[] args)
    {
        Func<int, int, int> f = (_, _) => <AS:0>10</AS:0>;
        <AS:1>f(2);</AS:1>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active, capabilities: EditAndContinueTestVerifier.Net6RuntimeCapabilities);
    }
 
    [Fact]
    public void Lambdas_ActiveStatementRemoved1()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        Func<int, Func<int, int>> f = a =>
        {
            return b =>
            {
                <AS:0>return b;</AS:0>
            };
        };
 
        var z = f(1);
        <AS:1>z(2);</AS:1>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        Func<int, int> f = b =>
        {
            <AS:0>return b;</AS:0>
        };
 
        var z = f;
        <AS:1>z(2);</AS:1>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "return b;", CSharpFeaturesResources.lambda));
    }
 
    [Fact]
    public void Lambdas_ActiveStatementRemoved2()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        Func<int, Func<int, int>> f = a => (b) => <AS:0>b</AS:0>;
 
        var z = f(1);
        <AS:1>z(2);</AS:1>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        Func<int, int> f = <AS:0>(b)</AS:0> => b;
 
        var z = f;
        <AS:1>z(2);</AS:1>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "(b)", CSharpFeaturesResources.lambda));
    }
 
    [Fact]
    public void Lambdas_ActiveStatementRemoved3()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        Func<int, Func<int, int>> f = a =>
        {
            Func<int, int> z;
 
            F(b =>
            {
                <AS:0>return b;</AS:0>
            }, out z);
 
            return z;
        };
 
        var z = f(1);
        <AS:1>z(2);</AS:1>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        Func<int, int> f = b =>
        {
            <AS:0>F(b);</AS:0>
 
            return 1;
        };
 
        var z = f;
        <AS:1>z(2);</AS:1>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "F(b);", GetResource("lambda")));
    }
 
    [Fact]
    public void Lambdas_ActiveStatementRemoved4()
    {
        var src1 = @"
class C
{
    static void Main()
    {
        Func<int, Func<int, int>> f = a =>
        {
            <AS:1>z(2);</AS:1>
 
            return b =>
            {
                <AS:0>return b;</AS:0>
            };
        };
    }
}";
        var src2 = @"
class C
{
    static void Main()
    <AS:0,1>{</AS:0,1>
    
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            // reported because the old main body does not have active statement (only the lambda does):
            Diagnostic(RudeEditKind.UpdateMightNotHaveAnyEffect, "static void Main()", GetResource("method")),
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "{", CSharpFeaturesResources.lambda),
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "{", CSharpFeaturesResources.lambda));
    }
 
    [Fact]
    public void Queries_ActiveStatementRemoved_WhereClause()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        var s = from a in b where <AS:0>b.goo</AS:0> select b.bar;
        <AS:1>s.ToArray();</AS:1>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        var s = <AS:0>from</AS:0> a in b select b.bar;
        <AS:1>s.ToArray();</AS:1>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "from", CSharpFeaturesResources.where_clause));
    }
 
    [Fact]
    public void Queries_ActiveStatementRemoved_LetClause()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        var s = from a in b let x = <AS:0>b.goo</AS:0> select x;
        <AS:1>s.ToArray();</AS:1>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        var s = <AS:0>from</AS:0> a in b select a.bar;
        <AS:1>s.ToArray();</AS:1>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "from", CSharpFeaturesResources.let_clause));
    }
 
    [Fact]
    public void Queries_ActiveStatementRemoved_JoinClauseLeft()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        var s = from a in b
                join c in d on <AS:0>a.goo</AS:0> equals c.bar
                select a.bar;
 
        <AS:1>s.ToArray();</AS:1>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        var s = <AS:0>from</AS:0> a in b select a.bar;
        <AS:1>s.ToArray();</AS:1>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "from", CSharpFeaturesResources.join_clause));
    }
 
    [Fact]
    public void Queries_ActiveStatementRemoved_OrderBy1()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        var s = from a in b
                orderby <AS:0>a.x</AS:0>, a.y descending, a.z ascending
                select a;
 
        <AS:1>s.ToArray();</AS:1>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        var s = <AS:0>from</AS:0> a in b select a.bar;
        <AS:1>s.ToArray();</AS:1>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "from", CSharpFeaturesResources.orderby_clause));
    }
 
    [Fact]
    public void Queries_ActiveStatementRemoved_OrderBy2()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        var s = from a in b
                orderby a.x, <AS:0>a.y</AS:0> descending, a.z ascending
                select a;
 
        <AS:1>s.ToArray();</AS:1>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        var s = <AS:0>from</AS:0> a in b select a.bar;
        <AS:1>s.ToArray();</AS:1>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "from", CSharpFeaturesResources.orderby_clause));
    }
 
    [Fact]
    public void Queries_ActiveStatementRemoved_OrderBy3()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        var s = from a in b
                orderby a.x, a.y descending, <AS:0>a.z</AS:0> ascending
                select a;
 
        <AS:1>s.ToArray();</AS:1>
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    {
        var s = <AS:0>from</AS:0> a in b select a.bar;
        <AS:1>s.ToArray();</AS:1>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "from", CSharpFeaturesResources.orderby_clause));
    }
 
    [Fact]
    public void Queries_Remove_JoinInto1()
    {
        var src1 = @"
class C
{
    static void F()
    {
        var q = from x in xs
                join y in ys on F() equals G() into g
                select <AS:0>1</AS:0>;
    }
}";
        var src2 = @"
class C
{
    static void F()
    {
        var q = from x in xs
                join y in ys on F() equals G()
                select <AS:0>1</AS:0>;
    }
}";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Queries_Remove_QueryContinuation1()
    {
        var src1 = @"
class C
{
    static void F()
    {
        var q = from x in xs
                group x by x.F() into g
                where <AS:0>g.F()</AS:0>
                select 1;
    }
}";
        var src2 = @"
class C
{
    static void F()
    {
        var q = from x in xs
                group x by x.F() <AS:0>into</AS:0> g
                select 1;
    }
}";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "into", CSharpFeaturesResources.where_clause));
    }
 
    [Fact]
    public void Queries_Remove_QueryContinuation2()
    {
        var src1 = @"
class C
{
    static void F()
    {
        var q = from x in xs
                group x by x.F() into g
                select <AS:0>1</AS:0>;
    }
}";
        var src2 = @"
class C
{
    static void F()
    {
        var q = from x in xs
                <AS:0>join</AS:0> y in ys on F() equals G() into g
                select 1;
    }
}";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "join", CSharpFeaturesResources.select_clause));
    }
 
    [Fact]
    public void Queries_Select_Reduced1()
    {
        var src1 = @"
class C
{
    static void F()
    {
        var q = from a in array
                where a > 0
                select <AS:0>a + 1</AS:0>;
    }
}";
        var src2 = @"
class C
{
    static void F()
    {
        var q = from a in array
                where a > 0
                <AS:0>select</AS:0> a;
    }
}";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "select", CSharpFeaturesResources.select_clause));
    }
 
    [Fact]
    public void Queries_Select_Reduced2()
    {
        var src1 = @"
class C
{
    static int F(IEnumerable<int> e) => <AS:0>1</AS:0>;
 
    static void F()
    {
        <AS:1>F(from a in array where a > 0 select a + 1);</AS:1>
    }
}";
        var src2 = @"
class C
{
    static int F(IEnumerable<int> e) => <AS:0>1</AS:0>;
   
    static void F()
    {
        <AS:1>F(from a in array where a > 0 select a);</AS:1>
    }
}";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "F(from a in array where a > 0 select a);"));
    }
 
    [Fact]
    public void Queries_GroupBy_Reduced1()
    {
        var src1 = @"
class C
{
    static void F()
    {
        var q = from a in array
                group <AS:0>a + 1</AS:0> by a;
    }
}";
        var src2 = @"
class C
{
    static void F()
    {
        var q = from a in array
                <AS:0>group</AS:0> a by a;
    }
}";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "group", CSharpFeaturesResources.groupby_clause));
    }
 
    [Fact]
    public void Queries_GroupBy_Reduced2()
    {
        var src1 = @"
class C
{
    static int F(IEnumerable<IGrouping<int, int>> e) => <AS:0>1</AS:0>;
 
    static void F()
    {
        <AS:1>F(from a in array group a by a);</AS:1>
    }
}";
        var src2 = @"
class C
{
    static int F(IEnumerable<IGrouping<int, int>> e) => <AS:0>1</AS:0>;
   
    static void F()
    {
        <AS:1>F(from a in array group a + 1 by a);</AS:1>
    }
}";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "F(from a in array group a + 1 by a);"));
    }
 
    #endregion
 
    #region State Machines
 
    [Fact]
    public void MethodToIteratorMethod_WithActiveStatement()
    {
        var src1 = @"
class C
{
    static IEnumerable<int> F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        return new[] { 1, 2, 3 };
    }
}
";
        var src2 = @"
class C
{
    static IEnumerable<int> F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        yield return 1;
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "static IEnumerable<int> F()"));
    }
 
    [Fact]
    public void MethodToIteratorMethod_WithActiveStatementInLambda()
    {
        var src1 = @"
class C
{
    static IEnumerable<int> F()
    {
        var f = new Action(() => { <AS:0>Console.WriteLine(1);</AS:0> });
        return new[] { 1, 2, 3 };
    }
}
";
        var src2 = @"
class C
{
    static IEnumerable<int> F()
    {
        var f = new Action(() => { <AS:0>Console.WriteLine(1);</AS:0> });
        yield return 1;
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // should not contain RUDE_EDIT_INSERT_AROUND
        edits.VerifySemanticDiagnostics(
            active,
            capabilities: EditAndContinueCapabilities.NewTypeDefinition | EditAndContinueCapabilities.AddExplicitInterfaceImplementation);
    }
 
    [Fact]
    public void MethodToIteratorMethod_WithoutActiveStatement()
    {
        var src1 = @"
class C
{
    static IEnumerable<int> F()
    {
        Console.WriteLine(1);
        return new[] { 1, 2, 3 };
    }
}
";
        var src2 = @"
class C
{
    static IEnumerable<int> F()
    {
        Console.WriteLine(1);
        yield return 1;
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            active,
            capabilities: EditAndContinueCapabilities.NewTypeDefinition | EditAndContinueCapabilities.AddExplicitInterfaceImplementation);
    }
 
    [Fact]
    public void MethodToAsyncMethod_WithActiveStatement_AwaitExpression()
    {
        var src1 = @"
class C
{
    static Task<int> F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
 
        return Task.FromResult(1);
    }
}
";
        var src2 = @"
class C
{
    static async Task<int> F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        return await Task.FromResult(1);
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "static async Task<int> F()"));
    }
 
    [Fact]
    public void MethodToAsyncMethod_WithActiveStatement_AwaitForEach()
    {
        var src1 = @"
class C
{
    static Task<int> F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
 
        return Task.FromResult(1);
    }
}
";
        var src2 = @"
class C
{
    static async Task<int> F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        await foreach (var x in AsyncIter()) { }
        return 1;
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "static async Task<int> F()"));
    }
 
    [Fact]
    public void MethodToAsyncMethod_WithActiveStatement_AwaitUsing()
    {
        var src1 = @"
class C
{
    static Task<int> F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
 
        return Task.FromResult(1);
    }
}
";
        var src2 = @"
class C
{
    static async Task<int> F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        await using IAsyncDisposable x = new AsyncDisposable(), y = new AsyncDisposable();
        return 1;
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "static async Task<int> F()"));
    }
 
    [Fact]
    public void MethodToAsyncMethod_WithActiveStatement_NoAwait1()
    {
        var src1 = @"
class C
{
    static void F()
    <AS:0>{</AS:0>
        Console.WriteLine(1);
    }
}
";
        var src2 = @"
class C
{
    static async void F()
    <AS:0>{</AS:0>
        Console.WriteLine(1);
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "static async void F()"));
    }
 
    [Fact]
    public void MethodToAsyncMethod_WithActiveStatement_NoAwait2()
    {
        var src1 = @"
class C
{
    static void F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var src2 = @"
class C
{
    static async void F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "static async void F()"));
    }
 
    [Fact]
    public void MethodToAsyncMethod_WithActiveStatementInLambda1()
    {
        var src1 = @"
class C
{
    static Task<int> F()
    {
        var f = new Action(() => { <AS:0>Console.WriteLine(1);</AS:0> });
        return Task.FromResult(1);
    }
}
";
        var src2 = @"
class C
{
    static async Task<int> F()
    {
        var f = new Action(() => { <AS:0>Console.WriteLine(1);</AS:0> });
        return await Task.FromResult(1);
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // should not contain RUDE_EDIT_INSERT_AROUND
        edits.VerifySemanticDiagnostics(
            active,
            capabilities: EditAndContinueCapabilities.NewTypeDefinition | EditAndContinueCapabilities.AddExplicitInterfaceImplementation);
    }
 
    [Fact]
    public void MethodToAsyncMethod_WithActiveStatementInLambda_2()
    {
        var src1 = @"
class C
{
    static void F()
    {
        var f = new Action(() => { <AS:1>Console.WriteLine(1);</AS:1> });
        <AS:0>f();</AS:0>
    }
}
";
        var src2 = @"
class C
{
    static async void F()
    {
        var f = new Action(() => { <AS:1>Console.WriteLine(1);</AS:1> });
        <AS:0>f();</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "static async void F()"));
    }
 
    [Fact]
    public void MethodToAsyncMethod_WithLambda()
    {
        var src1 = @"
class C
{
    static void F()
    <AS:0>{</AS:0>
        var f = new Action(() => { Console.WriteLine(1); });
        f();
    }
}
";
        var src2 = @"
class C
{
    static async void F()
    <AS:0>{</AS:0>
        var f = new Action(() => { Console.WriteLine(1); });
        f();
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "static async void F()"));
    }
 
    [Fact]
    public void MethodToAsyncMethod_WithoutActiveStatement_1()
    {
        var src1 = @"
class C
{
    static Task<int> F()
    {
        Console.WriteLine(1);
        return Task.FromResult(1);
    }
}
";
        var src2 = @"
class C
{
    static async Task<int> F()
    {
        Console.WriteLine(1);
        return await Task.FromResult(1);
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            active,
            capabilities: EditAndContinueCapabilities.NewTypeDefinition | EditAndContinueCapabilities.AddExplicitInterfaceImplementation);
    }
 
    [Fact]
    public void MethodToAsyncMethod_WithoutActiveStatement_2()
    {
        var src1 = @"
class C
{
    static void F()
    {
        Console.WriteLine(1);
    }
}
";
        var src2 = @"
class C
{
    static async void F()
    {
        Console.WriteLine(1);
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            capabilities: EditAndContinueCapabilities.NewTypeDefinition | EditAndContinueCapabilities.AddExplicitInterfaceImplementation);
    }
 
    [Fact]
    public void LambdaToAsyncLambda_WithActiveStatement()
    {
        var src1 = @"
using System;
using System.Threading.Tasks;
 
class C
{
    static void F()
    {
        var f = new Func<Task<int>>(() => 
        { 
            <AS:0>Console.WriteLine(1);</AS:0>
            return Task.FromResult(1);
        });
    }
}
";
        var src2 = @"
using System;
using System.Threading.Tasks;
 
class C
{
    static void F()
    {
        var f = new Func<Task<int>>(async () => 
        { 
            <AS:0>Console.WriteLine(1);</AS:0>
            return await Task.FromResult(1);
        });
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "()"));
    }
 
    [Fact]
    public void LambdaToAsyncLambda_WithActiveStatement_NoAwait()
    {
        var src1 = @"
using System;
 
class C
{
    static void F()
    {
        var f = new Action(() => { <AS:0>Console.WriteLine(1);</AS:0> });
    }
}
";
        var src2 = @"
using System;
 
class C
{
    static void F()
    {
        var f = new Action(async () => { <AS:0>Console.WriteLine(1);</AS:0> });
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "()"));
    }
 
    [Fact]
    public void LambdaToAsyncLambda_WithActiveStatement_NoAwait_Nested()
    {
        var src1 = @"
class C
{
    static void F()
    {
        var f = new Func<int, Func<int, int>>(a => <AS:0>b => 1</AS:0>);
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        var f = new Func<int, Func<int, int>>(async a => <AS:0>b => 1</AS:0>);
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "a"));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37054")]
    public void LocalFunctionToAsyncLocalFunction_BlockBody_WithActiveStatement()
    {
        var src1 = @"
class C
{
    static void F()
    {
        Task<int> f()
        { 
            <AS:0>Console.WriteLine(1);</AS:0>
            return Task.FromResult(1);
        }
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        async Task<int> f()
        {
            <AS:0>Console.WriteLine(1);</AS:0>
            return await Task.FromResult(1);
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "f"));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61415")]
    public void LocalFunction_EditAroundTry_WithActiveStatement()
    {
        var src1 =
            """
            <AS:0>F();</AS:0>
 
            void F()
            {
                try
                {
                    <AS:1>G();</AS:1>
                }
                <ER:1.0>catch
                {
                }</ER:1.0>
            }
 
            void G()
            <AS:2>{</AS:2>
            }
            """;
        var src2 =
            """
            <AS:0>F();</AS:0>
 
            void F()
            {
                System.Console.WriteLine(1);
                try
                {
                    <AS:1>G();</AS:1>
                }
                <ER:1.0>catch
                {
                }</ER:1.0>
            }
 
            void G()
            <AS:2>{</AS:2>
            }
            """;
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37054")]
    public void LocalFunctionToAsyncLocalFunction_ExpressionBody_WithActiveStatement()
    {
        var src1 = @"
class C
{
    static void F()
    {
        Task<int> f() => <AS:0>Task.FromResult(1)</AS:0>;
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        async Task<int> f() => <AS:0>await Task.FromResult(1)</AS:0>;
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "f"));
    }
 
    [Fact]
    public void AnonymousFunctionToAsyncAnonymousFunction_WithActiveStatement_NoAwait()
    {
        var src1 = @"
using System.Threading.Tasks;
 
class C
{
    static void F()
    {
        var f = new Func<Task>(delegate() { <AS:0>Console.WriteLine(1);</AS:0> return Task.CompletedTask; });
    }
}
";
        var src2 = @"
using System.Threading.Tasks;
 
class C
{
    static async void F()
    {
        var f = new Func<Task>(async delegate() { <AS:0>Console.WriteLine(1);</AS:0> });
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, FeaturesResources.delegate_));
    }
 
    [Fact]
    public void AsyncMethodEdit_Semantics()
    {
        var src1 = @"
using System;
using System.Threading.Tasks;
 
class C
{
    static async Task<int> F()
    {
        await using var x = new AsyncDisposable();
 
        await foreach (var x in AsyncIter()) 
        {
            Console.WriteLine(x);
        }
 
        return await Task.FromResult(1);
    }
}
";
        var src2 = @"
using System;
using System.Threading.Tasks;
 
class C
{
    static async Task<int> F()
    {
        await using var x = new AsyncDisposable();
 
        await foreach (var x in AsyncIter()) 
        {
            Console.WriteLine(x + 1);
        }
 
        return await Task.FromResult(2);
    }
}
";
        var edits = GetTopEdits(src1, src2);
        _ = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType);
    }
 
    [Fact]
    public void IteratorMethodEdit_Semantics()
    {
        var src1 = @"
using System;
using System.Collections.Generic;
 
class C
{
    static IEnumerable<int> F()
    {
        Console.WriteLine(1);
        yield return 1;
    }
}
";
        var src2 = @"
using System;
using System.Collections.Generic;
 
class C
{
    static IEnumerable<int> F()
    {
        Console.WriteLine(2);
        yield return 2;
    }
}
";
        var edits = GetTopEdits(src1, src2);
        _ = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType);
    }
 
    [Fact]
    public void AsyncIteratorMethodEdit_Semantics()
    {
        var src1 = @"
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
 
class C
{
    static async IAsyncEnumerable<int> F()
    {
        Console.WriteLine(1);
        await Task.Delay(1);
        yield return 1;
    }
}
";
        var src2 = @"
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
 
class C
{
    static async IAsyncEnumerable<int> F()
    {
        Console.WriteLine(2);
        await Task.Delay(2);
        yield return 2;
    }
}
";
        var edits = GetTopEdits(src1, src2);
        _ = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            targetFrameworks: [TargetFramework.NetCoreApp],
            capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType);
    }
 
    [Fact]
    public void AsyncMethodToMethod()
    {
        var src1 = @"
class C
{
    static async void F()
    {
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ChangingFromAsynchronousToSynchronous, "static void F()", FeaturesResources.method));
    }
 
    #endregion
 
    #region Misplaced AS 
 
    [Fact]
    public void MisplacedActiveStatement1()
    {
        var src1 = @"
<AS:1>class C</AS:1>
{
    public static int F(int a)
    {
        <AS:0>return a;</AS:0> 
        <AS:2>return a;</AS:2> 
    }
}";
        var src2 = @"
class C
{
    public static int F(int a)
    {
        <AS:0>return a;</AS:0> 
        <AS:2>return a;</AS:2> 
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void MisplacedActiveStatement2()
    {
        var src1 = @"
class C
{
    static <AS:0>void</AS:0> Main(string[] args)
    {
    }
}";
        var src2 = @"
class C
{
    static void Main(string[] args)
    <AS:0>{</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void MisplacedTrackingSpan1()
    {
        var src1 = @"
class C
{
    static <AS:0>void</AS:0> Main(string[] args)
    {
    }
}";
        var src2 = @"
class C
{
    static <TS:0>void</TS:0> Main(string[] args)
    <AS:0>{</AS:0>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    #endregion
 
    #region C# 7.0
 
    [Fact]
    public void UpdateAroundActiveStatement_IsPattern()
    {
        var src1 = @"
class C
{
    static void F(object x)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        if (x is int i) { Console.WriteLine(""match""); }
    }
}
";
        var src2 = @"
class C
{
    static void F(object x)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        if (x is string s) { Console.WriteLine(""match""); }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UpdateAroundActiveStatement_DeconstructionDeclarationStatement()
    {
        var src1 = @"
class C
{
    static void F(object x)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        var (x, y) = (1, 2);
    }
}
";
        var src2 = @"
class C
{
    static void F(object x)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        var (x, y) = x;
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UpdateAroundActiveStatement_DeconstructionForEach()
    {
        var src1 = @"
class C
{
    static void F(object o)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        foreach (var (x, y) in new[] { (1, 2) }) { Console.WriteLine(2); }
    }
}
";
        var src2 = @"
class C
{
    static void F(object o)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        foreach (var (x, y) in new[] { o }) { Console.WriteLine(2); }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UpdateAroundActiveStatement_VarDeconstruction()
    {
        var src1 = @"
class C
{
    static void F(object o1, object o2)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        for (var (x, y) = o1; ; ) { }
    }
}
";
        var src2 = @"
class C
{
    static void F(object o1, object o2)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        for (var (x, y) = o2; ; ) { }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UpdateAroundActiveStatement_TypedDeconstruction()
    {
        var src1 = @"
class C
{
    static void F(object o1, object o2)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        for ((int x, int y) = o1; ; ) { }
    }
}
";
        var src2 = @"
class C
{
    static void F(object o1, object o2)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        for ((int x, int y) = o2; ; ) { }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UpdateAroundActiveStatement_Tuple()
    {
        var src1 = @"
class C
{
    static void F(object o)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        (int, int) t;
    }
}
";
        var src2 = @"
class C
{
    static void F(object o)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        (int, int) t = (1, 2);
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UpdateAroundActiveStatement_LocalFunction()
    {
        var src1 = @"
class C
{
    static void F(object o)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        void M() { Console.WriteLine(2); }
    }
}
";
        var src2 = @"
class C
{
    static void F(object o)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        void M() { Console.WriteLine(3); }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UpdateAroundActiveStatement_OutVar()
    {
        var src1 = @"
class C
{
    static void F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        M();
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        M(out var x);
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UpdateAroundActiveStatement_OutVarRemoved()
    {
        var src1 = @"
class C
{
    static void F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        M(out var x);
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UpdateAroundActiveStatement_Ref()
    {
        var src1 = @"
class C
{
    static void F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        ref int i = ref 1;
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        ref int i = ref 2;
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UpdateAroundActiveStatement_DeconstructionDeclaration()
    {
        var src1 = @"
class C
{
    static void F(object o1, object o2)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        var (x, y) = o1;
    }
}
";
        var src2 = @"
class C
{
    static void F(object o1, object o2)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        var (x, y) = o2;
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UpdateAroundActiveStatement_DeconstructionAssignment()
    {
        var src1 = @"
class C
{
    static void F(object o1, object o2)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        int x, y;
        (x, y) = o1;
    }
}
";
        var src2 = @"
class C
{
    static void F(object o1, object o2)
    {
        <AS:0>Console.WriteLine(1);</AS:0>
        int x, y;
        (x, y) = o2;
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void UpdateAroundActiveStatement_SwitchWithPattern()
    {
        var src1 = @"
class C
{
    static void F(object o1, object o2)
    {
        <AS:0>System.Console.WriteLine(1);</AS:0>
        switch (o1)
        {
            case int i:
                break;
        }
    }
}
";
        var src2 = @"
class C
{
    static void F(object o1, object o2)
    {
        <AS:0>System.Console.WriteLine(1);</AS:0>
        switch (o2)
        {
            case int i:
                break;
        }
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
        edits.VerifySemanticDiagnostics();
    }
 
    #endregion
 
    #region Nullable
 
    [Fact]
    public void ChangeLocalNullableToNonNullable()
    {
        var src1 = @"
class C
{
    static void F()
    {
        <AS:0>string? s = ""a"";</AS:0>
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        <AS:0>string s = ""a"";</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void ChangeLocalNonNullableToNullable()
    {
        var src1 = @"
class C
{
    static void F()
    {
        <AS:0>string s = ""a"";</AS:0>
    }
}
";
        var src2 = @"
class C
{
    static void F()
    {
        <AS:0>string? s = ""a"";</AS:0>
    }
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    #endregion
 
    #region Partial Types
 
    [Fact]
    public void InsertDeleteMethod_Inactive()
    {
        // Moving inactive method declaration in a file with active statements.
 
        var srcA1 = "partial class C { void F1() { <AS:0>System.Console.WriteLine(1);</AS:0> } }";
        var srcB1 = "partial class C { void F2() { } }";
        var srcA2 = "partial class C { void F1() { <AS:0>System.Console.WriteLine(1);</AS:0> } void F2() { } }";
        var srcB2 = "partial class C { }";
 
        EditAndContinueValidation.VerifySemantics(
            [GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2)],
            [
                DocumentResults(
                    activeStatements: GetActiveStatements(srcA1, srcA2, documentIndex: 0),
                    semanticEdits:
                    [
                        SemanticEdit(SemanticEditKind.Update, c => c.GetMember<INamedTypeSymbol>("C").GetMember("F2")),
                    ]),
                DocumentResults(
                    activeStatements: GetActiveStatements(srcB1, srcB2, documentIndex: 1))
            ]);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/51177")]
    [WorkItem("https://github.com/dotnet/roslyn/issues/54758")]
    public void InsertDeleteMethod_Active()
    {
        // Moving active method declaration in a file with active statements.
        // TODO: this is currently a rude edit
 
        var srcA1 = "partial class C { }";
        var srcB1 = "partial class C { void F() { <AS:0>System.Console.WriteLine(1);</AS:0> } }";
        var srcA2 = "partial class C { void F() { System.Console.WriteLine(1); } }";
        var srcB2 = "<AS:0>partial class C</AS:0> { }";
 
        EditAndContinueValidation.VerifySemantics(
            [GetTopEdits(srcA1, srcA2, documentIndex: 0), GetTopEdits(srcB1, srcB2, documentIndex: 1)],
            [
                DocumentResults(
                    activeStatements: GetActiveStatements(srcA1, srcA2, documentIndex: 0),
                    semanticEdits:
                    [
                        SemanticEdit(SemanticEditKind.Update, c => c.GetMember<INamedTypeSymbol>("C").GetMember("F")),
                    ]),
                DocumentResults(
                    activeStatements: GetActiveStatements(srcB1, srcB2, documentIndex: 1),
                    diagnostics: [Diagnostic(RudeEditKind.DeleteActiveStatement, "partial class C", GetResource("method", "F()"))])
            ]);
    }
 
    [Fact]
    public void InsertDeleteMethod_Active_EntirePartialTypeDeclaration()
    {
        var srcA1 = "partial class C { }";
        var srcB1 = "partial class C { void F() { <AS:0>System.Console.WriteLine(1);</AS:0> } }";
        var srcA2 = "partial class C { void F() { System.Console.WriteLine(1); } }";
        var srcB2 = "<AS:0/>";
 
        EditAndContinueValidation.VerifySemantics(
            [GetTopEdits(srcA1, srcA2, documentIndex: 0), GetTopEdits(srcB1, srcB2, documentIndex: 1)],
            [
                DocumentResults(
                    activeStatements: GetActiveStatements(srcA1, srcA2, documentIndex: 0),
                    semanticEdits:
                    [
                        SemanticEdit(SemanticEditKind.Update, c => c.GetMember<INamedTypeSymbol>("C").GetMember("F")),
                    ]),
                DocumentResults(
                    activeStatements: GetActiveStatements(srcB1, srcB2, documentIndex: 1),
                    diagnostics: [Diagnostic(RudeEditKind.DeleteActiveStatement, "", GetResource("method", "C.F()"))])
            ]);
    }
 
    #endregion
 
    #region Records
 
    [Fact]
    public void Record()
    {
        var src1 = @"
record C(int X)
{
    public int X { get; init; } = <AS:0>1</AS:0>;
}";
        var src2 = @"
record C(int X)
{
    public int X { get; init; } = <AS:0>2</AS:0>;
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Record_Constructor()
    {
        var src1 = @"
record C(int X)
{
    public int X { get; init; } = <AS:0>1</AS:0>;
 
    static void Main(string[] args)
    {
        <AS:1>var x = new C(1);</AS:1>
    }
}";
        var src2 = @"
record C(int X)
{
    public int X { get; init; } = <AS:0>2</AS:0>;
 
    static void Main(string[] args)
    {
        <AS:1>var x = new C(1);</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void Record_FieldInitializer_Lambda2()
    {
        var src1 = @"
record C(int X)
{
    Func<int, Func<int>> a = z => () => <AS:0>z + 1</AS:0>;
 
    static void Main(string[] args)
    {
        <AS:1>new C(1).a(1)();</AS:1>
    }
}";
        var src2 = @"
record C(int X)
{
    Func<int, Func<int>> a = z => () => <AS:0>z + 2</AS:0>;
 
    static void Main(string[] args)
    {
        <AS:1>new C(1).a(1)();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    #endregion
 
    #region Line Mapping
 
    /// <summary>
    /// Validates that changes in #line directives produce semantic updates of the containing method.
    /// </summary>
    [Fact]
    public void LineMapping_ChangeLineNumber_WithinMethod()
    {
        var src1 = @"
class C
{
#line 1 ""a""
    static void F()
    {
        <AS:0>A();</AS:0>
#line 5 ""b""
        B(1);
        <AS:1>B();</AS:1>
#line 2 ""c""
        <AS:2>C();</AS:2>
        <AS:3>C();</AS:3>
#line hidden
        D();
#line default
        <AS:4>E();</AS:4>
    }
}";
        var src2 = @"
class C
{
#line 1 ""a""
    static void F()
    {
        <AS:0>A();</AS:0>
#line 5 ""b""
        B(2);
        <AS:1>B();</AS:1>
#line 9 ""c""
        <AS:2>C();</AS:2>
        <AS:3>C();</AS:3>
#line hidden
        D();
#line default
        <AS:4>E();</AS:4>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void LineMapping_ChangeFilePath()
    {
        var src1 = @"
class C
{
    static void F()
    {
        <AS:0>A();</AS:0>
#line 1 ""a""
        <AS:1>B();</AS:1>
    }
}";
        var src2 = @"
class C
{
    static void F()
    {
        <AS:0>A();</AS:0>
#line 1 ""b""
        <AS:1>B();</AS:1>
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "B();", string.Format(FeaturesResources._0_directive, "line")));
    }
 
    [Fact]
    public void LineMapping_ExceptionRegions_ChangeLineNumber()
    {
        var src1 = @"
class C
{
    static void F()
    <AS:0>{</AS:0>
        try
        {
            try
            {
                <AS:1>Goo();</AS:1>
            }
#line 20 ""a""
            <ER:1.1>catch (E1 e) { }</ER:1.1>
#line default
        }
#line 20 ""b""
        <ER:1.0>catch (E2 e) { }</ER:1.0>
#line default
    }
}";
        var src2 = @"
class C
{
    static void F()
    <AS:0>{</AS:0>
        try
        {
            try
            {
                <AS:1>Goo();</AS:1>
            }
#line 20 ""a""
            <ER:1.1>catch (E1 e) { }</ER:1.1>
#line default
        }
#line 30 ""b""
        <ER:1.0>catch (E2 e) { }</ER:1.0>
#line default
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52971")]
    public void LineMapping_ExceptionRegions_ChangeFilePath()
    {
        var src1 = @"
class C
{
    static void F()
    <AS:0>{</AS:0>
        try
        {
            try
            {
                <AS:1>Goo();</AS:1>
            }
#line 20 ""a""
            <ER:1.1>catch (E1 e) { }</ER:1.1>
#line default
        }
#line 20 ""b""
        <ER:1.0>catch (E2 e) { }</ER:1.0>
#line default
    }
}";
        var src2 = @"
class C
{
    static void F()
    <AS:0>{</AS:0>
        try
        {
            try
            {
                <AS:1>Goo();</AS:1>
            }
#line 20 ""a""
            <ER:1.1>catch (E1 e) { }</ER:1.1>
#line default
        }
#line 20 ""c""
        <ER:1.0>catch (E2 e) { }</ER:1.0>
#line default
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // TODO: rude edit should be reported
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact(Skip = "https://github.com/dotnet/roslyn/issues/52971"), WorkItem("https://github.com/dotnet/roslyn/issues/52971")]
    public void LineMapping_ExceptionRegions_LineChange_MultipleMappedFiles()
    {
        var src1 = @"
class C
{
    static void F()
    <AS:0>{</AS:0>
        try
        {
            <AS:1>Goo();</AS:1>
        }
#line 20 ""a""
        <ER:1.1>catch (E1 e) { }</ER:1.1>
#line 20 ""b""
        <ER:1.0>catch (E2 e) { }</ER:1.0>
#line default
    }
}";
        var src2 = @"
class C
{
    static void F()
    <AS:0>{</AS:0>
        try
        {
            <AS:1>Goo();</AS:1>
        }
#line 20 ""a""
        <ER:1.1>catch (E1 e) { }</ER:1.1>
#line 30 ""b""
        <ER:1.0>catch (E2 e) { }</ER:1.0>
#line default
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        // TODO: rude edit?
        edits.VerifySemanticDiagnostics(active);
    }
 
    #endregion
 
    #region Misc
 
    [Fact]
    public void Delete_All_SourceText()
    {
        var src1 = @"
class C
{
    static void Main(string[] args)
    {
        <AS:1>Goo(1);</AS:1>
    }
 
    static void Goo(int a)
    {
        <AS:0>Console.WriteLine(a);</AS:0>
    }
}";
        var src2 = @"";
        var edits = GetTopEdits(src1, src2);
 
        edits.VerifySemanticDiagnostics(
            Diagnostic(RudeEditKind.Delete, null, DeletedSymbolDisplay(FeaturesResources.class_, "C")));
    }
 
    [Fact]
    public void PartiallyExecutedActiveStatement()
    {
        var src1 = @"
class C
{
    public static void F()
    {
        <AS:0>Console.WriteLine(1);</AS:0> 
        <AS:1>Console.WriteLine(2);</AS:1> 
        <AS:2>Console.WriteLine(3);</AS:2> 
        <AS:3>Console.WriteLine(4);</AS:3> 
        <AS:4>Console.WriteLine(5);</AS:4> 
    }
}";
        var src2 = @"
class C
{
    public static void F()
    {
        <AS:0>Console.WriteLine(10);</AS:0> 
        <AS:1>Console.WriteLine(20);</AS:1> 
        <AS:2>Console.WriteLine(30);</AS:2> 
        <AS:3>Console.WriteLine(40);</AS:3> 
        <AS:4>Console.WriteLine(50);</AS:4> 
    }
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2, flags:
        [
            ActiveStatementFlags.PartiallyExecuted | ActiveStatementFlags.LeafFrame,
            ActiveStatementFlags.PartiallyExecuted | ActiveStatementFlags.NonLeafFrame,
            ActiveStatementFlags.LeafFrame,
            ActiveStatementFlags.NonLeafFrame,
            ActiveStatementFlags.NonLeafFrame | ActiveStatementFlags.LeafFrame
        ]);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.PartiallyExecutedActiveStatementUpdate, "Console.WriteLine(10);"),
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "Console.WriteLine(20);"),
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "Console.WriteLine(40);"),
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "Console.WriteLine(50);"));
    }
 
    [Fact]
    public void PartiallyExecutedActiveStatement_Deleted1()
    {
        var src1 = @"
class C
{
    public static void F()
    {
        <AS:0>Console.WriteLine(1);</AS:0> 
    }
}";
        var src2 = @"
class C
{
    public static void F()
    { 
    <AS:0>}</AS:0>
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2, flags:
        [
            ActiveStatementFlags.PartiallyExecuted | ActiveStatementFlags.LeafFrame
        ]);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.PartiallyExecutedActiveStatementDelete, "{", FeaturesResources.code));
    }
 
    [Fact]
    public void PartiallyExecutedActiveStatement_Deleted2()
    {
        var src1 = @"
class C
{
    public static void F()
    {
        <AS:0>Console.WriteLine(1);</AS:0> 
    }
}";
        var src2 = @"
class C
{
    public static void F()
    { 
    <AS:0>}</AS:0>
}";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2, flags:
        [
            ActiveStatementFlags.NonLeafFrame | ActiveStatementFlags.LeafFrame
        ]);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code));
    }
 
    [Fact]
    public void Block_Delete()
    {
        var src1 = @"
class C
{
    public static void F()
    {
        G(1);
        <AS:0>{</AS:0> G(2); }
        G(3);
    }
}
";
        var src2 = @"
class C
{
    public static void F()
    {
        G(1);
        <AS:0>G(3);</AS:0>
    }
}
";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Theory, CombinatorialData]
    public void MemberBodyInternalError(bool outOfMemory)
    {
        var src1 = @"
class C
{
    public static void F()
    {
        <AS:1>G();</AS:1>
    }
 
    public static void G()
    {
        <AS:0>H(1);</AS:0>
    }
 
    public static void H(int x)
    {
    }
}
";
        var src2 = @"
class C
{
    public static void F()
    {
        <AS:1>G();</AS:1>
    }
 
    public static void G()
    {
        <AS:0>H(2);</AS:0>
    }
 
    public static void H(int x)
    {
    }
}
";
 
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
        var validator = new CSharpEditAndContinueTestVerifier(faultInjector: node =>
        {
            if (node.Parent is MethodDeclarationSyntax methodDecl && methodDecl.Identifier.Text == "G")
            {
                throw outOfMemory ? new OutOfMemoryException() : new SimpleToStringException();
            }
        });
 
        var expectedDiagnostic = outOfMemory
            ? Diagnostic(RudeEditKind.MemberBodyTooBig, "public static void G()", "G")
            : Diagnostic(RudeEditKind.MemberBodyInternalError, "public static void G()", "G", SimpleToStringException.ToStringOutput);
 
        validator.VerifySemantics(
            [edits],
            TargetFramework.NetCoreApp,
            [DocumentResults(diagnostics: [expectedDiagnostic])]);
    }
 
    /// <summary>
    /// Custom exception class that has a fixed ToString so that tests aren't relying
    /// on stack traces, which could make them flaky
    /// </summary>
    private class SimpleToStringException : Exception
    {
        public const string ToStringOutput = "<Exception>";
 
        public override string ToString()
        {
            return ToStringOutput;
        }
    }
 
    #endregion
 
    #region Top Level Statements
 
    [Fact]
    public void TopLevelStatements_UpdateAroundActiveStatement_LocalFunction()
    {
        var src1 = @"
using System;
 
<AS:0>Console.WriteLine(1);</AS:0>
void M() { Console.WriteLine(2); }
";
        var src2 = @"
using System;
 
<AS:0>Console.WriteLine(1);</AS:0>
void M() { Console.WriteLine(3); }
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void TopLevelStatements_UpdateAroundActiveStatement_OutVar()
    {
        var src1 = @"
using System;
 
<AS:0>Console.WriteLine(1);</AS:0>
M();
";
        var src2 = @"
using System;
 
<AS:0>Console.WriteLine(1);</AS:0>
M(out var x);
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active);
    }
 
    [Fact]
    public void TopLevelStatements_Inner()
    {
        var src1 = @"
using System;
 
<AS:1>Goo(1);</AS:1>
 
static void Goo(int a)
{
    <AS:0>Console.WriteLine(a);</AS:0>
}
";
        var src2 = @"
using System;
 
while (true)
{
    <AS:1>Goo(2);</AS:1>
}
 
static void Goo(int a)
{
    <AS:0>Console.WriteLine(a);</AS:0>
}
";
        var edits = GetTopEdits(src1, src2);
        var active = GetActiveStatements(src1, src2);
 
        edits.VerifySemanticDiagnostics(active,
            Diagnostic(RudeEditKind.ActiveStatementUpdate, "Goo(2);"));
    }
 
    #endregion
}