// 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

using System;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
    /// <summary>
    /// Tests for the region analysis APIs.
    /// </summary>
    /// <remarks>
    /// Please add your tests to other files if possible:
    ///     * FlowDiagnosticTests.cs - all tests on Diagnostics
    ///     * IterationJumpYieldStatementTests.cs - while, do, for, foreach, break, continue, goto, iterator (yield break, yield return)
    ///     * TryLockUsingStatementTests.cs - try-catch-finally, lock, &amp; using statement
    ///     * PatternsVsRegions.cs - region analysis tests for pattern matching
    /// </remarks>
    public partial class RegionAnalysisTests : FlowTestBase
    {
        #region "Expressions"

        [WorkItem(545047, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545047")]
        [Fact]
        public void DataFlowsInAndNullable_Field()
        {
            // WARNING: if this test is edited, the test with the 
            //          test with the same name in VB must be modified too
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
struct S
{
    public int F;
    public S(int f)
    {
        this.F = f;
    }
    static void Main(string[] args)
    {
        int? i = 1;
        S s = new S(1);

/*<bind>*/
        Console.WriteLine(i.Value);
        Console.WriteLine(s.F);
/*</bind>*/
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("i, s", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("args, i, s", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("args, i, s", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("i, s", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("args, i, s", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
        }

        [Fact]
        public void DataFlowsOutAndStructField()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
struct S
{
    public int F;
    public S(int f)
    {
        this.F = f;
    }
    static void Main(string[] args)
    {
        S s = new S(1);
/*<bind>*/
        s.F = 1;
/*</bind>*/
        var x = s.F;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("s", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("s", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("args, s", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("args, s", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("s", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("s", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("args, s, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
        }

        [Fact]
        public void DataFlowsInAndNullable_Property()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
struct S
{
    public int F;
    public S(int f)
    {
        this.F = f;
    }
    public int P { get; set; }

    static void Main(string[] args)
    {
        int? i = 1;
        S s = new S(1);

/*<bind>*/
        Console.WriteLine(i.Value);
        Console.WriteLine(s.P);
/*</bind>*/
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("i, s", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("args, i, s", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("args, i, s", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("i, s", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("args, i, s", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
        }

        [WorkItem(538238, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538238")]
        [Fact]
        public void TestDataFlowsIn03()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class Program
{
    static void Main(string[] args)
    {
        int x = 1;
        int y = 2;
        int z = /*<bind>*/x + y/*</bind>*/;
    }
}
");
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("args, x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestDataFlowForValueTypes()
        {
            // WARNING: test matches the same test in VB (TestDataFlowForValueTypes)
            //          Keep the two tests in sync!

            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class Tst
{
    public static void Main()
    {
        S0 a;
        S1 b;
        S2 c;
        S3 d;
        E0 e;
        E1 f;

/*<bind>*/
        Console.WriteLine(a);
        Console.WriteLine(b);
        Console.WriteLine(c);
        Console.WriteLine(d);
        Console.WriteLine(e);
        Console.WriteLine(f);
/*</bind>*/
    }
}


struct S0
{
}

struct S1
{
    public S0 s0;
}

struct S2
{
    public S0 s0;
    public int s1;
}

struct S3
{
    public S2 s;
    public object s1;
}

enum E0
{
}

enum E1
{
    V1
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Equal("a, b, c, d, e, f", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
            Assert.Equal("a, b, c, d, e, f", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [WorkItem(538997, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538997")]
        [Fact]
        public void TestDataFlowsIn04()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
using System;
class Program
{
    static void Main()
    {
        string s = "";
        Func<string> f = /*<bind>*/s/*</bind>*/.ToString;
    }
}
");
            Assert.Equal("s", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("s", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("s", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestDataFlowsOutExpression01()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public void F(int x)
    {
        int a = 1, y;
        int tmp = x +
/*<bind>*/
            (y = x = 2)
/*</bind>*/
            + (a = 2);
        int c = a + 4 + x + y;
    }
}");
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsOut));
            Assert.Equal("this, x, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x, a, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [WorkItem(540171, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540171")]
        [Fact]
        public void TestIncrement()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C
{
    static void M(int i)
    {
        /*<bind>*/i++/*</bind>*/;
        M(i);
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(543695, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543695")]
        [Fact]
        public void FlowAnalysisOnTypeOrNamespace1()
        {
            var results = CompileAndAnalyzeDataFlowExpression(@"
class C
{
    static void M(int i)
    {
        /*<bind>*/ System.Console /*</bind>*/ .WriteLine(i);
    }
}
");
            Assert.False(results.Succeeded);
        }

        [WorkItem(543695, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543695")]
        [Fact]
        public void FlowAnalysisOnTypeOrNamespace3()
        {
            var results = CompileAndAnalyzeDataFlowExpression(@"
public class A
{
    public class B
    {
        public static void M() { }
    }
}

class C
{
    static void M(int i)
    {
        /*<bind>*/ A.B /*</bind>*/ .M(i);
    }
}
");
            Assert.False(results.Succeeded);
        }

        [WorkItem(543695, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543695")]
        [Fact]
        public void FlowAnalysisOnTypeOrNamespace4()
        {
            var results = CompileAndAnalyzeDataFlowExpression(@"
public class A
{
    public class B
    {
        public static void M() { }
    }
}

class C
{
    static void M(int i)
    {
        /*<bind>*/ A /*</bind>*/ .B.M(i);
    }
}
");
            Assert.False(results.Succeeded);
        }

        [WorkItem(540183, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540183")]
        [Fact]
        public void DataFlowsOutIncrement01()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C
{
    static void M(int i)
    {
        /*<bind>*/i++/*</bind>*/;
        M(i);
    }
}
");
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
        }

        [WorkItem(6359, "DevDiv_Projects/Roslyn")]
        [Fact]
        public void DataFlowsOutPreDecrement01()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class Test
{
    string method(string s, int i)
    {
        string[] myvar = new string[i];
 
        myvar[0] = s;
        /*<bind>*/myvar[--i] = s + i.ToString()/*</bind>*/;
        return myvar[i];
    }
}");
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, s, i, myvar", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, s, i, myvar", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestBranchOfTernaryOperator()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C {
    static void Main()
    {
        bool x = true;
        bool y = x ? 
/*<bind>*/
x
/*</bind>*/
 : true;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(540832, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540832")]
        [Fact]
        public void TestAssignmentExpressionAsBranchOfTernaryOperator()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C {
    static void Main()
    {
        int x;
        int y = true ? 
/*<bind>*/
x = 1
/*</bind>*/
 : x;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestAlwaysAssignedWithTernaryOperator()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C
{
    public void F(int x)
    {
        int a, b, x = 100;
        /*<bind>*/
        int c = true ? a = 1 : b = 2;
        /*</bind>*/
    }
}");
            Assert.Equal("a, c", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("this, x, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x, a, x, c", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned04()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        int i;
        i =
/*<bind>*/
        int.Parse(args[0].ToString())
/*</bind>*/
            ;
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned05()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        bool a = true;
        bool b;
        int c =
/*<bind>*/
        (b = a) && (b = !a)
/*</bind>*/
          ? 1 : 2;
    }
}");
            Assert.Equal("b", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a, b", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned06()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        bool a = true;
        bool b;
        int c =
/*<bind>*/
        a && (b = !a)
/*</bind>*/
          ? 1 : 2;
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned07()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        bool a = true;
        bool b;
        int c =
/*<bind>*/
        (b = a) && !a
/*</bind>*/
          ? 1 : 2;
    }
}");
            Assert.Equal("b", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a, b", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned08()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        bool a = true;
        bool b;
        int c =
/*<bind>*/
        (b = a) || (b = !a)
/*</bind>*/
          ? 1 : 2;
    }
}");
            Assert.Equal("b", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a, b", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned09()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        bool a = true;
        bool b;
        int c =
/*<bind>*/
        a || (b = !a)
/*</bind>*/
          ? 1 : 2;
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned10()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        bool a = true;
        bool b;
        int c =
/*<bind>*/
        (b = a) || !a
/*</bind>*/
          ? 1 : 2;
    }
}");
            Assert.Equal("b", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a, b", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned11()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        object a = new object;
        object b;
        object c =
/*<bind>*/
        (b = a) ?? (b = null)
/*</bind>*/
        ;
    }
}");
            Assert.Equal("b", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a, b", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned12()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        object a = new object;
        object b;
        object c =
/*<bind>*/
        a ?? (b = null)
/*</bind>*/
        ;
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned13()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        object a = new object;
        object b;
        object c =
/*<bind>*/
        (b = a) ?? null
/*</bind>*/
        ;
    }
}");
            Assert.Equal("b", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a, b", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned14()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        bool a = true;
        bool b, c, d, e, f;
        bool c = (b = a) ? (c = a) : (d = a) ? (e = a) : /*<bind>*/ (f = a) /*</bind>*/;
    }
}");
            Assert.Equal("f", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a, b, d", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a, b, d, f", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned15()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        bool a = true;
        bool b, c, d, e, f;
        bool c = (b = a) ? (c = a) : /*<bind>*/ (d = a) ? (e = a) : (f = a) /*</bind>*/;
    }
}");
            Assert.Equal("d", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a, b", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a, b, d", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned16()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static bool B(out bool b) { b = true; return b; }
    public static void Main(string[] args)
    {
        bool a, b;
        bool c = B(out a) && B(out /*<bind>*/b/*</bind>*/);
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned17()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static bool B(out bool b) { b = true; return b; }
    public static void Main(string[] args)
    {
        bool a, b;
        bool c = /*<bind>*/B(out a) && B(out b)/*</bind>*/;
    }
}");
            Assert.Equal("a", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned18()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static bool B(out bool b) { b = true; return b; }
    public static void Main(string[] args)
    {
        bool a, b;
        bool c = B(out a) || B(out /*<bind>*/b/*</bind>*/);
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned19()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static bool B(out bool b) { b = true; return b; }
    public static void Main(string[] args)
    {
        bool a, b;
        bool c = /*<bind>*/B(out a) || B(out b)/*</bind>*/;
    }
}");
            Assert.Equal("a", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned22()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static bool B(out bool b) { b = true; return b; }
    public static void Main(string[] args)
    {
        bool a, b;
        if (/*<bind>*/B(out a)/*</bind>*/) a = true; else b = true;
    }
}");
            Assert.Equal("a", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssignedAndWrittenInside()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        int i =
/*<bind>*/
        int.Parse(args[0].ToString())
/*</bind>*/
            ;
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("args", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestWrittenInside03()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        int i;
        i =
/*<bind>*/
        int.Parse(args[0].ToString())
/*</bind>*/
            ;
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("args", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestReadWrite01()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        int x = 3;
        /*<bind>*/x/*</bind>*/ = 3;
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Equal("args, x", GetSymbolNamesJoined(analysis.WrittenOutside));
            Assert.Equal("args, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestReadWrite02()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void Main(string[] args)
    {
        int x = 3;
        /*<bind>*/x/*</bind>*/ += 3;
    }
}");
            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Equal("args, x", GetSymbolNamesJoined(analysis.WrittenOutside));
            Assert.Equal("args, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestReadWrite03()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void M(out int x) { x = 1; }
    public static void Main(string[] args)
    {
        int x = 3;
        M(out /*<bind>*/x/*</bind>*/);
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Equal("args, x", GetSymbolNamesJoined(analysis.WrittenOutside));
            Assert.Equal("args, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestReadWrite04()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static void M(ref int x) { x = 1; }
    public static void Main(string[] args)
    {
        int x = 3;
        M(ref /*<bind>*/x/*</bind>*/);
    }
}");
            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Equal("args, x", GetSymbolNamesJoined(analysis.WrittenOutside));
            Assert.Equal("args, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAssignmentExpressionSelection()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C {
    static void Main()
    {
        int x = (
/*<bind>*/
x = 1
/*</bind>*/
) + x;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestSingleVariableSelection()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C {
    static void Main()
    {
        bool x = true;
        bool y = x | 
/*<bind>*/
x
/*</bind>*/
;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestParenthesizedAssignmentExpressionSelection()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C {
    static void Main()
    {
        bool x = true;
        bool y = x | 
/*<bind>*/
(x = x)
/*</bind>*/
 | x;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestRefArgumentSelection()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C {
    static void Main()
    {
        int x = 0;
        Goo(ref 
/*<bind>*/
x
/*</bind>*/
);
        System.Console.WriteLine(x);
    }

    static void Goo(ref int x) { }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(540066, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540066")]
        [Fact]
        public void AnalysisOfBadRef()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C
{
    static void Main()
    {
        /*<bind>*/Main(ref 1)/*</bind>*/;
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAlwaysAssigned20NullCoalescing()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public static object B(out object b) { b = null; return b; }
    public static void Main(string[] args)
    {
        object a, b;
        object c = B(out a) ?? B(out /*<bind>*/b/*</bind>*/);
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [WorkItem(528662, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528662")]
        [Fact]
        public void TestNullCoalescingWithConstNullLeft()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
struct STest {
    
    public static string SM()
    {
        const string s = null;
        var ss = ""Q"";
        var ret = /*<bind>*/( s ?? (ss = ""C""))/*</bind>*/ + ss;
        return ret;
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Equal("ss", GetSymbolNamesJoined(dataFlows.AlwaysAssigned));
            Assert.Equal("s", GetSymbolNamesJoined(dataFlows.DataFlowsIn));
            Assert.Equal("ss", GetSymbolNamesJoined(dataFlows.DataFlowsOut));
            Assert.Equal("s, ss", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("s, ss", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
        }

        [WorkItem(528662, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528662")]
        [Fact]
        public void TestNullCoalescingWithConstNotNullLeft()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
class Test {
    
    public static string SM()
    {
        const string s = ""Not Null"";
        var ss = ""QC"";
        var ret = /*<bind>*/ s ?? ss /*</bind>*/ + ""\r\n"";
        return ret;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Equal("s", GetSymbolNamesJoined(dataFlows.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsOut));
            Assert.Equal("s, ss", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("s, ss", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
        }

        [WorkItem(8935, "DevDiv_Projects/Roslyn")]
        [Fact]
        public void TestDefaultOperator01()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Collections.Generic;

class Test<T> {
    public T GetT()     {
        return /*<bind>*/ default(T) /*</bind>*/;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsOut));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestTypeOfOperator01()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Collections.Generic;

class Test<T>
{
    public short GetT(T t)
    {
        if (/*<bind>*/ typeof(T) == typeof(int) /*</bind>*/)
            return 123;

        return 456;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsOut));
            Assert.Equal("this, t", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("this, t", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestIsOperator01()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Collections.Generic;

struct Test<T>
{
    public string GetT(T t)
    {
        if /*<bind>*/(t is string)/*</bind>*/
            return ""SSS"";

        return null;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Equal("t", GetSymbolNamesJoined(dataFlows.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsOut));
            Assert.Equal("this, t", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("this, t", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void TestAsOperator01()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Collections.Generic;

struct Test<T>
{
    public string GetT(T t)
    {
        string ret = null;
        if (t is string)
            ret = /*<bind>*/t as string/*</bind>*/;

        return ret;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Equal("t", GetSymbolNamesJoined(dataFlows.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsOut));
            Assert.Equal("this, t, ret", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("this, t, ret", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
        }

        [WorkItem(4028, "DevDiv_Projects/Roslyn")]
        [Fact]
        public void TestArrayInitializer()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C {
    static void Main()
    {
        int y = 1;
        int[,] x = { { 
/*<bind>*/
y
/*</bind>*/
 } };
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("y, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestImplicitStackAllocArrayInitializer()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C {
    static void Main()
    {
        int z = 1;
        int y = 1;
        var x = stackalloc[] { 
/*<bind>*/
y
/*</bind>*/
, z++
        };
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("z, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("z, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("z", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("z, y, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestStackAllocArrayInitializer()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C {
    static void Main()
    {
        int z = 1;
        int y = 1;
        var x = stackalloc int[] { 
/*<bind>*/
y
/*</bind>*/
, z++
        };
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("z, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("z, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("z", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("z, y, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(539286, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539286")]
        [Fact]
        public void TestAnalysisInFieldInitializers()
        {
            var results1 = CompileAndAnalyzeDataFlowExpression(@"
using System;
class C {
    static void Main()
    {
        Func<int, int> f = p => 
        {
            int x = 1;
            int y = 1;
            return /*<bind>*/1 + (x=2) + p + y/*</bind>*/;
        };

        f(1);
    }
}
");
            var results2 = CompileAndAnalyzeDataFlowExpression(@"
using System;
class C {
    static Func<int, int> f = p => 
    {
        int x = 1;
        int y = 1;
        return /*<bind>*/1 + (x=2) + p + y/*</bind>*/;
    };

    static void Main()
    {
        int r = f(1);
    }
}
");
            Assert.Equal(GetSymbolNamesJoined(results1.AlwaysAssigned),
                GetSymbolNamesJoined(results2.AlwaysAssigned));
            Assert.Equal(GetSymbolNamesJoined(results1.Captured),
                GetSymbolNamesJoined(results2.Captured));
            Assert.Equal(GetSymbolNamesJoined(results1.CapturedInside),
                GetSymbolNamesJoined(results2.CapturedInside));
            Assert.Equal(GetSymbolNamesJoined(results1.CapturedOutside),
                GetSymbolNamesJoined(results2.CapturedOutside));
            Assert.Equal(GetSymbolNamesJoined(results1.DataFlowsIn),
                GetSymbolNamesJoined(results2.DataFlowsIn));
            Assert.Equal(GetSymbolNamesJoined(results1.DataFlowsOut),
                GetSymbolNamesJoined(results2.DataFlowsOut));
            Assert.Equal("p, x, y",
                GetSymbolNamesJoined(results2.DefinitelyAssignedOnEntry));
            Assert.Equal("p, x, y",
                GetSymbolNamesJoined(results2.DefinitelyAssignedOnExit));
            Assert.Equal(GetSymbolNamesJoined(results1.ReadInside),
                GetSymbolNamesJoined(results2.ReadInside));
            Assert.Equal(GetSymbolNamesJoined(results1.ReadOutside),
                string.Join(", ", new string[] { "f" }.Concat((results2.ReadOutside).Select(symbol => symbol.Name)).OrderBy(name => name)));
            Assert.Equal(GetSymbolNamesJoined(results1.WrittenInside),
                GetSymbolNamesJoined(results2.WrittenInside));
            Assert.Equal(GetSymbolNamesJoined(results1.WrittenOutside),
                string.Join(", ", new string[] { "f" }.Concat((results2.WrittenOutside).Select(symbol => symbol.Name)).OrderBy(name => name)));
        }

        [WorkItem(539286, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539286")]
        [Fact]
        public void TestAnalysisInSimpleFieldInitializers()
        {
            var results1 = CompileAndAnalyzeDataFlowExpression(@"
using System;
class C {
    int x = 1;
    int y = 1;
    int z = /*<bind>*/1 + (x=2) + p + y/*</bind>*/;
}
");
            var results2 = CompileAndAnalyzeDataFlowExpression(@"
using System;
class C {
    int x = 1;
    int y = 1;
    static void Main()
    {
        /*<bind>*/1 + (x=2) + p + y/*</bind>*/;
    }
}
");

            //  NOTE: 'f' should not be reported in results1.AlwaysAssigned, this issue will be addressed separately
            Assert.Equal(GetSymbolNamesJoined(results1.AlwaysAssigned),
                GetSymbolNamesJoined(results2.AlwaysAssigned));
            Assert.Equal(GetSymbolNamesJoined(results1.Captured),
                GetSymbolNamesJoined(results2.Captured));
            Assert.Equal(GetSymbolNamesJoined(results1.CapturedInside),
                GetSymbolNamesJoined(results2.CapturedInside));
            Assert.Equal(GetSymbolNamesJoined(results1.CapturedOutside),
                GetSymbolNamesJoined(results2.CapturedOutside));
            Assert.Equal(GetSymbolNamesJoined(results1.DataFlowsIn),
                GetSymbolNamesJoined(results2.DataFlowsIn));
            Assert.Equal(GetSymbolNamesJoined(results1.DataFlowsOut),
                GetSymbolNamesJoined(results2.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results2.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(results2.DefinitelyAssignedOnExit));
            Assert.Equal(GetSymbolNamesJoined(results1.ReadInside),
                GetSymbolNamesJoined(results2.ReadInside));
            Assert.Equal(GetSymbolNamesJoined(results1.ReadOutside),
                GetSymbolNamesJoined(results2.ReadOutside));
            Assert.Equal(GetSymbolNamesJoined(results1.WrittenInside),
                GetSymbolNamesJoined(results2.WrittenInside));
            Assert.Equal(GetSymbolNamesJoined(results1.WrittenOutside),
                GetSymbolNamesJoined(results2.WrittenOutside));
        }

        [WorkItem(541968, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541968")]
        [Fact]
        public void ConstantFieldInitializerExpression()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
using System;
public class Aa
{
    const int myLength = /*<bind>*/5/*</bind>*/;
}
");

            Assert.Null(GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
        }

        [WorkItem(541968, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541968")]
        [Fact]
        public void ConstantFieldInitializerExpression2()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
using System;
public class Aa
{
    // NOTE: illegal, but still a region we should handle.
    const bool myLength = true || ((Func<int, int>)(x => { int y = x; return /*<bind>*/y/*</bind>*/; }))(1) == 2;
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
            Assert.Equal("System.Int32 y", dataFlows.DataFlowsIn.Single().ToTestDisplayString());
            Assert.Equal("System.Int32 y", dataFlows.ReadInside.Single().ToTestDisplayString());
        }

        [WorkItem(541968, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541968")]
        [Fact]
        public void FieldInitializerExpression()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
using System;
public class Aa
{
    bool myLength = true || ((Func<int, int>)(x => { int y = x; return /*<bind>*/y/*</bind>*/; }))(1) == 2;
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
            Assert.Equal("System.Int32 y", dataFlows.DataFlowsIn.Single().ToTestDisplayString());
            Assert.Equal("System.Int32 y", dataFlows.ReadInside.Single().ToTestDisplayString());
        }

        [WorkItem(542454, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542454")]
        [Fact]
        public void IdentifierNameInObjectCreationExpr()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
class myClass
{
    static int Main()
    {
        myClass oc = new /*<bind>*/myClass/*</bind>*/();
        return 0;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
        }

        [WorkItem(542463, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542463")]
        [Fact]
        public void MethodGroupInDelegateCreation()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
class C
{
    void Method()
    {
        System.Action a = new System.Action(/*<bind>*/Method/*</bind>*/);
    }
}
");

            Assert.Equal("this", dataFlows.ReadInside.Single().Name);
        }

        [WorkItem(542771, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542771")]
        [Fact]
        public void BindInCaseLabel()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
class TestShapes
{
    static void Main()
    {
        color s = color.blue;
        switch (s)
        {
            case true ? /*<bind>*/ color.blue /*</bind>*/ : color.blue:
                break;
            default: goto default;
        }
    }
}
enum color { blue, green }");
            var tmp = dataFlows.VariablesDeclared; // ensure no exception thrown
            Assert.Empty(dataFlows.VariablesDeclared);
        }

        [WorkItem(542915, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542915")]
        [Fact]
        public void BindLiteralExprInEnumDecl()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
enum Number
{
    Zero = /*<bind>*/0/*</bind>*/
}
");
            Assert.True(dataFlows.Succeeded);
            Assert.Empty(dataFlows.VariablesDeclared);
        }

        [WorkItem(542944, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542944")]
        [Fact]
        public void AssignToConst()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    static void Main(string[] args)
    {
        const string a = null;
        /*<bind>*/a = null;/*</bind>*/
    }
}
");
            Assert.Equal("a", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("args, a", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [WorkItem(543987, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543987")]
        [Fact]
        public void TestAddressOfUnassignedStructLocal()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class Program
{
    static void Main()
    {
        int x;
        int* px = /*<bind>*/&x/*</bind>*/;
    }
}
");
            Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.UnsafeAddressTaken));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("px", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [WorkItem(543987, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543987")]
        [Fact]
        public void TestAddressOfAssignedStructLocal()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class Program
{
    static void Main()
    {
        int x = 1;
        int* px = /*<bind>*/&x/*</bind>*/;
    }
}
");
            Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.UnsafeAddressTaken));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, px", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [WorkItem(543987, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543987")]
        [Fact]
        public void TestAddressOfUnassignedStructField()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
public struct S
{
    public int x;
    public int y;
}

class Program
{
    static void Main()
    {
        S s;
        int* px = /*<bind>*/&s.x/*</bind>*/;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Equal("s", GetSymbolNamesJoined(analysis.UnsafeAddressTaken));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("s", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("px", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [WorkItem(543987, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543987")]
        [Fact]
        public void TestAddressOfAssignedStructField()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
public struct S
{
    public int x;
    public int y;
}

class Program
{
    static void Main()
    {
        S s;
        s.x = 2;
        int* px = /*<bind>*/&s.x/*</bind>*/;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Equal("s", GetSymbolNamesJoined(analysis.UnsafeAddressTaken));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("s", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("s", GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("s", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("s", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("s, px", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestAddressOfAssignedStructField2()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
public struct S
{
    public int x;
}

class Program
{
    static void Main()
    {
        S s;
        s.x = 2;
        int* px = /*<bind>*/&s.x/*</bind>*/;
    }
}
");
            // Really ???
            Assert.Equal("s", GetSymbolNamesJoined(analysis.AlwaysAssigned));

            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Equal("s", GetSymbolNamesJoined(analysis.UnsafeAddressTaken));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("s", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("s", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("s", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("s", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("s", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("s, px", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        // Make sure that assignment is consistent with address-of.
        [Fact]
        public void TestAssignToStructField()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
public struct S
{
    public int x;
    public int y;
}

class Program
{
    static void Main()
    {
        S s;
        int x = /*<bind>*/s.x = 1/*</bind>*/;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("s", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact, WorkItem(544314, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544314")]
        public void TestOmittedLambdaPointerTypeParameter()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
using System;

unsafe public class Test
{
    public delegate int D(int* p);
    public static void Main()
    {
		int i = 10;
		int* p = &i;
		D d = /*<bind>*/delegate { return *p;}/*</bind>*/;
	}
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("p", GetSymbolNamesJoined(analysis.Captured));
            Assert.Equal("p", GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Equal("i", GetSymbolNamesJoined(analysis.UnsafeAddressTaken));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("p", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("i, p", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("i, p", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("p", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("i", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("i, p, d", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestObjectInitializerExpression()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
public class MemberInitializerTest
{   
    public int x;
    public int y { get; set; }

    public static void Main()
    {
        var i = /*<bind>*/ new MemberInitializerTest() { x = 1, y = 2 } /*</bind>*/;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("i", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestObjectInitializerExpression_LocalAccessed()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
public class MemberInitializerTest
{   
    public int x;
    public int y { get; set; }

    public static void Main()
    {
        int x = 0, y = 0;
        var i = /*<bind>*/ new MemberInitializerTest() { x = x, y = y } /*</bind>*/;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y, i", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestObjectInitializerExpression_InvalidAccess()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
public class MemberInitializerTest
{   
    public int x;
    public int y { get; set; }

    public static void Main()
    {
        var i = /*<bind>*/ new MemberInitializerTest() { x = x, y = y } /*</bind>*/;
        int x = 0, y = 0;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("i, x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestObjectInitializerExpression_LocalAccessed_InitializerExpressionSyntax()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
public class MemberInitializerTest
{   
    public int x;
    public int y { get; set; }

    public static void Main()
    {
        int x = 0, y = 0;
        var i = new MemberInitializerTest() /*<bind>*/ { x = x, y = y } /*</bind>*/;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y, i", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestObjectInitializerExpression_NestedObjectInitializer()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
public class Goo
{
    public int z;
}
public class MemberInitializerTest
{   
    public int x;
    public Goo y { get; set; }

    public static void Main()
    {
        int x = 0, z = 0;
        var i = new MemberInitializerTest() { x = x, y = /*<bind>*/ { z = z } /*</bind>*/ };
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("z", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x, z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x, z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("z", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, z, i", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestObjectInitializerExpression_VariableCaptured()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
public class Goo
{
    public delegate int D();
    public D z;
}
public class MemberInitializerTest
{   
    public int x;
    public Goo y { get; set; }

    public static void Main()
    {
        int x = 0, z = 0;
        var i = new MemberInitializerTest() /*<bind>*/ { x = x, y =  { z = () => z } } /*</bind>*/;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("z", GetSymbolNamesJoined(analysis.Captured));
            Assert.Equal("z", GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x, z", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x, z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x, z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x, z", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, z, i", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestWithExpression()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
#nullable enable

record B(string? X)
{
    static void M1(B b1)
    {
        var x = ""hello"";
        _ = /*<bind>*/b1 with { X = x }/*</bind>*/;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("b1, x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("b1, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("b1, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("b1, x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("b1, x", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void DefinitelyAssignedParameters()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
#nullable enable

class B
{
    static void M0(B b0)
    {
        M1(b0);

        static void M1(B b1)
        {
            _ = /*<bind>*/b1 + b2/*</bind>*/;
        }
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("b1", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("b0, b1", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("b0, b1", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("b1", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("b0", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("b0, b1", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestCollectionInitializerExpression()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Collections.Generic;
using System.Collections;

class Test
{
    public static int Main()
    {
        List<int> list = /*<bind>*/ new List<int>() { 1, 2, 3, 4, 5 } /*</bind>*/;
        return 0;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("list", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestCollectionInitializerExpression_LocalAccessed()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Collections.Generic;
using System.Collections;

class Test
{
    public static int Main()
    {
        int x = 1;
        List<int> list = new List<int>() /*<bind>*/ { x } /*</bind>*/;
        return 0;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, list", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestCollectionInitializerExpression_ComplexElementInitializer()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Collections.Generic;
using System.Collections;

class Test
{
    public static int Main()
    {
        int x = 1;
        List<int> list = new List<int>() { /*<bind>*/ { x } /*</bind>*/ };
        return 0;
    }
}
");
            // Nice to have: "x" flows in, "x" read inside, "list, x" written outside.
            Assert.False(analysis.Succeeded);
        }

        [Fact]
        public void TestCollectionInitializerExpression_VariableCaptured()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Collections.Generic;
using System.Collections;

class Test
{
    public delegate int D();
    public static int Main()
    {
        int x = 1;
        List<D> list = new List<D>() /*<bind>*/ { () => x } /*</bind>*/;
        return 0;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, list", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void ObjectInitializerInField()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Collections.Generic;

class C {  public Func<int, int, int> dele;  }

public class Test
{
    C c = /*<bind>*/new C { dele = delegate(int x, int y) { return x + y; } }/*</bind>*/;
}
");
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlows.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlows.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlows.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlows.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlows.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.WrittenOutside));
        }

        [Fact]
        public void CollectionInitializerInField()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Collections.Generic;

class C {  public Func<int, int, int> dele;  }

public class Test
{
    List<Func<int, int, int>> list = /*<bind>*/new List<Func<int, int, int>>() { (x, y) => { return x + y; } }/*</bind>*/;
}
");
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlows.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlows.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlows.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlows.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlows.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.WrittenOutside));
        }

        [Fact(), WorkItem(529329, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529329")]
        public void QueryAsFieldInitializer()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections;

class Test
{
    public IEnumerable e = /*<bind>*/
               from x in new[] { 1, 2, 3 }
               where BadExpression
               let y = x.ToString()
               select y /*</bind>*/;
}
");
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlows.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlows.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlows.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlows.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlows.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.WrittenOutside));
        }

        [WorkItem(544361, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544361")]
        [Fact]
        public void FullQueryExpression()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(
@"using System.Linq;
 
class Program
{
    static void Main(string[] args)
    {
        var q = /*<bind>*/from arg in args
                group arg by arg.Length into final
                select final/*</bind>*/;
    }
}");
            Assert.Equal("args", GetSymbolNamesJoined(dataFlows.DataFlowsIn));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
        }

        [WorkItem(669341, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/669341")]
        [Fact]
        public void ReceiverRead()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(
@"using System;

struct X
{
    public Y y;
}
struct Y
{
    public Z z;
}
struct Z
{
    public int Value;
}

class Test
{
    static void Main()
    {
        X x = new X();
        var value = /*<bind>*/x.y/*</bind>*/.z.Value;
    }
}");
            Assert.Equal("x", GetSymbolNamesJoined(dataFlows.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
        }

        [WorkItem(669341, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/669341")]
        [Fact]
        public void ReceiverWritten()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(
@"using System;

struct X
{
    public Y y;
}
struct Y
{
    public Z z;
}
struct Z
{
    public int Value;
}

class Test
{
    static void Main()
    {
        X x = new X();
        /*<bind>*/x.y/*</bind>*/.z.Value = 3;
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlows.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlows.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
        }

        [WorkItem(669341, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/669341")]
        [Fact]
        public void ReceiverReadAndWritten()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(
@"using System;

struct X
{
    public Y y;
}
struct Y
{
    public Z z;
}
struct Z
{
    public int Value;
}

class Test
{
    static void Main()
    {
        X x = new X();
        /*<bind>*/x.y/*</bind>*/.z.Value += 3;
    }
}");
            Assert.Equal("x", GetSymbolNamesJoined(dataFlows.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlows.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void UnaryPlus()
        {
            // reported at https://social.msdn.microsoft.com/Forums/vstudio/en-US/f5078027-def2-429d-9fef-ab7f240883d2/writteninside-for-unary-operators?forum=roslyn
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Main
{
    static int Main(int a)
    {
/*<bind>*/
        return +a;
/*</bind>*/
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("a", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("a", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("a", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("a", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
        }

        [Fact]
        public void NullCoalescingAssignment()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowMultipleExpressions(@"
public class C
{
    public static void Main()
    {
        C c;
        c ??= new C();

        object x1;
        object y1;
        /*<bind0>*/GetC(x1 = 1).Prop ??= (y1 = 2)/*</bind0>*/;
        x1.ToString();
        y1.ToString();

        object x2;
        object y2;
        /*<bind1>*/GetC(x2 = 1).Field ??= (y2 = 2)/*</bind1>*/;
        x2.ToString();
        y2.ToString();
    }
    static C GetC(object i) => null;
    object Prop { get; set; }
    object Field;
}
");

            var propertyDataFlowAnalysis = dataFlowAnalysisResults.First();
            var fieldDataFlowAnalysis = dataFlowAnalysisResults.Skip(1).Single();

            assertAllInfo(propertyDataFlowAnalysis, "x1", "y1", "x2", "y2");
            assertAllInfo(fieldDataFlowAnalysis, "x2", "y2", "x1", "y1");

            void assertAllInfo(DataFlowAnalysis dataFlowAnalysis, string currentX, string currentY, string otherX, string otherY)
            {
                Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.VariablesDeclared));
                Assert.Equal(currentX, GetSymbolNamesJoined(dataFlowAnalysis.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.DataFlowsIn));
                Assert.Equal($"{currentX}, {currentY}", GetSymbolNamesJoined(dataFlowAnalysis.DataFlowsOut));
                Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.ReadInside));
                Assert.Equal("c, x1, y1, x2, y2", GetSymbolNamesJoined(dataFlowAnalysis.ReadOutside));
                Assert.Equal($"{currentX}, {currentY}", GetSymbolNamesJoined(dataFlowAnalysis.WrittenInside));
                Assert.Equal($"c, {otherX}, {otherY}", GetSymbolNamesJoined(dataFlowAnalysis.WrittenOutside));
                Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.Captured));
                Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.CapturedOutside));
            }
        }

        [Fact]
        public void CondAccess_NullCoalescing_DataFlow()
        {
            // This test corresponds to ExtractMethodTests.TestFlowStateNullableParameters3
            var dataFlowAnalysis = CompileAndAnalyzeDataFlowExpression(@"
#nullable enable
class C
{
    public string M()
    {
        string? a = null;
        string? b = null;
        return /*<bind>*/(a + b + a)?.ToString()/*</bind>*/ ?? string.Empty;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.AlwaysAssigned));
            Assert.Equal("a, b", GetSymbolNamesJoined(dataFlowAnalysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.DataFlowsOut));
            Assert.Equal("a, b", GetSymbolNamesJoined(dataFlowAnalysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.WrittenInside));
            Assert.Equal("this, a, b", GetSymbolNamesJoined(dataFlowAnalysis.WrittenOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.CapturedOutside));
        }

        [Theory]
        [InlineData("c?.M0(x = 0)")]
        [InlineData("c!.M0(x = 0)")]
        public void CondAccess_Equals_DataFlowsOut_01(string leftOperand)
        {
            var dataFlowAnalysis = CompileAndAnalyzeDataFlowExpression(@"
#nullable enable
class C
{
    bool M0(object? obj) => false;

    public static void M(C? c)
    {
        int x = 0;
        if (" + leftOperand + @" == /*<bind>*/c!.M0(x = 0)/*</bind>*/)
        {
            x.ToString();
        }

        x.ToString();
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysis.AlwaysAssigned));
            Assert.Equal("c", GetSymbolNamesJoined(dataFlowAnalysis.DataFlowsIn));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysis.DataFlowsOut));
            Assert.Equal("c", GetSymbolNamesJoined(dataFlowAnalysis.ReadInside));
            Assert.Equal("c, x", GetSymbolNamesJoined(dataFlowAnalysis.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysis.WrittenInside));
            Assert.Equal("c, x", GetSymbolNamesJoined(dataFlowAnalysis.WrittenOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.CapturedOutside));
        }

        [Theory]
        [InlineData("c?.M0(x = 0)")]
        [InlineData("c!.M0(x = 0)")]
        public void CondAccess_Equals_DataFlowsOut_02(string leftOperand)
        {
            var dataFlowAnalysis = CompileAndAnalyzeDataFlowExpression(@"
#nullable enable
class C
{
    bool M0(object? obj) => false;

    public static void M(C? c)
    {
        int x = 0;
        if (" + leftOperand + @" == /*<bind>*/c!.M0(x = 0)/*</bind>*/)
        {
            x.ToString();
        }
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysis.AlwaysAssigned));
            Assert.Equal("c", GetSymbolNamesJoined(dataFlowAnalysis.DataFlowsIn));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysis.DataFlowsOut));
            Assert.Equal("c", GetSymbolNamesJoined(dataFlowAnalysis.ReadInside));
            Assert.Equal("c, x", GetSymbolNamesJoined(dataFlowAnalysis.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysis.WrittenInside));
            Assert.Equal("c, x", GetSymbolNamesJoined(dataFlowAnalysis.WrittenOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysis.CapturedOutside));
        }

        #endregion

        #region "constructor initializer"
        [Fact]
        public void TestDataFlowsInCtorInitPublicApi()
        {
            var program = @"
class C
{
    C(int x)
    {}
    
    C(int x, int y) /*<bind>*/ : this(x + y) /*</bind>*/
    {}
}
";
            var analysis = CompileAndGetModelAndConstructorInitializer(program,
                (model, constructorInitializer) => CSharpExtensions.AnalyzeDataFlow(model, constructorInitializer)
            );

            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact]
        public void TestDataFlowsInCtorInitPublicApi2()
        {
            var program = @"
class C
{
    C(int x)
    {}
    
    C(int x, int y) /*<bind>*/ : this(x + y) /*</bind>*/
    {}
}
";
            var analysis = CompileAndGetModelAndConstructorInitializer(program,
                (model, constructorInitializer) => global::Microsoft.CodeAnalysis.ModelExtensions.AnalyzeDataFlow(model, constructorInitializer)
            );

            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact]
        public void TestDataFlowsInCtorInit()
        {
            var analysis = CompileAndAnalyzeDataFlowConstructorInitializer(@"
class C
{
    C(int x)
    {}
    
    C(int x, int y) /*<bind>*/ : this(x + y) /*</bind>*/
    {}
}");
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact]
        public void TestDataFlowsInCtorInitVariablesDeclared()
        {
            var analysis = CompileAndAnalyzeDataFlowConstructorInitializer(@"
class C
{
    C(int x)
    {}

    C(int x)
    {}
    
    C(int x, int y) /*<bind>*/ : this((x++ + y is var b) switch { _ => b * 2}) /*</bind>*/
    {}
}");
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("x, b", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("b", GetSymbolNamesJoined(analysis.VariablesDeclared));
        }

        [Fact]
        public void TestDataFlowsInCtorInitComplex()
        {
            var analysis = CompileAndAnalyzeDataFlowConstructorInitializer(@"
public class BaseX
{
	public BaseX(out int ix, ref string i, in int s, in int s2, out int rrr)
	{
	}
}
	
public class X : BaseX
{
	public X(int r, out int ix, out int x, ref int i)/*<bind>*/  : 
		base(out ix, ref CalcValue(""ctor"", out x), CalcInt(""int"", out var y) + CalcInt(""int2"", out var y2),
        x + y + r + y2 + i++, out var rrr)
        /*</bind>*/
    {
        Console.WriteLine(y);
    }

    static string s;
    static ref string CalcValue(string text, out int i)
    {
        Console.WriteLine($""CalcInt({text})"");
        i = 42;
        return ref s;
    }

        static int CalcInt(string text, out int i)
        {
            Console.WriteLine($""CalcInt({text})"");
            i = 42;
            return i;
        }
}");
            Assert.Equal("r, i", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("ix, x, i, y", GetSymbolNamesJoined(analysis.DataFlowsOut));
            Assert.Equal("r, x, i, y, y2", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("ix, x, i, y", GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Equal("ix, x, i, y, y2, rrr", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("ix, x, i, y, y2, rrr", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("this, r, i", GetSymbolNamesJoined(analysis.WrittenOutside));
            Assert.Equal("y, y2, rrr", GetSymbolNamesJoined(analysis.VariablesDeclared));
        }

        [Fact]
        public void TestDataFlowsInCtorInitWrite()
        {
            var analysis = CompileAndAnalyzeDataFlowConstructorInitializer(@"
class C
{
    C(int x)
    {}
    
    C(int x, int y) /*<bind>*/ : this(x++ + y) /*</bind>*/
    {}
}");
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
        }
        #endregion

        #region "primary constructor initializer"

        [Fact]
        public void TestDataFlowsInPrimaryCtorInitPublicApi()
        {
            var program = @"
record Base(int x)

record C(int x, int y) /*<bind>*/ : Base(x + y) /*</bind>*/;
";
            var analysis = CompileAndGetModelAndPrimaryConstructorInitializer(program,
                (model, primaryConstructorInitializer) => CSharpExtensions.AnalyzeDataFlow(model, primaryConstructorInitializer)
            );

            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact]
        public void TestDataFlowsInPrimaryCtorInitPublicApi2()
        {
            var program = @"
record Base(int x)

record C(int x, int y) /*<bind>*/ : Base(x + y) /*</bind>*/;
";
            var analysis = CompileAndGetModelAndPrimaryConstructorInitializer(program,
                (model, primaryConstructorInitializer) => global::Microsoft.CodeAnalysis.ModelExtensions.AnalyzeDataFlow(model, primaryConstructorInitializer)
            );

            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact]
        public void TestDataFlowsInPrimaryCtorInit()
        {
            var analysis = CompileAndAnalyzeDataFlowPrimaryConstructorInitializer(@"
record Base(int x)

record C(int x, int y) /*<bind>*/ : Base(x + y) /*</bind>*/;
");
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact]
        public void TestDataFlowsInPrimaryCtorInitVariablesDeclared()
        {
            var analysis = CompileAndAnalyzeDataFlowPrimaryConstructorInitializer(@"
record Base(int x);

record C(int x, int y) /*<bind>*/ : Base((x++ + y is var b) switch { _ => b * 2}) /*</bind>*/;
");
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("x, b", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("b", GetSymbolNamesJoined(analysis.VariablesDeclared));
        }
        #endregion

        #region "Statements"

        [Fact]
        public void TestDataReadWrittenIncDecOperator()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
class C {
    static short Main()
    {
        short x = 0, y = 1, z = 2;
/*<bind>*/
        x++; y--;
/*</bind>*/
        return y;
    }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
            Assert.True(controlFlowAnalysisResults.StartPointIsReachable);
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y, z", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestTernaryExpressionWithAssignments()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
class C {
    static void Main()
    {
        bool x = true;
        int y;
/*<bind>*/
        int z = x ? y = 1 : y = 2;
/*</bind>*/
        y.ToString();
    }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Equal("z", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("y, z", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("y, z", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(542231, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542231")]
        [Fact]
        public void TestUnreachableRegion()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(
@"class C
{
    public static void Main(string[] args)
    {
        int i;
        return;
        /*<bind>*/
        i = i + 1;
        /*</bind>*/
        int j = i;
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
        }

        [WorkItem(542231, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542231")]
        [Fact]
        public void TestUnreachableRegion2()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(
@"class C
{
    public static void Main(string[] args)
    {
        string i = 0, j = 0, k = 0, l = 0;
        goto l1;
        /*<bind>*/
        Console.WriteLine(i);
        j = 1;
l1:
        Console.WriteLine(j);
        k = 1;
        goto l2;
        Console.WriteLine(k);
        l = 1;
l3:
        Console.WriteLine(l);
        i = 1;
        /*</bind>*/
l2:
        Console.WriteLine(i + j + k + l);
        goto l3;
    }
}");
            Assert.Equal("j, l", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("i, k", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
        }

        [WorkItem(542231, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542231")]
        [Fact]
        public void TestUnreachableRegionInExpression()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(
@"class C
{
    public static bool Main()
    {
        int i, j;
        return false && /*<bind>*/((i = i + 1) == 2 || (j = i) == 3)/*</bind>*/;
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
        }

        [Fact]
        public void TestDeclarationWithSelfReferenceAndTernaryOperator()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
class C {
    static void Main()
    {
/*<bind>*/
        int x = true ? 1 : x;
/*</bind>*/
    }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestDeclarationWithTernaryOperatorAndAssignment()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
class C {
    static void Main()
    {
/*<bind>*/
        int x, z, y = true ? 1 : x = z;
/*</bind>*/
    }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Equal("x, z, y", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("z", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestDictionaryInitializer()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
class C {

    static void Goo()
    {
        int i, j;
/*<bind>*/
        var s = new Dictionary<int, int>() {[i = j = 1] = 2 };
/*</bind>*/

        System.Console.WriteLine(i + j);
    }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
            Assert.True(controlFlowAnalysisResults.StartPointIsReachable);
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Equal("s", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("i, j, s", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("i, j", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("i, j", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("i, j, s", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
        }

        [WorkItem(542435, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542435")]
        [Fact]
        public void NullArgsToAnalyzeControlFlowStatements()
        {
            var compilation = CreateCompilation(@"
class C
{
    static void Main()
    {
        int i = 10;
    }
}
");

            var semanticModel = compilation.GetSemanticModel(compilation.SyntaxTrees[0]);
            var statement = compilation.SyntaxTrees[0].GetCompilationUnitRoot().DescendantNodesAndSelf().OfType<StatementSyntax>().First();
            Assert.Throws<ArgumentNullException>(() => semanticModel.AnalyzeControlFlow(statement, null));
            Assert.Throws<ArgumentNullException>(() => semanticModel.AnalyzeControlFlow(null, statement));
            Assert.Throws<ArgumentNullException>(() => semanticModel.AnalyzeControlFlow(null));
            Assert.Throws<ArgumentNullException>(() => semanticModel.AnalyzeDataFlow(null, statement));
            Assert.Throws<ArgumentNullException>(() => semanticModel.AnalyzeDataFlow(statement, null));
            Assert.Throws<ArgumentNullException>(() => semanticModel.AnalyzeDataFlow((StatementSyntax)null));
        }

        [WorkItem(542507, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542507")]
        [Fact]
        public void DateFlowAnalyzeForLocalWithInvalidRHS()
        {
            // Case 1
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
using System;

public class Test
{
    public delegate int D();
    public void goo(ref D d)
    {
/*<bind>*/
        d = { return 10;};
/*</bind>*/
    }
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            // Case 2
            analysis = CompileAndAnalyzeDataFlowStatements(@"
using System;

public class Gen<T>
{
    public void DefaultTest()
    {
/*<bind>*/
        object obj = default (new Gen<T>());
/*</bind>*/
    }
}
");
            Assert.Equal("obj", GetSymbolNamesJoined(analysis.VariablesDeclared));
        }

        [Fact]
        public void TestEntryPoints01()
        {
            var analysis = CompileAndAnalyzeControlFlowStatements(@"
class C {
    public void F()
    {
        goto L1; // 1
/*<bind>*/
        L1: ;
/*</bind>*/
        goto L1; // 2
    }
}");
            Assert.Equal(1, analysis.EntryPoints.Count());
        }

        [Fact]
        public void TestExitPoints01()
        {
            var analysis = CompileAndAnalyzeControlFlowStatements(@"
class C {
    public void F(int x)
    {
        L1: ; // 1
/*<bind>*/
        if (x == 0) goto L1;
        if (x == 1) goto L2;
        if (x == 3) goto L3;
        L3: ;
/*</bind>*/
        L2: ; // 2
    }
}");
            Assert.Equal(2, analysis.ExitPoints.Count());
        }

        [Fact]
        public void TestRegionCompletesNormally01()
        {
            var analysis = CompileAndAnalyzeControlFlowStatements(@"
class C {
    public void F(int x)
    {
/*<bind>*/
        goto L1;
/*</bind>*/
        L1: ;
    }
}");
            Assert.True(analysis.StartPointIsReachable);
            Assert.False(analysis.EndPointIsReachable);
        }

        [Fact]
        public void TestRegionCompletesNormally02()
        {
            var analysis = CompileAndAnalyzeControlFlowStatements(@"
class C {
    public void F(int x)
    {
/*<bind>*/
        x = 2;
/*</bind>*/
    }
}");
            Assert.True(analysis.EndPointIsReachable);
        }

        [Fact]
        public void TestRegionCompletesNormally03()
        {
            var analysis = CompileAndAnalyzeControlFlowStatements(@"
class C {
    public void F(int x)
    {
/*<bind>*/
        if (x == 0) return;
/*</bind>*/
    }
}");
            Assert.True(analysis.EndPointIsReachable);
            Assert.Equal(1, analysis.ExitPoints.Count());
        }

        [Fact]
        public void TestVariablesDeclared01()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
    {
        int a;
/*<bind>*/
        int b;
        int x, y = 1;
        { var z = ""a""; }
/*</bind>*/
        int c;
    }
}");
            Assert.Equal("b, x, y, z", GetSymbolNamesJoined(analysis.VariablesDeclared));
        }

        [Fact]
        public void TestVariablesInitializedWithSelfReference()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
    {
/*<bind>*/
        int x = x = 1;
        int y, z = 1;
/*</bind>*/
    }
}");
            Assert.Equal("x, y, z", GetSymbolNamesJoined(analysis.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("x, z", GetSymbolNamesJoined(analysis.AlwaysAssigned));
        }

        [Fact]
        public void AlwaysAssignedUnreachable()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
    {
        int y;
/*<bind>*/
        if (x == 1)
        {
            y = 2;
            return;
        }
        else
        {
            y = 3;
            throw new Exception();
        }
/*</bind>*/
        int = y;
    }
}");
            Assert.Equal("y", GetSymbolNamesJoined(analysis.AlwaysAssigned));
        }

        [WorkItem(538170, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538170")]
        [Fact]
        public void TestVariablesDeclared02()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
/*<bind>*/
    {
        int a;
        int b;
        int x, y = 1;
        { string z = ""a""; }
        int c;
    }
/*</bind>*/
}");
            Assert.Equal("a, b, x, y, z, c", GetSymbolNamesJoined(analysis.VariablesDeclared));
        }

        [WorkItem(541280, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541280")]
        [Fact]
        public void TestVariablesDeclared03()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F()
/*<bind>*/
    {
        int a = 0;
        long a = 1;
    }
/*</bind>*/
}");
            Assert.Equal("a, a", GetSymbolNamesJoined(analysis.VariablesDeclared));
            var intsym = analysis.VariablesDeclared.First() as ILocalSymbol;
            var longsym = analysis.VariablesDeclared.Last() as ILocalSymbol;
            Assert.Equal("Int32", intsym.Type.Name);
            Assert.Equal("Int64", longsym.Type.Name);
        }

        [WorkItem(539229, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539229")]
        [Fact]
        public void UnassignedVariableFlowsOut01()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    static void Main(string[] args)
    {
        int i = 10;
/*<bind>*/
        int j = j + i;
/*</bind>*/
        Console.Write(i);
        Console.Write(j); 
    }
}");
            Assert.Equal("j", GetSymbolNamesJoined(analysis.VariablesDeclared));
            Assert.Equal("i", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("j", GetSymbolNamesJoined(analysis.DataFlowsOut));
            Assert.Equal("i, j", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("i, j", GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Equal("j", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("args, i", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestDataFlowsIn01()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
    {
        int a = 1, y = 2;
/*<bind>*/
        int b = a + x + 3;
/*</bind>*/
        int c = a + 4 + y;
    }
}");
            Assert.Equal("x, a", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact]
        public void TestOutParameter01()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    void Test<T>(out T t) where T : class, new()
    {
/*<bind>*/
        T t1;
        Test(out t1);
        t = t1;
/*</bind>*/
        System.Console.WriteLine(t1.ToString());
    }
}
");
            Assert.Equal("this", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("t, t1", GetSymbolNamesJoined(analysis.ReadOutside));
        }

        [Fact]
        public void TestDataFlowsOut01()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
    {
        int a = 1, y;
/*<bind>*/
        if (x == 1) y = x = 2;
/*</bind>*/
        int c = a + 4 + x + y;
    }
}");
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DataFlowsOut));
        }

        [WorkItem(538146, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538146")]
        [Fact]
        public void TestDataFlowsOut02()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"class Program
{
    void Test(string[] args)
    {
/*<bind>*/
        int s = 10, i = 1;
        int b = s + i;
/*</bind>*/
        System.Console.WriteLine(s);
        System.Console.WriteLine(i);
    }
}");
            Assert.Equal("s, i", GetSymbolNamesJoined(analysis.DataFlowsOut));
        }

        [Fact]
        public void TestDataFlowsOut03()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(
@"using System.Text;
class Program
{
    private static string Main()
    {
        StringBuilder builder = new StringBuilder();
/*<bind>*/
        builder.Append(""Hello"");
        builder.Append("" From "");
        builder.Append("" Roslyn"");
/*</bind>*/
        return builder.ToString();
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));
        }

        [Fact]
        public void TestDataFlowsOut04()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"class Program
{
    void F(out int x)
    {
        /*<bind>*/
        x = 12;
        /*</bind>*/
    }
}");
            Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadOutside));
        }

        [Fact]
        public void TestDataFlowsOut05()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"class Program
{
    void F(out int x)
    {
        /*<bind>*/
        x = 12;
        return;
        /*</bind>*/
    }
}");
            Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadOutside));
        }

        [Fact]
        public void TestDataFlowsOut06()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"class Program
{
    void F(bool b)
    {
        int i = 1;
        while (b)
        {
            /*<bind>*/
            i = i + 1;
            /*</bind>*/
        }
    }
}");
            Assert.Equal("i", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("i", GetSymbolNamesJoined(analysis.DataFlowsOut));
            Assert.Equal("b", GetSymbolNamesJoined(analysis.ReadOutside));
        }

        [Fact]
        public void TestDataFlowsOut07()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"class Program
{
    void F(bool b)
    {
        int i;
        /*<bind>*/
        i = 2;
        goto next;
        /*</bind>*/
    next:
        int j = i;
    }
}");
            Assert.Equal("i", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("i", GetSymbolNamesJoined(analysis.DataFlowsOut));
            Assert.Equal("i", GetSymbolNamesJoined(analysis.ReadOutside));
        }

        [WorkItem(540793, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540793")]
        [Fact]
        public void TestDataFlowsOut08()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"class Program
{
    void F(bool b)
    {
        int i = 2;
        try
        {
            /*<bind>*/
            i = 1;
            /*</bind>*/
        }
        finally
        {
           int j = i;
        }
    }
}");
            Assert.Equal("i", GetSymbolNamesJoined(analysis.DataFlowsOut));
        }

        [Fact]
        public void TestDataFlowsOut09()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"class Program
{
    void Test(string[] args)
    {
        int i;
        string s;

        /*<bind>*/i = 10;
        s = args[0] + i.ToString();/*</bind>*/
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));
        }

        [Fact]
        public void TestDataFlowsOut10()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    static void Main(string[] args)
    {
        int x = 10;
/*<bind>*/
        int y;
        if (x == 10)
            y = 5;
/*</bind>*/
        Console.WriteLine(y);
    }
}
");
            Assert.Equal("y", GetSymbolNamesJoined(analysis.DataFlowsOut));
        }

        [Fact]
        public void TestAlwaysAssigned01()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
    {
        int a = 1, y = 1;
/*<bind>*/
        if (x == 2) a = 3; else a = 4;
        x = 4;
        if (x == 3) y = 12;
/*</bind>*/
        int c = a + 4 + y;
    }
}");
            Assert.Equal("x, a", GetSymbolNamesJoined(analysis.AlwaysAssigned));
        }

        [Fact]
        public void TestAlwaysAssigned02()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
    {
/*<bind>*/
        const int a = 1;
/*</bind>*/
    }
}");
            Assert.Equal("a", GetSymbolNamesJoined(analysis.AlwaysAssigned));
        }

        [WorkItem(540795, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540795")]
        [Fact]
        public void TestAlwaysAssigned03()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class Always {
    public void F()
    {
        ushort x = 0, y = 1, z;
/*<bind>*/
        x++;
        return;
        uint z = y;
/*</bind>*/
    }
}");
            Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
        }

        [Fact]
        public void TestReadInside01()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    void Test<T>(out T t) where T : class, new()
    {
/*<bind>*/
        T t1;
        Test(out t1);
        t = t1;
/*</bind>*/
        System.Console.WriteLine(t1.ToString());
    }
}
");
            Assert.Equal("this, t1", GetSymbolNamesJoined(analysis.ReadInside));
        }

        [Fact]
        public void TestAlwaysAssignedDuplicateVariables()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
    {
/*<bind>*/
        int a, a, b, b;
        b = 1;
/*</bind>*/
    }
}");
            Assert.Equal("b", GetSymbolNamesJoined(analysis.AlwaysAssigned));
        }

        [Fact]
        public void TestAccessedInsideOutside()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
    {
        int a, b, c, d, e, f, g, h, i;
        a = 1;
        c = b = a + x;
/*<bind>*/
        d = c;
        e = f = d;
/*</bind>*/
        g = e;
        h = i = g;
    }
}");
            Assert.Equal("c, d", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("d, e, f", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, a, e, g", GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Equal("this, x, a, b, c, g, h, i", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestAlwaysAssignedThroughParenthesizedExpression()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
    {
/*<bind>*/
        int a = 1, b, c, d, e;
        b = 2;
        (c) = 3;
        ((d)) = 4;
/*</bind>*/
    }
}");
            Assert.Equal("a, b, c, d", GetSymbolNamesJoined(analysis.AlwaysAssigned));
        }

        [Fact]
        public void TestAlwaysAssignedThroughCheckedExpression()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
    {
/*<bind>*/
        int e, f, g;
        checked(e) = 5;
        (unchecked(f)) = 5;
/*</bind>*/
    }
}");
            Assert.Equal("e, f", GetSymbolNamesJoined(analysis.AlwaysAssigned));
        }

        [Fact]
        public void TestAlwaysAssignedUsingAlternateNames()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
    {
/*<bind>*/
        int green, blue, red, yellow, brown;
        @green = 1;
        blu\u0065 = 2;
        re܏d = 3;
        yellow\uFFF9 = 4;
        @brown\uFFF9 = 5;
/*</bind>*/
    }
}");
            Assert.Equal("green, blue, red, yellow, brown", GetSymbolNamesJoined(analysis.AlwaysAssigned));
        }

        [Fact]
        public void TestAlwaysAssignedViaPassingAsOutParameter()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C {
    public void F(int x)
    {
/*<bind>*/
        int a;
        G(out a);
/*</bind>*/
    }

    void G(out int x) { x = 1; }
}");
            Assert.Equal("a", GetSymbolNamesJoined(analysis.AlwaysAssigned));
        }

        [Fact]
        public void TestAlwaysAssignedWithExcludedAssignment()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
partial class C
{
    public void F(int x)
    {
        /*<bind>*/
        int a, b;
        G(a = x = 1);
        H(b = 2);
        /*</bind>*/
    }

    partial void G(int x);
    partial void H(int x);
    partial void H(int x) { }
}");
            Assert.Equal("b", GetSymbolNamesJoined(analysis.AlwaysAssigned));
        }

        [Fact]
        public void TestDeclarationWithSelfReference()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
class C {
    static void Main()
    {
/*<bind>*/
        int x = x;
/*</bind>*/
    }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestIfStatementWithAssignments()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
class C {
    static void Main()
    {
        bool x = true;
        int y;
/*<bind>*/
        if (x) y = 1; else y = 2;
/*</bind>*/
        y.ToString();
    }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestIfStatementWithConstantCondition()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
class C {
    static void Main()
    {
        bool x = true;
        int y;
/*<bind>*/
        if (true) y = x;
/*</bind>*/
        y.ToString();
    }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestIfStatementWithNonConstantCondition()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
class C {
    static void Main()
    {
        bool x = true;
        int y;
/*<bind>*/
        if (true | x) y = x;
/*</bind>*/
        y.ToString();
    }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        //        [Obsolete]
        //        [Fact]
        //        public void TestNonStatementSelection()
        //        {
        //            var analysisResults = CompileAndAnalyzeControlAndDataFlowRegion(@"
        //class C {
        //    static void Main()
        //    {
        //        
        // /*<bind>*/
        //int
        // /*</bind>*/
        // x = 1;
        //    }
        //}
        //");
        //            var controlFlowAnalysisResults = analysisResults.Item1;
        //            var dataFlowAnalysisResults = analysisResults.Item2;
        //            Assert.True(controlFlowAnalysisResults.Succeeded);
        //            Assert.True(dataFlowAnalysisResults.Succeeded);
        //            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
        //            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
        //            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
        //            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.VariablesDeclared));
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.DataFlowsIn));
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.DataFlowsOut));
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.ReadInside));
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.ReadOutside));
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.WrittenInside));
        //            Assert.Equal("x", GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.WrittenOutside));
        //        }

        [Fact]
        public void TestInvocation()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
class C {
    static void Main()
    {
        int x = 1, y = 1;
/*<bind>*/
        Goo(x);
/*</bind>*/
    }

    static void Goo(int x) { }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestInvocationWithAssignmentInArguments()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
class C {
    static void Main()
    {
        int x = 1, y = 1;
/*<bind>*/
        Goo(x = y, y = 2);
/*</bind>*/
        int z = x + y;
    }

    static void Goo(int x, int y) { }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y, z", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact, WorkItem(538979, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538979")]
        public void AssertFromInvalidLocalDeclaration()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System;
public class MyClass
{
    public static int Main()
    {
       variant /*<bind>*/ v = new byte(2) /*</bind>*/;   // CS0246
        byte b = v;              // CS1729
        return 1;
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
        }

        [Fact, WorkItem(538979, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538979")]
        public void AssertFromInvalidKeywordAsExpr()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
class B : A
{
    public float M()
    {
/*<bind>*/
        {
            return base; // CS0175
        }
/*</bind>*/
    }
}

class A {}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            //var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(1, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.False(controlFlowAnalysisResults.EndPointIsReachable);
        }

        [WorkItem(539071, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539071")]
        [Fact]
        public void AssertFromFoldConstantEnumConversion()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
enum E { x, y, z }

class Test
{
    static int Main()
    {
/*<bind>*/
        E v = E.x;
        if (v != (E)((int)E.z - 1))
            return 0;
/*</bind>*/
        return 1;
    }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            //var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(1, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
        }

        [Fact]
        public void ByRefParameterNotInAppropriateCollections2()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    void Test<T>(ref T t)
    {
/*<bind>*/
        T t1 = GetValue<T>(ref t);
/*</bind>*/
        System.Console.WriteLine(t1.ToString());
    }
    T GetValue<T>(ref T t)
    {
        return t;
    }
}
");
            Assert.Equal("t1", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("t1", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("this, t", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("t, t1", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, t", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("t, t1", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("t, t1", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, t", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void UnreachableDeclaration()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    void F()
    {
/*<bind>*/
        int x;
/*</bind>*/
        System.Console.WriteLine(x);
    }
}
");
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void Parameters01()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    void F(int x, ref int y, out int z)
    {
/*<bind>*/
        y = z = 3;
/*</bind>*/
    }
}
");
            Assert.Equal("y, z", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("y, z", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("y, z", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(528308, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528308")]
        [Fact]
        public void RegionForIfElseIfWithoutElse()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;
public class Test
{
    ushort TestCase(ushort p)
    {
        /*<bind>*/
        if (p > 0)
        {
            return --p;
        }
        else if (p < 0)
        {
            return ++p;
        }
        /*</bind>*/
        // else
        {
            return 0;
        }
    }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Empty(controlFlowAnalysisResults.EntryPoints);
            Assert.Equal(2, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("p", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("p", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("p", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, p", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        //        [Obsolete]
        //        [Fact]
        //        public void TestBadRegion()
        //        {
        //            var analysisResults = CompileAndAnalyzeControlAndDataFlowRegion(@"
        //class C {
        //    static void Main()
        //    {
        //        int a = 1;
        //        int b = 1;
        // 
        //        if(a > 1)
        // /*<bind>*/
        //            a = 1;
        //        b = 2;
        // /*</bind>*/
        //    }
        //}
        //");
        //            var controlFlowAnalysisResults = analysisResults.Item1;
        //            var dataFlowAnalysisResults = analysisResults.Item2;
        //            Assert.False(controlFlowAnalysisResults.Succeeded);
        //            Assert.False(dataFlowAnalysisResults.Succeeded);
        //            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
        //            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
        //            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
        //            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.VariablesDeclared));
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.AlwaysAssigned));
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.DataFlowsIn));
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.DataFlowsOut));
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.ReadInside));
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.ReadOutside));
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.WrittenInside));
        //            Assert.Null(GetSymbolNamesSortedAndJoined(dataFlowAnalysisResults.WrittenOutside));
        //        }

        [WorkItem(541331, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541331")]
        [Fact]
        public void AttributeOnAccessorInvalid()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;

public class C
{
    public class AttributeX : Attribute { }

    public int Prop
    {
        get /*<bind>*/{ return 1; }/*</bind>*/
        protected [AttributeX] set { }
    }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            Assert.Empty(controlFlowAnalysisResults.EntryPoints);
            Assert.Equal(1, controlFlowAnalysisResults.ExitPoints.Count());
        }

        [WorkItem(541585, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541585")]
        [Fact]
        public void BadAssignThis()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
class Program
{
    static void Main(string[] args)
    {
        /*<bind>*/
         this = new S();
        /*</bind>*/
    }
}
 
struct S
{
}");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ReturnStatements.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(528623, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528623")]
        [Fact]
        public void TestElementAccess01()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
public class Test 
{
    public void M(long[] p)
    { 
        var v = new long[] { 1, 2, 3 };
/*<bind>*/
        v[0] = p[0];
        p[0] = v[1];
/*</bind>*/
        v[1] = v[0];
        p[2] = p[0];
    }    
}
");
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("p, v", GetSymbolNamesJoined(analysis.DataFlowsIn));
            // By Design
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));
            Assert.Equal("p, v", GetSymbolNamesJoined(analysis.ReadInside));
            // By Design
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("p, v", GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Equal("this, p, v", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [WorkItem(541947, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541947")]
        [Fact]
        public void BindPropertyAccessorBody()
        {
            var results = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;
public class A
{
     public int P
     {
       get /*<bind>*/ { return 0; } /*</bind>*/
     }
}
");

            var ctrlFlows = results.Item1;
            var dataFlows = results.Item2;

            Assert.False(ctrlFlows.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlows.VariablesDeclared));
        }

        [WorkItem(8926, "DevDiv_Projects/Roslyn")]
        [WorkItem(542346, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542346")]
        [WorkItem(528775, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528775")]
        [Fact]
        public void BindEventAccessorBody()
        {
            var results = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;
public class A
{
    public delegate void D();
    public event D E
    {
        add { /*NA*/ }
        remove /*<bind>*/ { /*NA*/ } /*</bind>*/
    }
}
");

            var ctrlFlows = results.Item1;
            var dataFlows = results.Item2;

            Assert.True(ctrlFlows.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlows.VariablesDeclared));
        }

        [WorkItem(541980, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541980")]
        [Fact]
        public void BindDuplicatedAccessor()
        {
            var results = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;
public class A
{
    public int P
    {
        get { return 1;}
        get /*<bind>*/ { return 0; } /*</bind>*/
    }
}
");

            var ctrlFlows = results.Item1;
            var dataFlows = results.Item2;

            var tmp = ctrlFlows.EndPointIsReachable; // ensure no exception thrown
            Assert.Empty(dataFlows.VariablesDeclared);
        }

        [WorkItem(543737, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543737")]
        [Fact]
        public void BlockSyntaxInAttributeDecl()
        {
            {
                var compilation = CreateCompilation(@"
[Attribute(delegate.Class)] 
public class C {
  public static int Main () {
    return 1;
  }
}
");
                var tree = compilation.SyntaxTrees.First();
                var index = tree.GetCompilationUnitRoot().ToFullString().IndexOf(".Class)", StringComparison.Ordinal);
                var tok = tree.GetCompilationUnitRoot().FindToken(index);
                var node = tok.Parent as StatementSyntax;
                Assert.Null(node);
            }
            {
                var results = CompileAndAnalyzeControlAndDataFlowStatements(@"
[Attribute(x => { /*<bind>*/int y = 12;/*</bind>*/ })] 
public class C {
  public static int Main () {
    return 1;
  }
}
");
                Assert.False(results.Item1.Succeeded);
                Assert.False(results.Item2.Succeeded);
            }
        }

        [Fact, WorkItem(529273, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529273")]
        public void IncrementDecrementOnNullable()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class C
{
    void M(ref sbyte p1, ref sbyte? p2)
    {
        byte? local_0 = 2;
        short? local_1;
        ushort non_nullable = 99;

        /*<bind>*/
        p1++;
        p2 = (sbyte?) (local_0.Value - 1);
        local_1 = (byte)(p2.Value + 1);
        var ret = local_1.HasValue ? local_1.Value : 0;
        --non_nullable;
        /*</bind>*/
    }
}
");
            Assert.Equal("ret", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("p1, p2, local_1, non_nullable, ret", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("p1, local_0, non_nullable", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("p1, p2", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("p1, p2, local_0, local_1, non_nullable", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("p1, p2", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("p1, p2, local_1, non_nullable, ret", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, p1, p2, local_0, non_nullable", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(17971, "https://github.com/dotnet/roslyn/issues/17971")]
        [Fact]
        public void VariablesDeclaredInBrokenForeach()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
struct S
{
    static void Main(string[] args)
    {
/*<bind>*/
        Console.WriteLine(1);
        foreach ()
        Console.WriteLine(2);
/*</bind>*/
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
        }

        [Fact]
        [WorkItem(4950, "https://github.com/dotnet/roslyn/issues/4950")]
        public void RegionWithUnsafeBlock()
        {
            var source =
@"using System;
class Program {
    static void Main(string[] args) {
        object value = args;

        // start
        IntPtr p;
        unsafe
        {
            object t = value;
            p = IntPtr.Zero;
        }
        // end

        Console.WriteLine(p);
    }
}
";
            foreach (string keyword in new[] { "unsafe", "checked", "unchecked" })
            {
                var compilation = CreateCompilation(source.Replace("unsafe", keyword));
                var tree = compilation.SyntaxTrees[0];
                var model = compilation.GetSemanticModel(tree);

                var stmt1 = tree.GetCompilationUnitRoot().DescendantNodesAndSelf().OfType<StatementSyntax>().Where(n => n.ToString() == "IntPtr p;").Single();
                var stmt2 = tree.GetCompilationUnitRoot().DescendantNodesAndSelf().OfType<StatementSyntax>().Where(n => n.ToString().StartsWith(keyword)).First();

                var dataFlowAnalysisResults = model.AnalyzeDataFlow(stmt1, stmt2);
                Assert.True(dataFlowAnalysisResults.Succeeded);
                Assert.Equal("p, t", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
                Assert.Equal("p, t", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
                Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
                Assert.Equal("value", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
                Assert.Equal("p", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
                Assert.Equal("args, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
                Assert.Equal("args, value, p, t", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
                Assert.Equal("value", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
                Assert.Equal("args, p", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
                Assert.Equal("p, t", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
                Assert.Equal("args, value", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            }
        }

        #endregion

        #region "lambda"

        [Fact]
        [WorkItem(41600, "https://github.com/dotnet/roslyn/pull/41600")]
        public void DataFlowAnalysisLocalFunctions10()
        {
            var dataFlow = CompileAndAnalyzeDataFlowExpression(@"
class C
{
    public void M()
    {
        bool Dummy(params object[] x) {return true;}

        try {}
        catch when (/*<bind>*/TakeOutParam(out var x1)/*</bind>*/ && x1 > 0)
        {
            Dummy(x1);
        }

        var x4 = 11;
        Dummy(x4);

        try {}
        catch when (TakeOutParam(out var x4) && x4 > 0)
        {
            Dummy(x4);
        }

        try {}
        catch when (x6 && TakeOutParam(out var x6))
        {
            Dummy(x6);
        }

        try {}
        catch when (TakeOutParam(out var x7) && x7 > 0)
        {
            var x7 = 12;
            Dummy(x7);
        }

        try {}
        catch when (TakeOutParam(out var x8) && x8 > 0)
        {
            Dummy(x8);
        }

        System.Console.WriteLine(x8);

        try {}
        catch when (TakeOutParam(out var x9) && x9 > 0)
        {   
            Dummy(x9);
            try {}
            catch when (TakeOutParam(out var x9) && x9 > 0) // 2
            {
                Dummy(x9);
            }
        }

        try {}
        catch when (TakeOutParam(y10, out var x10))
        {   
            var y10 = 12;
            Dummy(y10);
        }

        //    try {}
        //    catch when (TakeOutParam(y11, out var x11)
        //    {   
        //        let y11 = 12;
        //        Dummy(y11);
        //    }

        try {}
        catch when (Dummy(TakeOutParam(out var x14), 
                            TakeOutParam(out var x14), // 2
                            x14))
        {
            Dummy(x14);
        }

        try {}
        catch (System.Exception x15)
                when (Dummy(TakeOutParam(out var x15), x15))
        {
            Dummy(x15);
        }

        static bool TakeOutParam(out int x) 
        {
            x = 123;
            return true;
        }
        static bool TakeOutParam(object y, out int x)
        {
            x = 123;
            return true;
        }

    }
}
");
            Assert.True(dataFlow.Succeeded);
            Assert.Null(GetSymbolNamesJoined(dataFlow.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlow.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlow.CapturedOutside));
            Assert.Equal("x1", GetSymbolNamesJoined(dataFlow.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlow.DataFlowsIn));
            Assert.Equal("x1", GetSymbolNamesJoined(dataFlow.DataFlowsOut));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlow.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x1", GetSymbolNamesJoined(dataFlow.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(dataFlow.ReadInside));
            Assert.Equal("x1", GetSymbolNamesJoined(dataFlow.WrittenInside));
            Assert.Equal("this, x1, x4, x4, x6, x7, x7, x8, x9, x9, y10, x14, x15, x, x",
                GetSymbolNamesJoined(dataFlow.ReadOutside));
            Assert.Equal("this, x, x4, x4, x6, x7, x7, x8, x9, x9, x10, " +
                         "y10, x14, x14, x15, x15, x, y, x",
                GetSymbolNamesJoined(dataFlow.WrittenOutside));
        }

        [Fact]
        [WorkItem(39946, "https://github.com/dotnet/roslyn/issues/39946")]
        public void DataFlowAnalysisLocalFunctions9()
        {
            var results = CompileAndAnalyzeControlAndDataFlowStatements(@"
class C
{
    int Testing;

    void M()
    {
        local();

        /*<bind>*/
        NewMethod();
        /*</bind>*/
        
        Testing = 5;

        void local()
        { }
    }

    void NewMethod()
    {
    }
}");
            var dataFlow = results.dataFlowAnalysis;
            Assert.True(dataFlow.Succeeded);
            Assert.Null(GetSymbolNamesJoined(dataFlow.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlow.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlow.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlow.VariablesDeclared));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlow.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlow.DataFlowsOut));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlow.DefinitelyAssignedOnEntry));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlow.DefinitelyAssignedOnExit));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlow.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlow.WrittenInside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlow.ReadOutside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlow.WrittenOutside));

            var controlFlow = results.controlFlowAnalysis;
            Assert.True(controlFlow.Succeeded);
            Assert.True(controlFlow.EndPointIsReachable);
        }

        [Fact]
        [WorkItem(39946, "https://github.com/dotnet/roslyn/issues/39946")]
        public void ControlFlowAnalysisLocalFunctions01()
        {
            var controlFlow = CompileAndAnalyzeControlFlowStatements(@"
class C
{
    void M()
    {
        local();

        /*<bind>*/
        System.Console.WriteLine(0);
        /*</bind>*/

        void local()
        {
            throw null;
        }
    }
}");

            Assert.True(controlFlow.Succeeded);
            Assert.False(controlFlow.StartPointIsReachable);
            Assert.False(controlFlow.EndPointIsReachable);
        }

        [Fact]
        [WorkItem(39946, "https://github.com/dotnet/roslyn/issues/39946")]
        public void ControlFlowAnalysisLocalFunctions02()
        {
            var controlFlow = CompileAndAnalyzeControlFlowStatements(@"
class C
{
    void M()
    {
        /*<bind>*/
        local();
        System.Console.WriteLine(0);
        /*</bind>*/

        void local()
        {
            throw null;
        }
    }
}");

            Assert.True(controlFlow.Succeeded);
            Assert.True(controlFlow.StartPointIsReachable);
            Assert.False(controlFlow.EndPointIsReachable);
        }

        [Fact]
        [WorkItem(39946, "https://github.com/dotnet/roslyn/issues/39946")]
        public void ControlFlowAnalysisLocalFunctions03()
        {
            var controlFlow = CompileAndAnalyzeControlFlowStatements(@"
class C
{
    void M()
    {
        /*<bind>*/
        System.Console.WriteLine(0);
        /*</bind>*/
        local();

        void local()
        {
            throw null;
        }
    }
}");

            Assert.True(controlFlow.Succeeded);
            Assert.True(controlFlow.StartPointIsReachable);
            Assert.True(controlFlow.EndPointIsReachable);
        }

        [Fact]
        [WorkItem(39946, "https://github.com/dotnet/roslyn/issues/39946")]
        public void ControlFlowAnalysisLocalFunctions04()
        {
            var controlFlow = CompileAndAnalyzeControlFlowStatements(@"
class C
{
    void M()
    {
        System.Console.WriteLine(0);
        local();

        void local()
        {
            /*<bind>*/
            throw null;
            /*</bind>*/
        }
    }
}");

            Assert.True(controlFlow.Succeeded);
            Assert.True(controlFlow.StartPointIsReachable);
            Assert.False(controlFlow.EndPointIsReachable);
        }

        [Fact]
        [WorkItem(39946, "https://github.com/dotnet/roslyn/issues/39946")]
        public void ControlFlowAnalysisLocalFunctions05()
        {
            var controlFlow = CompileAndAnalyzeControlFlowStatements(@"
class C
{
    void M()
    {
        local();

        void local()
        {
            /*<bind>*/
            System.Console.WriteLine(0);
            /*</bind>*/
            throw null;
        }
    }
}");

            Assert.True(controlFlow.Succeeded);
            Assert.True(controlFlow.StartPointIsReachable);
            Assert.True(controlFlow.EndPointIsReachable);
        }

        [Fact]
        [WorkItem(39946, "https://github.com/dotnet/roslyn/issues/39946")]
        public void ControlFlowAnalysisLocalFunctions06()
        {
            var controlFlow = CompileAndAnalyzeControlFlowStatements(@"
class C
{
    void M()
    {
        void local()
        {
            throw null;
        }

        /*<bind>*/
        System.Console.WriteLine(0);
        /*</bind>*/
    }
}");

            Assert.True(controlFlow.Succeeded);
            Assert.True(controlFlow.StartPointIsReachable);
            Assert.True(controlFlow.EndPointIsReachable);
        }

        [Fact]
        public void TestReturnStatements03()
        {
            var analysis = CompileAndAnalyzeControlFlowStatements(@"
using System;
class C {
    public void F(int x)
    {
        if (x == 0) return;
/*<bind>*/
        if (x == 1) return;
        Func<int,int> f = (int i) => { return i+1; };
        if (x == 2) return;
/*</bind>*/
    }
}");
            Assert.Equal(2, analysis.ExitPoints.Count());
        }

        [Fact]
        public void TestReturnStatements04()
        {
            var analysis = CompileAndAnalyzeControlFlowStatements(@"
using System;
class C {
    public void F(int x)
    {
        if (x == 0) return;
        if (x == 1) return;
        Func<int,int> f = (int i) =>
        {
/*<bind>*/
            return i+1;
/*</bind>*/
        }
        ;
        if (x == 2) return;
    }
}");
            Assert.Equal(1, analysis.ExitPoints.Count());
        }

        [Fact]
        public void TestReturnStatements05()
        {
            var analysis = CompileAndAnalyzeControlFlowStatements(@"
using System;
class C {
    public void F(int x)
    {
        if (x == 0) return;
        if (x == 1) return;
/*<bind>*/
        Func<int,int?> f = (int i) =>
        {
            return i == 1 ? i+1 : null;
        }
        ;
/*</bind>*/
        if (x == 2) return; 
    }
}");
            Assert.True(analysis.Succeeded);
            Assert.Empty(analysis.ReturnStatements);
        }

        [Fact]
        public void TestReturnStatements06()
        {
            var analysis = CompileAndAnalyzeControlFlowStatements(@"
        using System;
        class C {
            public void F(uint? x)
            {
                if (x == null) return;
                if (x.Value == 1) return;
        /*<bind>*/
                Func<uint?, ulong?> f = (i) =>
                {
                    return i.Value +1;
                }
                ;
                if (x.Value == 2) return;
        /*</bind>*/
            }
        }");

            Assert.True(analysis.Succeeded);
            Assert.Equal(1, analysis.ExitPoints.Count());
        }

        [WorkItem(541198, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541198")]
        [Fact]
        public void TestReturnStatements07()
        {
            var analysis = CompileAndAnalyzeControlFlowStatements(@"
using System;
class C {
    public int F(int x)
    {
        Func<int,int> f = (int i) =>
        {
        goto XXX;
/*<bind>*/
        return 1;
/*</bind>*/
        }
        ;
    }
}");
            Assert.Equal(1, analysis.ExitPoints.Count());
        }

        [Fact]
        public void TestMultipleLambdaExpressions()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C
{
    void M()
    {
        int i;
        N(/*<bind>*/() => { M(); }/*</bind>*/, () => { i++; });
    }
    void N(System.Action x, System.Action y) { }
}");

            Assert.True(analysis.Succeeded);
            Assert.Equal("this, i", GetSymbolNamesJoined(analysis.Captured));
            Assert.Equal("this", GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Equal("i", GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Equal("this", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("this", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact, WorkItem(53591, "https://github.com/dotnet/roslyn/issues/53591")]
        public void TestNameOfInLambda()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C
{
    void M()
    {
        Func<string> x = /*<bind>*/() => nameof(ClosureCreated)/*</bind>*/;
    }
}");

            Assert.True(analysis.Succeeded);
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
        }

        [Fact, WorkItem(53591, "https://github.com/dotnet/roslyn/issues/53591")]
        public void TestNameOfWithAssignmentInLambda()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C
{
    void M()
    {
        Func<string> x = /*<bind>*/() => nameof(this = null)/*</bind>*/;
    }
}");

            Assert.True(analysis.Succeeded);
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
        }

        [Fact, WorkItem(53591, "https://github.com/dotnet/roslyn/issues/53591")]
        public void TestUnreachableThisInLambda()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C
{
    void M()
    {
        Func<string> x = /*<bind>*/() => false ? this.ToString() : string.Empty/*</bind>*/;
    }
}");

            Assert.True(analysis.Succeeded);
            Assert.Equal("this", GetSymbolNamesJoined(analysis.Captured));
            Assert.Equal("this", GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
        }

        [Fact]
        public void TestReturnFromLambda()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;
using System.Linq;
class Program
{
    static void Main(string[] args)
    {
        int i = 1;
        Func<int> lambda = () => { /*<bind>*/return i;/*</bind>*/ };
    }
}
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(1, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.False(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("args, i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("args, i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("args, i, lambda", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void DataFlowsOutLambda01()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;

delegate void D();
class Program
{
    static void Main(string[] args)
    {
        int i = 12;
        D d = () => {
            /*<bind>*/
            i = 14;
            return;
            /*</bind>*/
        };
        int j = i;
    }
}
");
            //var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("args, i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("args, i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void DataFlowsOutLambda02()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;

delegate void D();
class Program
{
    static void Main()
    {
        int? i = 12;
        D d = () => {
            /*<bind>*/
            i = 14;
            /*</bind>*/
            return;
        };
        int j = i.Value;
    }
}
");
            //var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
        }

        [Fact]
        public void DataFlowsOutLambda03()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;

delegate void D();
class Program
{
    static void Main(string[] args)
    {
        int i = 12;
        D d = () => {
            /*<bind>*/
            i = 14;
            /*</bind>*/
        };
        int j = i;
    }
}
");
            //var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("args, i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("args, i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
        }

        [WorkItem(538984, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538984")]
        [Fact]
        public void TestReadInside02()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class A
{
    void Method()
    {
        System.Func<int, int> a = x => /*<bind>*/x * x/*</bind>*/;
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, a, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestCaptured02()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
using System;
class C
{
    int field = 123;
    public void F(int x)
    {
        const int a = 1, y = 1;
/*<bind>*/
        Func<int> lambda = () => x + y + field;
/*</bind>*/
        int c = a + 4 + y;
    }
}");
            Assert.Equal("this, x", GetSymbolNamesJoined(analysis.Captured));
            Assert.Equal("this, x", GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("this, x, a, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x, a, y, lambda", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
        }

        [Fact, WorkItem(539648, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539648"), WorkItem(529185, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529185")]
        public void ReturnsInsideLambda()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;
class Program
{
    delegate R Func<T, R>(T t);
    static void Main(string[] args)
    {
        /*<bind>*/
        Func<int, int> f = (arg) =>
        {
            int s = 3;
            return s;
        };
        /*</bind>*/
        f.Invoke(2);
    }
}");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Empty(controlFlowAnalysisResults.ReturnStatements);
            Assert.Equal("f", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("args, f", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("f, arg, s", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
        }

        [WorkItem(539861, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539861")]
        [Fact]
        public void VariableDeclaredLambda01()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;
class Program
{
     delegate void TestDelegate(ref int x);
     static void Main(string[] args)
    {
        /*<bind>*/
        TestDelegate testDel = (ref int x) => {  };
        /*</bind>*/
        int p = 2;
        testDel(ref p);
        Console.WriteLine(p);
    }
}
");
            //var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("args, testDel", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("testDel, x", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("testDel, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
        }

        [WorkItem(539861, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539861")]
        [Fact]
        public void VariableDeclaredLambda02()
        {
            var results1 = CompileAndAnalyzeDataFlowStatements(@"
using System;
class Program
{
    delegate void TestDelegate(ref int? x);
    static void Main()
    {
        /*<bind>*/
        TestDelegate testDel = (ref int? x) => { int y = x; x.Value = 10; };
        /*</bind>*/
        int? p = 2;
        testDel(ref p);
        Console.WriteLine(p);
    }
}
");

            Assert.Equal("testDel, x, y", GetSymbolNamesJoined(results1.VariablesDeclared));
            Assert.Equal("testDel", GetSymbolNamesJoined(results1.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(results1.Captured));
            Assert.Null(GetSymbolNamesJoined(results1.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results1.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results1.DataFlowsIn));
            Assert.Equal("testDel", GetSymbolNamesJoined(results1.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results1.DefinitelyAssignedOnEntry));
            Assert.Equal("testDel", GetSymbolNamesJoined(results1.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(results1.ReadInside));
            Assert.Equal("testDel, p", GetSymbolNamesJoined(results1.ReadOutside));
            Assert.Equal("testDel, x, y", GetSymbolNamesJoined(results1.WrittenInside));
            Assert.Equal("p", GetSymbolNamesJoined(results1.WrittenOutside));
        }

        [WorkItem(540449, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540449")]
        [Fact]
        public void AnalysisInsideLambdas()
        {
            var results1 = CompileAndAnalyzeDataFlowExpression(@"
using System;
class C {
    static void Main()
    {
        Func<int, int> f = p => 
        {
            int x = 1;
            int y = 1;
            return /*<bind>*/1 + (x=2) + p + y/*</bind>*/;
        };
    }
}
");

            Assert.Equal("x", GetSymbolNamesJoined(results1.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(results1.Captured));
            Assert.Null(GetSymbolNamesJoined(results1.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results1.CapturedOutside));
            Assert.Equal("p, y", GetSymbolNamesJoined(results1.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(results1.DataFlowsOut));
            Assert.Equal("p, x, y", GetSymbolNamesJoined(results1.DefinitelyAssignedOnEntry));
            Assert.Equal("p, x, y", GetSymbolNamesJoined(results1.DefinitelyAssignedOnExit));
            Assert.Equal("p, y", GetSymbolNamesJoined(results1.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results1.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(results1.WrittenInside));
            Assert.Equal("f, p, x, y", GetSymbolNamesJoined(results1.WrittenOutside));
        }

        [WorkItem(528622, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528622")]
        [Fact]
        public void AlwaysAssignedParameterLambda()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(@"
using System;

internal class Test
{
    void M(sbyte[] ary)
    {
        /*<bind>*/
        ( (Action<short>)(x => { Console.Write(x); }) 
        )(ary[0])/*</bind>*/;
    }
}
");

            Assert.Null(GetSymbolNamesJoined(dataFlows.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlows.Captured));
            Assert.Equal("ary", GetSymbolNamesJoined(dataFlows.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsOut));
            Assert.Equal("this, ary", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("this, ary", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
            Assert.Equal("ary, x", GetSymbolNamesJoined(dataFlows.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlows.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.ReadOutside));
            Assert.Equal("this, ary", GetSymbolNamesJoined(dataFlows.WrittenOutside));
        }

        [WorkItem(541946, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541946")]
        [Fact]
        public void LambdaInTernaryWithEmptyBody()
        {
            var results = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;

public delegate void D();
public class A
{
    void M()
    {
        int i = 0;
/*<bind>*/
        D d = true ? (D)delegate { i++; } : delegate {  };
/*</bind>*/
    }
}
");

            var ctrlFlows = results.Item1;
            var dataFlows = results.Item2;

            Assert.True(ctrlFlows.EndPointIsReachable);
            Assert.Equal("d", GetSymbolNamesJoined(dataFlows.VariablesDeclared));
            Assert.Equal("d", GetSymbolNamesJoined(dataFlows.AlwaysAssigned));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlows.Captured));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlows.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.CapturedOutside));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlows.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlows.DataFlowsOut));
            Assert.Equal("this, i", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnEntry));
            Assert.Equal("this, i, d", GetSymbolNamesJoined(dataFlows.DefinitelyAssignedOnExit));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlows.ReadInside));
            Assert.Equal("i, d", GetSymbolNamesJoined(dataFlows.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(dataFlows.ReadOutside));
            Assert.Equal("this, i", GetSymbolNamesJoined(dataFlows.WrittenOutside));
        }

        [Fact]
        public void ForEachVariableInLambda()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System;
class Program
{
    static void Main()
    {
        var nums = new int?[] { 4, 5 };

        foreach (var num in /*<bind>*/nums/*</bind>*/)
        {
            Func<int, int> f = x => x + num.Value;
            Console.WriteLine(f(0));
        }
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("num", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Equal("num", GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("num, f, x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("nums, num, f, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(543398, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543398")]
        [Fact]
        public void LambdaBlockSyntax()
        {
            var source = @"
using System;
class c1
{
    void M()
    {
        var a = 0;

        foreach(var l in """")
        {
            Console.WriteLine(l);
            a = (int) l;
            l = (char) a;
        }

        Func<int> f = ()=>
        {
            var c = a; a = c; return 0;
        };

        var b = 0;
        Console.WriteLine(b);
    }
}";
            var tree = SyntaxFactory.ParseSyntaxTree(source);
            var comp = CSharpCompilation.Create("FlowAnalysis", syntaxTrees: new[] { tree });
            var model = comp.GetSemanticModel(tree);

            var methodBlock = tree.GetCompilationUnitRoot().DescendantNodes().OfType<BlockSyntax>().First();
            var foreachStatement = methodBlock.DescendantNodes().OfType<ForEachStatementSyntax>().First();
            var foreachBlock = foreachStatement.DescendantNodes().OfType<BlockSyntax>().First();
            var lambdaExpression = methodBlock.DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>().First();
            var lambdaBlock = lambdaExpression.DescendantNodes().OfType<BlockSyntax>().First();

            var flowAnalysis = model.AnalyzeDataFlow(methodBlock);
            Assert.Equal(4, flowAnalysis.ReadInside.Count());
            Assert.Equal(5, flowAnalysis.WrittenInside.Count());
            Assert.Equal(5, flowAnalysis.VariablesDeclared.Count());

            flowAnalysis = model.AnalyzeDataFlow(foreachBlock);
            Assert.Equal(2, flowAnalysis.ReadInside.Count());
            Assert.Equal(2, flowAnalysis.WrittenInside.Count());
            Assert.Equal(0, flowAnalysis.VariablesDeclared.Count());

            flowAnalysis = model.AnalyzeDataFlow(lambdaBlock);
            Assert.Equal(2, flowAnalysis.ReadInside.Count());
            Assert.Equal(2, flowAnalysis.WrittenInside.Count());
            Assert.Equal(1, flowAnalysis.VariablesDeclared.Count());
        }

        [Fact]
        public void StaticLambda_01()
        {
            var source = @"
using System;

class C
{
    static void Main()
    {
        int x = 42;
        Action fn = static () => Console.Write(x);
        fn();
    }
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (9,48): error CS8820: A static anonymous function cannot contain a reference to 'x'.
                //         Action fn = static () => Console.Write(x);
                Diagnostic(ErrorCode.ERR_StaticAnonymousFunctionCannotCaptureVariable, "x").WithArguments("x").WithLocation(9, 48)
                );

            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);

            var root = tree.GetRoot();
            var node = root.DescendantNodes().OfType<LambdaExpressionSyntax>().Single();

            var flowAnalysis = model.AnalyzeDataFlow(node);

            Assert.Equal("x", GetSymbolNamesJoined(flowAnalysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(flowAnalysis.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(flowAnalysis.VariablesDeclared));
        }

        [Fact]
        public void StaticLambda_02()
        {
            var source = @"
using System;

class C
{
    static void Main()
    {
        int x = 42;
        Action fn = static () =>
        {
            int y = x;
            x = 43;
            Console.Write(y);
        };
        fn();
    }
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (11,21): error CS8820: A static anonymous function cannot contain a reference to 'x'.
                //             int y = x;
                Diagnostic(ErrorCode.ERR_StaticAnonymousFunctionCannotCaptureVariable, "x").WithArguments("x").WithLocation(11, 21),
                // (12,13): error CS8820: A static anonymous function cannot contain a reference to 'x'.
                //             x = 43;
                Diagnostic(ErrorCode.ERR_StaticAnonymousFunctionCannotCaptureVariable, "x").WithArguments("x").WithLocation(12, 13)
                );

            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);

            var root = tree.GetRoot();
            var node = root.DescendantNodes().OfType<LambdaExpressionSyntax>().Single();

            var flowAnalysis = model.AnalyzeDataFlow(node);

            Assert.Equal("x, y", GetSymbolNamesJoined(flowAnalysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(flowAnalysis.WrittenInside));
            Assert.Equal("y", GetSymbolNamesJoined(flowAnalysis.VariablesDeclared));
        }

        [Fact]
        public void StaticLambda_03()
        {
            var source = @"
using System;

class C
{
    public static int x = 42;
    static void Main()
    {
        Action fn = static () =>
        {
            int y = x;
            x = 43;
            Console.Write(y);
        };
        fn();
    }
}
";
            verify(source);
            verify(source.Replace("static (", "("));

            void verify(string source)
            {
                var verifier = CompileAndVerify(source, parseOptions: TestOptions.Regular9, expectedOutput: "42");
                verifier.VerifyDiagnostics();

                var comp = verifier.Compilation;
                var tree = comp.SyntaxTrees.Single();
                var model = comp.GetSemanticModel(tree);

                var root = tree.GetRoot();
                var node = root.DescendantNodes().OfType<LambdaExpressionSyntax>().Single();

                var flowAnalysis = model.AnalyzeDataFlow(node);

                Assert.Equal("y", GetSymbolNamesJoined(flowAnalysis.ReadInside));
                Assert.Equal("y", GetSymbolNamesJoined(flowAnalysis.WrittenInside));
                Assert.Equal("y", GetSymbolNamesJoined(flowAnalysis.VariablesDeclared));
            }
        }

        #endregion

        #region "query expressions"

        [Fact]
        public void QueryExpression01()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var nums = new int[] { 1, 2, 3, 4 };
/*<bind>*/
        var q2 = from x in nums
                where (x > 2)
                where x > 3
                select x;
/*</bind>*/
    }
}");
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal("q2, x", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("q2", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("nums, q2", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("nums, x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("q2, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void QueryExpression02()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var nums = new sbyte[] { 1, 2, 3, 4 };

        var q2 = from x in nums
                where (x > 2)
                select /*<bind>*/ x+1 /*</bind>*/;
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("nums, x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("nums, q2, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void QueryExpression03()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var nums = new int?[] { 1, 2, null, 4 };
        var q2 = from x in nums
                 group x.Value + 1 by /*<bind>*/ x.Value % 2 /*</bind>*/;
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("nums, x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("nums, q2, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void QueryExpression04()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var nums = new uint[] { 1, 2, 3, 4 };
        var q2 = from int x in nums where x < 3 select /*<bind>*/ x /*</bind>*/;
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("nums, x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("nums, q2, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void QueryExpression05()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var nums = new sbyte[] { 1, 2, 3, 4 };
        var q2 = from int x in nums where x < 3 group /*<bind>*/ x /*</bind>*/ by x%2;
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("nums, x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("nums, q2, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(541916, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541916")]
        [Fact]
        public void ForEachVariableInQueryExpr()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var nums = new int[] { 4, 5 };

        foreach (var num in nums)
        {
            var q = from n in /*<bind>*/ nums /*</bind>*/ select num;
        }
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("num", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Equal("num", GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("nums, num", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("nums, num", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("nums, num", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("nums, num, q, n", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(541945, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541945")]
        [Fact]
        public void ForVariableInQueryExpr()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var nums = new int[] { 4, 5 };

        for (int num = 0; num < 10; num++)
        {
            var q = from n in /*<bind>*/ nums /*</bind>*/ select num;
        }
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("num", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("nums, num", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("nums, num", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("nums", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("num", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("nums, num, q, n", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(541926, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541926")]
        [Fact]
        public void Bug8863()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System.Linq;
class C
{
    static void Main(string[] args)
    {
        /*<bind>*/
        var temp = from x in ""abc""
                   let z = x.ToString()
                   select z into w
                   select w;
        /*</bind>*/
    }
}");
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal("temp, x, z, w", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("temp", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("args, temp", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("x, z, w", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("temp, x, z, w", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void Bug9415()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System;
using System.Collections.Generic;
using System.Linq;
 
class Program
{
    static void Main(string[] args)
    {
        var q1 = from x in new int[] { /*<bind>*/4/*</bind>*/, 5 }
                 orderby x
                 select x;
    }
}");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("args, q1, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(543546, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543546")]
        [Fact]
        public void GroupByClause()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System.Linq;

public class Test
{
    public static void Main()
    {
        var strings = new string[] { };
        var q = from s in strings
                select s into t
                    /*<bind>*/group t by t.Length/*</bind>*/;
    }
}");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
        }

        [WorkItem(1291, "https://github.com/dotnet/roslyn/issues/1291")]
        [Fact]
        public void CaptureInQuery()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System.Linq;

public class Test
{
    public static void Main(int[] data)
    {
        int y = 1;
        {
            int x = 2;
            var f2 = from a in data select a + y;
            var f3 = from a in data where x > 0 select a;
            var f4 = from a in data let b = 1 where /*<bind>*/M(() => b)/*</bind>*/ select a + b;
            var f5 = from c in data where M(() => c) select c;
        }
    }
    private static bool M(Func<int> f) => true;
}");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Equal("y, x, b", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Equal("b", GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Equal("y, x", GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
        }

        #endregion query expressions

        #region "switch statement tests"

        [Fact]
        public void LocalInOtherSwitchCase()
        {
            var dataFlows = CompileAndAnalyzeDataFlowExpression(
@"using System;
using System.Linq;
public class Test
{
    public static void Main()
    {
        int ret = 6;
        switch (ret)
        {
            case 1:
                int i = 10; break;
            case 2:
                var q1 = from j in new int[] { 3, 4 } select /*<bind>*/i/*</bind>*/;
                break;
        }
    }
}");
            Assert.Empty(dataFlows.DataFlowsOut);
        }

        [WorkItem(541639, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541639")]
        [Fact]
        public void VariableDeclInsideSwitchCaptureInLambdaExpr()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System;

class C
{
    public static void Main()
    {
        switch (10)
        {
            default:
                int i = 10;
                Func<int> f1 = () => /*<bind>*/i/*</bind>*/;
                break;
        }
    }
}
");
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("i, f1", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(541710, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541710")]
        [Fact]
        public void ArrayCreationExprInForEachInsideSwitchSection()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class Program
{
    static void Main()
    {
        switch ('2')
        {
            default:
                break;
            case '2':
                foreach (var i100 in new int[] {4, /*<bind>*/5/*</bind>*/ })
                {
                }
                break;
        }
    }
}
");
            Assert.Empty(dataFlowAnalysisResults.Captured);
            Assert.Empty(dataFlowAnalysisResults.CapturedInside);
            Assert.Empty(dataFlowAnalysisResults.CapturedOutside);
            Assert.Empty(dataFlowAnalysisResults.VariablesDeclared);
            Assert.Empty(dataFlowAnalysisResults.AlwaysAssigned);
            Assert.Empty(dataFlowAnalysisResults.DataFlowsIn);
            Assert.Empty(dataFlowAnalysisResults.DataFlowsOut);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Empty(dataFlowAnalysisResults.ReadInside);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Empty(dataFlowAnalysisResults.WrittenInside);
            Assert.Equal("i100", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void RegionInsideSwitchExpression()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class Program
{
    static void Main()
    {
        switch ('2')
        {
            default:
                break;
            case '2':
                switch (/*<bind>*/'2'/*</bind>*/)
                {
                     case '2': break;
                }
                break;
        }
    }
}
");
            Assert.Empty(dataFlowAnalysisResults.Captured);
            Assert.Empty(dataFlowAnalysisResults.CapturedInside);
            Assert.Empty(dataFlowAnalysisResults.CapturedOutside);
            Assert.Empty(dataFlowAnalysisResults.VariablesDeclared);
            Assert.Empty(dataFlowAnalysisResults.AlwaysAssigned);
            Assert.Empty(dataFlowAnalysisResults.DataFlowsIn);
            Assert.Empty(dataFlowAnalysisResults.DataFlowsOut);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Empty(dataFlowAnalysisResults.ReadInside);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Empty(dataFlowAnalysisResults.WrittenInside);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void NullableAsSwitchExpression()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    public void F(ulong? p)
    {
/*<bind>*/
        switch (p)
        {
            case null:
                break;
            case 1:
                goto case null;
            default:
                break;
        }
/*</bind>*/
    }
}
");
            Assert.Empty(dataFlowAnalysisResults.Captured);
            Assert.Empty(dataFlowAnalysisResults.CapturedInside);
            Assert.Empty(dataFlowAnalysisResults.CapturedOutside);
            Assert.Empty(dataFlowAnalysisResults.VariablesDeclared);
            Assert.Empty(dataFlowAnalysisResults.AlwaysAssigned);
            Assert.Equal("p", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Empty(dataFlowAnalysisResults.DataFlowsOut);
            Assert.Equal("this, p", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, p", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("p", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Empty(dataFlowAnalysisResults.WrittenInside);
            Assert.Equal("this, p", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        [WorkItem(17281, "https://github.com/dotnet/roslyn/issues/17281")]
        public void DiscardVsVariablesDeclared()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class A { }

class Test
{
    private void Repro(A node)
    {
/*<bind>*/
        switch (node)
        {
            case A _:
                break;
            case Unknown:
                break;
            default:
                return;
        }
/*</bind>*/
    }
}");
            Assert.Empty(dataFlowAnalysisResults.Captured);
            Assert.Empty(dataFlowAnalysisResults.CapturedInside);
            Assert.Empty(dataFlowAnalysisResults.CapturedOutside);
            Assert.Empty(dataFlowAnalysisResults.VariablesDeclared);
            Assert.Empty(dataFlowAnalysisResults.AlwaysAssigned);
            Assert.Equal("node", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Empty(dataFlowAnalysisResults.DataFlowsOut);
            Assert.Equal("this, node", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, node", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("node", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Empty(dataFlowAnalysisResults.WrittenInside);
            Assert.Equal("this, node", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        #endregion

        #region "Misc."

        [Fact, WorkItem(11298, "DevDiv_Projects/Roslyn")]
        public void BaseExpressionSyntax()
        {
            var source = @"
using System;

public class BaseClass
{
    public virtual void MyMeth()
    {
    }
}

public class MyClass : BaseClass
{
    public override void MyMeth()
    {
        base.MyMeth();
    }
    delegate BaseClass D();
    public void OtherMeth()
    {
        D f = () => base;
    }
    public static void Main()
    {
    }
}";
            var comp = CreateCompilation(source);
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);

            var invocation = tree.GetCompilationUnitRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
            var flowAnalysis = model.AnalyzeDataFlow(invocation);
            Assert.Empty(flowAnalysis.Captured);
            Assert.Empty(flowAnalysis.CapturedInside);
            Assert.Empty(flowAnalysis.CapturedOutside);
            Assert.Equal("MyClass this", flowAnalysis.DataFlowsIn.Single().ToTestDisplayString());
            Assert.Empty(flowAnalysis.DataFlowsOut);
            Assert.Equal("MyClass this", flowAnalysis.ReadInside.Single().ToTestDisplayString());
            Assert.Empty(flowAnalysis.WrittenInside);
            Assert.Equal("MyClass this", flowAnalysis.WrittenOutside.Single().ToTestDisplayString());

            var lambda = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>().Single();
            flowAnalysis = model.AnalyzeDataFlow(lambda);
            Assert.Equal("MyClass this", flowAnalysis.Captured.Single().ToTestDisplayString());
            Assert.Equal("MyClass this", flowAnalysis.DataFlowsIn.Single().ToTestDisplayString());
            Assert.Empty(flowAnalysis.DataFlowsOut);
            Assert.Equal("MyClass this", flowAnalysis.ReadInside.Single().ToTestDisplayString());
            Assert.Empty(flowAnalysis.WrittenInside);
            Assert.Equal("this, f", GetSymbolNamesJoined(flowAnalysis.WrittenOutside));
        }

        [WorkItem(543101, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543101")]
        [Fact]
        public void AnalysisInsideBaseClause()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
class A
{
    A(int x) : this(/*<bind>*/x.ToString()/*</bind>*/) { }
    A(string x) { }
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [WorkItem(543758, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543758")]
        [Fact]
        public void BlockSyntaxOfALambdaInAttributeArg()
        {
            var controlFlowAnalysisResults = CompileAndAnalyzeControlFlowStatements(@"
class Test
{
    [Attrib(() => /*<bind>*/{ }/*</bind>*/)]
    public static void Main()
    {
    }
}
");
            Assert.False(controlFlowAnalysisResults.Succeeded);
        }

        [WorkItem(529196, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529196")]
        [Fact()]
        public void DefaultValueOfOptionalParam()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
public class Derived
{
    public void Goo(int x = /*<bind>*/ 2 /*</bind>*/)
    {
    }
}
");
            Assert.True(dataFlowAnalysisResults.Succeeded);
        }

        [Fact]
        public void GenericStructureCycle()
        {
            var source =
@"struct S<T>
{
    public S<S<T>> F;
}
class C
{
    static void M()
    {
        S<object> o;
    }
}";
            var compilation = CreateEmptyCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
            var statement = GetFirstNode<StatementSyntax>(tree, root.ToFullString().IndexOf("S<object> o", StringComparison.Ordinal));
            var analysis = model.AnalyzeDataFlow(statement);
            Assert.True(analysis.Succeeded);
            Assert.Equal("o", GetSymbolNamesJoined(analysis.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [WorkItem(545372, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545372")]
        [Fact]
        public void AnalysisInSyntaxError01()
        {
            var source =
@"using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
 
class Program
{
    static void Main(string[] args)
    {
        Expression<Func<int>> f3 = () => if (args == null) {};
    }
}";
            var compilation = CreateEmptyCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
            var statement = GetLastNode<StatementSyntax>(tree, root.ToFullString().IndexOf("if", StringComparison.Ordinal));
            Assert.Equal("if (args == null) {}", statement.ToFullString());
            var analysis = model.AnalyzeDataFlow(statement);
            Assert.True(analysis.Succeeded);
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("args, f3", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [WorkItem(546964, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546964")]
        [Fact]
        public void AnalysisWithMissingMember()
        {
            var source =
@"class C
{
    void Goo(string[] args)
    {
        foreach (var s in args)
        {
            this.EditorOperations = 1;
        }
    }
}";
            var compilation = CreateEmptyCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
            var statement = GetLastNode<StatementSyntax>(tree, root.ToFullString().IndexOf("EditorOperations", StringComparison.Ordinal));
            Assert.Equal("this.EditorOperations = 1;", statement.ToString());
            var analysis = model.AnalyzeDataFlow(statement);
            Assert.True(analysis.Succeeded);
            var v = analysis.DataFlowsOut;
        }

        [Fact, WorkItem(547059, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/547059")]
        public void ObjectInitIncompleteCodeInQuery()
        {
            var source = @"
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        var symlist = new List<ISymbol>();
        var expList = from s in symlist
                      select new ExportedSymbol() { S
    }
}

public interface ISymbol
{ }

public class ExportedSymbol
{
    public ISymbol Symbol;
    public byte UseBits;
}
";

            var compilation = CreateEmptyCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var statement = tree.GetCompilationUnitRoot().DescendantNodes().OfType<BlockSyntax>().FirstOrDefault();
            var expectedtext = @"    {
        var symlist = new List<ISymbol>();
        var expList = from s in symlist
                      select new ExportedSymbol() { S
    }
}
";
            Assert.Equal(expectedtext, statement.ToFullString());
            var analysis = model.AnalyzeDataFlow(statement);
            Assert.True(analysis.Succeeded);
        }

        [Fact]
        public void StaticSetterAssignedInCtor()
        {
            var source =
@"class C
{
    C()
    {
        P = new object();
    }
    static object P { get; set; }
}";
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
            var statement = GetFirstNode<StatementSyntax>(tree, root.ToFullString().IndexOf("P = new object()", StringComparison.Ordinal));
            var analysis = model.AnalyzeDataFlow(statement);
            Assert.True(analysis.Succeeded);
        }

        [Fact]
        public void FieldBeforeAssignedInStructCtor()
        {
            var source =
@"struct S
{
    object value;
    S(object x)
    {
        S.Equals(value , value);
        this.value = null;
    }
}";
            var compilation = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            compilation.VerifyDiagnostics(
                // (6,18): error CS9015: Use of possibly unassigned field 'value'. Consider updating to language version '11.0' to auto-default the field.
                //         S.Equals(value , value);
                Diagnostic(ErrorCode.ERR_UseDefViolationFieldUnsupportedVersion, "value").WithArguments("value", "11.0").WithLocation(6, 18)
                );
            verify();

            compilation = CreateCompilation(source, parseOptions: TestOptions.Regular11);
            compilation.VerifyDiagnostics();
            verify();

            void verify()
            {
                var tree = compilation.SyntaxTrees[0];
                var model = compilation.GetSemanticModel(tree);
                var root = tree.GetRoot();
                var expression = GetLastNode<ExpressionSyntax>(tree, root.ToFullString().IndexOf("value ", StringComparison.Ordinal));
                var analysis = model.AnalyzeDataFlow(expression);
                Assert.True(analysis.Succeeded);
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));
            }
        }

        [Fact, WorkItem(14110, "https://github.com/dotnet/roslyn/issues/14110")]
        public void Test14110()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    static void Main()
    {
        var (a0, b0) = (1, 2);
        (var c0, int d0) = (3, 4);
        bool e0 = a0 is int f0;
        bool g0 = a0 is var h0;
        M(out int i0);
        M(out var j0);

/*<bind>*/
        var (a, b) = (1, 2);
        (var c, int d) = (3, 4);
        bool e = a is int f;
        bool g = a is var h;
        M(out int i);
        M(out var j);
/*</bind>*/

        var (a1, b1) = (1, 2);
        (var c1, int d1) = (3, 4);
        bool e1 = a1 is int f1;
        bool g1 = a1 is var h1;
        M(out int i1);
        M(out var j1);
}
    static void M(out int z) => throw null;
}
");
            Assert.Equal("a, b, c, d, e, f, g, h, i, j", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
        }

        [Fact, WorkItem(15640, "https://github.com/dotnet/roslyn/issues/15640")]
        public void Test15640()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
using System;

class Programand 
{
    static void Main()
    {
        foreach (var (a0, b0) in new[] { (1, 2) }) {}

/*<bind>*/
        foreach (var (a, b) in new[] { (1, 2) }) {}
/*</bind>*/

        foreach (var (a1, b1) in new[] { (1, 2) }) {}
    }
}
");
            Assert.Equal("a, b", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
        }

        [Fact]
        public void RegionAnalysisLocalFunctions()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        void Local() { }
        /*</bind>*/
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
        }

        [Fact]
        public void RegionAnalysisLocalFunctions2()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        void Local() { }

        /*<bind>*/
        Local();
        /*</bind>*/
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
        }

        [Fact]
        public void RegionAnalysisLocalFunctions3()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;
class C
{
    static void Main()
    {
        void Local() { }

        /*<bind>*/
        Action a = Local;
        /*</bind>*/
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
        }

        [Fact]
        public void RegionAnalysisLocalFunctions4()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;
class C
{
    static void Main()
    {
        void Local() { }

        /*<bind>*/
        var a = new Action(Local);
        /*</bind>*/
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
        }

        [Fact]
        public void RegionAnalysisLocalFunctions5()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
class C
{
    static void Main()
    {
        void Local()
        {
            /*<bind>*/
            int x = 0;
            x++;
            x = M(x + 1);
            /*</bind>*/
        }
        Local();
    }

    int M(int i) => i;
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("x", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
        }

        [Fact]
        public void RegionAnalysisLocalFunctions6()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
class C
{
    static void Main()
    {
        var a = new Action(() =>
        {
            void Local()
            {
                /*<bind>*/
                int x = 0;
                x++;
                x = M(x + 1);
                /*</bind>*/
            }
        });
        a();
    }

    int M(int i) => i;
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("x", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenOutside));
        }

        [Fact]
        public void RegionAnalysisLocalFunctions7()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;
class C
{
    static void Main()
    {
        void Local() { }

        /*<bind>*/
        var a = (Action)Local;
        /*</bind>*/
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
        }

        [Fact]
        public void RegionAnalysisLocalFunctions8()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
class C
{
    static void Main()
    {
        int x = 0;
        void Local() { x++; }
        Local();

        /*<bind>*/
        x++;
        x = M(x + 1);
        /*</bind>*/
    }

    int M(int i) => i;
}");
            Assert.True(results.Succeeded);
            Assert.Equal("x", GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Equal("x", GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Equal("x", GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(results.WrittenOutside));
        }

        [Fact]
        public void LocalFuncCapture1()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
public static class SomeClass
{
    private static void Repro( int arg )
    {
        /*<bind>*/int localValue = arg;/*</bind>*/

        int LocalCapture() => arg;
    }
}");
            Assert.True(results.Succeeded);
            Assert.Equal("arg", GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Equal("arg", GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("arg", GetSymbolNamesJoined(results.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Equal("arg", GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("arg, localValue", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("localValue", GetSymbolNamesJoined(results.AlwaysAssigned));
            Assert.Equal("arg", GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("arg", GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("localValue", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.UnsafeAddressTaken));
        }

        [Fact]
        public void LocalFuncCapture2()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
class C
{
    void M()
    {
        int x;
        Local();
        /*<bind>*/int y = x;/*</bind>*/

        int Local() { x = 0; }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Equal("x", GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Equal("x", GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("x", GetSymbolNamesJoined(results.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Equal("this, x", GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("y", GetSymbolNamesJoined(results.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("y", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.UnsafeAddressTaken));
        }

        [Fact]
        public void LocalFuncCapture3()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
class C
{
    void M()
    {
        int x;
        /*<bind>*/int y = x;/*</bind>*/
        Local();

        int Local() => x;
    }
}");
            Assert.True(results.Succeeded);
            Assert.Equal("x", GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Equal("x", GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("x", GetSymbolNamesJoined(results.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Equal("this", GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("this, y", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("y", GetSymbolNamesJoined(results.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("y", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.UnsafeAddressTaken));
        }

        [Fact]
        public void LocalFuncCapture4()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
class C
{
    void M()
    {
        int x, y = 0;
        /*<bind>*/x = y;/*</bind>*/
        Local();

        int Local() => x;
    }
}");
            Assert.True(results.Succeeded);
            Assert.Equal("x", GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Equal("x", GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("y", GetSymbolNamesJoined(results.DataFlowsIn));
            Assert.Equal("x", GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Equal("this, y", GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(results.AlwaysAssigned));
            Assert.Equal("y", GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Equal("this, y", GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.UnsafeAddressTaken));
        }

        [Fact]
        public void LocalFuncCapture5()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
class C
{
    int x = 0;

    void M()
    {
        /*<bind>*/
        int L(int a) => x;
        /*</bind>*/
        L();
    }
}");
            Assert.Equal("this", GetSymbolNamesJoined(results.Captured));
            Assert.Equal("this", GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Equal("this", GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("this", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("this", GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Equal("this", GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("this", GetSymbolNamesJoined(results.WrittenOutside));
        }

        [Fact]
        public void LocalFuncCapture6()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
class C
{
    void M(int x)
    {
        int y;
        int z;
        void Local()
        {
            /*<bind>*/
            x++;
            y = 0;
            y++;
            /*</bind>*/
        }
        Local();
    }
}");
            Assert.Equal("x, y", GetSymbolNamesJoined(results.Captured));
            Assert.Equal("x, y", GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            // TODO(https://github.com/dotnet/roslyn/issues/14214): This is wrong.
            // Both x and y should flow out.
            Assert.Equal("y", GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Equal("this, x", GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("x, y", GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("this, x", GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("x, y", GetSymbolNamesJoined(results.AlwaysAssigned));
        }

        [Fact]
        public void LocalFuncCapture7()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
class C
{
    void M()
    {
        int x;
        void L()
        {
            /*<bind>*/
            int y = 0;
            y++;
            x = 0;
            /*</bind>*/
        }
        x++;
    }
}");
            Assert.Equal("x", GetSymbolNamesJoined(results.Captured));
            Assert.Equal("x", GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("y", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Equal("this", GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("y", GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("this, x", GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("x, y", GetSymbolNamesJoined(results.AlwaysAssigned));
        }

        [Fact, WorkItem(37421, "https://github.com/dotnet/roslyn/issues/37421")]
        public void LocalFuncCapture8()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C
{
    int field = 123;
    void M(int x)
    {
        int a = 1, y = 1;
        int Outside() => x+field;
        /*<bind>*/
        int Inside() => y;
        /*</bind>*/
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(analysis.Captured));
            Assert.Equal("y", GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Equal("this, x", GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));
            Assert.Equal("this, x, a, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x, a, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
            Assert.Equal("y", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("this, x", GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Equal("this, x, a, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact, WorkItem(37421, "https://github.com/dotnet/roslyn/issues/37421")]
        public void LocalFuncCapture9()
        {
            var analysis = CompileAndAnalyzeDataFlowStatements(@"
class C
{
    int field = 123;
    void M(int x)
    {
        int a = 1, y = 1;
        int Outside() => x+field;
        Inside();
        /*<bind>*/
        int Inside() => y;
        /*</bind>*/
    }
}");
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(analysis.Captured));
            Assert.Equal("y", GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Equal("this, x", GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));
            Assert.Equal("this, x, a, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x, a, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
            Assert.Equal("y", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Equal("this, x, a, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void AssignmentInsideLocal01()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    static void Main()
    {
        int x = 3, y = 4;
        void Local()
        {
/*<bind>*/
            x = 1;
/*</bind>*/
        }
        Local();
        System.Console.WriteLine(x);
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
        }

        [Fact]
        public void AssignmentInsideLocal02()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    static void Main()
    {
        int x = 3, y = 4;
        void Local()
        {
/*<bind>*/
            if ("""".Length == 1)
            {
                x = 1;
            }
/*</bind>*/
        }
        Local();
        System.Console.WriteLine(x);
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
        }

        [Fact]
        public void AssignmentInsideLocal03()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    static void Main()
    {
        int x = 3, y = 4;
        void Local()
        {
/*<bind>*/
            if (false)
            {
                x = 1;
            }
/*</bind>*/
        }
        Local();
        System.Console.WriteLine(x);
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            // This is a conservative approximation, ignoring whether the branch containing
            // the assignment is reachable
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
        }

        [Fact]
        public void AssignmentInsideLocal04()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    static void Main()
    {
        int x = 3, y = 4;
        void Local()
        {
/*<bind>*/
            x = 1;
/*</bind>*/
            x = 1;
        }
        Local();
        System.Console.WriteLine(x);
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
        }

        [Fact]
        [WorkItem(39569, "https://github.com/dotnet/roslyn/issues/39569")]
        public void AssignmentInsideLocal05()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    static void Main()
    {
        int x = 3, y = 4;
        void Local()
        {
            x = 1;
        }
/*<bind>*/
        Local();
/*</bind>*/
        System.Console.WriteLine(x);
    }
}
");
            // Right now region analysis requires bound nodes for each variable and value being
            // assigned. This doesn't work with the current local function analysis because we only
            // store the slots, not the full boundnode of every assignment (which is impossible
            // anyway). This should be:
            //      Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
        }

        [Fact]
        public void AssignmentInsideLocal06()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    static void Main()
    {
        int x = 3, y = 4;
/*<bind>*/
        void Local()
        {
            x = 1;
        }
/*</bind>*/
        Local();
        System.Console.WriteLine(x);
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
        }

        [Fact]
        public void AssignmentInsideLocal07()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    static void Main()
    {
        int x = 3, y = 4;
/*<bind>*/
        void Local()
        {
            x = 1;
        }
        Local();
/*</bind>*/
        System.Console.WriteLine(x);
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
        }

        [Fact]
        public void AssignmentInsideLocal08()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    static void Main()
    {
        int x = 3, y = 4;
        void Local()
        {
/*<bind>*/
            if ("""".Length == 0)
            {
                x = 1;
                return;
            }
            else
            {
                y = 1;
            }
/*</bind>*/
        }
        Local();
        System.Console.WriteLine(x);
        System.Console.WriteLine(y);
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
        }

        [Fact]
        public void AssignmentInsideLocal09()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    static void Main()
    {
        int x = 3, y = 4;
        void Local()
        {
/*<bind>*/
            if ("""".Length == 0)
            {
                x = 1;
                return;
            }
            else
            {
                y = 1;
                throw new Exception();
            }
/*</bind>*/
        }
        Local();
        System.Console.WriteLine(x);
        System.Console.WriteLine(y);
    }
}
");
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            // N.B. This is not as precise as possible. The branch assigning y is unreachable, so
            // the result does not technically flow out. This is a conservative approximation.
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
        }

        [Fact, WorkItem(25043, "https://github.com/dotnet/roslyn/issues/25043")]
        public void FallThroughInSwitch_01()
        {
            var analysis = CompileAndAnalyzeControlFlowStatements(@"
class C
{
    void M()
    {
/*<bind>*/
        switch (true)
        {
            case true:
                void f()
                {
                }
        }
/*</bind>*/
    }
}");
            Assert.Equal(0, analysis.EntryPoints.Count());
        }

        [Fact, WorkItem(25043, "https://github.com/dotnet/roslyn/issues/25043")]
        public void FallThroughInSwitch_02()
        {
            var analysis = CompileAndAnalyzeControlFlowStatements(@"
class C
{
    void M()
    {
/*<bind>*/
        switch (true)
        {
            case true when true:
                void f()
                {
                }
        }
/*</bind>*/
    }
}");
            Assert.Equal(0, analysis.EntryPoints.Count());
        }

        [Fact]
        public void AnalysisOfTupleEquality()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
class A
{
    void M()
    {
        int x = 0;
        int y = 0;
        _ = /*<bind>*/(x, y) == (x = 0, 1)/*</bind>*/;
    }
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void AnalysisOfNestedTupleInTupleEquality()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
class A
{
    void M()
    {
        int x = 0;
        int y = 0;
        _ = (1, (2, 3)) == (0, /*<bind>*/(x = 0, y)/*</bind>*/);
    }
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void AnalysisOfExpressionInTupleEquality()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
class A
{
    void M()
    {
        int x = 0;
        int y = 0;
        _ = (1, 2) == (0, /*<bind>*/(x = 0) + y/*</bind>*/);
    }
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void AnalysisOfMixedDeconstruction()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
class A
{
    bool M()
    {
        int x = 0;
        string y;
        /*<bind>*/
        (x, (y, var z)) = (x, ("""", true))
        /*</bind>*/
        return z;
    }
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Equal("z", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x, y, z", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("z", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x, y, z", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("z", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x, y, z", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void AnalysisOfPropertyGetter_Inside_ReferenceType()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
class MyClass
{
    int _myProp;
    int MyProp
    {
        get => /*<bind>*/this._myProp;/*</bind>*/
        set => this._myProp = value;
    }
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void AnalysisOfPropertySetter_Inside_ReferenceType()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
class MyClass
{
    int _myProp;
    int MyProp
    {
        get => this._myProp;
        set => /*<bind>*/this._myProp = value;/*</bind>*/
    }
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void AnalysisOfPropertyGetter_Inside_ValueType()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
struct MyStruct
{
    int _myProp;
    int MyProp
    {
        get => /*<bind>*/this._myProp;/*</bind>*/
        set => this._myProp = value;
    }
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void AnalysisOfPropertySetter_Inside_ValueType()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
struct MyStruct
{
    int _myProp;
    int MyProp
    {
        get => this._myProp;
        set => /*<bind>*/this._myProp = value;/*</bind>*/
    }
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("value", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("value", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void AnalysisOfEventAdder_Inside_ReferenceType()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
class MyClass
{
    EventHandler _myEvent;
    event EventHandler MyEvent
    {
        add => /*<bind>*/ this._myEvent += value; /*</bind>*/
        remove => this._myEvent -= value;
    }
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void AnalysisOfEventRemover_Inside_ReferenceType()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
class MyClass
{
    EventHandler _myEvent;
    event EventHandler MyEvent
    {
        add => this._myEvent += value;
        remove => /*<bind>*/ this._myEvent -= value; /*</bind>*/
    }
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void AnalysisOfEventAdder_Inside_ValueType()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
struct MyStruct
{
    EventHandler _myEvent;
    event EventHandler MyEvent
    {
        add => /*<bind>*/ this._myEvent += value; /*</bind>*/
        remove => this._myEvent -= value;
    }
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void AnalysisOfEventRemover_Inside_ValueType()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
struct MyStruct
{
    EventHandler _myEvent;
    event EventHandler MyEvent
    {
        add => this._myEvent += value;
        remove => /*<bind>*/ this._myEvent -= value; /*</bind>*/
    }
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("this", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, value", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        [WorkItem(27969, "https://github.com/dotnet/roslyn/issues/27969")]
        public void CodeInInitializer01()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System;
class C
{
    object P { get; } = Create(nameof(P), /*<bind>*/x => true/*</bind>*/);

    static object Create(string name, Func<string, bool> f) => throw null;
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        [WorkItem(27969, "https://github.com/dotnet/roslyn/issues/27969")]
        public void CodeInInitializer02()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
using System;
class C
{
    object P { get; } = Create(P, /*<bind>*/x => true/*</bind>*/);

    static object Create(object name, Func<string, bool> f) => throw null;
}
");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        [WorkItem(19845, "https://github.com/dotnet/roslyn/issues/19845")]
        public void CodeInInitializer03()
        {
            var analysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C {
    static int X { get; set; }
    int Y = /*<bind>*/X/*</bind>*/;
}");
            var dataFlowAnalysisResults = analysisResults;
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        [WorkItem(26028, "https://github.com/dotnet/roslyn/issues/26028")]
        public void BrokenForeach01()
        {
            var source = @"class C
{
    void M()
    {
        foreach (var x
    }
}
";
            var compilation = CreateCompilation(source);
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);

            // The foreach loop is broken, so its embedded statement is filled in during syntax error recovery. It is zero-width.
            var stmt = tree.GetCompilationUnitRoot().DescendantNodesAndSelf().OfType<ForEachStatementSyntax>().Single().Statement;
            Assert.Equal(0, stmt.Span.Length);

            var dataFlowAnalysisResults = model.AnalyzeDataFlow(stmt);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, x", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        [WorkItem(30548, "https://github.com/dotnet/roslyn/issues/30548")]
        public void SymbolInDataFlowInButNotInReadInside()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp39
{
    class Program
    {
        void Method(out object test)
        {
            test = null;

            var a = test != null;
            /*<bind>*/if (a)
            {
                return;
            }

            if (A == a)
            {
                test = new object();
            }/*</bind>*/
        }
    }
}");

            var dataFlowAnalysisResults = analysisResults.Item2;

            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
            Assert.Equal("test, a", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Equal("test", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("this, test, a", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("this, test, a", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("a", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("test", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("test", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("this, test, a", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact, WorkItem(37427, "https://github.com/dotnet/roslyn/issues/37427")]
        public void RegionWithLocalFunctions()
        {
            // local functions inside the region
            var s1 = @"
class A
{
    static void M(int p)
    {
        int i, j;
        i = 1;
        /*<bind>*/
        int L1() => 1;
        int k;
        j = i;
        int L2() => 2;
        /*</bind>*/
        k = j;
    }
}
";
            // local functions outside the region
            var s2 = @"
class A
{
    static void M(int p)
    {
        int i, j;
        i = 1;
        int L1() => 1;
        /*<bind>*/
        int k;
        j = i;
        /*</bind>*/
        int L2() => 2;
        k = j;
    }
}
";
            foreach (var s in new[] { s1, s2 })
            {
                var analysisResults = CompileAndAnalyzeDataFlowStatements(s);
                var dataFlowAnalysisResults = analysisResults;
                Assert.True(dataFlowAnalysisResults.Succeeded);
                Assert.Equal("k", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
                Assert.Equal("j", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
                Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.CapturedOutside));
                Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
                Assert.Equal("j", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
                Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
                Assert.Equal("j", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
                Assert.Equal("j", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
                Assert.Equal("p, i, k", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            }
        }

        [Fact]
        public void TestAddressOfUnassignedStructLocal_02()
        {
            // This test demonstrates that "data flow analysis" pays attention to private fields
            // of structs imported from metadata.
            var libSource = @"
public struct Struct
{
    private string Field;
}";

            var libraryReference = CreateCompilation(libSource).EmitToImageReference();
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class Program
{
    static void Main()
    {
        Struct x; // considered not definitely assigned because it has a field

        Struct * px = /*<bind>*/&x/*</bind>*/; // address taken of an unassigned variable
    }
}
", libraryReference);
            Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.UnsafeAddressTaken));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("px", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [WorkItem(57428, "https://github.com/dotnet/roslyn/issues/57428")]
        [Fact]
        public void AttributeArgumentWithLambdaBody_01()
        {
            var source =
@"using System.Runtime.InteropServices;
class Program
{
    static void F([DefaultParameterValue(() => { return 0; })] object obj)
    {
    }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (4,42): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
                //     static void F([DefaultParameterValue(() => { return 0; })] object obj)
                Diagnostic(ErrorCode.ERR_BadAttributeArgument, "() => { return 0; }").WithLocation(4, 42));

            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var expr = tree.GetRoot().DescendantNodes().OfType<LiteralExpressionSyntax>().Single();
            var analysis = model.AnalyzeDataFlow(expr);
            Assert.False(analysis.Succeeded);
        }

        [Fact]
        public void AttributeArgumentWithLambdaBody_02()
        {
            var source =
@"using System;
class A : Attribute
{
    internal A(object o) { }
}
class Program
{
    static void F([A(() => { return 0; })] object obj)
    {
    }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (8,22): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
                //     static void F([A(() => { return 0; })] object obj)
                Diagnostic(ErrorCode.ERR_BadAttributeArgument, "() => { return 0; }").WithLocation(8, 22));

            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var expr = tree.GetRoot().DescendantNodes().OfType<LiteralExpressionSyntax>().Single();
            var analysis = model.AnalyzeDataFlow(expr);
            Assert.False(analysis.Succeeded);
        }

        #endregion

        #region "Used Local Functions"

        [Fact]
        public void RegionAnalysisUsedLocalFunctions()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        void Local() { }
        /*</bind>*/
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Null(GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions2()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Local();
        /*</bind>*/
        void Local() { }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions3()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Local();
        /*</bind>*/
        void Local() { }
        void Unused(){ }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions4()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Local();
        /*</bind>*/
        void Local()
        {
            Second();
        }

        void Second() { }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local, Second", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions5()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Local();
        /*</bind>*/
        void Local()
        {
            void Sub() { }
        }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions6()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Local();
        /*</bind>*/
        void Local()
        {
            Sub();
            void Sub() { }
        }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local, Sub", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions7()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Local();
        /*</bind>*/
        void Local()
        {
            Second();
        }

        void Second()
        {
            Sub();
            void Sub() { }
        }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local, Second, Sub", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions8()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        System.Action a = new System.Action(Local);
        /*</bind>*/

        void Local()
        {
            Second();
        }

        void Second()
        {
            Sub();
            void Sub() { }
        }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local, Second, Sub", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions9()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Local();
        /*</bind>*/
        static void Local()
        {
            Sub();
            void Sub() { }
        }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local, Sub", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions10()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Local();
        /*</bind>*/
        void Local()
        {
            Sub();
            static void Sub() { }
        }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local, Sub", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions11()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Local();
        /*</bind>*/
        static void Local()
        {
            Sub();
            static void Sub() { }
        }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local, Sub", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions12()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        Action a = () => Local();
        /*<bind>*/
        a();
        /*</bind>*/
        void Local() { }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("a", GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions13()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Action a = () => Local();
        /*</bind>*/
        a();
        void Local() { }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Equal("a", GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions14()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        Action a = () => Local();
        /*<bind>*/
        a();
        /*</bind>*/
        void Local()
        {
            Sub();
            void Sub();
        }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("a", GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local, Sub", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions15()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Action a = () => Local();
        /*</bind>*/
        a();
        void Local()
        {
            Sub();
            void Sub();
        }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Equal("a", GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local, Sub", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions16()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        Action a = () => Local();
        /*<bind>*/
        a();
        /*</bind>*/
        static void Local() { }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("a", GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions17()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Action a = () => Local();
        /*</bind>*/
        a();
        static void Local() { }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Equal("a", GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions18()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        Action a = () => Local();
        /*<bind>*/
        a();
        /*</bind>*/
        static void Local()
        {
            Sub();
            static void Sub();
        }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("a", GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local, Sub", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions19()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Action a = () => Local();
        /*</bind>*/
        a();
        static void Local()
        {
            Sub();
            static void Sub();
        }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Equal("a", GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local, Sub", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions20()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Action a = Local;
        /*</bind>*/
        void Local() { }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions21()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Action a = Local;
        /*</bind>*/
        void Local()
        {
            Sub();
            void Sub();
        }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local, Sub", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions22()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Action a = Local;
        /*</bind>*/
        static void Local() { }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void RegionAnalysisUsedLocalFunctions23()
        {
            var results = CompileAndAnalyzeDataFlowStatements(@"
using System;

class C
{
    static void Main()
    {
        /*<bind>*/
        Action a = Local;
        /*</bind>*/
        static void Local()
        {
            Sub();
            static void Sub();
        }
    }
}");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Equal("a", GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("a", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(results.ReadInside));
            Assert.Equal("a", GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Equal("Local, Sub", GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        #endregion

        #region "Top level statements"

        [Fact]
        public void TestTopLevelStatements()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;
using System.Linq;

/*<bind>*/
Console.Write(1);
Console.Write(2);
Console.Write(3);
Console.Write(4);
Console.Write(5);
/*</bind>*/
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestTopLevelStatements_Lambda()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;
using System.Linq;

int i = 1;
Func<int> lambda = () => { /*<bind>*/return i;/*</bind>*/ };
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(1, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.False(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("i, args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("i, args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("i, lambda, args", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Fact]
        public void TestTopLevelStatements_LambdaCapturingArgs()
        {
            var analysisResults = CompileAndAnalyzeControlAndDataFlowStatements(@"
using System;
using System.Linq;

Func<int> lambda = () => { /*<bind>*/return args.Length;/*</bind>*/ };
");
            var controlFlowAnalysisResults = analysisResults.Item1;
            var dataFlowAnalysisResults = analysisResults.Item2;
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(1, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.False(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("lambda, args", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        #endregion

        #region Interpolated String Handlers

        [Theory]
        [CombinatorialData]
        public void TestInterpolatedStringHandlers(bool validityParameter, bool useBoolReturns)
        {
            var code = @"
using System.Runtime.CompilerServices;

int i1;
int i2;

/*<bind>*/
CustomHandler c = $""{i1 = 1}{i2 = 2}"";
/*</bind>*/

[InterpolatedStringHandler]
public struct CustomHandler
{
    public CustomHandler(int literalLength, int formattedCount" + (validityParameter ? ", out bool success" : "") + @")
    {
" + (validityParameter ? "success = true;" : "") + @"
    }

    public " + (useBoolReturns ? "bool" : "void") + @" AppendFormatted(int i) => throw null;
}
" + InterpolatedStringHandlerAttribute;

            var (controlFlowAnalysisResults, dataFlowAnalysisResults) = CompileAndAnalyzeControlAndDataFlowStatements(code);
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Equal("c", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));

            var definitelyAssigned = (validityParameter, useBoolReturns) switch
            {
                (true, _) => "c",
                (_, true) => "i1, c",
                (_, false) => "i1, i2, c"
            };

            Assert.Equal(definitelyAssigned + ", args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("i1, i2, c", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void TestRawInterpolatedStringHandlers(bool validityParameter, bool useBoolReturns)
        {
            var code = @"
using System.Runtime.CompilerServices;

int i1;
int i2;

/*<bind>*/
CustomHandler c = $""""""{i1 = 1}{i2 = 2}"""""";
/*</bind>*/

[InterpolatedStringHandler]
public struct CustomHandler
{
    public CustomHandler(int literalLength, int formattedCount" + (validityParameter ? ", out bool success" : "") + @")
    {
" + (validityParameter ? "success = true;" : "") + @"
    }

    public " + (useBoolReturns ? "bool" : "void") + @" AppendFormatted(int i) => throw null;
}
" + InterpolatedStringHandlerAttribute;

            var (controlFlowAnalysisResults, dataFlowAnalysisResults) = CompileAndAnalyzeControlAndDataFlowStatements(code);
            Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count());
            Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count());
            Assert.True(controlFlowAnalysisResults.EndPointIsReachable);
            Assert.Equal("c", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnEntry));

            var definitelyAssigned = (validityParameter, useBoolReturns) switch
            {
                (true, _) => "c",
                (_, true) => "i1, c",
                (_, false) => "i1, i2, c"
            };

            Assert.Equal(definitelyAssigned + ", args", GetSymbolNamesJoined(dataFlowAnalysisResults.DefinitelyAssignedOnExit));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Equal("i1, i2, c", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("args", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
        }

        #endregion

        [Fact]
        public void TestDataFlowsArrayInit_01()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public void F(int x)
    {
        int a = 1, y = 2;
        int[] b = /*<bind>*/{ a + x + 3 } /*</bind>*/;
        int c = a + 4 + y;
    }
}");
            Assert.Equal("x, a", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact]
        public void TestDataFlowsArrayInit_02()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public void F(int x)
    {
        int a = 1, y = 2;
        int[,] b = /*<bind>*/{ { a + x + 3 } }/*</bind>*/;
        int c = a + 4 + y;
    }
}");
            Assert.Equal("x, a", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact]
        public void TestDataFlowsArrayInit_03()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public void F(int x)
    {
        int a = 1, y = 2;
        int[,] b = {/*<bind>*/{ a + x + 3 } /*</bind>*/};
        int c = a + 4 + y;
    }
}");
            Assert.Equal("x, a", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact]
        [WorkItem(57572, "https://github.com/dotnet/roslyn/issues/57572")]
        public void TestDataFlowsArrayInit_04()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public void F(int x)
    {
        int a = 1, y = 2;
        int[] b = new int[] /*<bind>*/{ a + x + 3 } /*</bind>*/;
        int c = a + 4 + y;
    }
}");
            Assert.Equal("x, a", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact]
        [WorkItem(57572, "https://github.com/dotnet/roslyn/issues/57572")]
        public void TestDataFlowsArrayInit_05()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public void F(int x)
    {
        int a = 1, y = 2;
        int[,] b = new int[,] /*<bind>*/{ {a + x + 3} } /*</bind>*/;
        int c = a + 4 + y;
    }
}");
            Assert.Equal("x, a", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact]
        [WorkItem(57572, "https://github.com/dotnet/roslyn/issues/57572")]
        public void TestDataFlowsArrayInit_06()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public void F(int x)
    {
        int a = 1, y = 2;
        int[,] b = new int[,] {/*<bind>*/{ a + x + 3 } /*</bind>*/};
        int c = a + 4 + y;
    }
}");
            Assert.Equal("x, a", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact]
        public void TestDataFlowsObjectInit()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C {
    public int Data;
    public void F(int x)
    {
        int a = 1, y = 2;
        var b = new object() /*<bind>*/{ Data = a + x + 3 } /*</bind>*/;
        int c = a + 4 + y;
    }
}");
            Assert.Equal("x, a", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact, WorkItem(60134, "https://github.com/dotnet/roslyn/issues/60134")]
        public void TestDataFlowsStackArrayInit_01()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
class C
{
	public void F(int x)
	{
		int a = 1, y = 2;
		var b = stackalloc int[] /*<bind>*/{ a + x + 3 } /*</bind>*/;
		int c = a + 4 + y;
	}
}
");
            Assert.Equal("x, a", GetSymbolNamesJoined(analysis.DataFlowsIn));
        }

        [Fact, WorkItem(60134, "https://github.com/dotnet/roslyn/issues/60134")]
        public void TestDataFlowsStackArrayInit_02()
        {
            var comp = CreateCompilation(@"
#nullable enable
unsafe class C
{
	void F()
	{
        bool b = true;
		var c = stackalloc int[] { b ? M(out var x) : x };
	}
    static int M(out int i) => throw null!;
}
", options: TestOptions.UnsafeDebugDll);

            comp.VerifyDiagnostics(
                // (8,49): error CS0165: Use of unassigned local variable 'x'
                // 		var c = stackalloc int[] { b ? M(out var x) : x };
                Diagnostic(ErrorCode.ERR_UseDefViolation, "x").WithArguments("x").WithLocation(8, 49)
                );
        }

        [Fact, WorkItem(59738, "https://github.com/dotnet/roslyn/issues/59738")]
        public void TestDataFlowsOfIdentifierWithDelegateConversion()
        {
            var results = CompileAndAnalyzeDataFlowExpression(@"
using System;

internal static class NoExtensionMethods
{
    internal static Func<T> AsFunc<T>(this T value) where T : class
    {
        return new Func<T>(/*<bind>*/ value /*</bind>*/.Return);
    }

    private static T Return<T>(this T value)
    {
        return value;
    }

    static void Main()
    {
        Console.WriteLine(((object)42).AsFunc()());
    }
}
	");
            Assert.True(results.Succeeded);
            Assert.Null(GetSymbolNamesJoined(results.Captured));
            Assert.Null(GetSymbolNamesJoined(results.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(results.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(results.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(results.DataFlowsOut));
            Assert.Equal("value", GetSymbolNamesJoined(results.DefinitelyAssignedOnEntry));
            Assert.Equal("value", GetSymbolNamesJoined(results.DefinitelyAssignedOnExit));
            Assert.Equal("value", GetSymbolNamesJoined(results.ReadInside));
            Assert.Null(GetSymbolNamesJoined(results.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(results.ReadOutside));
            Assert.Equal("value", GetSymbolNamesJoined(results.WrittenOutside));
            Assert.Null(GetSymbolNamesJoined(results.UsedLocalFunctions));
        }

        [Fact]
        public void TestDataFlowsOfIdentifierWithDelegateConversionCast()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
using System;

internal static class NoExtensionMethods
{
    internal static Func<T> AsFunc<T>(this T value) where T : class
    {
        return (Func<T>)/*<bind>*/ value /*</bind>*/.Return;
    }

    private static T Return<T>(this T value)
    {
        return value;
    }
}
");
            Assert.True(analysis.Succeeded);
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Equal("value", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("value", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("value", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
            Assert.Equal("value", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("value", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void TestDataFlowsOfIdentifierWithDelegateConversionTarget()
        {
            var analysis = CompileAndAnalyzeDataFlowExpression(@"
using System;

internal static class NoExtensionMethods
{
    internal static Func<T> AsFunc<T>(this T value) where T : class
    {
        Func<T> result =/*<bind>*/ value /*</bind>*/.Return;
        return result;
    }

    private static T Return<T>(this T value)
    {
        return value;
    }
}
");
            Assert.True(analysis.Succeeded);
            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Equal("value", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("value", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("value", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));
            Assert.Equal("value", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("result", GetSymbolNamesJoined(analysis.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("value, result", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact, WorkItem(59738, "https://github.com/dotnet/roslyn/issues/59738")]
        public void DefiniteAssignmentInReceiverOfExtensionMethodInDelegateCreation()
        {
            var comp = CreateCompilation(@"
using System;
bool b = true;
_ = new Func<string>((b ? M(out var i) : i.ToString()).ExtensionMethod);

string M(out int i)
{
    throw null;
}

static class Extension
{
    public static string ExtensionMethod(this string s) => throw null;
}
	");
            comp.VerifyDiagnostics(
                // (4,42): error CS0165: Use of unassigned local variable 'i'
                // _ = new Func<string>((b ? M(out var i) : i.ToString()).ExtensionMethod);
                Diagnostic(ErrorCode.ERR_UseDefViolation, "i").WithArguments("i").WithLocation(4, 42)
                );
        }

        [Fact, WorkItem(59738, "https://github.com/dotnet/roslyn/issues/59738")]
        public void DefiniteAssignmentShouldSkipImplicitThisInStaticMethodConversion()
        {
            var comp = CreateCompilation(@"
using System;
public struct C
{
    private object field;
    public C(Action a)
    {
        // implicit `this` receiver should be ignored in definite assignment
        a = new(M);
        field = 1;
    }

    public C(Action a, int ignored)
    {
        // implicit `this` receiver should be ignored in definite assignment
        a = new Action(M);
        field = 1;
    }

    public void Method1(Action a)
    {
        // explicit `this` disallowed
        a = new Action(this.M);
    }

    public void Method2(Action a, C c)
    {
        // instance receiver disallowed
        a = new Action(c.M);
    }

    private static void M()
    {
    }
}
");
            comp.VerifyDiagnostics(
                // (23,24): error CS0176: Member 'C.M()' cannot be accessed with an instance reference; qualify it with a type name instead
                //         a = new Action(this.M);
                Diagnostic(ErrorCode.ERR_ObjectProhibited, "this.M").WithArguments("C.M()").WithLocation(23, 24),
                // (29,24): error CS0176: Member 'C.M()' cannot be accessed with an instance reference; qualify it with a type name instead
                //         a = new Action(c.M);
                Diagnostic(ErrorCode.ERR_ObjectProhibited, "c.M").WithArguments("C.M()").WithLocation(29, 24)
                );
        }

        [Fact, WorkItem(59738, "https://github.com/dotnet/roslyn/issues/59738")]
        public void DefiniteAssignmentWithExplicitThisInStaticMethodConversion()
        {
            var comp = CreateCompilation(@"
using System;
public struct C
{
    private object field;
    public void Method1(Action a)
    {
        a = new Action(this.M);
        field = 1;
    }

    public void Method2(Action a, C c)
    {
        a = new Action(c.M);
    }
}
public static class Extension
{
    public static void M(this C c)
    {
    }
}
");
            comp.VerifyDiagnostics(
                // (8,24): error CS1113: Extension method 'Extension.M(C)' defined on value type 'C' cannot be used to create delegates
                //         a = new Action(this.M);
                Diagnostic(ErrorCode.ERR_ValueTypeExtDelegate, "this.M").WithArguments("Extension.M(C)", "C").WithLocation(8, 24),
                // (14,24): error CS1113: Extension method 'Extension.M(C)' defined on value type 'C' cannot be used to create delegates
                //         a = new Action(c.M);
                Diagnostic(ErrorCode.ERR_ValueTypeExtDelegate, "c.M").WithArguments("Extension.M(C)", "C").WithLocation(14, 24)
                );
        }

        [Fact]
        public void PrimaryConstructors_01()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    int X() => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    int X() => /*<bind>*/x/*</bind>*/;
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int x)
    {
        X();
        int X() => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int x)
    {
        X();
        static int X() => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int x)
    {
        _ = () => /*<bind>*/x/*</bind>*/;
    }
}
"),
"x"); // https://github.com/dotnet/roslyn/issues/66557

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int x)
    {
        _ = static () => /*<bind>*/x/*</bind>*/;
    }
}
"),
"x"); // https://github.com/dotnet/roslyn/issues/66557

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B() : this(1) { _ = /*<bind>*/x/*</bind>*/; }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B() : this(1) { _ = /*<bind>*/x/*</bind>*/; }
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x)
    {
        X();
        int X() => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x)
    {
        X();
        static int X() => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x)
    {
        _ = () => /*<bind>*/x/*</bind>*/;
    }
}
"),
"x"); // https://github.com/dotnet/roslyn/issues/66557

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x)
    {
        _ = static () => /*<bind>*/x/*</bind>*/;
    }
}
"),
"x"); // https://github.com/dotnet/roslyn/issues/66557

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B() : this(/*<bind>*/x/*</bind>*/) {}
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B() : this(/*<bind>*/x/*</bind>*/) {}
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x) : this(() => /*<bind>*/x/*</bind>*/)
    {
    }

    B(System.Func<int> x){}
}
"),
"x"); // https://github.com/dotnet/roslyn/issues/66557

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x) : this(static () => /*<bind>*/x/*</bind>*/)
    {
    }

    B(System.Func<int> x){}
}
"),
"x"); // https://github.com/dotnet/roslyn/issues/66557

            static void verify(DataFlowAnalysis analysis, string dataFlowsIn = null)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Equal(dataFlowsIn, GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_02()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
struct B(int x)
{
    B() : this(1) { _ = /*<bind>*/x/*</bind>*/; }
    public int y;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
struct B(int x)
{
    B() : this(1) { _ = /*<bind>*/x/*</bind>*/; }
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
struct B
{
    B(int x) : this("""")
    {
        X();
        int X() => /*<bind>*/x/*</bind>*/;
    }

    B(string x) {}
    public int y;
}
"), thisIsAssignedOnEntry: false);

            static void verify(DataFlowAnalysis analysis, bool thisIsAssignedOnEntry = true)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal((thisIsAssignedOnEntry ? "this, " : "") + "x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal((thisIsAssignedOnEntry ? "this, " : "") + "x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Equal("this", GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_03()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
struct B(int x)
{
    B() : this(/*<bind>*/x/*</bind>*/) {}
    public int y;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
struct B(int x)
{
    B() : this(/*<bind>*/x/*</bind>*/) {}
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
struct B
{
    B(int x) : this(() => /*<bind>*/x/*</bind>*/)
    {
    }

    B(System.Func<int> x){}
    public int y;
}
"),
"x"); // https://github.com/dotnet/roslyn/issues/66557

            static void verify(DataFlowAnalysis analysis, string dataFlowsIn = null)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Equal(dataFlowsIn, GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Equal("this", GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_04()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y)
{
    int X() => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int x, int y)
    {
        X();
        int X() => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int x, int y)
    {
        X();
        static int X() => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int x, int y)
    {
        _ = () => /*<bind>*/x/*</bind>*/;
    }
}
"),
"x"); // https://github.com/dotnet/roslyn/issues/66557

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int x, int y)
    {
        _ = static () => /*<bind>*/x/*</bind>*/;
    }
}
"),
"x"); // https://github.com/dotnet/roslyn/issues/66557

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y)
{
    B() : this(1, 2) { _ = /*<bind>*/x/*</bind>*/; }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x, int y)
    {
        X();
        int X() => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x, int y)
    {
        X();
        static int X() => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x, int y)
    {
        _ = () => /*<bind>*/x/*</bind>*/;
    }
}
"),
"x"); // https://github.com/dotnet/roslyn/issues/66557

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x, int y)
    {
        _ = static () => /*<bind>*/x/*</bind>*/;
    }
}
"),
"x"); // https://github.com/dotnet/roslyn/issues/66557

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y)
{
    B() : this(1, /*<bind>*/x/*</bind>*/) { }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x, int y) : this(() => /*<bind>*/x/*</bind>*/)
    {
    }

    B(System.Func<int> x) {}
}
"),
"x"); // https://github.com/dotnet/roslyn/issues/66557

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x, int y) : this(static () => /*<bind>*/x/*</bind>*/)
    {
    }

    B(System.Func<int> x) {}
}
"),
"x"); // https://github.com/dotnet/roslyn/issues/66557

            static void verify(DataFlowAnalysis analysis, string dataFlowsIn = null)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Equal(dataFlowsIn, GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("this, x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("this, x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x, y", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_05()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int y)
{
    int X(int x) => /*<bind>*/x/*</bind>*/;
}
"));
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int y)
{
    int X(int x) => /*<bind>*/x/*</bind>*/;
    int Y() => y; 
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int y)
    {
        X(1);
        int X(int x) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int y)
    {
        X(1);
        static int X(int x) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int y)
    {
        _ = (int x) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int y)
    {
        _ = static (int x) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int y)
{
    B(short x) : this(1) => /*<bind>*/x/*</bind>*/;
}
"));
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int y)
{
    B(short x) : this(1) => /*<bind>*/x/*</bind>*/;
    int Y() => y; 
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int y)
    {
        X(1);
        int X(int x) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int y)
    {
        X(1);
        static int X(int x) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int y)
    {
        _ = (int x) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int y)
    {
        _ = static (int x) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int y)
{
    B(short x) : this(/*<bind>*/x/*</bind>*/) {}
}
"));
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int y)
{
    B(short x) : this(/*<bind>*/x/*</bind>*/) {}
    int Y() => y; 
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int y) : this((int x) => /*<bind>*/x/*</bind>*/)
    {
    }

    B(System.Func<int, int> x) {}
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int y) : this(static (int x) => /*<bind>*/x/*</bind>*/)
    {
    }

    B(System.Func<int, int> x) {}
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(analysis.Captured));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("this, x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("this, x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x, y", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_06()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static int X() => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static int X() => /*<bind>*/x/*</bind>*/;
    int M() => x;
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Null(GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        [Fact]
        public void PrimaryConstructors_07()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y)
{
    static int X() => /*<bind>*/x/*</bind>*/;
}
"));
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y)
{
    static int X() => /*<bind>*/x/*</bind>*/;
    int M() => y;
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Null(GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_08()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int y)
{
    static int X(int x) => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int y)
{
    static int X(int x) => /*<bind>*/x/*</bind>*/;
    int Y() => y; 
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(analysis.Captured));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_09()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    int X = /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    int X { get; } = /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(System.Action x)
{
    event System.Action X = /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    int X = /*<bind>*/x/*</bind>*/;
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    int X { get; } = /*<bind>*/x/*</bind>*/;
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(System.Action x)
{
    event System.Action X = /*<bind>*/x/*</bind>*/;
    System.Action M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    static void M(int x)
    {
        _ = /*<bind>*/x/*</bind>*/;
    }
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(analysis.Captured));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        [Fact]
        public void PrimaryConstructors_10()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y)
{
    int X = /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y)
{
    int X { get; } = /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(System.Action x, int y)
{
    event System.Action X = /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y)
{
    int X = /*<bind>*/x/*</bind>*/;
    int M() => y;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y)
{
    int X { get; } = /*<bind>*/x/*</bind>*/;
    int M() => y;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(System.Action x, int y)
{
    event System.Action X = /*<bind>*/x/*</bind>*/;
    int M() => y;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    static void M(int x, int y)
    {
        _ = /*<bind>*/x/*</bind>*/;
    }
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(analysis.Captured));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Equal("x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        [Fact]
        public void PrimaryConstructors_11()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static int X = /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static int X { get; } = /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(System.Action x)
{
    static event System.Action X = /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static int X = /*<bind>*/x/*</bind>*/;
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static int X { get; } = /*<bind>*/x/*</bind>*/;
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(System.Action x)
{
    static event System.Action X = /*<bind>*/x/*</bind>*/;
    System.Action M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y)
{
    static int X = /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y)
{
    static int X { get; } = /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(System.Action x, int y)
{
    static event System.Action X = /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y)
{
    static int X = /*<bind>*/x/*</bind>*/;
    int M() => y;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y)
{
    static int X { get; } = /*<bind>*/x/*</bind>*/;
    int M() => y;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(System.Action x, int y)
{
    static event System.Action X = /*<bind>*/x/*</bind>*/;
    int M() => y;
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(analysis.Captured));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Null(GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        [Fact]
        public void PrimaryConstructors_12()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x) : A(/*<bind>*/x/*</bind>*/)
{
}

class A(int x);
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x) : A(/*<bind>*/x/*</bind>*/)
{
    int M() => x;
}

class A(int x);
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B : A
{
    B(int x) : base(/*<bind>*/x/*</bind>*/)
    {
    }
}

class A(int x);
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(analysis.Captured));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_13()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y) : A(/*<bind>*/x/*</bind>*/)
{
}

class A(int x);
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x, int y) : A(/*<bind>*/x/*</bind>*/)
{
    int M() => y;
}

class A(int x);
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B : A
{
    B(int x, int y) : base(/*<bind>*/x/*</bind>*/)
    {
    }
}

class A(int x);
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(analysis.Captured));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("this, x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("this, x, y", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x, y", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_14()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    int X() => /*<bind>*/x = 1/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    int X() => /*<bind>*/x = 1/*</bind>*/;
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int x)
    {
        X();
        int X() => /*<bind>*/x = 1/*</bind>*/;
    }
}
"), null);

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int x)
    {
        X();
        static int X() => /*<bind>*/x = 1/*</bind>*/;
    }
}
"), null);

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int x)
    {
        _ = () => /*<bind>*/x = 1/*</bind>*/;
    }
}
"), null);

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(int x)
    {
        _ = static () => /*<bind>*/x = 1/*</bind>*/;
    }
}
"), null);

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B() : this(1) { _ = /*<bind>*/x = 1/*</bind>*/; }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B() : this(1) { _ = /*<bind>*/x = 1/*</bind>*/; }
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x)
    {
        X();
        int X() => /*<bind>*/x = 1/*</bind>*/;
    }
}
"), null);

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x)
    {
        X();
        static int X() => /*<bind>*/x = 1/*</bind>*/;
    }
}
"), null);

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x)
    {
        _ = () => /*<bind>*/x = 1/*</bind>*/;
    }
}
"), null);

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x)
    {
        _ = static () => /*<bind>*/x = 1/*</bind>*/;
    }
}
"), null);

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B() : this(/*<bind>*/x = 1/*</bind>*/) {}
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B() : this(/*<bind>*/x = 1/*</bind>*/) {}
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x) : this(() => /*<bind>*/x = 1/*</bind>*/)
    {
    }

    B(System.Func<int> x){}
}
"), null);

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(int x) : this(static () => /*<bind>*/x = 1/*</bind>*/)
    {
    }

    B(System.Func<int> x){}
}
"), null);

            static void verify(DataFlowAnalysis analysis, string dataFlowsOut = "x")
            {
                Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Equal(dataFlowsOut, GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_15()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int X() => /*<bind>*/x = 1/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int X() => /*<bind>*/x = 1/*</bind>*/;
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(out int x)
    {
        x = 1;
        X();
        int X() => /*<bind>*/x = 1/*</bind>*/;
    }
}
"), xIsAssignedOnEntry: false);

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(out int x)
    {
        x = 1;
        X();
        static int X() => /*<bind>*/x = 1/*</bind>*/;
    }
}
"), xIsAssignedOnEntry: false);

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(out int x)
    {
        x = 1;
        _ = () => /*<bind>*/x = 1/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    void M(out int x)
    {
        x = 1;
        _ = static () => /*<bind>*/x = 1/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    B() : this(1) { _ = /*<bind>*/x = 1/*</bind>*/; }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    B() : this(1) { _ = /*<bind>*/x = 1/*</bind>*/; }
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(out int x)
    {
        x = 1;
        X();
        int X() => /*<bind>*/x = 1/*</bind>*/;
    }
}
"), xIsAssignedOnEntry: false);

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(out int x)
    {
        x = 1;
        X();
        static int X() => /*<bind>*/x = 1/*</bind>*/;
    }
}
"), xIsAssignedOnEntry: false);

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(out int x)
    {
        x = 1;
        _ = () => /*<bind>*/x = 1/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(out int x)
    {
        x = 1;
        _ = static () => /*<bind>*/x = 1/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    B() : this(/*<bind>*/x = 1/*</bind>*/) {}
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    B() : this(/*<bind>*/x = 1/*</bind>*/) {}
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(out int x) : this(x = 1, () => /*<bind>*/x = 1/*</bind>*/)
    {
    }

    B(int x, System.Func<int> x){}
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    B(out int x) : this(x = 1, static () => /*<bind>*/x = 1/*</bind>*/)
    {
    }

    B(int x, System.Func<int> x){}
}
"));

            static void verify(DataFlowAnalysis analysis, bool xIsAssignedOnEntry = true)
            {
                Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("this" + (xIsAssignedOnEntry ? ", x" : ""), GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_16()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    int X = /*<bind>*/x = 1/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    int X { get; } = /*<bind>*/x = 1/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(System.Action x)
{
    event System.Action X = /*<bind>*/x = null/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    int X = /*<bind>*/x = 1/*</bind>*/;
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    int X { get; } = /*<bind>*/x = 1/*</bind>*/;
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(System.Action x)
{
    event System.Action X = /*<bind>*/x = null/*</bind>*/;
    System.Action M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    static void M(int x)
    {
        _ = /*<bind>*/x = 1/*</bind>*/;
    }
}
"), null);

            static void verify(DataFlowAnalysis analysis, string dataFlowsOut = "x")
            {
                Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(analysis.Captured));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Equal(dataFlowsOut, GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        [Fact]
        public void PrimaryConstructors_17()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    int X = /*<bind>*/x = 1/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    int X { get; } = /*<bind>*/x = 1/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out System.Action x)
{
    int Y = x = null;
    event System.Action X = /*<bind>*/x = null/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    int X = /*<bind>*/x = 1/*</bind>*/;
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    int X { get; } = /*<bind>*/x = 1/*</bind>*/;
    int M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out System.Action x)
{
    int Y = x = null;
    event System.Action X = /*<bind>*/x = null/*</bind>*/;
    System.Action M() => x;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B
{
    static void M(out int x)
    {
        _ = /*<bind>*/x = 1/*</bind>*/;
    }
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(analysis.Captured));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Null(GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        [Fact]
        public void PrimaryConstructors_18()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x) : A(/*<bind>*/x = 1/*</bind>*/)
{
}

class A(int x);
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x) : A(/*<bind>*/x = 1/*</bind>*/)
{
    int M() => x;
}

class A(int x);
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B : A
{
    B(int x) : base(/*<bind>*/x = 1/*</bind>*/)
    {
    }
}

class A(int x);
"), null);

            static void verify(DataFlowAnalysis analysis, string dataFlowsOut = "x")
            {
                Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(analysis.Captured));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Equal(dataFlowsOut, GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_19()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x) : A(/*<bind>*/x = 1/*</bind>*/)
{
}

class A(int x);
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x) : A(/*<bind>*/x = 1/*</bind>*/)
{
    int M() => x;
}

class A(int x);
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B : A
{
    B(out int x) : base(/*<bind>*/x = 1/*</bind>*/)
    {
    }
}

class A(int x);
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Null(GetSymbolNamesJoined(analysis.Captured));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("this", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("this, x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_20()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    void X(int y)
    {
        Y(1);
        int Y(int z) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    void X(int y)
    {
        Y(1);
        static int Y(int z) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    void X(int y)
    {
        _ = (int z) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    void X(int y)
    {
        _ = static (int z) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B(string y) : this(1)
    {
        Y(1);
        int Y(int z) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B(string y) : this(1)
    {
        Y(1);
        static int Y(int z) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B(string y) : this(1)
    {
        _ = (int z) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B(string y) : this(1)
    {
        _ = static (int z) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B(string y) : this((int z) => /*<bind>*/x/*</bind>*/) {}

    B(System.Action<int> x) : this(1) {} 
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B(string y) : this(static (int z) => /*<bind>*/x/*</bind>*/) {}

    B(System.Action<int> x) : this(1) {} 
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("this, x, y, z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("this, x, y, z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x, y, z", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_21()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static void X(int y)
    {
        Y(1);
        int Y(int z) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static void X(int y)
    {
        Y(1);
        static int Y(int z) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static void X(int y)
    {
        _ = (int z) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static void X(int y)
    {
        _ = static (int z) => /*<bind>*/x/*</bind>*/;
    }
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("y, z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Equal("y, z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("y, z", GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        [Fact]
        public void PrimaryConstructors_22()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    System.Func<int, int> X = (int z) => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    System.Func<int, int> X { get; } = (int z) => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    event System.Func<int, int> X = (int z) => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    System.Func<int, int> X = static (int z) => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    System.Func<int, int> X { get; } = static (int z) => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    event System.Func<int, int> X = static (int z) => /*<bind>*/x/*</bind>*/;
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("x, z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Equal("x, z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("x, z", GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        [Fact]
        public void PrimaryConstructors_23()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static System.Func<int, int> X = (int z) => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static System.Func<int, int> X { get; } = (int z) => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static event System.Func<int, int> X = (int z) => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static System.Func<int, int> X = static (int z) => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static System.Func<int, int> X { get; } = static (int z) => /*<bind>*/x/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static event System.Func<int, int> X = static (int z) => /*<bind>*/x/*</bind>*/;
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Equal("z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("z", GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        [Fact]
        public void PrimaryConstructors_24()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x) : A((int z) => /*<bind>*/x/*</bind>*/)
{
}

class A(System.Func<int, int> x);
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x) : A(static (int z) => /*<bind>*/x/*</bind>*/)
{
}

class A(System.Func<int, int> x);
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("this, x, z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("this, x, z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x, z", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_25()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    void X(int y)
    {
        Y(1);
        void Y(int z1)
        {
            _ = (int z2) => /*<bind>*/x/*</bind>*/;
        }
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    void X(int y)
    {
        Y(1);
        static void Y(int z1)
        {
            _ = static (int z2) => /*<bind>*/x/*</bind>*/;
        }
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    void X(int y)
    {
        _ = (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        }
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    void X(int y)
    {
        _ = static (int z1) =>
        {
            Y(1);
            static int Y(int z2) => /*<bind>*/x/*</bind>*/;
        }
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B(string y) : this(1)
    {
        Y(1);
        void Y(int z1)
        {
            _ = (int z2) => /*<bind>*/x/*</bind>*/;
        }
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B(string y) : this(1)
    {
        Y(1);
        static void Y(int z1)
        {
            _ = static (int z2) => /*<bind>*/x/*</bind>*/;
        }
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B(string y) : this(1)
    {
        _ = (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        }
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B(string y) : this(1)
    {
        _ = static (int z1) =>
        {
            Y(1);
            static int Y(int z2) => /*<bind>*/x/*</bind>*/;
        }
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B(string y) : this((int z1) =>
                        {
                            Y(1);
                            int Y(int z2) => /*<bind>*/x/*</bind>*/;
                        }) {}

    B(System.Action<int> x) : this(1) {} 
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    B(string y) : this(static (int z1) =>
                        {
                            Y(1);
                            static int Y(int z2) => /*<bind>*/x/*</bind>*/;
                        }) {}

    B(System.Action<int> x) : this(1) {} 
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("this, x, y, z1, z2", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("this, x, y, z1, z2", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x, y, z1, z2", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_26()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static void X(int y)
    {
        Y(1);
        void Y(int z1)
        {
            _ = (int z2) => /*<bind>*/x/*</bind>*/;
        }
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static void X(int y)
    {
        Y(1);
        static void Y(int z1)
        {
            _ = static (int z2) => /*<bind>*/x/*</bind>*/;
        }
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static void X(int y)
    {
        _ = (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        }
    }
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static void X(int y)
    {
        _ = static (int z1) =>
        {
            Y(1);
            static int Y(int z2) => /*<bind>*/x/*</bind>*/;
        }
    }
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("y, z1, z2", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Equal("y, z1, z2", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("y, z1, z2", GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        [Fact]
        public void PrimaryConstructors_27()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    System.Action<int> X = (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    System.Action<int> X { get; } = (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    event System.Action<int> X = (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    System.Action<int> X = (int z1) =>
        {
            Y(1);
            static int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    System.Action<int> X { get; } = (int z1) =>
        {
            Y(1);
            static int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    event System.Action<int> X = (int z1) =>
        {
            Y(1);
            static int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    System.Action<int> X = static (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    System.Action<int> X { get; } = static (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    event System.Action<int> X = static (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("x, z1, z2", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Equal("x, z1, z2", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("x, z1, z2", GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        [Fact]
        public void PrimaryConstructors_28()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static System.Action<int> X = (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static System.Action<int> X { get; } = (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static event System.Action<int> X = (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static System.Action<int> X = (int z1) =>
        {
            Y(1);
            static int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static System.Action<int> X { get; } = (int z1) =>
        {
            Y(1);
            static int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static event System.Action<int> X = (int z1) =>
        {
            Y(1);
            static int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static System.Action<int> X = static (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static System.Action<int> X { get; } = static (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x)
{
    static event System.Action<int> X = static (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        };
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("z1, z2", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Equal("z1, z2", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("z1, z2", GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        [Fact]
        public void PrimaryConstructors_29()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x) : A((int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        })
{
}

class A(System.Action<int> x);
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x) : A(static (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x/*</bind>*/;
        })
{
}

class A(System.Action<int> x);
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(int x) : A((int z1) =>
        {
            Y(1);
            static int Y(int z2) => /*<bind>*/x/*</bind>*/;
        })
{
}

class A(System.Action<int> x);
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("this, x, z1, z2", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry, sort: true));
                Assert.Equal("this, x, z1, z2", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit, sort: true));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("this, x, z1, z2", GetSymbolNamesJoined(analysis.WrittenOutside, sort: true));
            }
        }

        [Fact]
        public void PrimaryConstructors_30()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    System.Action<int> X = (int z) => /*<bind>*/x = 1/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    System.Action<int> X { get; } = (int z) => /*<bind>*/x = 1/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = null;
    event System.Action<int> X = (int z) => /*<bind>*/x = 1/*</bind>*/;
}
"));
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    System.Action<int> X = static (int z) => /*<bind>*/x = 1/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    System.Action<int> X { get; } = static (int z) => /*<bind>*/x = 1/*</bind>*/;
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = null;
    event System.Action<int> X = static (int z) => /*<bind>*/x = 1/*</bind>*/;
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Equal("x, z", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("z", GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        [Fact]
        public void PrimaryConstructors_31()
        {
            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    System.Action<int> X = (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x = 1/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    System.Action<int> X { get; } = (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x = 1/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = null;
    event System.Action<int> X = (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x = 1/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    System.Action<int> X = static (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x = 1/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    System.Action<int> X { get; } = static (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x = 1/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = null;
    event System.Action<int> X = static (int z1) =>
        {
            Y(1);
            int Y(int z2) => /*<bind>*/x = 1/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    System.Action<int> X = (int z1) =>
        {
            Y(1);
            static int Y(int z2) => /*<bind>*/x = 1/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = 2;
    System.Action<int> X { get; } = (int z1) =>
        {
            Y(1);
            static int Y(int z2) => /*<bind>*/x = 1/*</bind>*/;
        };
}
"));

            verify(CompileAndAnalyzeDataFlowExpression(@"
class B(out int x)
{
    int Y = x = null;
    event System.Action<int> X = (int z1) =>
        {
            Y(1);
            static int Y(int z2) => /*<bind>*/x = 1/*</bind>*/;
        };
}
"));

            static void verify(DataFlowAnalysis analysis)
            {
                Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
                Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
                Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsOut));

                Assert.Equal("z1, z2", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
                Assert.Equal("x, z1, z2", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

                Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadOutside));

                Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
                Assert.Equal("z1, z2", GetSymbolNamesJoined(analysis.WrittenOutside));
            }
        }

        private const string InlineArray1Definition =
@"
[System.Runtime.CompilerServices.InlineArray(1)]
public struct Buffer1
{
    private int _element0;
}
";

        private const string InlineArray2Definition =
@"
[System.Runtime.CompilerServices.InlineArray(2)]
public struct Buffer2
{
    private int _element0;
}
";

        private const string InlineArray22Definition =
@"
[System.Runtime.CompilerServices.InlineArray(2)]
public struct Buffer22
{
    private Buffer2 _element0;
}
" + InlineArray2Definition;

        [Theory]
        [CombinatorialData]
        public void InlineArrays_010(bool isRef, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + (isRef ? "ref " : "") + @"Buffer2 x)
    {
        /*<bind>*/x[" + index + @"] = 1/*</bind>*/;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));

            if (isRef)
            {
                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsOut));
            }
            else
            {
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));
            }

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));

            if (isRef)
            {
                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadOutside));
            }
            else
            {
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));
            }

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_011([CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(Buffer2 x)
    {
        var d =  () => /*<bind>*/x[" + index + @"] = 1/*</bind>*/;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, d", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_020(bool isRef, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + (isRef ? "ref " : "") + @"Buffer22 x)
    {
        /*<bind>*/x[" + index + @"][" + index + @"] = 1/*</bind>*/;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));

            if (isRef)
            {
                Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsOut));
            }
            else
            {
                Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));
            }

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));

            if (isRef)
            {
                Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadOutside));
            }
            else
            {
                Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));
            }

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_030(bool isRef, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + (isRef ? "ref " : "") + @"Buffer2 x, int i)
    {
        /*<bind>*/x[" + index + @"] = 1/*</bind>*/;
        _ = x[i];
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x, i", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x, i", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, i", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, i", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_040(bool isRef, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + (isRef ? "ref " : "") + @"Buffer22 x, int i)
    {
        /*<bind>*/x[" + index + @"][" + index + @"] = 1/*</bind>*/;
        _ = x[i][i];
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x, i", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x, i", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, i", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, i", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_050(bool isRef, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + (isRef ? "ref " : "") + @"Buffer2 x)
    {
        ref int y = ref /*<bind>*/x[" + index + @"]/*</bind>*/;
        y++;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_051(bool isRef, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + (isRef ? "ref " : "") + @"Buffer2 x)
    {
        ref int y = ref /*<bind>*/x/*</bind>*/[" + index + @"];
        y++;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_052(bool isRef, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + (isRef ? "ref " : "") + @"Buffer2 x)
    {
        ref int y = ref x[/*<bind>*/" + index + @"/*</bind>*/];
        y++;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_060(bool isRef, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + (isRef ? "ref " : "") + @"Buffer22 x)
    {
        ref int y = ref /*<bind>*/x[" + index + @"][" + index + @"]/*</bind>*/;
        y++;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_061(bool isRef, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + (isRef ? "ref " : "") + @"Buffer22 x)
    {
        ref int y = ref /*<bind>*/x[" + index + @"]/*</bind>*/[" + index + @"];
        y++;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_062(bool isRef, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + (isRef ? "ref " : "") + @"Buffer22 x)
    {
        ref int y = ref /*<bind>*/x/*</bind>*/[" + index + @"][" + index + @"];
        y++;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_063(bool isRef, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + (isRef ? "ref " : "") + @"Buffer22 x)
    {
        ref int y = ref x[/*<bind>*/" + index + @"/*</bind>*/][" + index + @"];
        y++;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_064(bool isRef, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + (isRef ? "ref " : "") + @"Buffer22 x)
    {
        ref int y = ref x[" + index + @"][/*<bind>*/" + index + @"/*</bind>*/];
        y++;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_070([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer2 x)
    {
        ref readonly int y = ref /*<bind>*/x[" + index + @"]/*</bind>*/;
        _ = y;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_071([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer2 x)
    {
        ref readonly int y = ref /*<bind>*/x/*</bind>*/[" + index + @"];
        _ = y;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_072([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer2 x)
    {
        ref readonly int y = ref x[/*<bind>*/" + index + @"/*</bind>*/];
        _ = y;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_080([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        ref readonly int y = ref /*<bind>*/x[" + index + @"][" + index + @"]/*</bind>*/;
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_081([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        ref readonly int y = ref /*<bind>*/x[" + index + @"]/*</bind>*/[" + index + @"];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_082([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        ref readonly int y = ref /*<bind>*/x/*</bind>*/[" + index + @"][" + index + @"];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_083([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        ref readonly int y = ref x[/*<bind>*/" + index + @"/*</bind>*/][" + index + @"];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_084([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        ref readonly int y = ref x[" + index + @"][/*<bind>*/" + index + @"/*</bind>*/];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_090([CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M()
    {
        Buffer2 x;
        /*<bind>*/x[" + index + @"] = 1/*</bind>*/;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_091([CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M()
    {
        Buffer2 x = default;
        /*<bind>*/x[" + index + @"].F += 1/*</bind>*/;
    }
}
[System.Runtime.CompilerServices.InlineArray(2)]
public struct Buffer2
{
    private S _element0;
}

struct S
{
    public int F;
}
", TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void InlineArrays_100()
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M()
    {
        Buffer1 x;
        /*<bind>*/x[0] = 1/*</bind>*/;
    }
}
" + InlineArray1Definition, TargetFramework.Net80);

            Assert.Equal("x", GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Null(GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Null(GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Null(GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_110([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer2 x)
    {
        int y = /*<bind>*/x[" + index + @"]/*</bind>*/;
        _ = y;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_111([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer2 x)
    {
        int y = /*<bind>*/x/*</bind>*/[" + index + @"];
        _ = y;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_112([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer2 x)
    {
        int y = x[/*<bind>*/" + index + @"/*</bind>*/];
        _ = y;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_113([CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(Buffer2 x)
    {
        System.Action d = () =>
        {
            int y = /*<bind>*/x[" + index + @"]/*</bind>*/;
            _ = y;
        };   
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, d, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_120([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        int y = /*<bind>*/x[" + index + @"][" + index + @"]/*</bind>*/;
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_121([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        int y = /*<bind>*/x[" + index + @"]/*</bind>*/[" + index + @"];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_122([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        int y = /*<bind>*/x/*</bind>*/[" + index + @"][" + index + @"];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_123([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        int y = x[/*<bind>*/" + index + @"/*</bind>*/][" + index + @"];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_124([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        int y = x[" + index + @"][/*<bind>*/" + index + @"/*</bind>*/];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_130([CombinatorialValues("ref ", "in ", "")] string refModifier)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer2 x)
    {
        var y = /*<bind>*/x[0..2]/*</bind>*/;
        _ = y;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_131([CombinatorialValues("ref ", "in ", "")] string refModifier)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer2 x)
    {
        var y = /*<bind>*/x/*</bind>*/[0..2];
        _ = y;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_132([CombinatorialValues("ref ", "in ", "")] string refModifier)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer2 x)
    {
        var y = x[/*<bind>*/0..2/*</bind>*/];
        _ = y;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact]
        public void InlineArrays_133()
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(Buffer2 x)
    {
        System.Action d = () =>
        {
            var y = /*<bind>*/x[0..2]/*</bind>*/;
            _ = y;
        };
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, d, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_140([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        var y = /*<bind>*/x[" + index + @"][0..2]/*</bind>*/;
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_141([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        var y = /*<bind>*/x[" + index + @"]/*</bind>*/[0..2];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_142([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        var y = /*<bind>*/x/*</bind>*/[" + index + @"][0..2];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_143([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        var y = x[/*<bind>*/" + index + @"/*</bind>*/][0..2];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_144([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        var y = x[" + index + @"][/*<bind>*/0..2/*</bind>*/];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_150([CombinatorialValues("ref ", "in ", "")] string refModifier, bool readOnly)
        {
            if (refModifier == "in " && !readOnly)
            {
                return;
            }

            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer2 x)
    {
        var y = (System." + (readOnly ? "ReadOnly" : "") + @"Span<int>)/*<bind>*/x/*</bind>*/;
        _ = y;
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_153(bool readOnly)
        {
            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(Buffer2 x)
    {
        System.Action d = () =>
        {
            var y = (System." + (readOnly ? "ReadOnly" : "") + @"Span<int>)/*<bind>*/x/*</bind>*/;
            _ = y;
        };
    }
}
" + InlineArray2Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.Captured));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, d, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_160([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index, bool readOnly)
        {
            if (refModifier == "in " && !readOnly)
            {
                return;
            }

            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        var y = (System." + (readOnly ? "ReadOnly" : "") + @"Span<int>)/*<bind>*/x[" + index + @"]/*</bind>*/;
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_162([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index, bool readOnly)
        {
            if (refModifier == "in " && !readOnly)
            {
                return;
            }

            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        var y = (System." + (readOnly ? "ReadOnly" : "") + @"Span<int>)/*<bind>*/x/*</bind>*/[" + index + @"];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal(refModifier != "" ? "x, y" : "y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Theory]
        [CombinatorialData]
        public void InlineArrays_163([CombinatorialValues("ref ", "in ", "")] string refModifier, [CombinatorialValues(0, 1)] int index, bool readOnly)
        {
            if (refModifier == "in " && !readOnly)
            {
                return;
            }

            DataFlowAnalysis analysis = CompileAndAnalyzeDataFlowExpression(
@"
class B
{
    static void M(" + refModifier + @"Buffer22 x)
    {
        var y = (System." + (readOnly ? "ReadOnly" : "") + @"Span<int>)x[/*<bind>*/" + index + @"/*</bind>*/];
        _ = y;
    }
}
" + InlineArray22Definition, TargetFramework.Net80);

            Assert.Null(GetSymbolNamesJoined(analysis.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(analysis.Captured));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedInside));
            Assert.Null(GetSymbolNamesJoined(analysis.CapturedOutside));
            Assert.Null(GetSymbolNamesJoined(analysis.VariablesDeclared));

            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(analysis.DataFlowsOut));

            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnEntry));
            Assert.Equal("x", GetSymbolNamesJoined(analysis.DefinitelyAssignedOnExit));

            Assert.Null(GetSymbolNamesJoined(analysis.ReadInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.ReadOutside));

            Assert.Null(GetSymbolNamesJoined(analysis.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(analysis.WrittenOutside));
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69148")]
        public void RefField_Assignment()
        {
            var comp = CreateCompilation("""
                ref struct RS
                {
                    ref int ri;
                    public RS() => ri = 0;
                }
                """,
                targetFramework: TargetFramework.NetCoreApp);
            comp.VerifyEmitDiagnostics(
                // (3,13): warning CS9265: Field 'RS.ri' is never ref-assigned to, and will always have its default value (null reference)
                //     ref int ri;
                Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "ri").WithArguments("RS.ri").WithLocation(3, 13),
                // (4,20): warning CS9201: Ref field 'ri' should be ref-assigned before use.
                //     public RS() => ri = 0;
                Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(4, 20));

            var tree = comp.CommonSyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var assignment = tree.GetRoot().DescendantNodes().OfType<AssignmentExpressionSyntax>().Single();

            var flowAnalysis = model.AnalyzeDataFlow(assignment);
            Assert.Equal("this", GetSymbolNamesJoined(flowAnalysis.ReadInside));
            Assert.Equal("this", GetSymbolNamesJoined(flowAnalysis.WrittenInside));
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69148")]
        public void RefField_RefAssignment()
        {
            var comp = CreateCompilation("""
                ref struct RS
                {
                    ref int ri;
                    public unsafe RS() => ri = ref *default(int*);
                }
                """,
                targetFramework: TargetFramework.NetCoreApp,
                options: TestOptions.UnsafeDebugDll);
            comp.VerifyEmitDiagnostics();

            var tree = comp.CommonSyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var assignment = tree.GetRoot().DescendantNodes().OfType<AssignmentExpressionSyntax>().Single();

            var flowAnalysis = model.AnalyzeDataFlow(assignment);
            Assert.Null(GetSymbolNamesJoined(flowAnalysis.ReadInside));
            Assert.Equal("this", GetSymbolNamesJoined(flowAnalysis.WrittenInside));
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38087")]
        public void Repro_38087()
        {
            var comp = CreateCompilation("""
                class Program
                {
                    private static void Repro()
                    {
                        int i = 1, j = 2;
                        int k = i + j + 1;
                    }
                }
                """);
            comp.VerifyEmitDiagnostics();

            var tree = comp.CommonSyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);

            var decls = tree.GetRoot().DescendantNodes().OfType<LocalDeclarationStatementSyntax>().ToArray();
            Assert.Equal(2, decls.Length);
            var decl = decls[1];
            Assert.Equal("int k = i + j + 1;", decl.ToString());
            var flowAnalysis = model.AnalyzeDataFlow(decl);
            Assert.Equal("i, j", GetSymbolNamesJoined(flowAnalysis.ReadInside));

            var binOps = tree.GetRoot().DescendantNodes().OfType<BinaryExpressionSyntax>().ToArray();
            Assert.Equal(2, binOps.Length);
            var add = binOps[0];
            Assert.Equal("i + j + 1", add.ToString());
            flowAnalysis = model.AnalyzeDataFlow(add);
            Assert.Equal("i, j", GetSymbolNamesJoined(flowAnalysis.ReadInside));

            add = binOps[1];
            Assert.Equal("i + j", add.ToString());
            flowAnalysis = model.AnalyzeDataFlow(add);
            Assert.Equal("i, j", GetSymbolNamesJoined(flowAnalysis.ReadInside));
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38087")]
        public void FourBinaryOperands()
        {
            var comp = CreateCompilation("""
                class Program
                {
                    private static void Repro()
                    {
                        int i = 1, j = 2, k = 3, l = 4;
                        _ = i + j + k + l;
                    }
                }
                """);
            comp.VerifyEmitDiagnostics();

            var tree = comp.CommonSyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);

            var decl = tree.GetRoot().DescendantNodes().OfType<ExpressionStatementSyntax>().Single();
            Assert.Equal("_ = i + j + k + l;", decl.ToString());
            var flowAnalysis = model.AnalyzeDataFlow(decl);
            Assert.Equal("i, j, k, l", GetSymbolNamesJoined(flowAnalysis.ReadInside));

            var binOps = tree.GetRoot().DescendantNodes().OfType<BinaryExpressionSyntax>().ToArray();
            Assert.Equal(3, binOps.Length);
            var add = binOps[0];
            Assert.Equal("i + j + k + l", add.ToString());
            flowAnalysis = model.AnalyzeDataFlow(add);
            Assert.Equal("i, j, k, l", GetSymbolNamesJoined(flowAnalysis.ReadInside));

            add = binOps[1];
            Assert.Equal("i + j + k", add.ToString());
            flowAnalysis = model.AnalyzeDataFlow(add);
            Assert.Equal("i, j, k", GetSymbolNamesJoined(flowAnalysis.ReadInside));

            add = binOps[2];
            Assert.Equal("i + j", add.ToString());
            flowAnalysis = model.AnalyzeDataFlow(add);
            Assert.Equal("i, j", GetSymbolNamesJoined(flowAnalysis.ReadInside));
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38087")]
        public void BinaryOpConditionalAccess()
        {
            var comp = CreateCompilation("""
                class C
                {
                    public bool M(out int x) { x = 0; return false; }

                    private static void Repro(C c)
                    {
                        const bool y = true;
                        const bool z = true;
                        int x;
                        _ = c?.M(out x) == y == z;
                    }
                }
                """);
            comp.VerifyEmitDiagnostics();

            var tree = comp.CommonSyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);

            var decl = tree.GetRoot().DescendantNodes().OfType<ExpressionStatementSyntax>().Last();
            Assert.Equal("_ = c?.M(out x) == y == z;", decl.ToString());
            var flowAnalysis = model.AnalyzeDataFlow(decl);
            Assert.Equal("c, y, z", GetSymbolNamesJoined(flowAnalysis.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(flowAnalysis.WrittenInside));

            var binOps = tree.GetRoot().DescendantNodes().OfType<BinaryExpressionSyntax>().ToArray();
            Assert.Equal(2, binOps.Length);

            var binOp = binOps[0];
            Assert.Equal("c?.M(out x) == y == z", binOp.ToString());
            flowAnalysis = model.AnalyzeDataFlow(binOp);
            Assert.Equal("c, y, z", GetSymbolNamesJoined(flowAnalysis.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(flowAnalysis.WrittenInside));

            binOp = binOps[1];
            Assert.Equal("c?.M(out x) == y", binOp.ToString());
            flowAnalysis = model.AnalyzeDataFlow(binOp);
            Assert.Equal("c, y", GetSymbolNamesJoined(flowAnalysis.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(flowAnalysis.WrittenInside));
        }
    }
}
