// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.CompilerServices;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.DotNet.ApiSymbolExtensions;
using Microsoft.DotNet.ApiSymbolExtensions.Filtering;
using Microsoft.DotNet.ApiSymbolExtensions.Logging;
using Microsoft.DotNet.ApiSymbolExtensions.Tests;
using Microsoft.DotNet.GenAPI.Filtering;

namespace Microsoft.DotNet.GenAPI.Tests
{
    public class CSharpFileBuilderTests
    {
        class AllowAllFilter : ISymbolFilter
        {
            public bool Include(ISymbol symbol) => true;
        }

        private static MetadataReference[] MetadataReferences { get; } = new[] { MetadataReference.CreateFromFile(typeof(object).Assembly!.Location!) };

        private static SyntaxTree GetSyntaxTree(string syntax) =>
            CSharpSyntaxTree.ParseText(syntax);

        private void RunTest(string original,
            string expected,
            bool includeInternalSymbols = true,
            bool includeEffectivelyPrivateSymbols = true,
            bool includeExplicitInterfaceImplementationSymbols = true,
            bool allowUnsafe = false,
            string excludedAttributeFile = null,
            [CallerMemberName] string assemblyName = "")
        {
            StringWriter stringWriter = new();

            // Configure symbol filters
            AccessibilitySymbolFilter accessibilitySymbolFilter = new(
                includeInternalSymbols,
                includeEffectivelyPrivateSymbols,
                includeExplicitInterfaceImplementationSymbols);

            CompositeSymbolFilter symbolFilter = new CompositeSymbolFilter()
                .Add(new ImplicitSymbolFilter())
                .Add(accessibilitySymbolFilter);

            CompositeSymbolFilter attributeDataSymbolFilter = new();
            if (excludedAttributeFile is not null)
            {
                attributeDataSymbolFilter.Add(new DocIdSymbolFilter(new string[] { excludedAttributeFile }));
            }
            attributeDataSymbolFilter.Add(accessibilitySymbolFilter);

            IAssemblySymbolWriter csharpFileBuilder = new CSharpFileBuilder(
                new ConsoleLog(MessageImportance.Low),
                symbolFilter,
                attributeDataSymbolFilter,
                stringWriter,
                null,
                false,
                MetadataReferences);

            using Stream assemblyStream = SymbolFactory.EmitAssemblyStreamFromSyntax(original, enableNullable: true, allowUnsafe: allowUnsafe, assemblyName: assemblyName);
            AssemblySymbolLoader assemblySymbolLoader = new(resolveAssemblyReferences: true, includeInternalSymbols: includeInternalSymbols);
            assemblySymbolLoader.AddReferenceSearchPaths(typeof(object).Assembly!.Location!);
            assemblySymbolLoader.AddReferenceSearchPaths(typeof(DynamicAttribute).Assembly!.Location!);
            IAssemblySymbol assemblySymbol = assemblySymbolLoader.LoadAssembly(assemblyName, assemblyStream);

            csharpFileBuilder.WriteAssembly(assemblySymbol);

            StringBuilder stringBuilder = stringWriter.GetStringBuilder();
            string resultedString = stringBuilder.ToString();

            stringBuilder.Remove(0, stringBuilder.Length);

            SyntaxTree resultedSyntaxTree = GetSyntaxTree(resultedString);
            SyntaxTree expectedSyntaxTree = GetSyntaxTree(expected);

            // compare SyntaxTree and not string representation
            Assert.True(resultedSyntaxTree.IsEquivalentTo(expectedSyntaxTree),
                $"Expected:\n{expected}\nResulted:\n{resultedString}");
        }

        [Fact]
        public void TestNamespaceDeclaration()
        {
            RunTest(original: """
                namespace A
                {
                namespace B {}

                namespace C.D { public struct Bar {} }
                }
                """,
                expected: """
                namespace A.C.D { public partial struct Bar {} }
                """);
        }

        [Fact]
        public void TestClassDeclaration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public class PublicClass { }

                    class InternalClass { }

                    public sealed class PublicSealedClass { }

                    public partial class ProtectedPartialClass { }
                }
                """,
                expected: """
                namespace Foo
                {
                    internal partial class InternalClass { }

                    /// `partial` keyword is not added!
                    public partial class ProtectedPartialClass { }

                    public partial class PublicClass { }

                    public sealed partial class PublicSealedClass { }
                }
                """);
        }

        [Fact]
        public void TestStructDeclaration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public struct PublicStruct { }

                    struct InternalStruct { }

                    readonly struct ReadonlyStruct { }

                    public readonly struct PublicReadonlyStruct { }

                    record struct RecordStruct { }

                    readonly record struct ReadonlyRecordStruct { }

                    public ref struct PublicRefStruct { }

                    public readonly ref struct PublicReadonlyRefStruct { }
                }
                """,
                // It's expected that record structs are expanded - they're effectively syntactic sugar that is not persisted in metadata
                expected: """
                namespace Foo
                {
                    internal partial struct InternalStruct
                    {
                    }

                    public readonly ref partial struct PublicReadonlyRefStruct
                    {
                    }

                    public readonly partial struct PublicReadonlyStruct
                    {
                    }

                    public ref partial struct PublicRefStruct
                    {
                    }

                    public partial struct PublicStruct
                    {
                    }

                    internal readonly partial struct ReadonlyRecordStruct : System.IEquatable<ReadonlyRecordStruct>
                    {
                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public readonly bool Equals(ReadonlyRecordStruct other) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly bool Equals(object obj) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly int GetHashCode() { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator ==(ReadonlyRecordStruct left, ReadonlyRecordStruct right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator !=(ReadonlyRecordStruct left, ReadonlyRecordStruct right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly string ToString() { throw null; }
                    }

                    internal readonly partial struct ReadonlyStruct
                    {
                    }

                    internal partial struct RecordStruct : System.IEquatable<RecordStruct>
                    {
                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public readonly bool Equals(RecordStruct other) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly bool Equals(object obj) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly int GetHashCode() { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator ==(RecordStruct left, RecordStruct right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator !=(RecordStruct left, RecordStruct right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly string ToString() { throw null; }
                    }
                }
                """);
        }

        [Fact]
        public void TestRecordDeclaration()
        {
            RunTest(original: """
                namespace Foo
                {   
                    public record RecordClass;
                    public record RecordClass1(int i);
                    public record RecordClass2(string s, int i);
                    public record DerivedRecord(string s, int i, double d) : RecordClass2(s, i);
                    public record DerivedRecord2(string x, int i, double d) : RecordClass2(default(string)!, i);
                    public record DerivedRecord3(string x, int i, double d) : RecordClass2(default(string)!, i);
                    public record DerivedRecord4(double d) : RecordClass2(default(string)!, default);
                    public record DerivedRecord5() : RecordClass2(default(string)!, default);
                
                    public record RecordClassWithMethods(int i)
                    {
                        public void DoSomething() { }
                        public static void DoSomethingStatic() { }
                    }

                    public record RecordClassWithProperties(int i)
                    {
                        public int AddI { get; set; }
                        public int AddIinit { get; init; }
                        public int AddIro { get; }
                    }
                    public record RecordClassWithConstructors(int i)
                    {
                        public RecordClassWithConstructors() : this(1) { }
                        public RecordClassWithConstructors(string s) : this(int.Parse(s)) { }
                    }
                    public record RecordWithPrivateDefaultConstructor
                    {
                        private RecordWithPrivateDefaultConstructor() { }
                    }
                    public sealed record SealedRecordWithPrivateDefaultConstructor
                    {
                        private SealedRecordWithPrivateDefaultConstructor() { }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial record DerivedRecord(string s, int i, double d) : RecordClass2(default!, default)
                    {
                    }

                    public partial record DerivedRecord2(string x, int i, double d) : RecordClass2(default!, default)
                    {
                    }

                    public partial record DerivedRecord3(string x, int i, double d) : RecordClass2(default!, default)
                    {
                    }

                    public partial record DerivedRecord4(double d) : RecordClass2(default!, default)
                    {
                    }

                    public partial record DerivedRecord5() : RecordClass2(default!, default)
                    {
                    }

                    public partial record RecordClass()
                    {
                    }

                    public partial record RecordClass1(int i)
                    {
                    }

                    public partial record RecordClass2(string s, int i)
                    {
                    }

                    public partial record RecordClassWithConstructors(int i)
                    {
                        public RecordClassWithConstructors() { }

                        public RecordClassWithConstructors(string s) { }
                    }

                    public partial record RecordClassWithMethods(int i)
                    {
                        public void DoSomething() { }

                        public static void DoSomethingStatic() { }
                    }

                    public partial record RecordClassWithProperties(int i)
                    {
                        public int AddI { get { throw null; } set { } }

                        public int AddIinit { get { throw null; } init { } }

                        public int AddIro { get { throw null; } }
                    }

                    public partial record RecordWithPrivateDefaultConstructor
                    {
                        private RecordWithPrivateDefaultConstructor() { }
                    }

                    public sealed partial record SealedRecordWithPrivateDefaultConstructor
                    {
                        private SealedRecordWithPrivateDefaultConstructor() { }
                    }
                }
                """);
        }

        [Fact]
        public void TestRecordStructDeclaration()
        {
            RunTest(original: """
                namespace Foo
                {
                    
                    public record struct RecordStruct;                    
                    public record struct RecordStruct1(int i);
                    public record struct RecordStruct2(string s, int i);
                
                    public record struct RecordStructWithMethods(int i)
                    {
                        public void DoSomething() { }
                        public static void DoSomethingStatic() { }
                    }

                    public record struct RecordStructWithProperties(int i)
                    {
                        public int AddI { get; set; }
                        public int AddIinit { get; init; }
                        public int AddIro { get; }
                    }
                    public record struct RecordStructWithConstructors(int i)
                    {
                        public RecordStructWithConstructors() : this(1) { }
                        public RecordStructWithConstructors(string s) : this(int.Parse(s)) { }
                    }
                
                }
                """,
                expected: """                
                namespace Foo
                {
                    public partial struct RecordStruct : System.IEquatable<RecordStruct>
                    {
                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public readonly bool Equals(RecordStruct other) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly bool Equals(object obj) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly int GetHashCode() { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator ==(RecordStruct left, RecordStruct right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator !=(RecordStruct left, RecordStruct right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly string ToString() { throw null; }
                    }

                    public partial struct RecordStruct1 : System.IEquatable<RecordStruct1>
                    {
                        private int _dummyPrimitive;
                        public RecordStruct1(int i) { }

                        public int i { get { throw null; } set { } }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public readonly void Deconstruct(out int i) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public readonly bool Equals(RecordStruct1 other) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly bool Equals(object obj) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly int GetHashCode() { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator ==(RecordStruct1 left, RecordStruct1 right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator !=(RecordStruct1 left, RecordStruct1 right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly string ToString() { throw null; }
                    }

                    public partial struct RecordStruct2 : System.IEquatable<RecordStruct2>
                    {
                        private object _dummy;
                        private int _dummyPrimitive;
                        public RecordStruct2(string s, int i) { }

                        public int i { get { throw null; } set { } }

                        public string s { get { throw null; } set { } }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public readonly void Deconstruct(out string s, out int i) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public readonly bool Equals(RecordStruct2 other) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly bool Equals(object obj) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly int GetHashCode() { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator ==(RecordStruct2 left, RecordStruct2 right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator !=(RecordStruct2 left, RecordStruct2 right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly string ToString() { throw null; }
                    }

                    public partial struct RecordStructWithConstructors : System.IEquatable<RecordStructWithConstructors>
                    {
                        private int _dummyPrimitive;
                        public RecordStructWithConstructors() { }

                        public RecordStructWithConstructors(int i) { }

                        public RecordStructWithConstructors(string s) { }

                        public int i { get { throw null; } set { } }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public readonly void Deconstruct(out int i) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public readonly bool Equals(RecordStructWithConstructors other) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly bool Equals(object obj) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly int GetHashCode() { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator ==(RecordStructWithConstructors left, RecordStructWithConstructors right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator !=(RecordStructWithConstructors left, RecordStructWithConstructors right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly string ToString() { throw null; }
                    }

                    public partial struct RecordStructWithMethods : System.IEquatable<RecordStructWithMethods>
                    {
                        private int _dummyPrimitive;
                        public RecordStructWithMethods(int i) { }

                        public int i { get { throw null; } set { } }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public readonly void Deconstruct(out int i) { throw null; }

                        public void DoSomething() { }

                        public static void DoSomethingStatic() { }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public readonly bool Equals(RecordStructWithMethods other) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly bool Equals(object obj) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly int GetHashCode() { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator ==(RecordStructWithMethods left, RecordStructWithMethods right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator !=(RecordStructWithMethods left, RecordStructWithMethods right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly string ToString() { throw null; }
                    }

                    public partial struct RecordStructWithProperties : System.IEquatable<RecordStructWithProperties>
                    {
                        private int _dummyPrimitive;
                        public RecordStructWithProperties(int i) { }

                        public int AddI { get { throw null; } set { } }

                        public int AddIinit { get { throw null; } init { } }

                        public int AddIro { get { throw null; } }

                        public int i { get { throw null; } set { } }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public readonly void Deconstruct(out int i) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public readonly bool Equals(RecordStructWithProperties other) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly bool Equals(object obj) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly int GetHashCode() { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator ==(RecordStructWithProperties left, RecordStructWithProperties right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public static bool operator !=(RecordStructWithProperties left, RecordStructWithProperties right) { throw null; }

                        [System.Runtime.CompilerServices.CompilerGenerated]
                        public override readonly string ToString() { throw null; }
                    }
                }
                """);
        }

        [Fact]
        public void TestInterfaceGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public interface IPoint
                    {
                        // Property signatures:
                        int X { get; set; }
                        int Y { get; set; }

                        double CalculateDistance(IPoint p);
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial interface IPoint
                    {
                        // Property signatures:
                        int X { get; set; }
                        int Y { get; set; }

                        double CalculateDistance(IPoint p);
                    }
                }
                """);
        }

        [Fact]
        public void TestEnumGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public enum Color
                    {
                        White = 0,
                        Green = 100,
                        Blue = 200
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public enum Color
                    {
                        White = 0,
                        Green = 100,
                        Blue = 200
                    }
                }
                """);
        }

        [Fact]
        public void TestPropertyGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public class Car
                    {
                        public int? Drivers { get; }
                        public int Wheels { get => 4; }
                        public bool IsRunning { get; set; }
                        public bool Is4x4 { get => false; set { } }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial class Car
                    {
                        public int? Drivers { get { throw null; } }
                        public bool Is4x4 { get { throw null; } set { } }
                        public bool IsRunning { get { throw null; } set { } }
                        public int Wheels { get { throw null; } }
                    }
                }
                """);
        }

        [Fact]
        public void TestAbstractPropertyGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    abstract class Car
                    {
                        abstract protected int? Wheels { get; }
                        abstract public bool IsRunning { get; set; }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    internal abstract partial class Car
                    {
                        public abstract bool IsRunning { get; set; }
                        protected abstract int? Wheels { get; }
                    }
                }
                """);
        }

        [Fact]
        public void TestExplicitInterfaceImplementation()
        {
            RunTest(original: """
                namespace Foo
                {
                    public interface IControl
                    {
                        void Paint();
                    }
                    public interface ISurface
                    {
                        void Paint();
                    }

                    public class SampleClass : IControl, ISurface
                    {
                        public void Paint()
                        {
                        }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial interface IControl
                    {
                        void Paint();
                    }
                    public partial interface ISurface
                    {
                        void Paint();
                    }

                    public partial class SampleClass : IControl, ISurface
                    {
                        public void Paint()
                        {
                        }
                    }
                }
                """);
        }

        [Fact]
        public void TestPartiallySpecifiedGenericClassGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public class BaseNodeMultiple<T, U> { }

                    public class Node4<T> : BaseNodeMultiple<T, int> { }

                    public class Node5<T, U> : BaseNodeMultiple<T, U> { }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial class BaseNodeMultiple <T, U> { }

                    public partial class Node4 <T> : BaseNodeMultiple<T, int> { }

                    public partial class Node5 <T, U> : BaseNodeMultiple<T, U> { }
                }
                """);
        }

        [Fact]
        public void TestGenericClassWitConstraintsParameterGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public class SuperKeyType<K, V, U>
                        where U : System.IComparable<U>
                        where V : new()
                    { }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial class SuperKeyType <K, V, U> where V : new()
                        where U : System.IComparable<U>
                    {
                    }
                }
                """);
        }

        [Fact]
        public void TestPublicMembersGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public enum Kind
                    {
                        None = 0,
                        Disable = 1
                    }

                    public readonly struct Options
                    {
                        public readonly bool BoolMember = true;
                        public readonly Kind KindMember = Kind.Disable;

                        public Options(Kind kindVal)
                            : this(kindVal, false)
                        {
                        }

                        public Options(Kind kindVal, bool boolVal)
                        {
                            BoolMember = boolVal;
                            KindMember = kindVal;
                        }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public enum Kind
                    {
                        None = 0,
                        Disable = 1
                    }

                    public readonly partial struct Options
                    {
                        public readonly bool BoolMember;
                        public readonly Kind KindMember;
                        public Options(Kind kindVal, bool boolVal) { }
                        public Options(Kind kindVal) { }
                    }
                }
                """);
        }

        [Fact]
        public void TestDelegateGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public delegate bool SyntaxReceiverCreator(int a, bool b);
                }
                """,
                expected: """
                namespace Foo
                {
                    public delegate bool SyntaxReceiverCreator(int a, bool b);
                }
                """);
        }

        [Fact]
        public void TestAbstractEventGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public abstract class AbstractEvents
                    {
                        public abstract event System.EventHandler<bool> TextChanged;
                    }

                    public class Events
                    {
                        public event System.EventHandler<string> OnNewMessage { add { } remove { } }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public abstract partial class AbstractEvents
                    {
                        public abstract event System.EventHandler<bool> TextChanged;
                    }

                    public partial class Events
                    {
                        public event System.EventHandler<string> OnNewMessage { add { } remove { } }
                    }
                }
                """);
        }

        [Fact]
        public void TestCustomAttributeGeneration()
        {
            RunTest(original: """
                using System;
                using System.Diagnostics;

                namespace Foo
                {
                    public enum Animal
                    {
                        Dog = 1,
                        Cat,
                        Bird,
                    }

                    public class AnimalTypeAttribute : Attribute
                    {
                        protected Animal thePet;

                        public AnimalTypeAttribute(Animal pet)
                        {
                            thePet = pet;
                        }

                        public Animal Pet
                        {
                            get { return thePet; }
                            set { thePet = value; }
                        }
                    }

                    [AnimalType(Animal.Cat)]
                    public class Creature
                    {
                        [AnimalType(Animal.Cat)]
                        [Conditional("DEBUG"), Conditional("TEST1")]
                        public void SayHello() { }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public enum Animal
                    {
                        Dog = 1,
                        Cat = 2,
                        Bird = 3
                    }

                    public partial class AnimalTypeAttribute : System.Attribute
                    {
                        protected Animal thePet;
                        public AnimalTypeAttribute(Animal pet) { }
                        public Animal Pet { get { throw null; } set { } }
                    }

                    [AnimalType(Animal.Cat)]
                    public partial class Creature
                    {
                        [AnimalType(Animal.Cat)]
                        [System.Diagnostics.Conditional("DEBUG")]
                        [System.Diagnostics.Conditional("TEST1")]
                        public void SayHello() { }
                    }
                }
                """);
        }

        [Fact]
        public void TestFullyQualifiedNamesForDefaultEnumParameters()
        {
            RunTest(original: """
                namespace Foo
                {
                    public enum Animal
                    {
                        Dog = 1,
                        Cat = 2,
                        Bird = 3
                    }

                    public class AnimalProperty {
                        public Animal _animal;

                        public AnimalProperty(Animal animal = Animal.Cat)
                        {
                            _animal = animal;
                        }

                        public int Execute(int p = 42) { return p; }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public enum Animal
                    {
                        Dog = 1,
                        Cat = 2,
                        Bird = 3
                    }

                    public partial class AnimalProperty {
                        public Animal _animal;

                        public AnimalProperty(Animal animal = Animal.Cat) { }

                        public int Execute(int p = 42) { throw null; }
                    }
                }
                """);
        }

        [Fact]
        public void TestCustomComparisonOperatorGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public class Car : System.IEquatable<Car>
                    {
                        public bool Equals(Car? c) { return true; }
                        public override bool Equals(object? o) { return true; }
                        public override int GetHashCode() => 0;
                        public static bool operator ==(Car lhs, Car rhs) { return true; }
                        public static bool operator !=(Car lhs, Car rhs) { return false; }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial class Car : System.IEquatable<Car>
                    {
                        public bool Equals(Car? c) { throw null; }
                        public override bool Equals(object? o) { throw null; }
                        public override int GetHashCode() { throw null; }
                        public static bool operator ==(Car lhs, Car rhs) { throw null; }
                        public static bool operator !=(Car lhs, Car rhs) { throw null; }
                    }
                }
                """);
        }

        [Fact]
        public void TestNestedClassGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public class Car
                    {
                        public class Engine
                        {
                            public class Cylinder
                            { }
                        }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial class Car
                    {
                        public partial class Engine
                        {
                            public partial class Cylinder
                            { }
                        }
                    }
                }
                """);
        }
        [Fact]
        public void TestExplicitInterfaceImplementationMethodGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public abstract class MemoryManager : System.IDisposable
                    {
                        void System.IDisposable.Dispose() { }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public abstract partial class MemoryManager : System.IDisposable
                    {
                        void System.IDisposable.Dispose() { }
                    }
                }
                """);
        }

        [Fact]
        public void TestNullabilityGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public class Bar
                    {
                        public int? AMember { get; set; }
                        public string? BMember { get; }

                        public string? Execute(string? a, int? b) { return null; }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial class Bar
                    {
                        public int? AMember { get { throw null; } set { } }
                        public string? BMember { get { throw null; } }

                        public string? Execute(string? a, int? b) { throw null; }
                    }
                }
                """);
        }

        [Fact]
        public void TestExtensionMethodsGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public static class MyExtensions
                    {
                        public static int WordCount(this string str) { return 42; }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public static partial class MyExtensions
                    {
                        public static int WordCount(this string str) { throw null; }
                    }
                }
                """);
        }

        [Fact]
        public void TestMethodsWithVariableNumberOfArgumentsGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public class Bar
                    {
                        public void Execute(params int[] list) { }
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial class Bar
                    {
                        public void Execute(params int[] list) { }
                    }
                }
                """);
        }

        [Fact]
        public void TestConversionOperatorGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public readonly struct Digit
                    {
                        private readonly byte digit;

                        public Digit(byte digit)
                        {
                            this.digit = digit;
                        }

                        public static implicit operator byte(Digit d) => d.digit;
                        public static explicit operator Digit(byte b) => new Digit(b);
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public readonly partial struct Digit
                    {
                        private readonly int _dummyPrimitive;

                        public Digit(byte digit) { }
                        public static explicit operator Digit(byte b) { throw null; }

                        public static implicit operator byte(Digit d) { throw null; }
                    }
                }
                """);
        }

        [Fact]
        public void TestDestructorGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public class Bar
                    {
                        ~Bar() {}
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial class Bar
                    {
                        ~Bar() {}
                    }
                }
                """);
        }

        [Fact]
        public void TestExplicitInterfaceImplementationPropertyGeneration()
        {
            RunTest(original: """
                    namespace Foo
                    {
                        public interface IFoo
                        {
                            int FooField { get; set; }
                            void FooMethod();
                        }

                        public class Bar : IFoo
                        {
                            int BarField { get; set; }
                            int IFoo.FooField { get; set; }

                            void IFoo.FooMethod() { }
                        }
                    }
                    """,
                expected: """
                    namespace Foo
                    {
                        public partial class Bar : IFoo
                        {
                            int IFoo.FooField { get { throw null; } set { } }
                            void IFoo.FooMethod() { }
                        }

                        public partial interface IFoo
                        {
                            int FooField { get; set; }
                            void FooMethod();
                        }
                    }
                    """);
        }

        [Fact]
        public void TestAccessibilityGenerationForPropertyAccessors()
        {
            RunTest(original: """
                    namespace Foo
                    {
                        public class Bar
                        {
                            public int P { get; protected set; }
                        }
                    }
                    """,
                expected: """
                    namespace Foo
                    {
                        public partial class Bar
                        {
                            public int P { get { throw null; } protected set { } }
                        }
                    }
                    """);
        }

        [Fact]
        public void TestConstantFieldGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public class Bar
                    {
                        public const int CurrentEra = 0;
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial class Bar
                    {
                        public const int CurrentEra = 0;
                    }
                }
                """
            );
        }

        [Fact]
        public void TestTypeParameterVarianceGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public delegate void Action<in T>(T obj);
                    public partial interface IAsyncEnumerable<out T>
                    {
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public delegate void Action<in T>(T obj);
                    public partial interface IAsyncEnumerable<out T>
                    {
                    }
                }
                """
            );
        }

        [Fact]
        public void TestRefMembersGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public class Bar<T>
                    {
                    #pragma warning disable CS8597
                        public ref T GetPinnableReference() { throw null; }
                        public ref readonly T this[int index] { get { throw null; } }
                        public ref int P { get { throw null; } }
                    #pragma warning restore CS8597
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial class Bar<T>
                    {
                    #pragma warning disable CS8597
                        public ref readonly T this[int index] { get { throw null; } }
                        public ref int P { get { throw null; } }
                        public ref T GetPinnableReference() { throw null; }
                    #pragma warning restore CS8597
                    }
                }
                """
            );
        }

        [Fact]
        public void TestDefaultConstraintOnOverrideGeneration()
        {
            RunTest(original: """
                namespace Foo
                {
                    public abstract partial class A
                    {
                        public abstract TResult? Accept<TResult>(int a);
                    }

                    public sealed partial class B : A
                    {
                    #pragma warning disable CS8597
                        public override TResult? Accept<TResult>(int a) where TResult : default { throw null; }
                    #pragma warning restore CS8597
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public abstract partial class A
                    {
                        public abstract TResult? Accept<TResult>(int a);
                    }

                    public sealed partial class B : A
                    {
                    #pragma warning disable CS8597
                        public override TResult? Accept<TResult>(int a) where TResult : default { throw null; }
                    #pragma warning restore CS8597
                    }
                }
                """
            );
        }

        [Fact]
        public void TestSynthesizePrivateFieldsForValueTypes()
        {
            RunTest(original: """
                using System;

                namespace Foo
                {
                    public struct Bar
                    {
                        #pragma warning disable 0169
                        private IntPtr intPtr;
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial struct Bar
                    {
                        private int _dummyPrimitive;
                    }
                }
                """);
        }

        [Fact]
        public void TestSynthesizePrivateFieldsForReferenceTypes()
        {
            RunTest(original: """
                namespace Foo
                {
                    public struct Bar
                    {
                        #pragma warning disable 0169
                        private object field;
                    }
                }
                """,
                expected: """
                namespace Foo
                {
                    public partial struct Bar
                    {
                        private object _dummy;
                        private int _dummyPrimitive;
                    }
                }
                """);
        }

        [Fact]
        public void TestSynthesizePrivateFieldsForGenericTypes()
        {
            RunTest(original: """
                namespace Foo
                {
                    public struct Bar<T>
                    {
                        #pragma warning disable 0169
                        private T _field;
                    }
                }
                """,
            expected: """
                namespace Foo
                {
                    public partial struct Bar<T>
                    {
                        private T _field;
                    }
                }
                """);
        }

        [Fact]
        public void TestSynthesizePrivateFieldsForNestedGenericTypes()
        {
            RunTest(original: """
                using System.Collections.Generic;

                namespace Foo
                {
                    public struct Bar<T> where T : notnull
                    {
                        #pragma warning disable 0169
                        private Dictionary<int, List<T>> _field;
                    }
                }
                """,
            expected: """
                namespace Foo
                {
                    public partial struct Bar<T>
                    {
                        private System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<T>> _field;
                        private object _dummy;
                        private int _dummyPrimitive;
                    }
                }
                """);
        }

        [Fact]
        public void TestSynthesizePrivateFieldsAngleBrackets()
        {
            RunTest(original: """
                using System.Collections.Generic;

                namespace Foo
                {
                    public readonly struct Bar<T> where T : notnull
                    {
                        public List<Bar<T>> Baz { get; }
                    }
                }
                """,
            expected: """
                namespace Foo
                {
                    public readonly partial struct Bar<T>
                    {
                        private readonly System.Collections.Generic.List<Bar<T>> _Baz_k__BackingField;
                        private readonly object _dummy;
                        private readonly int _dummyPrimitive;
                        public System.Collections.Generic.List<Bar<T>> Baz { get { throw null; } }
                    }
                }
                """);
        }

        [Fact]
        public void TestSynthesizePrivateFieldsForInaccessibleNestedGenericTypes()
        {
            RunTest(original: """
                namespace A
                {
                    internal class Bar<T> {}

                    public struct Foo<T>
                    {
                        #pragma warning disable 0169
                        // as the includeInternalSymbols field is set to false and the Bar<> class is internal -
                        //   we must skip generation of the `_field` private field.
                        private Bar<T> _field;
                    }
                }
                """,
            expected: """
                namespace A
                {
                    public partial struct Foo<T>
                    {
                        private object _dummy;
                        private int _dummyPrimitive;
                    }
                }
                """,
                includeInternalSymbols: false);
        }

        [Fact]
        public void TestBaseTypeWithoutExplicitDefault()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class B
                        {
                        }

                        public class C : B
                        {
                            public C() {}
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class B
                        {
                        }

                        public partial class C : B
                        {
                        }
                    }
                    """);
        }

        [Fact]
        public void TestBaseTypeWithExplicitDefaultConstructor()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class B
                        {
                            public B() {}
                        }

                        public class C : B
                        {
                            public C() {}
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class B
                        {
                        }

                        public partial class C : B
                        {
                        }
                    }
                    """);
        }

        [Fact]
        public void TestInternalParameterlessConstructors()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class B
                        {
                            internal B() {}
                        }

                        public class C : B
                        {
                            internal C() : base() {}
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class B
                        {
                            internal B() {}
                        }

                        public partial class C : B
                        {
                            internal C() {}
                        }
                    }
                    """,
                    includeInternalSymbols: false);
        }

        [Fact]
        public void TestInternalParameterizedConstructors()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class B
                        {
                            public B(int i) {}
                        }
                    
                        public class C : B
                        {
                            internal C() : base(0) {}
                        }
                    
                        public class D : B
                        {
                            internal D(int i) : base(i) {}
                        }

                        public class E
                        {
                            internal E(int i) {}
                            internal E(string s) {}
                            internal E(P p) {}
                        }

                        internal class P { }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class B
                        {
                            public B(int i) {}
                        }
                    
                        public partial class C : B
                        {
                            internal C() : base(default) {}
                        }

                        public partial class D : B
                        {
                            internal D() : base(default) {}
                        }

                        public partial class E
                        {
                            internal E() {}
                        }
                    }
                    """,
                    includeInternalSymbols: false);
        }

        [Fact]
        public void TestInternalParameterizedConstructorsPreserveInternals()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class B
                        {
                            public B(int i) {}
                        }
                    
                        public class C : B
                        {
                            internal C() : base(0) {}
                        }
                    
                        public class D : B
                        {
                            internal D(int i) : base(i) {}
                        }

                        public class E
                        {
                            internal E(int i) {}
                            internal E(string s) {}
                            internal E(P p) {}
                        }

                        internal class P { }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class B
                        {
                            public B(int i) { }
                        }

                        public partial class C : B
                        {
                            internal C() : base(default) { }
                        }

                        public partial class D : B
                        {
                            internal D(int i) : base(default) { }
                        }

                        public partial class E
                        {
                            internal E(P p) { }

                            internal E(int i) { }

                            internal E(string s) { }
                        }

                        internal partial class P
                        {
                        }
                    }
                    """,
                    includeInternalSymbols: true);
        }

        [Fact]
        public void TestInternalConstructorCallingProtected()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class B
                        {
                            protected B() {}
                        }

                        public class C : B
                        {
                            internal C() {}
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class B
                        {
                            protected B() {}
                        }                    
                    
                        public partial class C : B
                        {
                            internal C() {}
                        }
                    }
                    """,
                    includeInternalSymbols: false);
        }

        [Fact]
        public void TestBaseTypeWithoutDefaultConstructor()
        {
            RunTest(original: """
                    namespace Foo
                    {
                        public class A
                        {
                        }

                        public class B
                        {
                            public B(int p1, string p2, A p3) { }
                        }

                        public class C : B
                        {
                            public C() : base(1, "", new A()) {}
                        }
                    }
                    """,
                expected: """
                    namespace Foo
                    {
                        public partial class A
                        {
                        }

                        public partial class B
                        {
                            public B(int p1, string p2, A p3) { }
                        }

                        public partial class C : B
                        {
                            public C() : base(default, default!, default!) {}
                        }
                    }
                    """);
        }

        [Fact]
        public void TestBaseTypeWithMultipleNonDefaultConstructors()
        {
            RunTest(original: """
                    namespace Foo
                    {
                        public class A
                        {
                        }

                        public class B
                        {
                            public B(int p1, string p2, A p3) { }
                            public B(int p1, string p2) { }
                            public B(int p1) { }
                        }

                        public class C : B
                        {
                            public C() : base(1, "", new A()) {}
                        }
                    }
                    """,
                expected: """
                    namespace Foo
                    {
                        public partial class A
                        {
                        }

                        public partial class B
                        {
                            public B(int p1, string p2, A p3) { }
                            public B(int p1, string p2) { }
                            public B(int p1) { }
                        }

                        public partial class C : B
                        {
                            public C() : base(default) {}
                        }
                    }
                    """);
        }

        [Fact]
        public void TestBaseTypeWithAmbiguousNonDefaultConstructors()
        {
            RunTest(original: """
                    namespace Foo
                    {
                        public class A
                        {
                            public A(char c) { }
                            public A(int i) { }
                            public A(string s) { }
                        }

                        public class B : A
                        {
                            public B() : base("") {}
                        }
                    }
                    """,
                expected: """
                    namespace Foo
                    {
                        public partial class A
                        {
                            public A(char c) { }
                            public A(int i) { }
                            public A(string s) { }
                        }

                        public partial class B : A
                        {
                            public B() : base(default(char)) {}
                        }
                    }
                    """);
        }

        [Fact()]
        public void TestBaseTypeWithAmbiguousNonDefaultConstructorsRegression31655()
        {
            RunTest(original: """
                    namespace Foo
                    {
                        public class A
                        {
                            public A(Id id, System.Collections.Generic.IEnumerable<D> deps) { }
                            public A(string s, V v) { }
                        }

                        public class B : A
                        {
                            public B() : base(new Id(), new D[0]) {}
                        }

                        public class D { }

                        public class Id { }
                    
                        public class V { }
                    }
                    """,
                expected: """
                    namespace Foo
                    {
                        public partial class A
                        {
                            public A(Id id, System.Collections.Generic.IEnumerable<D> deps) { }
                            public A(string s, V v) { }
                        }

                        public partial class B : A
                        {
                            public B() : base(default!, default(System.Collections.Generic.IEnumerable<D>)!) {}
                        }

                        public partial class D { }

                        public partial class Id { }

                        public partial class V { }
                    }
                    """);
        }

        [Fact]
        public void TestBaseTypeConstructorWithObsoleteAttribute()
        {
            RunTest(original: """
                    namespace Foo
                    {
                        public class B
                        {
                            public B(int p1, string p2) { }
                            [System.Obsolete("Constructor is deprecated.", true)]
                            public B(int p1) { }
                        }

                        public class C : B
                        {
                            public C() : base(1, "") { }
                        }
                    }
                    """,
                expected: """
                    namespace Foo
                    {
                        public partial class B
                        {
                            public B(int p1, string p2) { }
                            [System.Obsolete("Constructor is deprecated.", true)]
                            public B(int p1) { }
                        }

                        public partial class C : B
                        {
                            public C() : base(default, default!) { }
                        }
                    }
                    """);
        }

        [Fact]
        public void TestObsoleteBaseTypeConstructorWithoutErrorParameter()
        {
            RunTest(original: """
                    namespace Foo
                    {
                        public class B
                        {
                            public B(int p1, string p2) { }
                            [System.Obsolete("Constructor is deprecated.")]
                            public B(int p1) { }
                        }

                        public class C : B
                        {
                            public C() : base(1, "") { }
                        }
                    }
                    """,
                expected: """
                    namespace Foo
                    {
                        public partial class B
                        {
                            public B(int p1, string p2) { }
                            [System.Obsolete("Constructor is deprecated.")]
                            public B(int p1) { }
                        }

                        public partial class C : B
                        {
                            public C() : base(default) { }
                        }
                    }
                    """);
        }

        [Fact]
        public void TestObsoleteBaseTypeConstructorWithoutMessageParameter()
        {
            RunTest(original: """
                    namespace Foo
                    {
                        public class B
                        {
                            public B(int p1, string p2) { }
                            [System.Obsolete(null)]
                            public B(int p1) { }
                        }

                        public class C : B
                        {
                            public C() : base(1, "") { }
                        }
                    }
                    """,
                expected: """
                    namespace Foo
                    {
                        public partial class B
                        {
                            public B(int p1, string p2) { }
                            [System.Obsolete(null)]
                            public B(int p1) { }
                        }

                        public partial class C : B
                        {
                            public C() : base(default) { }
                        }
                    }
                    """);
        }

        [Fact]
        public void TestFilterOutInternalExplicitInterfaceImplementation()
        {
            RunTest(original: """
                    namespace A
                    {
                        internal interface Foo
                        {
                            void XYZ();
                            int ABC { get; set; }
                        }

                        public class Bar : Foo
                        {
                            int Foo.ABC { get => 1; set { } }
                            void Foo.XYZ() { }
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class Bar
                        {
                        }
                    }
                    """,
                includeInternalSymbols: false);
        }

        [Fact]
        public void TestMethodsWithReferenceParameterGeneration()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class foo
                        {
                            public void Execute(out int i) { i = 1; }
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class foo
                        {
                            public void Execute(out int i) { throw null; }
                        }
                    }
                    """,
                includeInternalSymbols: false);
        }

        [Fact(Skip = "https://github.com/dotnet/roslyn/issues/67019")]
        public void TestInterfaceWithOperatorGeneration()
        {
            RunTest(original: """
                    namespace A
                    {
                        public interface IntType
                        {
                            public static IntType operator +(IntType left, IntType right) => left + right;
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial interface IntType
                        {
                            public static IntType operator +(IntType left, IntType right) => left + right;
                        }
                    }
                    """,
                 includeInternalSymbols: false);
        }

        [Fact(Skip = "https://github.com/dotnet/roslyn/issues/67019")]
        public void TestInterfaceWithCheckedOperatorGeneration()
        {
            RunTest(original: """
                    namespace A
                    {
                        public interface IAdditionOperators<TSelf, TOther, TResult>
                            where TSelf : IAdditionOperators<TSelf, TOther, TResult>?
                        {
                            static abstract TResult operator +(TSelf left, TOther right);
                            static virtual TResult operator checked +(TSelf left, TOther right) => left + right;
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public interface IAdditionOperators<TSelf, TOther, TResult>
                            where TSelf : IAdditionOperators<TSelf, TOther, TResult>?
                        {
                            static abstract TResult operator +(TSelf left, TOther right);
                            static virtual TResult operator checked +(TSelf left, TOther right) { throw null; }
                        }
                    }
                    """,
                 includeInternalSymbols: false);
        }

        [Fact]
        public void TestUnsafeFieldGeneration()
        {
            RunTest(original: """
                    namespace A
                    {
                        public struct Node
                        {
                            public unsafe Node* Left;
                            public unsafe Node* Right;
                            public int Value;
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial struct Node
                        {
                            public unsafe Node* Left;
                            public unsafe Node* Right;
                            public int Value;
                        }
                    }
                    """,
                includeInternalSymbols: false,
                allowUnsafe: true);
        }

        [Fact]
        public void TestUnsafeMethodGeneration()
        {
            RunTest(original: """
                    namespace A
                    {
                        public unsafe class A
                        {
                            public virtual void F(char* p) {}
                        }

                        public class B: A
                        {
                            public unsafe override void F(char* p) {}
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class A
                        {
                            public virtual unsafe void F(char* p) { }
                        }

                        public partial class B : A
                        {
                            public override unsafe void F(char* p) { }
                        }
                    }
                    """,
                includeInternalSymbols: false,
                allowUnsafe: true);
        }

        [Fact]
        public void TestUnsafeConstructorGeneration()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class Bar
                        {
                            public unsafe Bar(char* f) { }
                        }

                        public class Foo : Bar
                        {
                            public unsafe Foo(char* f) : base(f) { }
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class Bar
                        {
                            public unsafe Bar(char* f) { }
                        }

                        public partial class Foo : Bar
                        {
                            public unsafe Foo(char* f) : base(default) { }
                        }
                    }
                    """,
                includeInternalSymbols: false,
                allowUnsafe: true);
        }

        [Fact]
        public void TestUnsafeBaseConstructorGeneration()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class Bar
                        {
                            public unsafe Bar(char* f) { }
                        }

                        public class Foo : Bar
                        {
                            public unsafe Foo() : base(default) { }
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class Bar
                        {
                            public unsafe Bar(char* f) { }
                        }

                        public partial class Foo : Bar
                        {
                            public unsafe Foo() : base(default) { }
                        }
                    }
                    """,
                includeInternalSymbols: false,
                allowUnsafe: true);
        }

        [Fact]
        public void TestInternalDefaultConstructorGeneration()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class Bar
                        {
                            public Bar(int a) { }
                        }

                        public class Foo : Bar
                        {
                            internal Foo() : base(1) { }
                        }
                    }
                    namespace B
                    {
                        public class Bar
                        {
                            public Bar(int a) { }
                        }

                        public class Foo : Bar
                        {
                            private Foo() : base(1) { }
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class Bar
                        {
                            public Bar(int a) { }
                        }

                        public partial class Foo : Bar
                        {
                            internal Foo() : base(default) { }
                        }
                    }
                    namespace B
                    {
                        public partial class Bar
                        {
                            public Bar(int a) { }
                        }

                        public partial class Foo : Bar
                        {
                            internal Foo() : base(default) { }
                        }
                    }
                    """,
                includeInternalSymbols: false);
        }

        [Fact]
        public void TestPrivateDefaultConstructorGeneration()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class Bar
                        {
                            public Bar(int a) { }
                        }

                        public class Foo : Bar
                        {
                            private Foo() : base(1) { }
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class Bar
                        {
                            public Bar(int a) { }
                        }

                        public partial class Foo : Bar
                        {
                            private Foo() : base(default) { }
                        }
                    }
                    """,
                includeInternalSymbols: true,
                includeEffectivelyPrivateSymbols: true);
        }

        [Fact]
        public void TestInternalDefaultConstructorGenerationForGenericType()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class Bar
                        {
                            public Bar(int a) { }
                        }

                        public class Foo<T> : Bar
                        {
                            internal Foo() : base(1) { }
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class Bar
                        {
                            public Bar(int a) { }
                        }

                        public partial class Foo<T> : Bar
                        {
                            internal Foo() : base(default) { }
                        }
                    }
                    """,
                includeInternalSymbols: false);
        }

        [Fact]
        public void TestExplicitParameterlessConstructorNotRemoved()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class Bar
                        {
                            public Bar() { }
                            public Bar(int a) { }
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class Bar
                        {
                            public Bar() { }
                            public Bar(int a) { }
                        }
                    }
                    """,
                includeInternalSymbols: false);
        }

        [Fact]
        public void TestBaseClassWithExplicitDefaultConstructor()
        {
            RunTest(original: """
                    namespace A
                    {
                        public class Bar
                        {
                            public Bar() { }
                        }

                        public class Foo : Bar
                        {
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class Bar
                        {
                        }

                        public partial class Foo : Bar
                        {
                        }
                    }
                    """,
                includeInternalSymbols: false);
        }

        [Fact]
        public void TestGenericBaseInterfaceWithInaccessibleTypeArguments()
        {
            RunTest(original: """
                    namespace A
                    {
                        internal class IOption2
                        {
                        }

                        public interface IOption
                        {
                        }

                        public interface AreEqual<T>
                        {
                            bool Compare(T other);
                        }

                        public class PerLanguageOption : AreEqual<IOption2>, IOption
                        {
                            bool AreEqual<IOption2>.Compare(IOption2 other) => false;
                        }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial interface AreEqual<T>
                        {
                            bool Compare(T other);
                        }

                        public partial interface IOption
                        {
                        }

                        public partial class PerLanguageOption : IOption
                        {
                        }
                    }
                    """,
                includeInternalSymbols: false);
        }

        [Fact]
        public void NewKeywordWhenBaseMethodIsHidden()
        {
            RunTest(original: """
                    namespace A
                    {
                        using System;
                        public partial class C : IFun, IExplicit, IExplicit2 {
                            public int Foo;
                            public const int Bar = 29;
                            public int Baz { get; }
                            public int ExplicitProperty { get; }
                            #pragma warning disable 8618
                            public event EventHandler MyEvent;
                            void IExplicit.Explicit() {}
                            #pragma warning disable 8625
                            public void Do() => MyEvent(default(object), default(EventArgs));
                            public void Do(float f) {}
                            public static void DoStatic() {}
                            public void Explicit2() {}
                            public void Fun() {}
                            public void Gen<T>() {}
                            public void Zoo() {}
                            public class MyNestedClass {}
                            public struct MyNestedStruct {}
                            public class MyNestedGenericClass<T> {}
                            public struct MyNestedGenericStruct<T> {}
                            public C this[int i]
                            {
                              get => default(C)!;
                              set {}
                            }
                        }
                        public class D : C, IExplicit, IExplicit2 {
                            public new int Foo;
                            public new const int Bar = 30;
                            int IExplicit2.ExplicitProperty { get; }
                            public new int Baz { get; set; }
                            public new event EventHandler MyEvent;
                            void IExplicit2.Explicit2() {}
                            public new void Do() => MyEvent(default(object), default(EventArgs));
                            public void Do(int i) {}
                            public new static void DoStatic() {}
                            public void Explicit() {}
                            public new void Fun() {}
                            public new void Gen<T>() where T : IComparable {}
                            public new class MyNestedClass {}
                            public new struct MyNestedStruct {}
                            public new class MyNestedGenericClass<T> {}
                            public new struct MyNestedGenericStruct<T> {}
                            public new D this[int i]
                            {
                              get => default(D)!;
                              set {}
                            }
                        }
                        public class E : C, IExplicit, IExplicit2 {
                            public new int Bar;
                            public new const int Do = 30;
                            int IExplicit2.ExplicitProperty { get; }
                            public new int Foo { get; set; }
                            public new event EventHandler MyNestedClass;
                            void IExplicit.Explicit() {}
                            void IExplicit2.Explicit2() {}
                            public new void Baz() => MyNestedClass(default(object), default(EventArgs));
                            public new void MyNestedStruct(double d) {}
                            public new void Zoo() {}
                        }
                        public interface IExplicit {
                            void Explicit();
                        }
                        public interface IExplicit2 {
                            int ExplicitProperty { get; }
                            void Explicit2();
                        }
                        public interface IFun {
                            void Fun();
                        }
                    }
                    """,
                    expected: """
                    namespace A
                    {
                        public partial class C : IFun, IExplicit, IExplicit2
                        {
                            public const int Bar = 29;
                            public int Foo;
                            public int Baz { get { throw null; } }
                            public int ExplicitProperty { get { throw null; } }
                            public C this[int i] { get { throw null; } set {} }
                            public event System.EventHandler MyEvent { add {} remove {} }
                            void IExplicit.Explicit() {}
                            public void Do() {}
                            public void Do(float f) {}
                            public static void DoStatic() {}
                            public void Explicit2() {}
                            public void Fun() {}
                            public void Gen<T>() {}
                            public void Zoo() {}
                            public partial class MyNestedClass {}
                            public partial class MyNestedGenericClass<T> {}
                            public partial struct MyNestedGenericStruct<T> {}
                            public partial struct MyNestedStruct {}
                        }
                        public partial class D : C, IExplicit, IExplicit2
                        {
                            public new const int Bar = 30;
                            public new int Foo;
                            int IExplicit2.ExplicitProperty { get { throw null; } }
                            public new int Baz { get { throw null; } set {} }
                            public new D this[int i] { get { throw null; } set {} }
                            public new event System.EventHandler MyEvent { add {} remove {} }
                            void IExplicit2.Explicit2() {}
                            public new void Do() {}
                            public void Do(int i) {}
                            public new static void DoStatic() {}
                            public void Explicit() {}
                            public new void Fun() {}
                            public new void Gen<T>() where T : System.IComparable {}
                            public new partial class MyNestedClass {}
                            public new partial class MyNestedGenericClass<T> {}
                            public new partial struct MyNestedGenericStruct<T> {}
                            public new partial struct MyNestedStruct {}
                        }
                        public partial class E : C, IExplicit, IExplicit2
                        {
                            public new int Bar;
                            public new const int Do = 30;
                            int IExplicit2.ExplicitProperty { get { throw null; } }
                            public new int Foo { get { throw null; } set {} }
                            public new event System.EventHandler MyNestedClass { add {} remove {} }
                            void IExplicit.Explicit() {}
                            void IExplicit2.Explicit2() {}
                            public new void Baz() {}
                            public new void MyNestedStruct(double d) {}
                            public new void Zoo() {}
                        }
                        public partial interface IExplicit {
                            void Explicit();
                        }
                        public partial interface IExplicit2 {
                            int ExplicitProperty { get; }
                            void Explicit2();
                        }
                        public partial interface IFun {
                            void Fun();
                        }
                    }
                    """);
        }

        [Theory]
        [InlineData(true)]
        [InlineData(false)]
        public void TestAttributeWithInternalTypeArgumentOmitted(bool includeInternalSymbols)
        {
            string expected = includeInternalSymbols ? """
                    namespace A
                    {
                        public partial class AnyTestAttribute : System.Attribute
                        {
                            public AnyTestAttribute(System.Type xType) { }

                            public System.Type XType { get { throw null; } set { } }
                        }

                        internal partial class InternalClass
                        {
                        }

                        [AnyTest(typeof(InternalClass))]
                        [System.Obsolete]
                        public partial class PublicClass
                        {
                        }
                    }
                    """ : """
                    namespace A
                    {
                        public partial class AnyTestAttribute : System.Attribute
                        {
                            public AnyTestAttribute(System.Type xType) { }

                            public System.Type XType { get { throw null; } set { } }
                        }

                        [System.Obsolete]
                        public partial class PublicClass
                        {
                        }
                    }
                    """;

            RunTest(original: """
                    namespace A
                    {
                        internal class InternalClass { }
                        public partial class AnyTestAttribute : System.Attribute
                        {
                            public AnyTestAttribute(System.Type xType)
                            {
                                XType = xType;
                            }

                            public System.Type XType { get; set; }
                        }

                        [AnyTest(typeof(InternalClass))]
                        [System.Obsolete]
                        public class PublicClass { }
                    }
                    """,
                expected: expected,
                includeInternalSymbols: includeInternalSymbols);
        }

        [Fact]
        public void TestAttributesExcludedWithFilter()
        {
            using TempDirectory root = new();
            string filePath = Path.Combine(root.DirPath, "exclusions.txt");
            File.WriteAllText(filePath, "T:A.AnyTestAttribute");

            RunTest(original: """
                    namespace A
                    {
                        public partial class AnyTestAttribute : System.Attribute
                        {
                            public AnyTestAttribute(System.Type xType)
                            {
                                XType = xType;
                            }

                            public System.Type XType { get; set; }
                        }

                        [AnyTest(typeof(string))]
                        [System.Obsolete]
                        public class PublicClass { }
                    }
                    """,
                expected: """
                    namespace A
                    {
                        public partial class AnyTestAttribute : System.Attribute
                        {
                            public AnyTestAttribute(System.Type xType) { }

                            public System.Type XType { get { throw null; } set { } }
                        }

                        [System.Obsolete]
                        public partial class PublicClass
                        {
                        }
                    }
                    """,
                includeInternalSymbols: false,
                excludedAttributeFile: filePath);
        }

        [Fact]
        public void TestGenericClassImplementsGenericInterface()
        {
            RunTest(original: """
                    using System;
                    namespace A
                    {
                        public class Foo<T> : System.Collections.ICollection, System.Collections.Generic.ICollection<T>
                        {
                            int System.Collections.Generic.ICollection<T>.Count => throw new NotImplementedException();
                            bool System.Collections.Generic.ICollection<T>.IsReadOnly => throw new NotImplementedException();
                            int System.Collections.ICollection.Count => throw new NotImplementedException();
                            bool System.Collections.ICollection.IsSynchronized => throw new NotImplementedException();
                            object System.Collections.ICollection.SyncRoot => throw new NotImplementedException();
                            void System.Collections.Generic.ICollection<T>.Add(T item) => throw new NotImplementedException();
                            void System.Collections.Generic.ICollection<T>.Clear() => throw new NotImplementedException();
                            bool System.Collections.Generic.ICollection<T>.Contains(T item) => throw new NotImplementedException();
                            void System.Collections.Generic.ICollection<T>.CopyTo(T[] array, int arrayIndex) => throw new NotImplementedException();
                            bool System.Collections.Generic.ICollection<T>.Remove(T item) => throw new NotImplementedException();
                            System.Collections.Generic.IEnumerator<T> System.Collections.Generic.IEnumerable<T>.GetEnumerator() => throw new NotImplementedException();
                            void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw new NotImplementedException();
                            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw new NotImplementedException();

                        }
                    }
                    
                    """,
                // https://github.com/dotnet/sdk/issues/32195 tracks interface expansion
                expected: """
                    namespace A
                    {
                        public partial class Foo<T> : System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>
                        {
                            int System.Collections.Generic.ICollection<T>.Count { get { throw null; } }
                            bool System.Collections.Generic.ICollection<T>.IsReadOnly { get { throw null; } }
                            int System.Collections.ICollection.Count { get { throw null; } }
                            bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
                            object System.Collections.ICollection.SyncRoot { get { throw null; } }
                            void System.Collections.Generic.ICollection<T>.Add(T item) { }
                            void System.Collections.Generic.ICollection<T>.Clear() { }
                            bool System.Collections.Generic.ICollection<T>.Contains(T item) { throw null; }
                            void System.Collections.Generic.ICollection<T>.CopyTo(T[] array, int arrayIndex) { }
                            bool System.Collections.Generic.ICollection<T>.Remove(T item) { throw null; }
                            System.Collections.Generic.IEnumerator<T> System.Collections.Generic.IEnumerable<T>.GetEnumerator() { throw null; }
                            void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
                            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
                        }
                    }
                    """,
                includeInternalSymbols: false);
        }

        [Fact]
        public void TestTypeForwardsToGenericTypesRegression31250()
        {
            RunTest(original: """
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,,,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,,,,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,,,,,>))]
                    """,
                expected: """
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,,,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Action<,,,,,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,,,,>))]
                    [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,,,,,>))]
                    """,
                includeInternalSymbols: false);
        }

        [Fact]
        public void ReservedAttributesAreOmitted()
        {
            RunTest(original: """
                namespace N {
                    public ref struct C<T>
                        where T : unmanaged
                    {
                        public required (string? k, dynamic v, nint n) X { get; init; }    
                    }

                    public static class E
                    {
                        public static void M<T>(this object c, scoped System.ReadOnlySpan<T> values) { }
                    }
                }
                """,
                expected: """                
                namespace N
                {
                    public ref partial struct C<T>
                        where T : unmanaged
                    {
                        public required (string? k, dynamic v, nint n) X { get { throw null; } init { } }
                    }

                    public static partial class E
                    {
                        public static void M<T>(this object c, scoped System.ReadOnlySpan<T> values) { }
                    }
                }
                """);
        }

        [Fact]
        public void TestExplicitInterfaceIndexer()
        {
            RunTest(original: """
                    namespace a
                    {
                        public interface IFooList
                        {
                             object this[int index] { get; set; }
                        }

                        public struct Bar : IFooList
                        {
                        #pragma warning disable CS8597
                            public string this[int index] { get { throw null; } set { } }
                            object IFooList.this[int index] { get { throw null; } set { } }
                        #pragma warning restore CS8597
                        }
                    }
                    """,
                expected: """
                    namespace a
                    {
                        public partial struct Bar : IFooList
                        {
                            object IFooList.this[int index] { get { throw null; } set { } }
                            public string this[int index] { get { throw null; } set { } }
                        }

                        public partial interface IFooList
                        {
                            object this[int index] { get; set; }
                        }
                    }
                    """,
                includeInternalSymbols: false);
        }

        [Fact]
        public void TestExplicitInterfaceNonGenericCollections()
        {
            RunTest(original: """
                    using System;
                    using System.Collections;
                    namespace a
                    {
                        #pragma warning disable CS8597
                        
                        public partial class MyStringCollection : ICollection, IEnumerable, IList
                        {
                            public int Count { get { throw null; } }
                            public string this[int index] { get { throw null; } set { } }
                            bool ICollection.IsSynchronized { get { throw null; } }
                            object ICollection.SyncRoot { get { throw null; } }
                            bool IList.IsFixedSize { get { throw null; } }
                            bool IList.IsReadOnly { get { throw null; } }
                            object? IList.this[int index] { get { throw null; } set { } }
                            public int Add(string value) { throw null; }
                            public void AddRange(string[] value) { }
                            public void AddRange(MyStringCollection value) { }
                            public void Clear() { }
                            public bool Contains(string value) { throw null; }
                            public void CopyTo(string[] array, int index) { }
                            public override int GetHashCode() { throw null; }
                            public int IndexOf(string value) { throw null; }
                            public void Insert(int index, string value) { }
                            public void Remove(string value) { }
                            public void RemoveAt(int index) { }
                            void ICollection.CopyTo(Array array, int index) { }
                            IEnumerator IEnumerable.GetEnumerator() { throw null; }
                            int IList.Add(object? value) { throw null; }
                            bool IList.Contains(object? value) { throw null; }                            
                            int IList.IndexOf(object? value) { throw null; }
                            void IList.Insert(int index, object? value) { }
                            void IList.Remove(object? value) { }
                        }

                        #pragma warning restore CS8597
                    }
                    """,
                expected: """                    
                    namespace a
                    {
                        public partial class MyStringCollection : System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList
                        {
                            public int Count { get { throw null; } }
                            public string this[int index] { get { throw null; } set { } }
                            bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
                            object System.Collections.ICollection.SyncRoot { get { throw null; } }
                            bool System.Collections.IList.IsFixedSize { get { throw null; } }
                            bool System.Collections.IList.IsReadOnly { get { throw null; } }
                            object? System.Collections.IList.this[int index] { get { throw null; } set { } }
                            public int Add(string value) { throw null; }
                            public void AddRange(MyStringCollection value) { }
                            public void AddRange(string[] value) { }
                            public void Clear() { }
                            public bool Contains(string value) { throw null; }
                            public void CopyTo(string[] array, int index) { }
                            public override int GetHashCode() { throw null; }
                            public int IndexOf(string value) { throw null; }
                            public void Insert(int index, string value) { }
                            public void Remove(string value) { }
                            public void RemoveAt(int index) { }
                            void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
                            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
                            int System.Collections.IList.Add(object? value) { throw null; }
                            bool System.Collections.IList.Contains(object? value) { throw null; }
                            int System.Collections.IList.IndexOf(object? value) { throw null; }
                            void System.Collections.IList.Insert(int index, object? value) { }
                            void System.Collections.IList.Remove(object? value) { }
                        }
                    }
                    """,
                includeInternalSymbols: false);
        }
    }
}
