diff --git a/CODEOWNERS b/CODEOWNERS
index b91420ada3f2..3857c6bea65e 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -85,10 +85,15 @@
# Compatibility tools owned by runtime team
/src/Compatibility/ @dotnet/area-infrastructure-libraries
+
+# Area-ApiCompat
/test/Microsoft.DotNet.ApiCompatibility*/ @dotnet/area-infrastructure-libraries
/test/Microsoft.DotNet.ApiCompat*/ @dotnet/area-infrastructure-libraries
/test/Microsoft.DotNet.PackageValidation*/ @dotnet/area-infrastructure-libraries
+# Area-ApiDiff
+/test/Microsoft.DotNet.ApiDiff.Tests/ @dotnet/area-infrastructure-libraries
+
# Area-GenAPI
/src/Compatibility/GenAPI/ @dotnet/area-infrastructure-libraries
/src/Compatibility/Microsoft.DotNet.ApiSymbolExtensions/ @dotnet/area-infrastructure-libraries
diff --git a/eng/Signing.props b/eng/Signing.props
index 394e062266ff..0d77fc3ee4c7 100644
--- a/eng/Signing.props
+++ b/eng/Signing.props
@@ -25,10 +25,19 @@
-
+
+
+
+
+
+
+
+
+
+
diff --git a/sdk.sln b/sdk.sln
index fd8023d6d38d..6caa53d27a92 100644
--- a/sdk.sln
+++ b/sdk.sln
@@ -505,7 +505,7 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Microsoft.WebTools.AspireSe
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Net.Sdk.Compilers.Toolset", "src\Microsoft.Net.Sdk.Compilers.Toolset\Microsoft.Net.Sdk.Compilers.Toolset.csproj", "{FA579C03-2EB4-4D47-88EE-BFF339E96FAF}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.WebTools.AspireService.Tests", "test\Microsoft.WebTools.AspireService.Tests\Microsoft.WebTools.AspireService.Tests.csproj", "{1F0B4B3C-DC88-4740-B04F-1707102E9930}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.WebTools.AspireService.Tests", "test\Microsoft.WebTools.AspireService.Tests\Microsoft.WebTools.AspireService.Tests.csproj", "{1F0B4B3C-DC88-4740-B04F-1707102E9930}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSMSBuildExtensions", "src\VSMSBuildExtensions\VSMSBuildExtensions.proj", "{D9617F63-15F4-4CA2-8ECF-728A94B45D82}"
EndProject
@@ -521,468 +521,1430 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DotNet.HotReload.
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Microsoft.DotNet.HotReload.Agent.Data", "src\BuiltInTools\HotReloadAgent.Data\Microsoft.DotNet.HotReload.Agent.Data.shproj", "{0762B436-F4B0-4008-9097-BB5FF6BD84AF}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ApiDiff", "ApiDiff", "{C66B5859-B05E-5DF4-58E9-78CA919DB89A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DotNet.ApiDiff", "src\Compatibility\ApiDiff\Microsoft.DotNet.ApiDiff\Microsoft.DotNet.ApiDiff.csproj", "{E5A15C4C-DCAD-4A5A-93E5-A56822910D82}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DotNet.ApiDiff.Tool", "src\Compatibility\ApiDiff\Microsoft.DotNet.ApiDiff.Tool\Microsoft.DotNet.ApiDiff.Tool.csproj", "{C09261DE-A222-4536-B0CC-53EB0F7A650B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ApiDiff", "ApiDiff", "{AFA55F45-CFCB-9821-A210-2D3496088416}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DotNet.ApiDiff.Tests", "test\Microsoft.DotNet.ApiDiff.Tests\Microsoft.DotNet.ApiDiff.Tests.csproj", "{86007D8A-DE78-4C27-9DCC-84A64038610F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{61C31F8E-FE7C-47CC-B21C-3DEE499AD6F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61C31F8E-FE7C-47CC-B21C-3DEE499AD6F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {61C31F8E-FE7C-47CC-B21C-3DEE499AD6F5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {61C31F8E-FE7C-47CC-B21C-3DEE499AD6F5}.Debug|x64.Build.0 = Debug|Any CPU
+ {61C31F8E-FE7C-47CC-B21C-3DEE499AD6F5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {61C31F8E-FE7C-47CC-B21C-3DEE499AD6F5}.Debug|x86.Build.0 = Debug|Any CPU
{61C31F8E-FE7C-47CC-B21C-3DEE499AD6F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61C31F8E-FE7C-47CC-B21C-3DEE499AD6F5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {61C31F8E-FE7C-47CC-B21C-3DEE499AD6F5}.Release|x64.ActiveCfg = Release|Any CPU
+ {61C31F8E-FE7C-47CC-B21C-3DEE499AD6F5}.Release|x64.Build.0 = Release|Any CPU
+ {61C31F8E-FE7C-47CC-B21C-3DEE499AD6F5}.Release|x86.ActiveCfg = Release|Any CPU
+ {61C31F8E-FE7C-47CC-B21C-3DEE499AD6F5}.Release|x86.Build.0 = Release|Any CPU
{6ADADB58-92D3-438C-8D97-F495B59A83C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6ADADB58-92D3-438C-8D97-F495B59A83C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6ADADB58-92D3-438C-8D97-F495B59A83C0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6ADADB58-92D3-438C-8D97-F495B59A83C0}.Debug|x64.Build.0 = Debug|Any CPU
+ {6ADADB58-92D3-438C-8D97-F495B59A83C0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6ADADB58-92D3-438C-8D97-F495B59A83C0}.Debug|x86.Build.0 = Debug|Any CPU
{6ADADB58-92D3-438C-8D97-F495B59A83C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6ADADB58-92D3-438C-8D97-F495B59A83C0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6ADADB58-92D3-438C-8D97-F495B59A83C0}.Release|x64.ActiveCfg = Release|Any CPU
+ {6ADADB58-92D3-438C-8D97-F495B59A83C0}.Release|x64.Build.0 = Release|Any CPU
+ {6ADADB58-92D3-438C-8D97-F495B59A83C0}.Release|x86.ActiveCfg = Release|Any CPU
+ {6ADADB58-92D3-438C-8D97-F495B59A83C0}.Release|x86.Build.0 = Release|Any CPU
{9CFC1EB5-8CF4-41D3-B91D-7D88B52F0B07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9CFC1EB5-8CF4-41D3-B91D-7D88B52F0B07}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9CFC1EB5-8CF4-41D3-B91D-7D88B52F0B07}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9CFC1EB5-8CF4-41D3-B91D-7D88B52F0B07}.Debug|x64.Build.0 = Debug|Any CPU
+ {9CFC1EB5-8CF4-41D3-B91D-7D88B52F0B07}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9CFC1EB5-8CF4-41D3-B91D-7D88B52F0B07}.Debug|x86.Build.0 = Debug|Any CPU
{9CFC1EB5-8CF4-41D3-B91D-7D88B52F0B07}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9CFC1EB5-8CF4-41D3-B91D-7D88B52F0B07}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9CFC1EB5-8CF4-41D3-B91D-7D88B52F0B07}.Release|x64.ActiveCfg = Release|Any CPU
+ {9CFC1EB5-8CF4-41D3-B91D-7D88B52F0B07}.Release|x64.Build.0 = Release|Any CPU
+ {9CFC1EB5-8CF4-41D3-B91D-7D88B52F0B07}.Release|x86.ActiveCfg = Release|Any CPU
+ {9CFC1EB5-8CF4-41D3-B91D-7D88B52F0B07}.Release|x86.Build.0 = Release|Any CPU
{2D749C5D-B033-4B7F-A00E-354A6229DB8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D749C5D-B033-4B7F-A00E-354A6229DB8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2D749C5D-B033-4B7F-A00E-354A6229DB8D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2D749C5D-B033-4B7F-A00E-354A6229DB8D}.Debug|x64.Build.0 = Debug|Any CPU
+ {2D749C5D-B033-4B7F-A00E-354A6229DB8D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2D749C5D-B033-4B7F-A00E-354A6229DB8D}.Debug|x86.Build.0 = Debug|Any CPU
{2D749C5D-B033-4B7F-A00E-354A6229DB8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D749C5D-B033-4B7F-A00E-354A6229DB8D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2D749C5D-B033-4B7F-A00E-354A6229DB8D}.Release|x64.ActiveCfg = Release|Any CPU
+ {2D749C5D-B033-4B7F-A00E-354A6229DB8D}.Release|x64.Build.0 = Release|Any CPU
+ {2D749C5D-B033-4B7F-A00E-354A6229DB8D}.Release|x86.ActiveCfg = Release|Any CPU
+ {2D749C5D-B033-4B7F-A00E-354A6229DB8D}.Release|x86.Build.0 = Release|Any CPU
{52CB4546-DD2D-4207-B6E1-494C9506D1C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{52CB4546-DD2D-4207-B6E1-494C9506D1C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {52CB4546-DD2D-4207-B6E1-494C9506D1C1}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {52CB4546-DD2D-4207-B6E1-494C9506D1C1}.Debug|x64.Build.0 = Debug|Any CPU
+ {52CB4546-DD2D-4207-B6E1-494C9506D1C1}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {52CB4546-DD2D-4207-B6E1-494C9506D1C1}.Debug|x86.Build.0 = Debug|Any CPU
{52CB4546-DD2D-4207-B6E1-494C9506D1C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{52CB4546-DD2D-4207-B6E1-494C9506D1C1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {52CB4546-DD2D-4207-B6E1-494C9506D1C1}.Release|x64.ActiveCfg = Release|Any CPU
+ {52CB4546-DD2D-4207-B6E1-494C9506D1C1}.Release|x64.Build.0 = Release|Any CPU
+ {52CB4546-DD2D-4207-B6E1-494C9506D1C1}.Release|x86.ActiveCfg = Release|Any CPU
+ {52CB4546-DD2D-4207-B6E1-494C9506D1C1}.Release|x86.Build.0 = Release|Any CPU
{5CBFF0EE-71EA-49CC-8369-34A9A62C8116}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5CBFF0EE-71EA-49CC-8369-34A9A62C8116}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5CBFF0EE-71EA-49CC-8369-34A9A62C8116}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5CBFF0EE-71EA-49CC-8369-34A9A62C8116}.Debug|x64.Build.0 = Debug|Any CPU
+ {5CBFF0EE-71EA-49CC-8369-34A9A62C8116}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5CBFF0EE-71EA-49CC-8369-34A9A62C8116}.Debug|x86.Build.0 = Debug|Any CPU
{5CBFF0EE-71EA-49CC-8369-34A9A62C8116}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5CBFF0EE-71EA-49CC-8369-34A9A62C8116}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5CBFF0EE-71EA-49CC-8369-34A9A62C8116}.Release|x64.ActiveCfg = Release|Any CPU
+ {5CBFF0EE-71EA-49CC-8369-34A9A62C8116}.Release|x64.Build.0 = Release|Any CPU
+ {5CBFF0EE-71EA-49CC-8369-34A9A62C8116}.Release|x86.ActiveCfg = Release|Any CPU
+ {5CBFF0EE-71EA-49CC-8369-34A9A62C8116}.Release|x86.Build.0 = Release|Any CPU
{8746DC05-3035-4F24-9F2C-BAAAB5B50FD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8746DC05-3035-4F24-9F2C-BAAAB5B50FD3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8746DC05-3035-4F24-9F2C-BAAAB5B50FD3}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8746DC05-3035-4F24-9F2C-BAAAB5B50FD3}.Debug|x64.Build.0 = Debug|Any CPU
+ {8746DC05-3035-4F24-9F2C-BAAAB5B50FD3}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8746DC05-3035-4F24-9F2C-BAAAB5B50FD3}.Debug|x86.Build.0 = Debug|Any CPU
{8746DC05-3035-4F24-9F2C-BAAAB5B50FD3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8746DC05-3035-4F24-9F2C-BAAAB5B50FD3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8746DC05-3035-4F24-9F2C-BAAAB5B50FD3}.Release|x64.ActiveCfg = Release|Any CPU
+ {8746DC05-3035-4F24-9F2C-BAAAB5B50FD3}.Release|x64.Build.0 = Release|Any CPU
+ {8746DC05-3035-4F24-9F2C-BAAAB5B50FD3}.Release|x86.ActiveCfg = Release|Any CPU
+ {8746DC05-3035-4F24-9F2C-BAAAB5B50FD3}.Release|x86.Build.0 = Release|Any CPU
{5B3E6EC9-AD8D-4F68-A9F8-C60CF11F4753}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5B3E6EC9-AD8D-4F68-A9F8-C60CF11F4753}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5B3E6EC9-AD8D-4F68-A9F8-C60CF11F4753}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5B3E6EC9-AD8D-4F68-A9F8-C60CF11F4753}.Debug|x64.Build.0 = Debug|Any CPU
+ {5B3E6EC9-AD8D-4F68-A9F8-C60CF11F4753}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5B3E6EC9-AD8D-4F68-A9F8-C60CF11F4753}.Debug|x86.Build.0 = Debug|Any CPU
{5B3E6EC9-AD8D-4F68-A9F8-C60CF11F4753}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5B3E6EC9-AD8D-4F68-A9F8-C60CF11F4753}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5B3E6EC9-AD8D-4F68-A9F8-C60CF11F4753}.Release|x64.ActiveCfg = Release|Any CPU
+ {5B3E6EC9-AD8D-4F68-A9F8-C60CF11F4753}.Release|x64.Build.0 = Release|Any CPU
+ {5B3E6EC9-AD8D-4F68-A9F8-C60CF11F4753}.Release|x86.ActiveCfg = Release|Any CPU
+ {5B3E6EC9-AD8D-4F68-A9F8-C60CF11F4753}.Release|x86.Build.0 = Release|Any CPU
{8283544E-9704-40C5-BEC2-2781413AA3CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8283544E-9704-40C5-BEC2-2781413AA3CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8283544E-9704-40C5-BEC2-2781413AA3CF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8283544E-9704-40C5-BEC2-2781413AA3CF}.Debug|x64.Build.0 = Debug|Any CPU
+ {8283544E-9704-40C5-BEC2-2781413AA3CF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8283544E-9704-40C5-BEC2-2781413AA3CF}.Debug|x86.Build.0 = Debug|Any CPU
{8283544E-9704-40C5-BEC2-2781413AA3CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8283544E-9704-40C5-BEC2-2781413AA3CF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8283544E-9704-40C5-BEC2-2781413AA3CF}.Release|x64.ActiveCfg = Release|Any CPU
+ {8283544E-9704-40C5-BEC2-2781413AA3CF}.Release|x64.Build.0 = Release|Any CPU
+ {8283544E-9704-40C5-BEC2-2781413AA3CF}.Release|x86.ActiveCfg = Release|Any CPU
+ {8283544E-9704-40C5-BEC2-2781413AA3CF}.Release|x86.Build.0 = Release|Any CPU
{112668D7-322D-4F83-A6CE-B814C25AD3BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{112668D7-322D-4F83-A6CE-B814C25AD3BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {112668D7-322D-4F83-A6CE-B814C25AD3BF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {112668D7-322D-4F83-A6CE-B814C25AD3BF}.Debug|x64.Build.0 = Debug|Any CPU
+ {112668D7-322D-4F83-A6CE-B814C25AD3BF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {112668D7-322D-4F83-A6CE-B814C25AD3BF}.Debug|x86.Build.0 = Debug|Any CPU
{112668D7-322D-4F83-A6CE-B814C25AD3BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{112668D7-322D-4F83-A6CE-B814C25AD3BF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {112668D7-322D-4F83-A6CE-B814C25AD3BF}.Release|x64.ActiveCfg = Release|Any CPU
+ {112668D7-322D-4F83-A6CE-B814C25AD3BF}.Release|x64.Build.0 = Release|Any CPU
+ {112668D7-322D-4F83-A6CE-B814C25AD3BF}.Release|x86.ActiveCfg = Release|Any CPU
+ {112668D7-322D-4F83-A6CE-B814C25AD3BF}.Release|x86.Build.0 = Release|Any CPU
{CAF71BDC-7B7D-4A43-AB8C-E440A1E4F108}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CAF71BDC-7B7D-4A43-AB8C-E440A1E4F108}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CAF71BDC-7B7D-4A43-AB8C-E440A1E4F108}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {CAF71BDC-7B7D-4A43-AB8C-E440A1E4F108}.Debug|x64.Build.0 = Debug|Any CPU
+ {CAF71BDC-7B7D-4A43-AB8C-E440A1E4F108}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {CAF71BDC-7B7D-4A43-AB8C-E440A1E4F108}.Debug|x86.Build.0 = Debug|Any CPU
{CAF71BDC-7B7D-4A43-AB8C-E440A1E4F108}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CAF71BDC-7B7D-4A43-AB8C-E440A1E4F108}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CAF71BDC-7B7D-4A43-AB8C-E440A1E4F108}.Release|x64.ActiveCfg = Release|Any CPU
+ {CAF71BDC-7B7D-4A43-AB8C-E440A1E4F108}.Release|x64.Build.0 = Release|Any CPU
+ {CAF71BDC-7B7D-4A43-AB8C-E440A1E4F108}.Release|x86.ActiveCfg = Release|Any CPU
+ {CAF71BDC-7B7D-4A43-AB8C-E440A1E4F108}.Release|x86.Build.0 = Release|Any CPU
{6F72FAA2-4E46-4382-940A-4F0290E070E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6F72FAA2-4E46-4382-940A-4F0290E070E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6F72FAA2-4E46-4382-940A-4F0290E070E2}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6F72FAA2-4E46-4382-940A-4F0290E070E2}.Debug|x64.Build.0 = Debug|Any CPU
+ {6F72FAA2-4E46-4382-940A-4F0290E070E2}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6F72FAA2-4E46-4382-940A-4F0290E070E2}.Debug|x86.Build.0 = Debug|Any CPU
{6F72FAA2-4E46-4382-940A-4F0290E070E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6F72FAA2-4E46-4382-940A-4F0290E070E2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6F72FAA2-4E46-4382-940A-4F0290E070E2}.Release|x64.ActiveCfg = Release|Any CPU
+ {6F72FAA2-4E46-4382-940A-4F0290E070E2}.Release|x64.Build.0 = Release|Any CPU
+ {6F72FAA2-4E46-4382-940A-4F0290E070E2}.Release|x86.ActiveCfg = Release|Any CPU
+ {6F72FAA2-4E46-4382-940A-4F0290E070E2}.Release|x86.Build.0 = Release|Any CPU
{E740A596-2CAE-476C-8062-49705C3A9CF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E740A596-2CAE-476C-8062-49705C3A9CF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E740A596-2CAE-476C-8062-49705C3A9CF0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E740A596-2CAE-476C-8062-49705C3A9CF0}.Debug|x64.Build.0 = Debug|Any CPU
+ {E740A596-2CAE-476C-8062-49705C3A9CF0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E740A596-2CAE-476C-8062-49705C3A9CF0}.Debug|x86.Build.0 = Debug|Any CPU
{E740A596-2CAE-476C-8062-49705C3A9CF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E740A596-2CAE-476C-8062-49705C3A9CF0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E740A596-2CAE-476C-8062-49705C3A9CF0}.Release|x64.ActiveCfg = Release|Any CPU
+ {E740A596-2CAE-476C-8062-49705C3A9CF0}.Release|x64.Build.0 = Release|Any CPU
+ {E740A596-2CAE-476C-8062-49705C3A9CF0}.Release|x86.ActiveCfg = Release|Any CPU
+ {E740A596-2CAE-476C-8062-49705C3A9CF0}.Release|x86.Build.0 = Release|Any CPU
{CC25E192-70AD-4D91-B288-3AD40065DBAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CC25E192-70AD-4D91-B288-3AD40065DBAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CC25E192-70AD-4D91-B288-3AD40065DBAC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {CC25E192-70AD-4D91-B288-3AD40065DBAC}.Debug|x64.Build.0 = Debug|Any CPU
+ {CC25E192-70AD-4D91-B288-3AD40065DBAC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {CC25E192-70AD-4D91-B288-3AD40065DBAC}.Debug|x86.Build.0 = Debug|Any CPU
{CC25E192-70AD-4D91-B288-3AD40065DBAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CC25E192-70AD-4D91-B288-3AD40065DBAC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CC25E192-70AD-4D91-B288-3AD40065DBAC}.Release|x64.ActiveCfg = Release|Any CPU
+ {CC25E192-70AD-4D91-B288-3AD40065DBAC}.Release|x64.Build.0 = Release|Any CPU
+ {CC25E192-70AD-4D91-B288-3AD40065DBAC}.Release|x86.ActiveCfg = Release|Any CPU
+ {CC25E192-70AD-4D91-B288-3AD40065DBAC}.Release|x86.Build.0 = Release|Any CPU
{0FA6CEE9-7A97-4036-8D48-39BA4F85118E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0FA6CEE9-7A97-4036-8D48-39BA4F85118E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0FA6CEE9-7A97-4036-8D48-39BA4F85118E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0FA6CEE9-7A97-4036-8D48-39BA4F85118E}.Debug|x64.Build.0 = Debug|Any CPU
+ {0FA6CEE9-7A97-4036-8D48-39BA4F85118E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0FA6CEE9-7A97-4036-8D48-39BA4F85118E}.Debug|x86.Build.0 = Debug|Any CPU
{0FA6CEE9-7A97-4036-8D48-39BA4F85118E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0FA6CEE9-7A97-4036-8D48-39BA4F85118E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0FA6CEE9-7A97-4036-8D48-39BA4F85118E}.Release|x64.ActiveCfg = Release|Any CPU
+ {0FA6CEE9-7A97-4036-8D48-39BA4F85118E}.Release|x64.Build.0 = Release|Any CPU
+ {0FA6CEE9-7A97-4036-8D48-39BA4F85118E}.Release|x86.ActiveCfg = Release|Any CPU
+ {0FA6CEE9-7A97-4036-8D48-39BA4F85118E}.Release|x86.Build.0 = Release|Any CPU
{B22C90C9-BA46-4F07-9613-253DD01E3EFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B22C90C9-BA46-4F07-9613-253DD01E3EFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B22C90C9-BA46-4F07-9613-253DD01E3EFF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B22C90C9-BA46-4F07-9613-253DD01E3EFF}.Debug|x64.Build.0 = Debug|Any CPU
+ {B22C90C9-BA46-4F07-9613-253DD01E3EFF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B22C90C9-BA46-4F07-9613-253DD01E3EFF}.Debug|x86.Build.0 = Debug|Any CPU
{B22C90C9-BA46-4F07-9613-253DD01E3EFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B22C90C9-BA46-4F07-9613-253DD01E3EFF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B22C90C9-BA46-4F07-9613-253DD01E3EFF}.Release|x64.ActiveCfg = Release|Any CPU
+ {B22C90C9-BA46-4F07-9613-253DD01E3EFF}.Release|x64.Build.0 = Release|Any CPU
+ {B22C90C9-BA46-4F07-9613-253DD01E3EFF}.Release|x86.ActiveCfg = Release|Any CPU
+ {B22C90C9-BA46-4F07-9613-253DD01E3EFF}.Release|x86.Build.0 = Release|Any CPU
{D62591F3-ED86-4014-B765-7CDA47F55EE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D62591F3-ED86-4014-B765-7CDA47F55EE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D62591F3-ED86-4014-B765-7CDA47F55EE2}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D62591F3-ED86-4014-B765-7CDA47F55EE2}.Debug|x64.Build.0 = Debug|Any CPU
+ {D62591F3-ED86-4014-B765-7CDA47F55EE2}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D62591F3-ED86-4014-B765-7CDA47F55EE2}.Debug|x86.Build.0 = Debug|Any CPU
{D62591F3-ED86-4014-B765-7CDA47F55EE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D62591F3-ED86-4014-B765-7CDA47F55EE2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D62591F3-ED86-4014-B765-7CDA47F55EE2}.Release|x64.ActiveCfg = Release|Any CPU
+ {D62591F3-ED86-4014-B765-7CDA47F55EE2}.Release|x64.Build.0 = Release|Any CPU
+ {D62591F3-ED86-4014-B765-7CDA47F55EE2}.Release|x86.ActiveCfg = Release|Any CPU
+ {D62591F3-ED86-4014-B765-7CDA47F55EE2}.Release|x86.Build.0 = Release|Any CPU
{8274C645-CBB8-4B94-B58D-5A485FA8514C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8274C645-CBB8-4B94-B58D-5A485FA8514C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8274C645-CBB8-4B94-B58D-5A485FA8514C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8274C645-CBB8-4B94-B58D-5A485FA8514C}.Debug|x64.Build.0 = Debug|Any CPU
+ {8274C645-CBB8-4B94-B58D-5A485FA8514C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8274C645-CBB8-4B94-B58D-5A485FA8514C}.Debug|x86.Build.0 = Debug|Any CPU
{8274C645-CBB8-4B94-B58D-5A485FA8514C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8274C645-CBB8-4B94-B58D-5A485FA8514C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8274C645-CBB8-4B94-B58D-5A485FA8514C}.Release|x64.ActiveCfg = Release|Any CPU
+ {8274C645-CBB8-4B94-B58D-5A485FA8514C}.Release|x64.Build.0 = Release|Any CPU
+ {8274C645-CBB8-4B94-B58D-5A485FA8514C}.Release|x86.ActiveCfg = Release|Any CPU
+ {8274C645-CBB8-4B94-B58D-5A485FA8514C}.Release|x86.Build.0 = Release|Any CPU
{10D77F17-F5CB-46A1-B2A9-178615430C0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10D77F17-F5CB-46A1-B2A9-178615430C0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {10D77F17-F5CB-46A1-B2A9-178615430C0E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {10D77F17-F5CB-46A1-B2A9-178615430C0E}.Debug|x64.Build.0 = Debug|Any CPU
+ {10D77F17-F5CB-46A1-B2A9-178615430C0E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {10D77F17-F5CB-46A1-B2A9-178615430C0E}.Debug|x86.Build.0 = Debug|Any CPU
{10D77F17-F5CB-46A1-B2A9-178615430C0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10D77F17-F5CB-46A1-B2A9-178615430C0E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {10D77F17-F5CB-46A1-B2A9-178615430C0E}.Release|x64.ActiveCfg = Release|Any CPU
+ {10D77F17-F5CB-46A1-B2A9-178615430C0E}.Release|x64.Build.0 = Release|Any CPU
+ {10D77F17-F5CB-46A1-B2A9-178615430C0E}.Release|x86.ActiveCfg = Release|Any CPU
+ {10D77F17-F5CB-46A1-B2A9-178615430C0E}.Release|x86.Build.0 = Release|Any CPU
{C2DF833D-2A83-408B-8122-3038ACDFDFD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C2DF833D-2A83-408B-8122-3038ACDFDFD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C2DF833D-2A83-408B-8122-3038ACDFDFD0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C2DF833D-2A83-408B-8122-3038ACDFDFD0}.Debug|x64.Build.0 = Debug|Any CPU
+ {C2DF833D-2A83-408B-8122-3038ACDFDFD0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C2DF833D-2A83-408B-8122-3038ACDFDFD0}.Debug|x86.Build.0 = Debug|Any CPU
{C2DF833D-2A83-408B-8122-3038ACDFDFD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C2DF833D-2A83-408B-8122-3038ACDFDFD0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C2DF833D-2A83-408B-8122-3038ACDFDFD0}.Release|x64.ActiveCfg = Release|Any CPU
+ {C2DF833D-2A83-408B-8122-3038ACDFDFD0}.Release|x64.Build.0 = Release|Any CPU
+ {C2DF833D-2A83-408B-8122-3038ACDFDFD0}.Release|x86.ActiveCfg = Release|Any CPU
+ {C2DF833D-2A83-408B-8122-3038ACDFDFD0}.Release|x86.Build.0 = Release|Any CPU
{AA273ACB-56FE-4F0C-8CC9-C2C45D31491D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA273ACB-56FE-4F0C-8CC9-C2C45D31491D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AA273ACB-56FE-4F0C-8CC9-C2C45D31491D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AA273ACB-56FE-4F0C-8CC9-C2C45D31491D}.Debug|x64.Build.0 = Debug|Any CPU
+ {AA273ACB-56FE-4F0C-8CC9-C2C45D31491D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AA273ACB-56FE-4F0C-8CC9-C2C45D31491D}.Debug|x86.Build.0 = Debug|Any CPU
{AA273ACB-56FE-4F0C-8CC9-C2C45D31491D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA273ACB-56FE-4F0C-8CC9-C2C45D31491D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AA273ACB-56FE-4F0C-8CC9-C2C45D31491D}.Release|x64.ActiveCfg = Release|Any CPU
+ {AA273ACB-56FE-4F0C-8CC9-C2C45D31491D}.Release|x64.Build.0 = Release|Any CPU
+ {AA273ACB-56FE-4F0C-8CC9-C2C45D31491D}.Release|x86.ActiveCfg = Release|Any CPU
+ {AA273ACB-56FE-4F0C-8CC9-C2C45D31491D}.Release|x86.Build.0 = Release|Any CPU
{C687CA8D-9843-4045-BC20-917953F6C864}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C687CA8D-9843-4045-BC20-917953F6C864}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C687CA8D-9843-4045-BC20-917953F6C864}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C687CA8D-9843-4045-BC20-917953F6C864}.Debug|x64.Build.0 = Debug|Any CPU
+ {C687CA8D-9843-4045-BC20-917953F6C864}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C687CA8D-9843-4045-BC20-917953F6C864}.Debug|x86.Build.0 = Debug|Any CPU
{C687CA8D-9843-4045-BC20-917953F6C864}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C687CA8D-9843-4045-BC20-917953F6C864}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C687CA8D-9843-4045-BC20-917953F6C864}.Release|x64.ActiveCfg = Release|Any CPU
+ {C687CA8D-9843-4045-BC20-917953F6C864}.Release|x64.Build.0 = Release|Any CPU
+ {C687CA8D-9843-4045-BC20-917953F6C864}.Release|x86.ActiveCfg = Release|Any CPU
+ {C687CA8D-9843-4045-BC20-917953F6C864}.Release|x86.Build.0 = Release|Any CPU
{64294C35-9001-4FF9-975F-43D283EE5FA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{64294C35-9001-4FF9-975F-43D283EE5FA9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {64294C35-9001-4FF9-975F-43D283EE5FA9}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {64294C35-9001-4FF9-975F-43D283EE5FA9}.Debug|x64.Build.0 = Debug|Any CPU
+ {64294C35-9001-4FF9-975F-43D283EE5FA9}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {64294C35-9001-4FF9-975F-43D283EE5FA9}.Debug|x86.Build.0 = Debug|Any CPU
{64294C35-9001-4FF9-975F-43D283EE5FA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64294C35-9001-4FF9-975F-43D283EE5FA9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {64294C35-9001-4FF9-975F-43D283EE5FA9}.Release|x64.ActiveCfg = Release|Any CPU
+ {64294C35-9001-4FF9-975F-43D283EE5FA9}.Release|x64.Build.0 = Release|Any CPU
+ {64294C35-9001-4FF9-975F-43D283EE5FA9}.Release|x86.ActiveCfg = Release|Any CPU
+ {64294C35-9001-4FF9-975F-43D283EE5FA9}.Release|x86.Build.0 = Release|Any CPU
{C5F191E5-BF2E-4A7A-AE1D-E2393AAA6F99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5F191E5-BF2E-4A7A-AE1D-E2393AAA6F99}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C5F191E5-BF2E-4A7A-AE1D-E2393AAA6F99}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C5F191E5-BF2E-4A7A-AE1D-E2393AAA6F99}.Debug|x64.Build.0 = Debug|Any CPU
+ {C5F191E5-BF2E-4A7A-AE1D-E2393AAA6F99}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C5F191E5-BF2E-4A7A-AE1D-E2393AAA6F99}.Debug|x86.Build.0 = Debug|Any CPU
{C5F191E5-BF2E-4A7A-AE1D-E2393AAA6F99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5F191E5-BF2E-4A7A-AE1D-E2393AAA6F99}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C5F191E5-BF2E-4A7A-AE1D-E2393AAA6F99}.Release|x64.ActiveCfg = Release|Any CPU
+ {C5F191E5-BF2E-4A7A-AE1D-E2393AAA6F99}.Release|x64.Build.0 = Release|Any CPU
+ {C5F191E5-BF2E-4A7A-AE1D-E2393AAA6F99}.Release|x86.ActiveCfg = Release|Any CPU
+ {C5F191E5-BF2E-4A7A-AE1D-E2393AAA6F99}.Release|x86.Build.0 = Release|Any CPU
{99334000-EBF8-44D9-90D0-BE998ED3FE60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{99334000-EBF8-44D9-90D0-BE998ED3FE60}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {99334000-EBF8-44D9-90D0-BE998ED3FE60}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {99334000-EBF8-44D9-90D0-BE998ED3FE60}.Debug|x64.Build.0 = Debug|Any CPU
+ {99334000-EBF8-44D9-90D0-BE998ED3FE60}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {99334000-EBF8-44D9-90D0-BE998ED3FE60}.Debug|x86.Build.0 = Debug|Any CPU
{99334000-EBF8-44D9-90D0-BE998ED3FE60}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99334000-EBF8-44D9-90D0-BE998ED3FE60}.Release|Any CPU.Build.0 = Release|Any CPU
+ {99334000-EBF8-44D9-90D0-BE998ED3FE60}.Release|x64.ActiveCfg = Release|Any CPU
+ {99334000-EBF8-44D9-90D0-BE998ED3FE60}.Release|x64.Build.0 = Release|Any CPU
+ {99334000-EBF8-44D9-90D0-BE998ED3FE60}.Release|x86.ActiveCfg = Release|Any CPU
+ {99334000-EBF8-44D9-90D0-BE998ED3FE60}.Release|x86.Build.0 = Release|Any CPU
{8FB015CE-1900-41EE-8E68-C222CE1B8561}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8FB015CE-1900-41EE-8E68-C222CE1B8561}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8FB015CE-1900-41EE-8E68-C222CE1B8561}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8FB015CE-1900-41EE-8E68-C222CE1B8561}.Debug|x64.Build.0 = Debug|Any CPU
+ {8FB015CE-1900-41EE-8E68-C222CE1B8561}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8FB015CE-1900-41EE-8E68-C222CE1B8561}.Debug|x86.Build.0 = Debug|Any CPU
{8FB015CE-1900-41EE-8E68-C222CE1B8561}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8FB015CE-1900-41EE-8E68-C222CE1B8561}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8FB015CE-1900-41EE-8E68-C222CE1B8561}.Release|x64.ActiveCfg = Release|Any CPU
+ {8FB015CE-1900-41EE-8E68-C222CE1B8561}.Release|x64.Build.0 = Release|Any CPU
+ {8FB015CE-1900-41EE-8E68-C222CE1B8561}.Release|x86.ActiveCfg = Release|Any CPU
+ {8FB015CE-1900-41EE-8E68-C222CE1B8561}.Release|x86.Build.0 = Release|Any CPU
{5D421BE2-66A9-43FC-877C-620ACED021EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D421BE2-66A9-43FC-877C-620ACED021EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5D421BE2-66A9-43FC-877C-620ACED021EB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5D421BE2-66A9-43FC-877C-620ACED021EB}.Debug|x64.Build.0 = Debug|Any CPU
+ {5D421BE2-66A9-43FC-877C-620ACED021EB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5D421BE2-66A9-43FC-877C-620ACED021EB}.Debug|x86.Build.0 = Debug|Any CPU
{5D421BE2-66A9-43FC-877C-620ACED021EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D421BE2-66A9-43FC-877C-620ACED021EB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5D421BE2-66A9-43FC-877C-620ACED021EB}.Release|x64.ActiveCfg = Release|Any CPU
+ {5D421BE2-66A9-43FC-877C-620ACED021EB}.Release|x64.Build.0 = Release|Any CPU
+ {5D421BE2-66A9-43FC-877C-620ACED021EB}.Release|x86.ActiveCfg = Release|Any CPU
+ {5D421BE2-66A9-43FC-877C-620ACED021EB}.Release|x86.Build.0 = Release|Any CPU
{587A6639-FA2A-498C-8FA2-F77925DB732B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{587A6639-FA2A-498C-8FA2-F77925DB732B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {587A6639-FA2A-498C-8FA2-F77925DB732B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {587A6639-FA2A-498C-8FA2-F77925DB732B}.Debug|x64.Build.0 = Debug|Any CPU
+ {587A6639-FA2A-498C-8FA2-F77925DB732B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {587A6639-FA2A-498C-8FA2-F77925DB732B}.Debug|x86.Build.0 = Debug|Any CPU
{587A6639-FA2A-498C-8FA2-F77925DB732B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{587A6639-FA2A-498C-8FA2-F77925DB732B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {587A6639-FA2A-498C-8FA2-F77925DB732B}.Release|x64.ActiveCfg = Release|Any CPU
+ {587A6639-FA2A-498C-8FA2-F77925DB732B}.Release|x64.Build.0 = Release|Any CPU
+ {587A6639-FA2A-498C-8FA2-F77925DB732B}.Release|x86.ActiveCfg = Release|Any CPU
+ {587A6639-FA2A-498C-8FA2-F77925DB732B}.Release|x86.Build.0 = Release|Any CPU
{2D8AA9EA-3013-47DE-B2DD-E074F67467ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D8AA9EA-3013-47DE-B2DD-E074F67467ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2D8AA9EA-3013-47DE-B2DD-E074F67467ED}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2D8AA9EA-3013-47DE-B2DD-E074F67467ED}.Debug|x64.Build.0 = Debug|Any CPU
+ {2D8AA9EA-3013-47DE-B2DD-E074F67467ED}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2D8AA9EA-3013-47DE-B2DD-E074F67467ED}.Debug|x86.Build.0 = Debug|Any CPU
{2D8AA9EA-3013-47DE-B2DD-E074F67467ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D8AA9EA-3013-47DE-B2DD-E074F67467ED}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2D8AA9EA-3013-47DE-B2DD-E074F67467ED}.Release|x64.ActiveCfg = Release|Any CPU
+ {2D8AA9EA-3013-47DE-B2DD-E074F67467ED}.Release|x64.Build.0 = Release|Any CPU
+ {2D8AA9EA-3013-47DE-B2DD-E074F67467ED}.Release|x86.ActiveCfg = Release|Any CPU
+ {2D8AA9EA-3013-47DE-B2DD-E074F67467ED}.Release|x86.Build.0 = Release|Any CPU
{A0EFB2CB-517F-4746-902E-D0EBEFFBD89B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A0EFB2CB-517F-4746-902E-D0EBEFFBD89B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A0EFB2CB-517F-4746-902E-D0EBEFFBD89B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A0EFB2CB-517F-4746-902E-D0EBEFFBD89B}.Debug|x64.Build.0 = Debug|Any CPU
+ {A0EFB2CB-517F-4746-902E-D0EBEFFBD89B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A0EFB2CB-517F-4746-902E-D0EBEFFBD89B}.Debug|x86.Build.0 = Debug|Any CPU
{A0EFB2CB-517F-4746-902E-D0EBEFFBD89B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A0EFB2CB-517F-4746-902E-D0EBEFFBD89B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A0EFB2CB-517F-4746-902E-D0EBEFFBD89B}.Release|x64.ActiveCfg = Release|Any CPU
+ {A0EFB2CB-517F-4746-902E-D0EBEFFBD89B}.Release|x64.Build.0 = Release|Any CPU
+ {A0EFB2CB-517F-4746-902E-D0EBEFFBD89B}.Release|x86.ActiveCfg = Release|Any CPU
+ {A0EFB2CB-517F-4746-902E-D0EBEFFBD89B}.Release|x86.Build.0 = Release|Any CPU
{C34FB893-2320-41A3-9D38-0061C22A6464}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C34FB893-2320-41A3-9D38-0061C22A6464}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C34FB893-2320-41A3-9D38-0061C22A6464}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C34FB893-2320-41A3-9D38-0061C22A6464}.Debug|x64.Build.0 = Debug|Any CPU
+ {C34FB893-2320-41A3-9D38-0061C22A6464}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C34FB893-2320-41A3-9D38-0061C22A6464}.Debug|x86.Build.0 = Debug|Any CPU
{C34FB893-2320-41A3-9D38-0061C22A6464}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C34FB893-2320-41A3-9D38-0061C22A6464}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C34FB893-2320-41A3-9D38-0061C22A6464}.Release|x64.ActiveCfg = Release|Any CPU
+ {C34FB893-2320-41A3-9D38-0061C22A6464}.Release|x64.Build.0 = Release|Any CPU
+ {C34FB893-2320-41A3-9D38-0061C22A6464}.Release|x86.ActiveCfg = Release|Any CPU
+ {C34FB893-2320-41A3-9D38-0061C22A6464}.Release|x86.Build.0 = Release|Any CPU
{0AE2AB83-1F0D-4E04-9C8D-5C35CE97FDDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0AE2AB83-1F0D-4E04-9C8D-5C35CE97FDDC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0AE2AB83-1F0D-4E04-9C8D-5C35CE97FDDC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0AE2AB83-1F0D-4E04-9C8D-5C35CE97FDDC}.Debug|x64.Build.0 = Debug|Any CPU
+ {0AE2AB83-1F0D-4E04-9C8D-5C35CE97FDDC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0AE2AB83-1F0D-4E04-9C8D-5C35CE97FDDC}.Debug|x86.Build.0 = Debug|Any CPU
{0AE2AB83-1F0D-4E04-9C8D-5C35CE97FDDC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0AE2AB83-1F0D-4E04-9C8D-5C35CE97FDDC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0AE2AB83-1F0D-4E04-9C8D-5C35CE97FDDC}.Release|x64.ActiveCfg = Release|Any CPU
+ {0AE2AB83-1F0D-4E04-9C8D-5C35CE97FDDC}.Release|x64.Build.0 = Release|Any CPU
+ {0AE2AB83-1F0D-4E04-9C8D-5C35CE97FDDC}.Release|x86.ActiveCfg = Release|Any CPU
+ {0AE2AB83-1F0D-4E04-9C8D-5C35CE97FDDC}.Release|x86.Build.0 = Release|Any CPU
{3D20D19D-74FB-4A43-B78C-B0AF90A696A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3D20D19D-74FB-4A43-B78C-B0AF90A696A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3D20D19D-74FB-4A43-B78C-B0AF90A696A0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3D20D19D-74FB-4A43-B78C-B0AF90A696A0}.Debug|x64.Build.0 = Debug|Any CPU
+ {3D20D19D-74FB-4A43-B78C-B0AF90A696A0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3D20D19D-74FB-4A43-B78C-B0AF90A696A0}.Debug|x86.Build.0 = Debug|Any CPU
{3D20D19D-74FB-4A43-B78C-B0AF90A696A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D20D19D-74FB-4A43-B78C-B0AF90A696A0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3D20D19D-74FB-4A43-B78C-B0AF90A696A0}.Release|x64.ActiveCfg = Release|Any CPU
+ {3D20D19D-74FB-4A43-B78C-B0AF90A696A0}.Release|x64.Build.0 = Release|Any CPU
+ {3D20D19D-74FB-4A43-B78C-B0AF90A696A0}.Release|x86.ActiveCfg = Release|Any CPU
+ {3D20D19D-74FB-4A43-B78C-B0AF90A696A0}.Release|x86.Build.0 = Release|Any CPU
{45281FB4-EAFA-4D62-84BA-47546C04D653}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{45281FB4-EAFA-4D62-84BA-47546C04D653}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {45281FB4-EAFA-4D62-84BA-47546C04D653}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {45281FB4-EAFA-4D62-84BA-47546C04D653}.Debug|x64.Build.0 = Debug|Any CPU
+ {45281FB4-EAFA-4D62-84BA-47546C04D653}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {45281FB4-EAFA-4D62-84BA-47546C04D653}.Debug|x86.Build.0 = Debug|Any CPU
{45281FB4-EAFA-4D62-84BA-47546C04D653}.Release|Any CPU.ActiveCfg = Release|Any CPU
{45281FB4-EAFA-4D62-84BA-47546C04D653}.Release|Any CPU.Build.0 = Release|Any CPU
+ {45281FB4-EAFA-4D62-84BA-47546C04D653}.Release|x64.ActiveCfg = Release|Any CPU
+ {45281FB4-EAFA-4D62-84BA-47546C04D653}.Release|x64.Build.0 = Release|Any CPU
+ {45281FB4-EAFA-4D62-84BA-47546C04D653}.Release|x86.ActiveCfg = Release|Any CPU
+ {45281FB4-EAFA-4D62-84BA-47546C04D653}.Release|x86.Build.0 = Release|Any CPU
{818165C4-6D22-4FA6-AAAF-DC66DA72450A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{818165C4-6D22-4FA6-AAAF-DC66DA72450A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {818165C4-6D22-4FA6-AAAF-DC66DA72450A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {818165C4-6D22-4FA6-AAAF-DC66DA72450A}.Debug|x64.Build.0 = Debug|Any CPU
+ {818165C4-6D22-4FA6-AAAF-DC66DA72450A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {818165C4-6D22-4FA6-AAAF-DC66DA72450A}.Debug|x86.Build.0 = Debug|Any CPU
{818165C4-6D22-4FA6-AAAF-DC66DA72450A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{818165C4-6D22-4FA6-AAAF-DC66DA72450A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {818165C4-6D22-4FA6-AAAF-DC66DA72450A}.Release|x64.ActiveCfg = Release|Any CPU
+ {818165C4-6D22-4FA6-AAAF-DC66DA72450A}.Release|x64.Build.0 = Release|Any CPU
+ {818165C4-6D22-4FA6-AAAF-DC66DA72450A}.Release|x86.ActiveCfg = Release|Any CPU
+ {818165C4-6D22-4FA6-AAAF-DC66DA72450A}.Release|x86.Build.0 = Release|Any CPU
{C713077C-5E5B-4512-8C40-53C90915557F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C713077C-5E5B-4512-8C40-53C90915557F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C713077C-5E5B-4512-8C40-53C90915557F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C713077C-5E5B-4512-8C40-53C90915557F}.Debug|x64.Build.0 = Debug|Any CPU
+ {C713077C-5E5B-4512-8C40-53C90915557F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C713077C-5E5B-4512-8C40-53C90915557F}.Debug|x86.Build.0 = Debug|Any CPU
{C713077C-5E5B-4512-8C40-53C90915557F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C713077C-5E5B-4512-8C40-53C90915557F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C713077C-5E5B-4512-8C40-53C90915557F}.Release|x64.ActiveCfg = Release|Any CPU
+ {C713077C-5E5B-4512-8C40-53C90915557F}.Release|x64.Build.0 = Release|Any CPU
+ {C713077C-5E5B-4512-8C40-53C90915557F}.Release|x86.ActiveCfg = Release|Any CPU
+ {C713077C-5E5B-4512-8C40-53C90915557F}.Release|x86.Build.0 = Release|Any CPU
{518B88F4-D9C0-4865-8D33-9BB09F7D4A3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{518B88F4-D9C0-4865-8D33-9BB09F7D4A3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {518B88F4-D9C0-4865-8D33-9BB09F7D4A3E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {518B88F4-D9C0-4865-8D33-9BB09F7D4A3E}.Debug|x64.Build.0 = Debug|Any CPU
+ {518B88F4-D9C0-4865-8D33-9BB09F7D4A3E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {518B88F4-D9C0-4865-8D33-9BB09F7D4A3E}.Debug|x86.Build.0 = Debug|Any CPU
{518B88F4-D9C0-4865-8D33-9BB09F7D4A3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{518B88F4-D9C0-4865-8D33-9BB09F7D4A3E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {518B88F4-D9C0-4865-8D33-9BB09F7D4A3E}.Release|x64.ActiveCfg = Release|Any CPU
+ {518B88F4-D9C0-4865-8D33-9BB09F7D4A3E}.Release|x64.Build.0 = Release|Any CPU
+ {518B88F4-D9C0-4865-8D33-9BB09F7D4A3E}.Release|x86.ActiveCfg = Release|Any CPU
+ {518B88F4-D9C0-4865-8D33-9BB09F7D4A3E}.Release|x86.Build.0 = Release|Any CPU
{CC92D8D8-5914-451E-8F8E-9623103BC186}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CC92D8D8-5914-451E-8F8E-9623103BC186}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CC92D8D8-5914-451E-8F8E-9623103BC186}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {CC92D8D8-5914-451E-8F8E-9623103BC186}.Debug|x64.Build.0 = Debug|Any CPU
+ {CC92D8D8-5914-451E-8F8E-9623103BC186}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {CC92D8D8-5914-451E-8F8E-9623103BC186}.Debug|x86.Build.0 = Debug|Any CPU
{CC92D8D8-5914-451E-8F8E-9623103BC186}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CC92D8D8-5914-451E-8F8E-9623103BC186}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CC92D8D8-5914-451E-8F8E-9623103BC186}.Release|x64.ActiveCfg = Release|Any CPU
+ {CC92D8D8-5914-451E-8F8E-9623103BC186}.Release|x64.Build.0 = Release|Any CPU
+ {CC92D8D8-5914-451E-8F8E-9623103BC186}.Release|x86.ActiveCfg = Release|Any CPU
+ {CC92D8D8-5914-451E-8F8E-9623103BC186}.Release|x86.Build.0 = Release|Any CPU
{ACB5302C-8641-4E12-B7F7-0122D2A97C31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ACB5302C-8641-4E12-B7F7-0122D2A97C31}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ACB5302C-8641-4E12-B7F7-0122D2A97C31}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {ACB5302C-8641-4E12-B7F7-0122D2A97C31}.Debug|x64.Build.0 = Debug|Any CPU
+ {ACB5302C-8641-4E12-B7F7-0122D2A97C31}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {ACB5302C-8641-4E12-B7F7-0122D2A97C31}.Debug|x86.Build.0 = Debug|Any CPU
{ACB5302C-8641-4E12-B7F7-0122D2A97C31}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ACB5302C-8641-4E12-B7F7-0122D2A97C31}.Release|Any CPU.Build.0 = Release|Any CPU
+ {ACB5302C-8641-4E12-B7F7-0122D2A97C31}.Release|x64.ActiveCfg = Release|Any CPU
+ {ACB5302C-8641-4E12-B7F7-0122D2A97C31}.Release|x64.Build.0 = Release|Any CPU
+ {ACB5302C-8641-4E12-B7F7-0122D2A97C31}.Release|x86.ActiveCfg = Release|Any CPU
+ {ACB5302C-8641-4E12-B7F7-0122D2A97C31}.Release|x86.Build.0 = Release|Any CPU
{1F26FAE6-2654-4E83-8936-146134638C59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1F26FAE6-2654-4E83-8936-146134638C59}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1F26FAE6-2654-4E83-8936-146134638C59}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1F26FAE6-2654-4E83-8936-146134638C59}.Debug|x64.Build.0 = Debug|Any CPU
+ {1F26FAE6-2654-4E83-8936-146134638C59}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1F26FAE6-2654-4E83-8936-146134638C59}.Debug|x86.Build.0 = Debug|Any CPU
{1F26FAE6-2654-4E83-8936-146134638C59}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1F26FAE6-2654-4E83-8936-146134638C59}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1F26FAE6-2654-4E83-8936-146134638C59}.Release|x64.ActiveCfg = Release|Any CPU
+ {1F26FAE6-2654-4E83-8936-146134638C59}.Release|x64.Build.0 = Release|Any CPU
+ {1F26FAE6-2654-4E83-8936-146134638C59}.Release|x86.ActiveCfg = Release|Any CPU
+ {1F26FAE6-2654-4E83-8936-146134638C59}.Release|x86.Build.0 = Release|Any CPU
{89F798D9-A8BA-4556-B2A2-39CEF3587093}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89F798D9-A8BA-4556-B2A2-39CEF3587093}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {89F798D9-A8BA-4556-B2A2-39CEF3587093}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {89F798D9-A8BA-4556-B2A2-39CEF3587093}.Debug|x64.Build.0 = Debug|Any CPU
+ {89F798D9-A8BA-4556-B2A2-39CEF3587093}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {89F798D9-A8BA-4556-B2A2-39CEF3587093}.Debug|x86.Build.0 = Debug|Any CPU
{89F798D9-A8BA-4556-B2A2-39CEF3587093}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89F798D9-A8BA-4556-B2A2-39CEF3587093}.Release|Any CPU.Build.0 = Release|Any CPU
+ {89F798D9-A8BA-4556-B2A2-39CEF3587093}.Release|x64.ActiveCfg = Release|Any CPU
+ {89F798D9-A8BA-4556-B2A2-39CEF3587093}.Release|x64.Build.0 = Release|Any CPU
+ {89F798D9-A8BA-4556-B2A2-39CEF3587093}.Release|x86.ActiveCfg = Release|Any CPU
+ {89F798D9-A8BA-4556-B2A2-39CEF3587093}.Release|x86.Build.0 = Release|Any CPU
{360F049F-D501-478A-98BD-A2BA4DB000B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{360F049F-D501-478A-98BD-A2BA4DB000B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {360F049F-D501-478A-98BD-A2BA4DB000B9}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {360F049F-D501-478A-98BD-A2BA4DB000B9}.Debug|x64.Build.0 = Debug|Any CPU
+ {360F049F-D501-478A-98BD-A2BA4DB000B9}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {360F049F-D501-478A-98BD-A2BA4DB000B9}.Debug|x86.Build.0 = Debug|Any CPU
{360F049F-D501-478A-98BD-A2BA4DB000B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{360F049F-D501-478A-98BD-A2BA4DB000B9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {360F049F-D501-478A-98BD-A2BA4DB000B9}.Release|x64.ActiveCfg = Release|Any CPU
+ {360F049F-D501-478A-98BD-A2BA4DB000B9}.Release|x64.Build.0 = Release|Any CPU
+ {360F049F-D501-478A-98BD-A2BA4DB000B9}.Release|x86.ActiveCfg = Release|Any CPU
+ {360F049F-D501-478A-98BD-A2BA4DB000B9}.Release|x86.Build.0 = Release|Any CPU
{2207EE89-63BC-4498-A5BE-F285FBCC8FD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2207EE89-63BC-4498-A5BE-F285FBCC8FD9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2207EE89-63BC-4498-A5BE-F285FBCC8FD9}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2207EE89-63BC-4498-A5BE-F285FBCC8FD9}.Debug|x64.Build.0 = Debug|Any CPU
+ {2207EE89-63BC-4498-A5BE-F285FBCC8FD9}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2207EE89-63BC-4498-A5BE-F285FBCC8FD9}.Debug|x86.Build.0 = Debug|Any CPU
{2207EE89-63BC-4498-A5BE-F285FBCC8FD9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2207EE89-63BC-4498-A5BE-F285FBCC8FD9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2207EE89-63BC-4498-A5BE-F285FBCC8FD9}.Release|x64.ActiveCfg = Release|Any CPU
+ {2207EE89-63BC-4498-A5BE-F285FBCC8FD9}.Release|x64.Build.0 = Release|Any CPU
+ {2207EE89-63BC-4498-A5BE-F285FBCC8FD9}.Release|x86.ActiveCfg = Release|Any CPU
+ {2207EE89-63BC-4498-A5BE-F285FBCC8FD9}.Release|x86.Build.0 = Release|Any CPU
{29D14D1A-F236-4D11-8E2A-8DCEBC4FAEC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{29D14D1A-F236-4D11-8E2A-8DCEBC4FAEC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {29D14D1A-F236-4D11-8E2A-8DCEBC4FAEC0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {29D14D1A-F236-4D11-8E2A-8DCEBC4FAEC0}.Debug|x64.Build.0 = Debug|Any CPU
+ {29D14D1A-F236-4D11-8E2A-8DCEBC4FAEC0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {29D14D1A-F236-4D11-8E2A-8DCEBC4FAEC0}.Debug|x86.Build.0 = Debug|Any CPU
{29D14D1A-F236-4D11-8E2A-8DCEBC4FAEC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{29D14D1A-F236-4D11-8E2A-8DCEBC4FAEC0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {29D14D1A-F236-4D11-8E2A-8DCEBC4FAEC0}.Release|x64.ActiveCfg = Release|Any CPU
+ {29D14D1A-F236-4D11-8E2A-8DCEBC4FAEC0}.Release|x64.Build.0 = Release|Any CPU
+ {29D14D1A-F236-4D11-8E2A-8DCEBC4FAEC0}.Release|x86.ActiveCfg = Release|Any CPU
+ {29D14D1A-F236-4D11-8E2A-8DCEBC4FAEC0}.Release|x86.Build.0 = Release|Any CPU
{C22A85E0-C09F-4E2D-81F6-82AB97932FE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C22A85E0-C09F-4E2D-81F6-82AB97932FE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C22A85E0-C09F-4E2D-81F6-82AB97932FE2}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C22A85E0-C09F-4E2D-81F6-82AB97932FE2}.Debug|x64.Build.0 = Debug|Any CPU
+ {C22A85E0-C09F-4E2D-81F6-82AB97932FE2}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C22A85E0-C09F-4E2D-81F6-82AB97932FE2}.Debug|x86.Build.0 = Debug|Any CPU
{C22A85E0-C09F-4E2D-81F6-82AB97932FE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C22A85E0-C09F-4E2D-81F6-82AB97932FE2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C22A85E0-C09F-4E2D-81F6-82AB97932FE2}.Release|x64.ActiveCfg = Release|Any CPU
+ {C22A85E0-C09F-4E2D-81F6-82AB97932FE2}.Release|x64.Build.0 = Release|Any CPU
+ {C22A85E0-C09F-4E2D-81F6-82AB97932FE2}.Release|x86.ActiveCfg = Release|Any CPU
+ {C22A85E0-C09F-4E2D-81F6-82AB97932FE2}.Release|x86.Build.0 = Release|Any CPU
{988D4839-B97F-42BB-A045-C79157CA7780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{988D4839-B97F-42BB-A045-C79157CA7780}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {988D4839-B97F-42BB-A045-C79157CA7780}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {988D4839-B97F-42BB-A045-C79157CA7780}.Debug|x64.Build.0 = Debug|Any CPU
+ {988D4839-B97F-42BB-A045-C79157CA7780}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {988D4839-B97F-42BB-A045-C79157CA7780}.Debug|x86.Build.0 = Debug|Any CPU
{988D4839-B97F-42BB-A045-C79157CA7780}.Release|Any CPU.ActiveCfg = Release|Any CPU
{988D4839-B97F-42BB-A045-C79157CA7780}.Release|Any CPU.Build.0 = Release|Any CPU
+ {988D4839-B97F-42BB-A045-C79157CA7780}.Release|x64.ActiveCfg = Release|Any CPU
+ {988D4839-B97F-42BB-A045-C79157CA7780}.Release|x64.Build.0 = Release|Any CPU
+ {988D4839-B97F-42BB-A045-C79157CA7780}.Release|x86.ActiveCfg = Release|Any CPU
+ {988D4839-B97F-42BB-A045-C79157CA7780}.Release|x86.Build.0 = Release|Any CPU
{56F189B0-6A8E-4A9D-B7AE-24241204E98D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{56F189B0-6A8E-4A9D-B7AE-24241204E98D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {56F189B0-6A8E-4A9D-B7AE-24241204E98D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {56F189B0-6A8E-4A9D-B7AE-24241204E98D}.Debug|x64.Build.0 = Debug|Any CPU
+ {56F189B0-6A8E-4A9D-B7AE-24241204E98D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {56F189B0-6A8E-4A9D-B7AE-24241204E98D}.Debug|x86.Build.0 = Debug|Any CPU
{56F189B0-6A8E-4A9D-B7AE-24241204E98D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{56F189B0-6A8E-4A9D-B7AE-24241204E98D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {56F189B0-6A8E-4A9D-B7AE-24241204E98D}.Release|x64.ActiveCfg = Release|Any CPU
+ {56F189B0-6A8E-4A9D-B7AE-24241204E98D}.Release|x64.Build.0 = Release|Any CPU
+ {56F189B0-6A8E-4A9D-B7AE-24241204E98D}.Release|x86.ActiveCfg = Release|Any CPU
+ {56F189B0-6A8E-4A9D-B7AE-24241204E98D}.Release|x86.Build.0 = Release|Any CPU
{445EFBD5-6730-4F09-943D-278E77501FFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{445EFBD5-6730-4F09-943D-278E77501FFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {445EFBD5-6730-4F09-943D-278E77501FFD}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {445EFBD5-6730-4F09-943D-278E77501FFD}.Debug|x64.Build.0 = Debug|Any CPU
+ {445EFBD5-6730-4F09-943D-278E77501FFD}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {445EFBD5-6730-4F09-943D-278E77501FFD}.Debug|x86.Build.0 = Debug|Any CPU
{445EFBD5-6730-4F09-943D-278E77501FFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{445EFBD5-6730-4F09-943D-278E77501FFD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {445EFBD5-6730-4F09-943D-278E77501FFD}.Release|x64.ActiveCfg = Release|Any CPU
+ {445EFBD5-6730-4F09-943D-278E77501FFD}.Release|x64.Build.0 = Release|Any CPU
+ {445EFBD5-6730-4F09-943D-278E77501FFD}.Release|x86.ActiveCfg = Release|Any CPU
+ {445EFBD5-6730-4F09-943D-278E77501FFD}.Release|x86.Build.0 = Release|Any CPU
{A82EF2B9-24BC-4569-8FE5-9EF51017F4CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A82EF2B9-24BC-4569-8FE5-9EF51017F4CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A82EF2B9-24BC-4569-8FE5-9EF51017F4CB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A82EF2B9-24BC-4569-8FE5-9EF51017F4CB}.Debug|x64.Build.0 = Debug|Any CPU
+ {A82EF2B9-24BC-4569-8FE5-9EF51017F4CB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A82EF2B9-24BC-4569-8FE5-9EF51017F4CB}.Debug|x86.Build.0 = Debug|Any CPU
{A82EF2B9-24BC-4569-8FE5-9EF51017F4CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A82EF2B9-24BC-4569-8FE5-9EF51017F4CB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A82EF2B9-24BC-4569-8FE5-9EF51017F4CB}.Release|x64.ActiveCfg = Release|Any CPU
+ {A82EF2B9-24BC-4569-8FE5-9EF51017F4CB}.Release|x64.Build.0 = Release|Any CPU
+ {A82EF2B9-24BC-4569-8FE5-9EF51017F4CB}.Release|x86.ActiveCfg = Release|Any CPU
+ {A82EF2B9-24BC-4569-8FE5-9EF51017F4CB}.Release|x86.Build.0 = Release|Any CPU
{CCE1A328-9CFE-44D3-B68F-FE84A039ACEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CCE1A328-9CFE-44D3-B68F-FE84A039ACEA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CCE1A328-9CFE-44D3-B68F-FE84A039ACEA}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {CCE1A328-9CFE-44D3-B68F-FE84A039ACEA}.Debug|x64.Build.0 = Debug|Any CPU
+ {CCE1A328-9CFE-44D3-B68F-FE84A039ACEA}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {CCE1A328-9CFE-44D3-B68F-FE84A039ACEA}.Debug|x86.Build.0 = Debug|Any CPU
{CCE1A328-9CFE-44D3-B68F-FE84A039ACEA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCE1A328-9CFE-44D3-B68F-FE84A039ACEA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CCE1A328-9CFE-44D3-B68F-FE84A039ACEA}.Release|x64.ActiveCfg = Release|Any CPU
+ {CCE1A328-9CFE-44D3-B68F-FE84A039ACEA}.Release|x64.Build.0 = Release|Any CPU
+ {CCE1A328-9CFE-44D3-B68F-FE84A039ACEA}.Release|x86.ActiveCfg = Release|Any CPU
+ {CCE1A328-9CFE-44D3-B68F-FE84A039ACEA}.Release|x86.Build.0 = Release|Any CPU
{81ADA3FA-AC26-4149-8CFC-EC7808ECB820}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81ADA3FA-AC26-4149-8CFC-EC7808ECB820}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {81ADA3FA-AC26-4149-8CFC-EC7808ECB820}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {81ADA3FA-AC26-4149-8CFC-EC7808ECB820}.Debug|x64.Build.0 = Debug|Any CPU
+ {81ADA3FA-AC26-4149-8CFC-EC7808ECB820}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {81ADA3FA-AC26-4149-8CFC-EC7808ECB820}.Debug|x86.Build.0 = Debug|Any CPU
{81ADA3FA-AC26-4149-8CFC-EC7808ECB820}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81ADA3FA-AC26-4149-8CFC-EC7808ECB820}.Release|Any CPU.Build.0 = Release|Any CPU
+ {81ADA3FA-AC26-4149-8CFC-EC7808ECB820}.Release|x64.ActiveCfg = Release|Any CPU
+ {81ADA3FA-AC26-4149-8CFC-EC7808ECB820}.Release|x64.Build.0 = Release|Any CPU
+ {81ADA3FA-AC26-4149-8CFC-EC7808ECB820}.Release|x86.ActiveCfg = Release|Any CPU
+ {81ADA3FA-AC26-4149-8CFC-EC7808ECB820}.Release|x86.Build.0 = Release|Any CPU
{A41DF752-6F21-4036-AD02-DD37B11A2723}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A41DF752-6F21-4036-AD02-DD37B11A2723}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A41DF752-6F21-4036-AD02-DD37B11A2723}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A41DF752-6F21-4036-AD02-DD37B11A2723}.Debug|x64.Build.0 = Debug|Any CPU
+ {A41DF752-6F21-4036-AD02-DD37B11A2723}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A41DF752-6F21-4036-AD02-DD37B11A2723}.Debug|x86.Build.0 = Debug|Any CPU
{A41DF752-6F21-4036-AD02-DD37B11A2723}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A41DF752-6F21-4036-AD02-DD37B11A2723}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A41DF752-6F21-4036-AD02-DD37B11A2723}.Release|x64.ActiveCfg = Release|Any CPU
+ {A41DF752-6F21-4036-AD02-DD37B11A2723}.Release|x64.Build.0 = Release|Any CPU
+ {A41DF752-6F21-4036-AD02-DD37B11A2723}.Release|x86.ActiveCfg = Release|Any CPU
+ {A41DF752-6F21-4036-AD02-DD37B11A2723}.Release|x86.Build.0 = Release|Any CPU
{4AE60971-C960-4DDF-B671-8B3E32C1AFD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4AE60971-C960-4DDF-B671-8B3E32C1AFD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4AE60971-C960-4DDF-B671-8B3E32C1AFD2}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {4AE60971-C960-4DDF-B671-8B3E32C1AFD2}.Debug|x64.Build.0 = Debug|Any CPU
+ {4AE60971-C960-4DDF-B671-8B3E32C1AFD2}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {4AE60971-C960-4DDF-B671-8B3E32C1AFD2}.Debug|x86.Build.0 = Debug|Any CPU
{4AE60971-C960-4DDF-B671-8B3E32C1AFD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4AE60971-C960-4DDF-B671-8B3E32C1AFD2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4AE60971-C960-4DDF-B671-8B3E32C1AFD2}.Release|x64.ActiveCfg = Release|Any CPU
+ {4AE60971-C960-4DDF-B671-8B3E32C1AFD2}.Release|x64.Build.0 = Release|Any CPU
+ {4AE60971-C960-4DDF-B671-8B3E32C1AFD2}.Release|x86.ActiveCfg = Release|Any CPU
+ {4AE60971-C960-4DDF-B671-8B3E32C1AFD2}.Release|x86.Build.0 = Release|Any CPU
{CB7F74C6-BF0A-4CD6-94B4-BBF47AF9BB56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CB7F74C6-BF0A-4CD6-94B4-BBF47AF9BB56}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CB7F74C6-BF0A-4CD6-94B4-BBF47AF9BB56}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {CB7F74C6-BF0A-4CD6-94B4-BBF47AF9BB56}.Debug|x64.Build.0 = Debug|Any CPU
+ {CB7F74C6-BF0A-4CD6-94B4-BBF47AF9BB56}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {CB7F74C6-BF0A-4CD6-94B4-BBF47AF9BB56}.Debug|x86.Build.0 = Debug|Any CPU
{CB7F74C6-BF0A-4CD6-94B4-BBF47AF9BB56}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CB7F74C6-BF0A-4CD6-94B4-BBF47AF9BB56}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CB7F74C6-BF0A-4CD6-94B4-BBF47AF9BB56}.Release|x64.ActiveCfg = Release|Any CPU
+ {CB7F74C6-BF0A-4CD6-94B4-BBF47AF9BB56}.Release|x64.Build.0 = Release|Any CPU
+ {CB7F74C6-BF0A-4CD6-94B4-BBF47AF9BB56}.Release|x86.ActiveCfg = Release|Any CPU
+ {CB7F74C6-BF0A-4CD6-94B4-BBF47AF9BB56}.Release|x86.Build.0 = Release|Any CPU
{6CFB4CBF-1618-4D13-8880-518939E1809A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6CFB4CBF-1618-4D13-8880-518939E1809A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6CFB4CBF-1618-4D13-8880-518939E1809A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6CFB4CBF-1618-4D13-8880-518939E1809A}.Debug|x64.Build.0 = Debug|Any CPU
+ {6CFB4CBF-1618-4D13-8880-518939E1809A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6CFB4CBF-1618-4D13-8880-518939E1809A}.Debug|x86.Build.0 = Debug|Any CPU
{6CFB4CBF-1618-4D13-8880-518939E1809A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6CFB4CBF-1618-4D13-8880-518939E1809A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6CFB4CBF-1618-4D13-8880-518939E1809A}.Release|x64.ActiveCfg = Release|Any CPU
+ {6CFB4CBF-1618-4D13-8880-518939E1809A}.Release|x64.Build.0 = Release|Any CPU
+ {6CFB4CBF-1618-4D13-8880-518939E1809A}.Release|x86.ActiveCfg = Release|Any CPU
+ {6CFB4CBF-1618-4D13-8880-518939E1809A}.Release|x86.Build.0 = Release|Any CPU
{066660EC-8570-4093-8259-04760F757430}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{066660EC-8570-4093-8259-04760F757430}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {066660EC-8570-4093-8259-04760F757430}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {066660EC-8570-4093-8259-04760F757430}.Debug|x64.Build.0 = Debug|Any CPU
+ {066660EC-8570-4093-8259-04760F757430}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {066660EC-8570-4093-8259-04760F757430}.Debug|x86.Build.0 = Debug|Any CPU
{066660EC-8570-4093-8259-04760F757430}.Release|Any CPU.ActiveCfg = Release|Any CPU
{066660EC-8570-4093-8259-04760F757430}.Release|Any CPU.Build.0 = Release|Any CPU
+ {066660EC-8570-4093-8259-04760F757430}.Release|x64.ActiveCfg = Release|Any CPU
+ {066660EC-8570-4093-8259-04760F757430}.Release|x64.Build.0 = Release|Any CPU
+ {066660EC-8570-4093-8259-04760F757430}.Release|x86.ActiveCfg = Release|Any CPU
+ {066660EC-8570-4093-8259-04760F757430}.Release|x86.Build.0 = Release|Any CPU
{8A0288C8-3F81-4CE1-B81A-C9BCDE506E57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A0288C8-3F81-4CE1-B81A-C9BCDE506E57}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8A0288C8-3F81-4CE1-B81A-C9BCDE506E57}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8A0288C8-3F81-4CE1-B81A-C9BCDE506E57}.Debug|x64.Build.0 = Debug|Any CPU
+ {8A0288C8-3F81-4CE1-B81A-C9BCDE506E57}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8A0288C8-3F81-4CE1-B81A-C9BCDE506E57}.Debug|x86.Build.0 = Debug|Any CPU
{8A0288C8-3F81-4CE1-B81A-C9BCDE506E57}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A0288C8-3F81-4CE1-B81A-C9BCDE506E57}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8A0288C8-3F81-4CE1-B81A-C9BCDE506E57}.Release|x64.ActiveCfg = Release|Any CPU
+ {8A0288C8-3F81-4CE1-B81A-C9BCDE506E57}.Release|x64.Build.0 = Release|Any CPU
+ {8A0288C8-3F81-4CE1-B81A-C9BCDE506E57}.Release|x86.ActiveCfg = Release|Any CPU
+ {8A0288C8-3F81-4CE1-B81A-C9BCDE506E57}.Release|x86.Build.0 = Release|Any CPU
{8076A8AF-01FA-4B3C-B2BB-BC612B1BD7D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8076A8AF-01FA-4B3C-B2BB-BC612B1BD7D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8076A8AF-01FA-4B3C-B2BB-BC612B1BD7D5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8076A8AF-01FA-4B3C-B2BB-BC612B1BD7D5}.Debug|x64.Build.0 = Debug|Any CPU
+ {8076A8AF-01FA-4B3C-B2BB-BC612B1BD7D5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8076A8AF-01FA-4B3C-B2BB-BC612B1BD7D5}.Debug|x86.Build.0 = Debug|Any CPU
{8076A8AF-01FA-4B3C-B2BB-BC612B1BD7D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8076A8AF-01FA-4B3C-B2BB-BC612B1BD7D5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8076A8AF-01FA-4B3C-B2BB-BC612B1BD7D5}.Release|x64.ActiveCfg = Release|Any CPU
+ {8076A8AF-01FA-4B3C-B2BB-BC612B1BD7D5}.Release|x64.Build.0 = Release|Any CPU
+ {8076A8AF-01FA-4B3C-B2BB-BC612B1BD7D5}.Release|x86.ActiveCfg = Release|Any CPU
+ {8076A8AF-01FA-4B3C-B2BB-BC612B1BD7D5}.Release|x86.Build.0 = Release|Any CPU
{08C9E634-39F3-4B24-BCEA-D0B21971EBBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08C9E634-39F3-4B24-BCEA-D0B21971EBBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {08C9E634-39F3-4B24-BCEA-D0B21971EBBE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {08C9E634-39F3-4B24-BCEA-D0B21971EBBE}.Debug|x64.Build.0 = Debug|Any CPU
+ {08C9E634-39F3-4B24-BCEA-D0B21971EBBE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {08C9E634-39F3-4B24-BCEA-D0B21971EBBE}.Debug|x86.Build.0 = Debug|Any CPU
{08C9E634-39F3-4B24-BCEA-D0B21971EBBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08C9E634-39F3-4B24-BCEA-D0B21971EBBE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {08C9E634-39F3-4B24-BCEA-D0B21971EBBE}.Release|x64.ActiveCfg = Release|Any CPU
+ {08C9E634-39F3-4B24-BCEA-D0B21971EBBE}.Release|x64.Build.0 = Release|Any CPU
+ {08C9E634-39F3-4B24-BCEA-D0B21971EBBE}.Release|x86.ActiveCfg = Release|Any CPU
+ {08C9E634-39F3-4B24-BCEA-D0B21971EBBE}.Release|x86.Build.0 = Release|Any CPU
{1BBFA19C-03F0-4D27-9D0D-0F8172642107}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1BBFA19C-03F0-4D27-9D0D-0F8172642107}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1BBFA19C-03F0-4D27-9D0D-0F8172642107}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1BBFA19C-03F0-4D27-9D0D-0F8172642107}.Debug|x64.Build.0 = Debug|Any CPU
+ {1BBFA19C-03F0-4D27-9D0D-0F8172642107}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1BBFA19C-03F0-4D27-9D0D-0F8172642107}.Debug|x86.Build.0 = Debug|Any CPU
{1BBFA19C-03F0-4D27-9D0D-0F8172642107}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1BBFA19C-03F0-4D27-9D0D-0F8172642107}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1BBFA19C-03F0-4D27-9D0D-0F8172642107}.Release|x64.ActiveCfg = Release|Any CPU
+ {1BBFA19C-03F0-4D27-9D0D-0F8172642107}.Release|x64.Build.0 = Release|Any CPU
+ {1BBFA19C-03F0-4D27-9D0D-0F8172642107}.Release|x86.ActiveCfg = Release|Any CPU
+ {1BBFA19C-03F0-4D27-9D0D-0F8172642107}.Release|x86.Build.0 = Release|Any CPU
{E97E9E7F-11B4-42F7-8B55-D0451F5E82A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E97E9E7F-11B4-42F7-8B55-D0451F5E82A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E97E9E7F-11B4-42F7-8B55-D0451F5E82A0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E97E9E7F-11B4-42F7-8B55-D0451F5E82A0}.Debug|x64.Build.0 = Debug|Any CPU
+ {E97E9E7F-11B4-42F7-8B55-D0451F5E82A0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E97E9E7F-11B4-42F7-8B55-D0451F5E82A0}.Debug|x86.Build.0 = Debug|Any CPU
{E97E9E7F-11B4-42F7-8B55-D0451F5E82A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E97E9E7F-11B4-42F7-8B55-D0451F5E82A0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E97E9E7F-11B4-42F7-8B55-D0451F5E82A0}.Release|x64.ActiveCfg = Release|Any CPU
+ {E97E9E7F-11B4-42F7-8B55-D0451F5E82A0}.Release|x64.Build.0 = Release|Any CPU
+ {E97E9E7F-11B4-42F7-8B55-D0451F5E82A0}.Release|x86.ActiveCfg = Release|Any CPU
+ {E97E9E7F-11B4-42F7-8B55-D0451F5E82A0}.Release|x86.Build.0 = Release|Any CPU
{3F5A028C-C51B-434A-8C10-37680CD2635C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F5A028C-C51B-434A-8C10-37680CD2635C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3F5A028C-C51B-434A-8C10-37680CD2635C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3F5A028C-C51B-434A-8C10-37680CD2635C}.Debug|x64.Build.0 = Debug|Any CPU
+ {3F5A028C-C51B-434A-8C10-37680CD2635C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3F5A028C-C51B-434A-8C10-37680CD2635C}.Debug|x86.Build.0 = Debug|Any CPU
{3F5A028C-C51B-434A-8C10-37680CD2635C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F5A028C-C51B-434A-8C10-37680CD2635C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3F5A028C-C51B-434A-8C10-37680CD2635C}.Release|x64.ActiveCfg = Release|Any CPU
+ {3F5A028C-C51B-434A-8C10-37680CD2635C}.Release|x64.Build.0 = Release|Any CPU
+ {3F5A028C-C51B-434A-8C10-37680CD2635C}.Release|x86.ActiveCfg = Release|Any CPU
+ {3F5A028C-C51B-434A-8C10-37680CD2635C}.Release|x86.Build.0 = Release|Any CPU
{24F084ED-35BB-401E-89F5-63E5E22C3B3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{24F084ED-35BB-401E-89F5-63E5E22C3B3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {24F084ED-35BB-401E-89F5-63E5E22C3B3B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {24F084ED-35BB-401E-89F5-63E5E22C3B3B}.Debug|x64.Build.0 = Debug|Any CPU
+ {24F084ED-35BB-401E-89F5-63E5E22C3B3B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {24F084ED-35BB-401E-89F5-63E5E22C3B3B}.Debug|x86.Build.0 = Debug|Any CPU
{24F084ED-35BB-401E-89F5-63E5E22C3B3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24F084ED-35BB-401E-89F5-63E5E22C3B3B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {24F084ED-35BB-401E-89F5-63E5E22C3B3B}.Release|x64.ActiveCfg = Release|Any CPU
+ {24F084ED-35BB-401E-89F5-63E5E22C3B3B}.Release|x64.Build.0 = Release|Any CPU
+ {24F084ED-35BB-401E-89F5-63E5E22C3B3B}.Release|x86.ActiveCfg = Release|Any CPU
+ {24F084ED-35BB-401E-89F5-63E5E22C3B3B}.Release|x86.Build.0 = Release|Any CPU
{3D002392-6308-41DF-8BD5-224CCC5B049F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3D002392-6308-41DF-8BD5-224CCC5B049F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3D002392-6308-41DF-8BD5-224CCC5B049F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3D002392-6308-41DF-8BD5-224CCC5B049F}.Debug|x64.Build.0 = Debug|Any CPU
+ {3D002392-6308-41DF-8BD5-224CCC5B049F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3D002392-6308-41DF-8BD5-224CCC5B049F}.Debug|x86.Build.0 = Debug|Any CPU
{3D002392-6308-41DF-8BD5-224CCC5B049F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D002392-6308-41DF-8BD5-224CCC5B049F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3D002392-6308-41DF-8BD5-224CCC5B049F}.Release|x64.ActiveCfg = Release|Any CPU
+ {3D002392-6308-41DF-8BD5-224CCC5B049F}.Release|x64.Build.0 = Release|Any CPU
+ {3D002392-6308-41DF-8BD5-224CCC5B049F}.Release|x86.ActiveCfg = Release|Any CPU
+ {3D002392-6308-41DF-8BD5-224CCC5B049F}.Release|x86.Build.0 = Release|Any CPU
{80932949-B8B2-4163-B325-76F8FDBE3897}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{80932949-B8B2-4163-B325-76F8FDBE3897}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {80932949-B8B2-4163-B325-76F8FDBE3897}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {80932949-B8B2-4163-B325-76F8FDBE3897}.Debug|x64.Build.0 = Debug|Any CPU
+ {80932949-B8B2-4163-B325-76F8FDBE3897}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {80932949-B8B2-4163-B325-76F8FDBE3897}.Debug|x86.Build.0 = Debug|Any CPU
{80932949-B8B2-4163-B325-76F8FDBE3897}.Release|Any CPU.ActiveCfg = Release|Any CPU
{80932949-B8B2-4163-B325-76F8FDBE3897}.Release|Any CPU.Build.0 = Release|Any CPU
+ {80932949-B8B2-4163-B325-76F8FDBE3897}.Release|x64.ActiveCfg = Release|Any CPU
+ {80932949-B8B2-4163-B325-76F8FDBE3897}.Release|x64.Build.0 = Release|Any CPU
+ {80932949-B8B2-4163-B325-76F8FDBE3897}.Release|x86.ActiveCfg = Release|Any CPU
+ {80932949-B8B2-4163-B325-76F8FDBE3897}.Release|x86.Build.0 = Release|Any CPU
{EEF4C7DD-CDC9-44B6-8B4F-725647D54ED8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EEF4C7DD-CDC9-44B6-8B4F-725647D54ED8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EEF4C7DD-CDC9-44B6-8B4F-725647D54ED8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {EEF4C7DD-CDC9-44B6-8B4F-725647D54ED8}.Debug|x64.Build.0 = Debug|Any CPU
+ {EEF4C7DD-CDC9-44B6-8B4F-725647D54ED8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {EEF4C7DD-CDC9-44B6-8B4F-725647D54ED8}.Debug|x86.Build.0 = Debug|Any CPU
{EEF4C7DD-CDC9-44B6-8B4F-725647D54ED8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EEF4C7DD-CDC9-44B6-8B4F-725647D54ED8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EEF4C7DD-CDC9-44B6-8B4F-725647D54ED8}.Release|x64.ActiveCfg = Release|Any CPU
+ {EEF4C7DD-CDC9-44B6-8B4F-725647D54ED8}.Release|x64.Build.0 = Release|Any CPU
+ {EEF4C7DD-CDC9-44B6-8B4F-725647D54ED8}.Release|x86.ActiveCfg = Release|Any CPU
+ {EEF4C7DD-CDC9-44B6-8B4F-725647D54ED8}.Release|x86.Build.0 = Release|Any CPU
{E56BEA9A-B52A-4781-9FF4-217439923319}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E56BEA9A-B52A-4781-9FF4-217439923319}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E56BEA9A-B52A-4781-9FF4-217439923319}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E56BEA9A-B52A-4781-9FF4-217439923319}.Debug|x64.Build.0 = Debug|Any CPU
+ {E56BEA9A-B52A-4781-9FF4-217439923319}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E56BEA9A-B52A-4781-9FF4-217439923319}.Debug|x86.Build.0 = Debug|Any CPU
{E56BEA9A-B52A-4781-9FF4-217439923319}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E56BEA9A-B52A-4781-9FF4-217439923319}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E56BEA9A-B52A-4781-9FF4-217439923319}.Release|x64.ActiveCfg = Release|Any CPU
+ {E56BEA9A-B52A-4781-9FF4-217439923319}.Release|x64.Build.0 = Release|Any CPU
+ {E56BEA9A-B52A-4781-9FF4-217439923319}.Release|x86.ActiveCfg = Release|Any CPU
+ {E56BEA9A-B52A-4781-9FF4-217439923319}.Release|x86.Build.0 = Release|Any CPU
{69C03400-12AC-4E4D-B970-6A880616BF68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{69C03400-12AC-4E4D-B970-6A880616BF68}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {69C03400-12AC-4E4D-B970-6A880616BF68}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {69C03400-12AC-4E4D-B970-6A880616BF68}.Debug|x64.Build.0 = Debug|Any CPU
+ {69C03400-12AC-4E4D-B970-6A880616BF68}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {69C03400-12AC-4E4D-B970-6A880616BF68}.Debug|x86.Build.0 = Debug|Any CPU
{69C03400-12AC-4E4D-B970-6A880616BF68}.Release|Any CPU.ActiveCfg = Release|Any CPU
{69C03400-12AC-4E4D-B970-6A880616BF68}.Release|Any CPU.Build.0 = Release|Any CPU
+ {69C03400-12AC-4E4D-B970-6A880616BF68}.Release|x64.ActiveCfg = Release|Any CPU
+ {69C03400-12AC-4E4D-B970-6A880616BF68}.Release|x64.Build.0 = Release|Any CPU
+ {69C03400-12AC-4E4D-B970-6A880616BF68}.Release|x86.ActiveCfg = Release|Any CPU
+ {69C03400-12AC-4E4D-B970-6A880616BF68}.Release|x86.Build.0 = Release|Any CPU
{FAAC2E23-A460-40FE-9207-C10EEE5A6A07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FAAC2E23-A460-40FE-9207-C10EEE5A6A07}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FAAC2E23-A460-40FE-9207-C10EEE5A6A07}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FAAC2E23-A460-40FE-9207-C10EEE5A6A07}.Debug|x64.Build.0 = Debug|Any CPU
+ {FAAC2E23-A460-40FE-9207-C10EEE5A6A07}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FAAC2E23-A460-40FE-9207-C10EEE5A6A07}.Debug|x86.Build.0 = Debug|Any CPU
{FAAC2E23-A460-40FE-9207-C10EEE5A6A07}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FAAC2E23-A460-40FE-9207-C10EEE5A6A07}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FAAC2E23-A460-40FE-9207-C10EEE5A6A07}.Release|x64.ActiveCfg = Release|Any CPU
+ {FAAC2E23-A460-40FE-9207-C10EEE5A6A07}.Release|x64.Build.0 = Release|Any CPU
+ {FAAC2E23-A460-40FE-9207-C10EEE5A6A07}.Release|x86.ActiveCfg = Release|Any CPU
+ {FAAC2E23-A460-40FE-9207-C10EEE5A6A07}.Release|x86.Build.0 = Release|Any CPU
{920F6448-C2D0-4B01-AC25-16214C5A6006}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{920F6448-C2D0-4B01-AC25-16214C5A6006}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {920F6448-C2D0-4B01-AC25-16214C5A6006}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {920F6448-C2D0-4B01-AC25-16214C5A6006}.Debug|x64.Build.0 = Debug|Any CPU
+ {920F6448-C2D0-4B01-AC25-16214C5A6006}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {920F6448-C2D0-4B01-AC25-16214C5A6006}.Debug|x86.Build.0 = Debug|Any CPU
{920F6448-C2D0-4B01-AC25-16214C5A6006}.Release|Any CPU.ActiveCfg = Release|Any CPU
{920F6448-C2D0-4B01-AC25-16214C5A6006}.Release|Any CPU.Build.0 = Release|Any CPU
+ {920F6448-C2D0-4B01-AC25-16214C5A6006}.Release|x64.ActiveCfg = Release|Any CPU
+ {920F6448-C2D0-4B01-AC25-16214C5A6006}.Release|x64.Build.0 = Release|Any CPU
+ {920F6448-C2D0-4B01-AC25-16214C5A6006}.Release|x86.ActiveCfg = Release|Any CPU
+ {920F6448-C2D0-4B01-AC25-16214C5A6006}.Release|x86.Build.0 = Release|Any CPU
{03C5A84A-982B-4F38-AC73-AB832C645C4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{03C5A84A-982B-4F38-AC73-AB832C645C4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {03C5A84A-982B-4F38-AC73-AB832C645C4A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {03C5A84A-982B-4F38-AC73-AB832C645C4A}.Debug|x64.Build.0 = Debug|Any CPU
+ {03C5A84A-982B-4F38-AC73-AB832C645C4A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {03C5A84A-982B-4F38-AC73-AB832C645C4A}.Debug|x86.Build.0 = Debug|Any CPU
{03C5A84A-982B-4F38-AC73-AB832C645C4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{03C5A84A-982B-4F38-AC73-AB832C645C4A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {03C5A84A-982B-4F38-AC73-AB832C645C4A}.Release|x64.ActiveCfg = Release|Any CPU
+ {03C5A84A-982B-4F38-AC73-AB832C645C4A}.Release|x64.Build.0 = Release|Any CPU
+ {03C5A84A-982B-4F38-AC73-AB832C645C4A}.Release|x86.ActiveCfg = Release|Any CPU
+ {03C5A84A-982B-4F38-AC73-AB832C645C4A}.Release|x86.Build.0 = Release|Any CPU
{0A3C9AFD-F6E6-4A5D-83FB-93BF66732696}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0A3C9AFD-F6E6-4A5D-83FB-93BF66732696}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0A3C9AFD-F6E6-4A5D-83FB-93BF66732696}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0A3C9AFD-F6E6-4A5D-83FB-93BF66732696}.Debug|x64.Build.0 = Debug|Any CPU
+ {0A3C9AFD-F6E6-4A5D-83FB-93BF66732696}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0A3C9AFD-F6E6-4A5D-83FB-93BF66732696}.Debug|x86.Build.0 = Debug|Any CPU
{0A3C9AFD-F6E6-4A5D-83FB-93BF66732696}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0A3C9AFD-F6E6-4A5D-83FB-93BF66732696}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0A3C9AFD-F6E6-4A5D-83FB-93BF66732696}.Release|x64.ActiveCfg = Release|Any CPU
+ {0A3C9AFD-F6E6-4A5D-83FB-93BF66732696}.Release|x64.Build.0 = Release|Any CPU
+ {0A3C9AFD-F6E6-4A5D-83FB-93BF66732696}.Release|x86.ActiveCfg = Release|Any CPU
+ {0A3C9AFD-F6E6-4A5D-83FB-93BF66732696}.Release|x86.Build.0 = Release|Any CPU
{08A18C0B-8985-49EE-AC80-EFEEDF18BCC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08A18C0B-8985-49EE-AC80-EFEEDF18BCC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {08A18C0B-8985-49EE-AC80-EFEEDF18BCC5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {08A18C0B-8985-49EE-AC80-EFEEDF18BCC5}.Debug|x64.Build.0 = Debug|Any CPU
+ {08A18C0B-8985-49EE-AC80-EFEEDF18BCC5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {08A18C0B-8985-49EE-AC80-EFEEDF18BCC5}.Debug|x86.Build.0 = Debug|Any CPU
{08A18C0B-8985-49EE-AC80-EFEEDF18BCC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08A18C0B-8985-49EE-AC80-EFEEDF18BCC5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {08A18C0B-8985-49EE-AC80-EFEEDF18BCC5}.Release|x64.ActiveCfg = Release|Any CPU
+ {08A18C0B-8985-49EE-AC80-EFEEDF18BCC5}.Release|x64.Build.0 = Release|Any CPU
+ {08A18C0B-8985-49EE-AC80-EFEEDF18BCC5}.Release|x86.ActiveCfg = Release|Any CPU
+ {08A18C0B-8985-49EE-AC80-EFEEDF18BCC5}.Release|x86.Build.0 = Release|Any CPU
{9C16B0D8-8B4D-479B-9861-2645BFB0A169}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C16B0D8-8B4D-479B-9861-2645BFB0A169}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9C16B0D8-8B4D-479B-9861-2645BFB0A169}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9C16B0D8-8B4D-479B-9861-2645BFB0A169}.Debug|x64.Build.0 = Debug|Any CPU
+ {9C16B0D8-8B4D-479B-9861-2645BFB0A169}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9C16B0D8-8B4D-479B-9861-2645BFB0A169}.Debug|x86.Build.0 = Debug|Any CPU
{9C16B0D8-8B4D-479B-9861-2645BFB0A169}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C16B0D8-8B4D-479B-9861-2645BFB0A169}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9C16B0D8-8B4D-479B-9861-2645BFB0A169}.Release|x64.ActiveCfg = Release|Any CPU
+ {9C16B0D8-8B4D-479B-9861-2645BFB0A169}.Release|x64.Build.0 = Release|Any CPU
+ {9C16B0D8-8B4D-479B-9861-2645BFB0A169}.Release|x86.ActiveCfg = Release|Any CPU
+ {9C16B0D8-8B4D-479B-9861-2645BFB0A169}.Release|x86.Build.0 = Release|Any CPU
{F08F3E99-5294-4CE7-B492-38FE588D8428}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F08F3E99-5294-4CE7-B492-38FE588D8428}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F08F3E99-5294-4CE7-B492-38FE588D8428}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F08F3E99-5294-4CE7-B492-38FE588D8428}.Debug|x64.Build.0 = Debug|Any CPU
+ {F08F3E99-5294-4CE7-B492-38FE588D8428}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F08F3E99-5294-4CE7-B492-38FE588D8428}.Debug|x86.Build.0 = Debug|Any CPU
{F08F3E99-5294-4CE7-B492-38FE588D8428}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F08F3E99-5294-4CE7-B492-38FE588D8428}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F08F3E99-5294-4CE7-B492-38FE588D8428}.Release|x64.ActiveCfg = Release|Any CPU
+ {F08F3E99-5294-4CE7-B492-38FE588D8428}.Release|x64.Build.0 = Release|Any CPU
+ {F08F3E99-5294-4CE7-B492-38FE588D8428}.Release|x86.ActiveCfg = Release|Any CPU
+ {F08F3E99-5294-4CE7-B492-38FE588D8428}.Release|x86.Build.0 = Release|Any CPU
{628C09B7-BE6B-4AD4-AF41-C8863C809B31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{628C09B7-BE6B-4AD4-AF41-C8863C809B31}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {628C09B7-BE6B-4AD4-AF41-C8863C809B31}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {628C09B7-BE6B-4AD4-AF41-C8863C809B31}.Debug|x64.Build.0 = Debug|Any CPU
+ {628C09B7-BE6B-4AD4-AF41-C8863C809B31}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {628C09B7-BE6B-4AD4-AF41-C8863C809B31}.Debug|x86.Build.0 = Debug|Any CPU
{628C09B7-BE6B-4AD4-AF41-C8863C809B31}.Release|Any CPU.ActiveCfg = Release|Any CPU
{628C09B7-BE6B-4AD4-AF41-C8863C809B31}.Release|Any CPU.Build.0 = Release|Any CPU
+ {628C09B7-BE6B-4AD4-AF41-C8863C809B31}.Release|x64.ActiveCfg = Release|Any CPU
+ {628C09B7-BE6B-4AD4-AF41-C8863C809B31}.Release|x64.Build.0 = Release|Any CPU
+ {628C09B7-BE6B-4AD4-AF41-C8863C809B31}.Release|x86.ActiveCfg = Release|Any CPU
+ {628C09B7-BE6B-4AD4-AF41-C8863C809B31}.Release|x86.Build.0 = Release|Any CPU
{92F4E400-8C28-41B9-9D7D-8E9A4535636B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{92F4E400-8C28-41B9-9D7D-8E9A4535636B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {92F4E400-8C28-41B9-9D7D-8E9A4535636B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {92F4E400-8C28-41B9-9D7D-8E9A4535636B}.Debug|x64.Build.0 = Debug|Any CPU
+ {92F4E400-8C28-41B9-9D7D-8E9A4535636B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {92F4E400-8C28-41B9-9D7D-8E9A4535636B}.Debug|x86.Build.0 = Debug|Any CPU
{92F4E400-8C28-41B9-9D7D-8E9A4535636B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{92F4E400-8C28-41B9-9D7D-8E9A4535636B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {92F4E400-8C28-41B9-9D7D-8E9A4535636B}.Release|x64.ActiveCfg = Release|Any CPU
+ {92F4E400-8C28-41B9-9D7D-8E9A4535636B}.Release|x64.Build.0 = Release|Any CPU
+ {92F4E400-8C28-41B9-9D7D-8E9A4535636B}.Release|x86.ActiveCfg = Release|Any CPU
+ {92F4E400-8C28-41B9-9D7D-8E9A4535636B}.Release|x86.Build.0 = Release|Any CPU
{AB7ADCF8-48AC-4885-9C70-16D752B97168}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AB7ADCF8-48AC-4885-9C70-16D752B97168}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AB7ADCF8-48AC-4885-9C70-16D752B97168}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AB7ADCF8-48AC-4885-9C70-16D752B97168}.Debug|x64.Build.0 = Debug|Any CPU
+ {AB7ADCF8-48AC-4885-9C70-16D752B97168}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AB7ADCF8-48AC-4885-9C70-16D752B97168}.Debug|x86.Build.0 = Debug|Any CPU
{AB7ADCF8-48AC-4885-9C70-16D752B97168}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB7ADCF8-48AC-4885-9C70-16D752B97168}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AB7ADCF8-48AC-4885-9C70-16D752B97168}.Release|x64.ActiveCfg = Release|Any CPU
+ {AB7ADCF8-48AC-4885-9C70-16D752B97168}.Release|x64.Build.0 = Release|Any CPU
+ {AB7ADCF8-48AC-4885-9C70-16D752B97168}.Release|x86.ActiveCfg = Release|Any CPU
+ {AB7ADCF8-48AC-4885-9C70-16D752B97168}.Release|x86.Build.0 = Release|Any CPU
{8868D816-C072-4B66-84D6-7E014EA16D48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8868D816-C072-4B66-84D6-7E014EA16D48}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8868D816-C072-4B66-84D6-7E014EA16D48}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8868D816-C072-4B66-84D6-7E014EA16D48}.Debug|x64.Build.0 = Debug|Any CPU
+ {8868D816-C072-4B66-84D6-7E014EA16D48}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8868D816-C072-4B66-84D6-7E014EA16D48}.Debug|x86.Build.0 = Debug|Any CPU
{8868D816-C072-4B66-84D6-7E014EA16D48}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8868D816-C072-4B66-84D6-7E014EA16D48}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8868D816-C072-4B66-84D6-7E014EA16D48}.Release|x64.ActiveCfg = Release|Any CPU
+ {8868D816-C072-4B66-84D6-7E014EA16D48}.Release|x64.Build.0 = Release|Any CPU
+ {8868D816-C072-4B66-84D6-7E014EA16D48}.Release|x86.ActiveCfg = Release|Any CPU
+ {8868D816-C072-4B66-84D6-7E014EA16D48}.Release|x86.Build.0 = Release|Any CPU
{AE43BEC0-4BB7-42E1-B2B7-60A36092C61A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AE43BEC0-4BB7-42E1-B2B7-60A36092C61A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AE43BEC0-4BB7-42E1-B2B7-60A36092C61A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AE43BEC0-4BB7-42E1-B2B7-60A36092C61A}.Debug|x64.Build.0 = Debug|Any CPU
+ {AE43BEC0-4BB7-42E1-B2B7-60A36092C61A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AE43BEC0-4BB7-42E1-B2B7-60A36092C61A}.Debug|x86.Build.0 = Debug|Any CPU
{AE43BEC0-4BB7-42E1-B2B7-60A36092C61A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE43BEC0-4BB7-42E1-B2B7-60A36092C61A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AE43BEC0-4BB7-42E1-B2B7-60A36092C61A}.Release|x64.ActiveCfg = Release|Any CPU
+ {AE43BEC0-4BB7-42E1-B2B7-60A36092C61A}.Release|x64.Build.0 = Release|Any CPU
+ {AE43BEC0-4BB7-42E1-B2B7-60A36092C61A}.Release|x86.ActiveCfg = Release|Any CPU
+ {AE43BEC0-4BB7-42E1-B2B7-60A36092C61A}.Release|x86.Build.0 = Release|Any CPU
{A9103B98-D888-4260-8A05-FA36F640698A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A9103B98-D888-4260-8A05-FA36F640698A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A9103B98-D888-4260-8A05-FA36F640698A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A9103B98-D888-4260-8A05-FA36F640698A}.Debug|x64.Build.0 = Debug|Any CPU
+ {A9103B98-D888-4260-8A05-FA36F640698A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A9103B98-D888-4260-8A05-FA36F640698A}.Debug|x86.Build.0 = Debug|Any CPU
{A9103B98-D888-4260-8A05-FA36F640698A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A9103B98-D888-4260-8A05-FA36F640698A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A9103B98-D888-4260-8A05-FA36F640698A}.Release|x64.ActiveCfg = Release|Any CPU
+ {A9103B98-D888-4260-8A05-FA36F640698A}.Release|x64.Build.0 = Release|Any CPU
+ {A9103B98-D888-4260-8A05-FA36F640698A}.Release|x86.ActiveCfg = Release|Any CPU
+ {A9103B98-D888-4260-8A05-FA36F640698A}.Release|x86.Build.0 = Release|Any CPU
{C37EC61D-6A88-4C15-B371-A61F23EF9072}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C37EC61D-6A88-4C15-B371-A61F23EF9072}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C37EC61D-6A88-4C15-B371-A61F23EF9072}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C37EC61D-6A88-4C15-B371-A61F23EF9072}.Debug|x64.Build.0 = Debug|Any CPU
+ {C37EC61D-6A88-4C15-B371-A61F23EF9072}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C37EC61D-6A88-4C15-B371-A61F23EF9072}.Debug|x86.Build.0 = Debug|Any CPU
{C37EC61D-6A88-4C15-B371-A61F23EF9072}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C37EC61D-6A88-4C15-B371-A61F23EF9072}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C37EC61D-6A88-4C15-B371-A61F23EF9072}.Release|x64.ActiveCfg = Release|Any CPU
+ {C37EC61D-6A88-4C15-B371-A61F23EF9072}.Release|x64.Build.0 = Release|Any CPU
+ {C37EC61D-6A88-4C15-B371-A61F23EF9072}.Release|x86.ActiveCfg = Release|Any CPU
+ {C37EC61D-6A88-4C15-B371-A61F23EF9072}.Release|x86.Build.0 = Release|Any CPU
{08238DE9-701B-4581-A414-51F94C99E44D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08238DE9-701B-4581-A414-51F94C99E44D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {08238DE9-701B-4581-A414-51F94C99E44D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {08238DE9-701B-4581-A414-51F94C99E44D}.Debug|x64.Build.0 = Debug|Any CPU
+ {08238DE9-701B-4581-A414-51F94C99E44D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {08238DE9-701B-4581-A414-51F94C99E44D}.Debug|x86.Build.0 = Debug|Any CPU
{08238DE9-701B-4581-A414-51F94C99E44D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08238DE9-701B-4581-A414-51F94C99E44D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {08238DE9-701B-4581-A414-51F94C99E44D}.Release|x64.ActiveCfg = Release|Any CPU
+ {08238DE9-701B-4581-A414-51F94C99E44D}.Release|x64.Build.0 = Release|Any CPU
+ {08238DE9-701B-4581-A414-51F94C99E44D}.Release|x86.ActiveCfg = Release|Any CPU
+ {08238DE9-701B-4581-A414-51F94C99E44D}.Release|x86.Build.0 = Release|Any CPU
{9C08C7BD-EC01-42FA-AF1B-4177686DFC64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C08C7BD-EC01-42FA-AF1B-4177686DFC64}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9C08C7BD-EC01-42FA-AF1B-4177686DFC64}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9C08C7BD-EC01-42FA-AF1B-4177686DFC64}.Debug|x64.Build.0 = Debug|Any CPU
+ {9C08C7BD-EC01-42FA-AF1B-4177686DFC64}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9C08C7BD-EC01-42FA-AF1B-4177686DFC64}.Debug|x86.Build.0 = Debug|Any CPU
{9C08C7BD-EC01-42FA-AF1B-4177686DFC64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C08C7BD-EC01-42FA-AF1B-4177686DFC64}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9C08C7BD-EC01-42FA-AF1B-4177686DFC64}.Release|x64.ActiveCfg = Release|Any CPU
+ {9C08C7BD-EC01-42FA-AF1B-4177686DFC64}.Release|x64.Build.0 = Release|Any CPU
+ {9C08C7BD-EC01-42FA-AF1B-4177686DFC64}.Release|x86.ActiveCfg = Release|Any CPU
+ {9C08C7BD-EC01-42FA-AF1B-4177686DFC64}.Release|x86.Build.0 = Release|Any CPU
{5D81D6AA-E198-4537-AE1C-549367DAF187}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D81D6AA-E198-4537-AE1C-549367DAF187}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5D81D6AA-E198-4537-AE1C-549367DAF187}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5D81D6AA-E198-4537-AE1C-549367DAF187}.Debug|x64.Build.0 = Debug|Any CPU
+ {5D81D6AA-E198-4537-AE1C-549367DAF187}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5D81D6AA-E198-4537-AE1C-549367DAF187}.Debug|x86.Build.0 = Debug|Any CPU
{5D81D6AA-E198-4537-AE1C-549367DAF187}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D81D6AA-E198-4537-AE1C-549367DAF187}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5D81D6AA-E198-4537-AE1C-549367DAF187}.Release|x64.ActiveCfg = Release|Any CPU
+ {5D81D6AA-E198-4537-AE1C-549367DAF187}.Release|x64.Build.0 = Release|Any CPU
+ {5D81D6AA-E198-4537-AE1C-549367DAF187}.Release|x86.ActiveCfg = Release|Any CPU
+ {5D81D6AA-E198-4537-AE1C-549367DAF187}.Release|x86.Build.0 = Release|Any CPU
{E2BC296E-2660-4692-B471-F6FCD4C19F6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E2BC296E-2660-4692-B471-F6FCD4C19F6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E2BC296E-2660-4692-B471-F6FCD4C19F6E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E2BC296E-2660-4692-B471-F6FCD4C19F6E}.Debug|x64.Build.0 = Debug|Any CPU
+ {E2BC296E-2660-4692-B471-F6FCD4C19F6E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E2BC296E-2660-4692-B471-F6FCD4C19F6E}.Debug|x86.Build.0 = Debug|Any CPU
{E2BC296E-2660-4692-B471-F6FCD4C19F6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2BC296E-2660-4692-B471-F6FCD4C19F6E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E2BC296E-2660-4692-B471-F6FCD4C19F6E}.Release|x64.ActiveCfg = Release|Any CPU
+ {E2BC296E-2660-4692-B471-F6FCD4C19F6E}.Release|x64.Build.0 = Release|Any CPU
+ {E2BC296E-2660-4692-B471-F6FCD4C19F6E}.Release|x86.ActiveCfg = Release|Any CPU
+ {E2BC296E-2660-4692-B471-F6FCD4C19F6E}.Release|x86.Build.0 = Release|Any CPU
{5F74AD67-A4AD-4660-A63C-844DAAF354C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5F74AD67-A4AD-4660-A63C-844DAAF354C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5F74AD67-A4AD-4660-A63C-844DAAF354C4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5F74AD67-A4AD-4660-A63C-844DAAF354C4}.Debug|x64.Build.0 = Debug|Any CPU
+ {5F74AD67-A4AD-4660-A63C-844DAAF354C4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5F74AD67-A4AD-4660-A63C-844DAAF354C4}.Debug|x86.Build.0 = Debug|Any CPU
{5F74AD67-A4AD-4660-A63C-844DAAF354C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5F74AD67-A4AD-4660-A63C-844DAAF354C4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5F74AD67-A4AD-4660-A63C-844DAAF354C4}.Release|x64.ActiveCfg = Release|Any CPU
+ {5F74AD67-A4AD-4660-A63C-844DAAF354C4}.Release|x64.Build.0 = Release|Any CPU
+ {5F74AD67-A4AD-4660-A63C-844DAAF354C4}.Release|x86.ActiveCfg = Release|Any CPU
+ {5F74AD67-A4AD-4660-A63C-844DAAF354C4}.Release|x86.Build.0 = Release|Any CPU
{C419AE2D-D318-49EB-8ECA-6A5DC13FE4EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C419AE2D-D318-49EB-8ECA-6A5DC13FE4EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C419AE2D-D318-49EB-8ECA-6A5DC13FE4EA}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C419AE2D-D318-49EB-8ECA-6A5DC13FE4EA}.Debug|x64.Build.0 = Debug|Any CPU
+ {C419AE2D-D318-49EB-8ECA-6A5DC13FE4EA}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C419AE2D-D318-49EB-8ECA-6A5DC13FE4EA}.Debug|x86.Build.0 = Debug|Any CPU
{C419AE2D-D318-49EB-8ECA-6A5DC13FE4EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C419AE2D-D318-49EB-8ECA-6A5DC13FE4EA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C419AE2D-D318-49EB-8ECA-6A5DC13FE4EA}.Release|x64.ActiveCfg = Release|Any CPU
+ {C419AE2D-D318-49EB-8ECA-6A5DC13FE4EA}.Release|x64.Build.0 = Release|Any CPU
+ {C419AE2D-D318-49EB-8ECA-6A5DC13FE4EA}.Release|x86.ActiveCfg = Release|Any CPU
+ {C419AE2D-D318-49EB-8ECA-6A5DC13FE4EA}.Release|x86.Build.0 = Release|Any CPU
{B8A61A5C-A9A4-45C5-97E3-CB368358682F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B8A61A5C-A9A4-45C5-97E3-CB368358682F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B8A61A5C-A9A4-45C5-97E3-CB368358682F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B8A61A5C-A9A4-45C5-97E3-CB368358682F}.Debug|x64.Build.0 = Debug|Any CPU
+ {B8A61A5C-A9A4-45C5-97E3-CB368358682F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B8A61A5C-A9A4-45C5-97E3-CB368358682F}.Debug|x86.Build.0 = Debug|Any CPU
{B8A61A5C-A9A4-45C5-97E3-CB368358682F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B8A61A5C-A9A4-45C5-97E3-CB368358682F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B8A61A5C-A9A4-45C5-97E3-CB368358682F}.Release|x64.ActiveCfg = Release|Any CPU
+ {B8A61A5C-A9A4-45C5-97E3-CB368358682F}.Release|x64.Build.0 = Release|Any CPU
+ {B8A61A5C-A9A4-45C5-97E3-CB368358682F}.Release|x86.ActiveCfg = Release|Any CPU
+ {B8A61A5C-A9A4-45C5-97E3-CB368358682F}.Release|x86.Build.0 = Release|Any CPU
{3D42A6BA-38DB-4AA5-9F86-8A78D00D9A07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3D42A6BA-38DB-4AA5-9F86-8A78D00D9A07}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3D42A6BA-38DB-4AA5-9F86-8A78D00D9A07}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3D42A6BA-38DB-4AA5-9F86-8A78D00D9A07}.Debug|x64.Build.0 = Debug|Any CPU
+ {3D42A6BA-38DB-4AA5-9F86-8A78D00D9A07}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3D42A6BA-38DB-4AA5-9F86-8A78D00D9A07}.Debug|x86.Build.0 = Debug|Any CPU
{3D42A6BA-38DB-4AA5-9F86-8A78D00D9A07}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D42A6BA-38DB-4AA5-9F86-8A78D00D9A07}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3D42A6BA-38DB-4AA5-9F86-8A78D00D9A07}.Release|x64.ActiveCfg = Release|Any CPU
+ {3D42A6BA-38DB-4AA5-9F86-8A78D00D9A07}.Release|x64.Build.0 = Release|Any CPU
+ {3D42A6BA-38DB-4AA5-9F86-8A78D00D9A07}.Release|x86.ActiveCfg = Release|Any CPU
+ {3D42A6BA-38DB-4AA5-9F86-8A78D00D9A07}.Release|x86.Build.0 = Release|Any CPU
{B8550E71-0CBE-4F88-AC79-2003EFED1DE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B8550E71-0CBE-4F88-AC79-2003EFED1DE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B8550E71-0CBE-4F88-AC79-2003EFED1DE1}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B8550E71-0CBE-4F88-AC79-2003EFED1DE1}.Debug|x64.Build.0 = Debug|Any CPU
+ {B8550E71-0CBE-4F88-AC79-2003EFED1DE1}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B8550E71-0CBE-4F88-AC79-2003EFED1DE1}.Debug|x86.Build.0 = Debug|Any CPU
{B8550E71-0CBE-4F88-AC79-2003EFED1DE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B8550E71-0CBE-4F88-AC79-2003EFED1DE1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B8550E71-0CBE-4F88-AC79-2003EFED1DE1}.Release|x64.ActiveCfg = Release|Any CPU
+ {B8550E71-0CBE-4F88-AC79-2003EFED1DE1}.Release|x64.Build.0 = Release|Any CPU
+ {B8550E71-0CBE-4F88-AC79-2003EFED1DE1}.Release|x86.ActiveCfg = Release|Any CPU
+ {B8550E71-0CBE-4F88-AC79-2003EFED1DE1}.Release|x86.Build.0 = Release|Any CPU
{754C18B9-AEDB-4455-BAF4-844C6CEEF8F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{754C18B9-AEDB-4455-BAF4-844C6CEEF8F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {754C18B9-AEDB-4455-BAF4-844C6CEEF8F7}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {754C18B9-AEDB-4455-BAF4-844C6CEEF8F7}.Debug|x64.Build.0 = Debug|Any CPU
+ {754C18B9-AEDB-4455-BAF4-844C6CEEF8F7}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {754C18B9-AEDB-4455-BAF4-844C6CEEF8F7}.Debug|x86.Build.0 = Debug|Any CPU
{754C18B9-AEDB-4455-BAF4-844C6CEEF8F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{754C18B9-AEDB-4455-BAF4-844C6CEEF8F7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {754C18B9-AEDB-4455-BAF4-844C6CEEF8F7}.Release|x64.ActiveCfg = Release|Any CPU
+ {754C18B9-AEDB-4455-BAF4-844C6CEEF8F7}.Release|x64.Build.0 = Release|Any CPU
+ {754C18B9-AEDB-4455-BAF4-844C6CEEF8F7}.Release|x86.ActiveCfg = Release|Any CPU
+ {754C18B9-AEDB-4455-BAF4-844C6CEEF8F7}.Release|x86.Build.0 = Release|Any CPU
{ECCDB04A-A365-4656-989D-4E258D286AE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ECCDB04A-A365-4656-989D-4E258D286AE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ECCDB04A-A365-4656-989D-4E258D286AE4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {ECCDB04A-A365-4656-989D-4E258D286AE4}.Debug|x64.Build.0 = Debug|Any CPU
+ {ECCDB04A-A365-4656-989D-4E258D286AE4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {ECCDB04A-A365-4656-989D-4E258D286AE4}.Debug|x86.Build.0 = Debug|Any CPU
{ECCDB04A-A365-4656-989D-4E258D286AE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ECCDB04A-A365-4656-989D-4E258D286AE4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {ECCDB04A-A365-4656-989D-4E258D286AE4}.Release|x64.ActiveCfg = Release|Any CPU
+ {ECCDB04A-A365-4656-989D-4E258D286AE4}.Release|x64.Build.0 = Release|Any CPU
+ {ECCDB04A-A365-4656-989D-4E258D286AE4}.Release|x86.ActiveCfg = Release|Any CPU
+ {ECCDB04A-A365-4656-989D-4E258D286AE4}.Release|x86.Build.0 = Release|Any CPU
{9E8C7C3B-B8B3-490C-BA11-E1F60ED4E21D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E8C7C3B-B8B3-490C-BA11-E1F60ED4E21D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9E8C7C3B-B8B3-490C-BA11-E1F60ED4E21D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9E8C7C3B-B8B3-490C-BA11-E1F60ED4E21D}.Debug|x64.Build.0 = Debug|Any CPU
+ {9E8C7C3B-B8B3-490C-BA11-E1F60ED4E21D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9E8C7C3B-B8B3-490C-BA11-E1F60ED4E21D}.Debug|x86.Build.0 = Debug|Any CPU
{9E8C7C3B-B8B3-490C-BA11-E1F60ED4E21D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E8C7C3B-B8B3-490C-BA11-E1F60ED4E21D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9E8C7C3B-B8B3-490C-BA11-E1F60ED4E21D}.Release|x64.ActiveCfg = Release|Any CPU
+ {9E8C7C3B-B8B3-490C-BA11-E1F60ED4E21D}.Release|x64.Build.0 = Release|Any CPU
+ {9E8C7C3B-B8B3-490C-BA11-E1F60ED4E21D}.Release|x86.ActiveCfg = Release|Any CPU
+ {9E8C7C3B-B8B3-490C-BA11-E1F60ED4E21D}.Release|x86.Build.0 = Release|Any CPU
{DEA8FE40-0AE9-4CE6-9430-089C985217CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DEA8FE40-0AE9-4CE6-9430-089C985217CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DEA8FE40-0AE9-4CE6-9430-089C985217CA}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {DEA8FE40-0AE9-4CE6-9430-089C985217CA}.Debug|x64.Build.0 = Debug|Any CPU
+ {DEA8FE40-0AE9-4CE6-9430-089C985217CA}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {DEA8FE40-0AE9-4CE6-9430-089C985217CA}.Debug|x86.Build.0 = Debug|Any CPU
{DEA8FE40-0AE9-4CE6-9430-089C985217CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DEA8FE40-0AE9-4CE6-9430-089C985217CA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DEA8FE40-0AE9-4CE6-9430-089C985217CA}.Release|x64.ActiveCfg = Release|Any CPU
+ {DEA8FE40-0AE9-4CE6-9430-089C985217CA}.Release|x64.Build.0 = Release|Any CPU
+ {DEA8FE40-0AE9-4CE6-9430-089C985217CA}.Release|x86.ActiveCfg = Release|Any CPU
+ {DEA8FE40-0AE9-4CE6-9430-089C985217CA}.Release|x86.Build.0 = Release|Any CPU
{F04DB812-7278-47F2-913E-225CE2EF150C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F04DB812-7278-47F2-913E-225CE2EF150C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F04DB812-7278-47F2-913E-225CE2EF150C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F04DB812-7278-47F2-913E-225CE2EF150C}.Debug|x64.Build.0 = Debug|Any CPU
+ {F04DB812-7278-47F2-913E-225CE2EF150C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F04DB812-7278-47F2-913E-225CE2EF150C}.Debug|x86.Build.0 = Debug|Any CPU
{F04DB812-7278-47F2-913E-225CE2EF150C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F04DB812-7278-47F2-913E-225CE2EF150C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F04DB812-7278-47F2-913E-225CE2EF150C}.Release|x64.ActiveCfg = Release|Any CPU
+ {F04DB812-7278-47F2-913E-225CE2EF150C}.Release|x64.Build.0 = Release|Any CPU
+ {F04DB812-7278-47F2-913E-225CE2EF150C}.Release|x86.ActiveCfg = Release|Any CPU
+ {F04DB812-7278-47F2-913E-225CE2EF150C}.Release|x86.Build.0 = Release|Any CPU
{7DCA2BEC-B1E1-4F2B-952A-A26B5110FDA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7DCA2BEC-B1E1-4F2B-952A-A26B5110FDA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7DCA2BEC-B1E1-4F2B-952A-A26B5110FDA5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7DCA2BEC-B1E1-4F2B-952A-A26B5110FDA5}.Debug|x64.Build.0 = Debug|Any CPU
+ {7DCA2BEC-B1E1-4F2B-952A-A26B5110FDA5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7DCA2BEC-B1E1-4F2B-952A-A26B5110FDA5}.Debug|x86.Build.0 = Debug|Any CPU
{7DCA2BEC-B1E1-4F2B-952A-A26B5110FDA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7DCA2BEC-B1E1-4F2B-952A-A26B5110FDA5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7DCA2BEC-B1E1-4F2B-952A-A26B5110FDA5}.Release|x64.ActiveCfg = Release|Any CPU
+ {7DCA2BEC-B1E1-4F2B-952A-A26B5110FDA5}.Release|x64.Build.0 = Release|Any CPU
+ {7DCA2BEC-B1E1-4F2B-952A-A26B5110FDA5}.Release|x86.ActiveCfg = Release|Any CPU
+ {7DCA2BEC-B1E1-4F2B-952A-A26B5110FDA5}.Release|x86.Build.0 = Release|Any CPU
{E54506B8-0B81-4FC4-99B5-5C67E19D4B09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E54506B8-0B81-4FC4-99B5-5C67E19D4B09}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E54506B8-0B81-4FC4-99B5-5C67E19D4B09}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E54506B8-0B81-4FC4-99B5-5C67E19D4B09}.Debug|x64.Build.0 = Debug|Any CPU
+ {E54506B8-0B81-4FC4-99B5-5C67E19D4B09}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E54506B8-0B81-4FC4-99B5-5C67E19D4B09}.Debug|x86.Build.0 = Debug|Any CPU
{E54506B8-0B81-4FC4-99B5-5C67E19D4B09}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E54506B8-0B81-4FC4-99B5-5C67E19D4B09}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E54506B8-0B81-4FC4-99B5-5C67E19D4B09}.Release|x64.ActiveCfg = Release|Any CPU
+ {E54506B8-0B81-4FC4-99B5-5C67E19D4B09}.Release|x64.Build.0 = Release|Any CPU
+ {E54506B8-0B81-4FC4-99B5-5C67E19D4B09}.Release|x86.ActiveCfg = Release|Any CPU
+ {E54506B8-0B81-4FC4-99B5-5C67E19D4B09}.Release|x86.Build.0 = Release|Any CPU
{FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Debug|x64.Build.0 = Debug|Any CPU
+ {FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Debug|x86.Build.0 = Debug|Any CPU
{FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Release|x64.ActiveCfg = Release|Any CPU
+ {FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Release|x64.Build.0 = Release|Any CPU
+ {FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Release|x86.ActiveCfg = Release|Any CPU
+ {FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Release|x86.Build.0 = Release|Any CPU
{36975025-857B-45F0-AB39-904B521A6713}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{36975025-857B-45F0-AB39-904B521A6713}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {36975025-857B-45F0-AB39-904B521A6713}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {36975025-857B-45F0-AB39-904B521A6713}.Debug|x64.Build.0 = Debug|Any CPU
+ {36975025-857B-45F0-AB39-904B521A6713}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {36975025-857B-45F0-AB39-904B521A6713}.Debug|x86.Build.0 = Debug|Any CPU
{36975025-857B-45F0-AB39-904B521A6713}.Release|Any CPU.ActiveCfg = Release|Any CPU
{36975025-857B-45F0-AB39-904B521A6713}.Release|Any CPU.Build.0 = Release|Any CPU
+ {36975025-857B-45F0-AB39-904B521A6713}.Release|x64.ActiveCfg = Release|Any CPU
+ {36975025-857B-45F0-AB39-904B521A6713}.Release|x64.Build.0 = Release|Any CPU
+ {36975025-857B-45F0-AB39-904B521A6713}.Release|x86.ActiveCfg = Release|Any CPU
+ {36975025-857B-45F0-AB39-904B521A6713}.Release|x86.Build.0 = Release|Any CPU
{7382A1CB-AA9A-4136-A548-17D7A67C6B0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7382A1CB-AA9A-4136-A548-17D7A67C6B0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7382A1CB-AA9A-4136-A548-17D7A67C6B0C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7382A1CB-AA9A-4136-A548-17D7A67C6B0C}.Debug|x64.Build.0 = Debug|Any CPU
+ {7382A1CB-AA9A-4136-A548-17D7A67C6B0C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7382A1CB-AA9A-4136-A548-17D7A67C6B0C}.Debug|x86.Build.0 = Debug|Any CPU
{7382A1CB-AA9A-4136-A548-17D7A67C6B0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7382A1CB-AA9A-4136-A548-17D7A67C6B0C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7382A1CB-AA9A-4136-A548-17D7A67C6B0C}.Release|x64.ActiveCfg = Release|Any CPU
+ {7382A1CB-AA9A-4136-A548-17D7A67C6B0C}.Release|x64.Build.0 = Release|Any CPU
+ {7382A1CB-AA9A-4136-A548-17D7A67C6B0C}.Release|x86.ActiveCfg = Release|Any CPU
+ {7382A1CB-AA9A-4136-A548-17D7A67C6B0C}.Release|x86.Build.0 = Release|Any CPU
{D7495CE7-64E5-4715-9304-799A41EC1D71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7495CE7-64E5-4715-9304-799A41EC1D71}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D7495CE7-64E5-4715-9304-799A41EC1D71}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D7495CE7-64E5-4715-9304-799A41EC1D71}.Debug|x64.Build.0 = Debug|Any CPU
+ {D7495CE7-64E5-4715-9304-799A41EC1D71}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D7495CE7-64E5-4715-9304-799A41EC1D71}.Debug|x86.Build.0 = Debug|Any CPU
{D7495CE7-64E5-4715-9304-799A41EC1D71}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7495CE7-64E5-4715-9304-799A41EC1D71}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D7495CE7-64E5-4715-9304-799A41EC1D71}.Release|x64.ActiveCfg = Release|Any CPU
+ {D7495CE7-64E5-4715-9304-799A41EC1D71}.Release|x64.Build.0 = Release|Any CPU
+ {D7495CE7-64E5-4715-9304-799A41EC1D71}.Release|x86.ActiveCfg = Release|Any CPU
+ {D7495CE7-64E5-4715-9304-799A41EC1D71}.Release|x86.Build.0 = Release|Any CPU
{32DA04FF-A951-43EA-B2FA-86A825009A97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{32DA04FF-A951-43EA-B2FA-86A825009A97}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {32DA04FF-A951-43EA-B2FA-86A825009A97}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {32DA04FF-A951-43EA-B2FA-86A825009A97}.Debug|x64.Build.0 = Debug|Any CPU
+ {32DA04FF-A951-43EA-B2FA-86A825009A97}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {32DA04FF-A951-43EA-B2FA-86A825009A97}.Debug|x86.Build.0 = Debug|Any CPU
{32DA04FF-A951-43EA-B2FA-86A825009A97}.Release|Any CPU.ActiveCfg = Release|Any CPU
{32DA04FF-A951-43EA-B2FA-86A825009A97}.Release|Any CPU.Build.0 = Release|Any CPU
+ {32DA04FF-A951-43EA-B2FA-86A825009A97}.Release|x64.ActiveCfg = Release|Any CPU
+ {32DA04FF-A951-43EA-B2FA-86A825009A97}.Release|x64.Build.0 = Release|Any CPU
+ {32DA04FF-A951-43EA-B2FA-86A825009A97}.Release|x86.ActiveCfg = Release|Any CPU
+ {32DA04FF-A951-43EA-B2FA-86A825009A97}.Release|x86.Build.0 = Release|Any CPU
{FAADC193-BA41-449D-97CE-0EF82836046A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FAADC193-BA41-449D-97CE-0EF82836046A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FAADC193-BA41-449D-97CE-0EF82836046A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FAADC193-BA41-449D-97CE-0EF82836046A}.Debug|x64.Build.0 = Debug|Any CPU
+ {FAADC193-BA41-449D-97CE-0EF82836046A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FAADC193-BA41-449D-97CE-0EF82836046A}.Debug|x86.Build.0 = Debug|Any CPU
{FAADC193-BA41-449D-97CE-0EF82836046A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FAADC193-BA41-449D-97CE-0EF82836046A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FAADC193-BA41-449D-97CE-0EF82836046A}.Release|x64.ActiveCfg = Release|Any CPU
+ {FAADC193-BA41-449D-97CE-0EF82836046A}.Release|x64.Build.0 = Release|Any CPU
+ {FAADC193-BA41-449D-97CE-0EF82836046A}.Release|x86.ActiveCfg = Release|Any CPU
+ {FAADC193-BA41-449D-97CE-0EF82836046A}.Release|x86.Build.0 = Release|Any CPU
+ {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Debug|x64.Build.0 = Debug|Any CPU
+ {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Debug|x86.Build.0 = Debug|Any CPU
+ {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Release|x64.ActiveCfg = Release|Any CPU
+ {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Release|x64.Build.0 = Release|Any CPU
+ {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Release|x86.ActiveCfg = Release|Any CPU
+ {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Release|x86.Build.0 = Release|Any CPU
{0CBA5FB8-71A3-457A-89F3-E52B9602164A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CBA5FB8-71A3-457A-89F3-E52B9602164A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0CBA5FB8-71A3-457A-89F3-E52B9602164A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0CBA5FB8-71A3-457A-89F3-E52B9602164A}.Debug|x64.Build.0 = Debug|Any CPU
+ {0CBA5FB8-71A3-457A-89F3-E52B9602164A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0CBA5FB8-71A3-457A-89F3-E52B9602164A}.Debug|x86.Build.0 = Debug|Any CPU
{0CBA5FB8-71A3-457A-89F3-E52B9602164A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CBA5FB8-71A3-457A-89F3-E52B9602164A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0CBA5FB8-71A3-457A-89F3-E52B9602164A}.Release|x64.ActiveCfg = Release|Any CPU
+ {0CBA5FB8-71A3-457A-89F3-E52B9602164A}.Release|x64.Build.0 = Release|Any CPU
+ {0CBA5FB8-71A3-457A-89F3-E52B9602164A}.Release|x86.ActiveCfg = Release|Any CPU
+ {0CBA5FB8-71A3-457A-89F3-E52B9602164A}.Release|x86.Build.0 = Release|Any CPU
{21C21975-84C1-4A24-8E21-F7EC790A4584}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21C21975-84C1-4A24-8E21-F7EC790A4584}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {21C21975-84C1-4A24-8E21-F7EC790A4584}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {21C21975-84C1-4A24-8E21-F7EC790A4584}.Debug|x64.Build.0 = Debug|Any CPU
+ {21C21975-84C1-4A24-8E21-F7EC790A4584}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {21C21975-84C1-4A24-8E21-F7EC790A4584}.Debug|x86.Build.0 = Debug|Any CPU
{21C21975-84C1-4A24-8E21-F7EC790A4584}.Release|Any CPU.ActiveCfg = Release|Any CPU
{21C21975-84C1-4A24-8E21-F7EC790A4584}.Release|Any CPU.Build.0 = Release|Any CPU
+ {21C21975-84C1-4A24-8E21-F7EC790A4584}.Release|x64.ActiveCfg = Release|Any CPU
+ {21C21975-84C1-4A24-8E21-F7EC790A4584}.Release|x64.Build.0 = Release|Any CPU
+ {21C21975-84C1-4A24-8E21-F7EC790A4584}.Release|x86.ActiveCfg = Release|Any CPU
+ {21C21975-84C1-4A24-8E21-F7EC790A4584}.Release|x86.Build.0 = Release|Any CPU
{19014C60-F87C-4CC7-AC0F-C41B6126EBCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19014C60-F87C-4CC7-AC0F-C41B6126EBCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {19014C60-F87C-4CC7-AC0F-C41B6126EBCE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {19014C60-F87C-4CC7-AC0F-C41B6126EBCE}.Debug|x64.Build.0 = Debug|Any CPU
+ {19014C60-F87C-4CC7-AC0F-C41B6126EBCE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {19014C60-F87C-4CC7-AC0F-C41B6126EBCE}.Debug|x86.Build.0 = Debug|Any CPU
{19014C60-F87C-4CC7-AC0F-C41B6126EBCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19014C60-F87C-4CC7-AC0F-C41B6126EBCE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {19014C60-F87C-4CC7-AC0F-C41B6126EBCE}.Release|x64.ActiveCfg = Release|Any CPU
+ {19014C60-F87C-4CC7-AC0F-C41B6126EBCE}.Release|x64.Build.0 = Release|Any CPU
+ {19014C60-F87C-4CC7-AC0F-C41B6126EBCE}.Release|x86.ActiveCfg = Release|Any CPU
+ {19014C60-F87C-4CC7-AC0F-C41B6126EBCE}.Release|x86.Build.0 = Release|Any CPU
{FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Debug|x64.Build.0 = Debug|Any CPU
+ {FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Debug|x86.Build.0 = Debug|Any CPU
{FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Release|x64.ActiveCfg = Release|Any CPU
+ {FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Release|x64.Build.0 = Release|Any CPU
+ {FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Release|x86.ActiveCfg = Release|Any CPU
+ {FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Release|x86.Build.0 = Release|Any CPU
{1F0B4B3C-DC88-4740-B04F-1707102E9930}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1F0B4B3C-DC88-4740-B04F-1707102E9930}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1F0B4B3C-DC88-4740-B04F-1707102E9930}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1F0B4B3C-DC88-4740-B04F-1707102E9930}.Debug|x64.Build.0 = Debug|Any CPU
+ {1F0B4B3C-DC88-4740-B04F-1707102E9930}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1F0B4B3C-DC88-4740-B04F-1707102E9930}.Debug|x86.Build.0 = Debug|Any CPU
{1F0B4B3C-DC88-4740-B04F-1707102E9930}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1F0B4B3C-DC88-4740-B04F-1707102E9930}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1F0B4B3C-DC88-4740-B04F-1707102E9930}.Release|x64.ActiveCfg = Release|Any CPU
+ {1F0B4B3C-DC88-4740-B04F-1707102E9930}.Release|x64.Build.0 = Release|Any CPU
+ {1F0B4B3C-DC88-4740-B04F-1707102E9930}.Release|x86.ActiveCfg = Release|Any CPU
+ {1F0B4B3C-DC88-4740-B04F-1707102E9930}.Release|x86.Build.0 = Release|Any CPU
{D9617F63-15F4-4CA2-8ECF-728A94B45D82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D9617F63-15F4-4CA2-8ECF-728A94B45D82}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D9617F63-15F4-4CA2-8ECF-728A94B45D82}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D9617F63-15F4-4CA2-8ECF-728A94B45D82}.Debug|x64.Build.0 = Debug|Any CPU
+ {D9617F63-15F4-4CA2-8ECF-728A94B45D82}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D9617F63-15F4-4CA2-8ECF-728A94B45D82}.Debug|x86.Build.0 = Debug|Any CPU
{D9617F63-15F4-4CA2-8ECF-728A94B45D82}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D9617F63-15F4-4CA2-8ECF-728A94B45D82}.Release|Any CPU.Build.0 = Release|Any CPU
- {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8D6A9984-118D-4415-A8FA-AB1F26CF5C44}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D9617F63-15F4-4CA2-8ECF-728A94B45D82}.Release|x64.ActiveCfg = Release|Any CPU
+ {D9617F63-15F4-4CA2-8ECF-728A94B45D82}.Release|x64.Build.0 = Release|Any CPU
+ {D9617F63-15F4-4CA2-8ECF-728A94B45D82}.Release|x86.ActiveCfg = Release|Any CPU
+ {D9617F63-15F4-4CA2-8ECF-728A94B45D82}.Release|x86.Build.0 = Release|Any CPU
{2FF79F82-60C1-349A-4726-7783D5A6D5DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2FF79F82-60C1-349A-4726-7783D5A6D5DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2FF79F82-60C1-349A-4726-7783D5A6D5DF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2FF79F82-60C1-349A-4726-7783D5A6D5DF}.Debug|x64.Build.0 = Debug|Any CPU
+ {2FF79F82-60C1-349A-4726-7783D5A6D5DF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2FF79F82-60C1-349A-4726-7783D5A6D5DF}.Debug|x86.Build.0 = Debug|Any CPU
{2FF79F82-60C1-349A-4726-7783D5A6D5DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2FF79F82-60C1-349A-4726-7783D5A6D5DF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2FF79F82-60C1-349A-4726-7783D5A6D5DF}.Release|x64.ActiveCfg = Release|Any CPU
+ {2FF79F82-60C1-349A-4726-7783D5A6D5DF}.Release|x64.Build.0 = Release|Any CPU
+ {2FF79F82-60C1-349A-4726-7783D5A6D5DF}.Release|x86.ActiveCfg = Release|Any CPU
+ {2FF79F82-60C1-349A-4726-7783D5A6D5DF}.Release|x86.Build.0 = Release|Any CPU
{692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Debug|x64.Build.0 = Debug|Any CPU
+ {692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Debug|x86.Build.0 = Debug|Any CPU
{692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Release|Any CPU.ActiveCfg = Release|Any CPU
{692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Release|Any CPU.Build.0 = Release|Any CPU
+ {692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Release|x64.ActiveCfg = Release|Any CPU
+ {692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Release|x64.Build.0 = Release|Any CPU
+ {692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Release|x86.ActiveCfg = Release|Any CPU
+ {692B71D8-9C31-D1EE-6C1B-570A12B18E39}.Release|x86.Build.0 = Release|Any CPU
{3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Debug|x64.Build.0 = Debug|Any CPU
+ {3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Debug|x86.Build.0 = Debug|Any CPU
{3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Release|x64.ActiveCfg = Release|Any CPU
+ {3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Release|x64.Build.0 = Release|Any CPU
+ {3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Release|x86.ActiveCfg = Release|Any CPU
+ {3DF5A9B8-6F90-4CFB-4518-0E97982B6748}.Release|x86.Build.0 = Release|Any CPU
+ {E5A15C4C-DCAD-4A5A-93E5-A56822910D82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E5A15C4C-DCAD-4A5A-93E5-A56822910D82}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E5A15C4C-DCAD-4A5A-93E5-A56822910D82}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E5A15C4C-DCAD-4A5A-93E5-A56822910D82}.Debug|x64.Build.0 = Debug|Any CPU
+ {E5A15C4C-DCAD-4A5A-93E5-A56822910D82}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E5A15C4C-DCAD-4A5A-93E5-A56822910D82}.Debug|x86.Build.0 = Debug|Any CPU
+ {E5A15C4C-DCAD-4A5A-93E5-A56822910D82}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E5A15C4C-DCAD-4A5A-93E5-A56822910D82}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E5A15C4C-DCAD-4A5A-93E5-A56822910D82}.Release|x64.ActiveCfg = Release|Any CPU
+ {E5A15C4C-DCAD-4A5A-93E5-A56822910D82}.Release|x64.Build.0 = Release|Any CPU
+ {E5A15C4C-DCAD-4A5A-93E5-A56822910D82}.Release|x86.ActiveCfg = Release|Any CPU
+ {E5A15C4C-DCAD-4A5A-93E5-A56822910D82}.Release|x86.Build.0 = Release|Any CPU
+ {C09261DE-A222-4536-B0CC-53EB0F7A650B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C09261DE-A222-4536-B0CC-53EB0F7A650B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C09261DE-A222-4536-B0CC-53EB0F7A650B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C09261DE-A222-4536-B0CC-53EB0F7A650B}.Debug|x64.Build.0 = Debug|Any CPU
+ {C09261DE-A222-4536-B0CC-53EB0F7A650B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C09261DE-A222-4536-B0CC-53EB0F7A650B}.Debug|x86.Build.0 = Debug|Any CPU
+ {C09261DE-A222-4536-B0CC-53EB0F7A650B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C09261DE-A222-4536-B0CC-53EB0F7A650B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C09261DE-A222-4536-B0CC-53EB0F7A650B}.Release|x64.ActiveCfg = Release|Any CPU
+ {C09261DE-A222-4536-B0CC-53EB0F7A650B}.Release|x64.Build.0 = Release|Any CPU
+ {C09261DE-A222-4536-B0CC-53EB0F7A650B}.Release|x86.ActiveCfg = Release|Any CPU
+ {C09261DE-A222-4536-B0CC-53EB0F7A650B}.Release|x86.Build.0 = Release|Any CPU
+ {86007D8A-DE78-4C27-9DCC-84A64038610F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {86007D8A-DE78-4C27-9DCC-84A64038610F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {86007D8A-DE78-4C27-9DCC-84A64038610F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {86007D8A-DE78-4C27-9DCC-84A64038610F}.Debug|x64.Build.0 = Debug|Any CPU
+ {86007D8A-DE78-4C27-9DCC-84A64038610F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {86007D8A-DE78-4C27-9DCC-84A64038610F}.Debug|x86.Build.0 = Debug|Any CPU
+ {86007D8A-DE78-4C27-9DCC-84A64038610F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {86007D8A-DE78-4C27-9DCC-84A64038610F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {86007D8A-DE78-4C27-9DCC-84A64038610F}.Release|x64.ActiveCfg = Release|Any CPU
+ {86007D8A-DE78-4C27-9DCC-84A64038610F}.Release|x64.Build.0 = Release|Any CPU
+ {86007D8A-DE78-4C27-9DCC-84A64038610F}.Release|x86.ActiveCfg = Release|Any CPU
+ {86007D8A-DE78-4C27-9DCC-84A64038610F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1151,6 +2113,7 @@ Global
{3FA6F1CB-295B-4414-B18F-93845917A8CD} = {22AB674F-ED91-4FBC-BFEE-8A1E82F9F05E}
{32DA04FF-A951-43EA-B2FA-86A825009A97} = {3FA6F1CB-295B-4414-B18F-93845917A8CD}
{FAADC193-BA41-449D-97CE-0EF82836046A} = {3FA6F1CB-295B-4414-B18F-93845917A8CD}
+ {8D6A9984-118D-4415-A8FA-AB1F26CF5C44} = {3FA6F1CB-295B-4414-B18F-93845917A8CD}
{0CBA5FB8-71A3-457A-89F3-E52B9602164A} = {3FA6F1CB-295B-4414-B18F-93845917A8CD}
{21C21975-84C1-4A24-8E21-F7EC790A4584} = {580D1AE7-AA8F-4912-8B76-105594E00B3B}
{19014C60-F87C-4CC7-AC0F-C41B6126EBCE} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
@@ -1158,13 +2121,17 @@ Global
{FA579C03-2EB4-4D47-88EE-BFF339E96FAF} = {22AB674F-ED91-4FBC-BFEE-8A1E82F9F05E}
{1F0B4B3C-DC88-4740-B04F-1707102E9930} = {580D1AE7-AA8F-4912-8B76-105594E00B3B}
{D9617F63-15F4-4CA2-8ECF-728A94B45D82} = {3FA6F1CB-295B-4414-B18F-93845917A8CD}
- {8D6A9984-118D-4415-A8FA-AB1F26CF5C44} = {3FA6F1CB-295B-4414-B18F-93845917A8CD}
{418B10BD-CA42-49F3-8F4A-D8CC90C8A17D} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
{2FF79F82-60C1-349A-4726-7783D5A6D5DF} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
{692B71D8-9C31-D1EE-6C1B-570A12B18E39} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
{FA3C7F91-42A2-45AD-897C-F646B081016C} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
{3DF5A9B8-6F90-4CFB-4518-0E97982B6748} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
{0762B436-F4B0-4008-9097-BB5FF6BD84AF} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
+ {C66B5859-B05E-5DF4-58E9-78CA919DB89A} = {44E564E1-AE0D-4313-A4E9-CBF2109397E3}
+ {E5A15C4C-DCAD-4A5A-93E5-A56822910D82} = {C66B5859-B05E-5DF4-58E9-78CA919DB89A}
+ {C09261DE-A222-4536-B0CC-53EB0F7A650B} = {C66B5859-B05E-5DF4-58E9-78CA919DB89A}
+ {AFA55F45-CFCB-9821-A210-2D3496088416} = {3AD322BF-405B-4A53-9858-51CF66E8509F}
+ {86007D8A-DE78-4C27-9DCC-84A64038610F} = {AFA55F45-CFCB-9821-A210-2D3496088416}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FB8F26CE-4DE6-433F-B32A-79183020BBD6}
diff --git a/src/Compatibility/ApiDiff/Directory.Build.props b/src/Compatibility/ApiDiff/Directory.Build.props
new file mode 100644
index 000000000000..0e5e89296832
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Directory.Build.props
@@ -0,0 +1,9 @@
+
+
+
+
+
+ true
+
+
+
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff.Tool/GenAPIDiffConfigurationBinder.cs b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff.Tool/GenAPIDiffConfigurationBinder.cs
new file mode 100644
index 000000000000..34b9cddfd1e4
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff.Tool/GenAPIDiffConfigurationBinder.cs
@@ -0,0 +1,63 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.CommandLine;
+using System.CommandLine.Binding;
+
+namespace Microsoft.DotNet.ApiDiff;
+
+// Binds System.CommandLine options to a DiffConfiguration object.
+internal class GenAPIDiffConfigurationBinder : BinderBase
+{
+ private readonly Option _optionBeforeAssembliesFolderPath;
+ private readonly Option _optionBeforeAssemblyReferencesFolderPath;
+ private readonly Option _optionAfterAssembliesFolderPath;
+ private readonly Option _optionAfterAssemblyReferencesFolderPath;
+ private readonly Option _optionOutputFolderPath;
+ private readonly Option _optionTableOfContentsTitle;
+ private readonly Option _optionAttributesToExclude;
+ private readonly Option _optionApisToExclude;
+ private readonly Option _optionAddPartialModifier;
+ private readonly Option _optionHideImplicitDefaultConstructors;
+ private readonly Option _optionDebug;
+
+ internal GenAPIDiffConfigurationBinder(Option optionBeforeAssembliesFolderPath,
+ Option optionBeforeAssemblyReferencesFolderPath,
+ Option optionAfterAssembliesFolderPath,
+ Option optionAfterAssemblyReferencesFolderPath,
+ Option optionOutputFolderPath,
+ Option optionTableOfContentsTitle,
+ Option optionAttributesToExclude,
+ Option optionApisToExclude,
+ Option optionAddPartialModifier,
+ Option optionHideImplicitDefaultConstructors,
+ Option optionDebug)
+ {
+ _optionBeforeAssembliesFolderPath = optionBeforeAssembliesFolderPath;
+ _optionBeforeAssemblyReferencesFolderPath = optionBeforeAssemblyReferencesFolderPath;
+ _optionAfterAssembliesFolderPath = optionAfterAssembliesFolderPath;
+ _optionAfterAssemblyReferencesFolderPath = optionAfterAssemblyReferencesFolderPath;
+ _optionOutputFolderPath = optionOutputFolderPath;
+ _optionTableOfContentsTitle = optionTableOfContentsTitle;
+ _optionAttributesToExclude = optionAttributesToExclude;
+ _optionApisToExclude = optionApisToExclude;
+ _optionAddPartialModifier = optionAddPartialModifier;
+ _optionHideImplicitDefaultConstructors = optionHideImplicitDefaultConstructors;
+ _optionDebug = optionDebug;
+ }
+
+ protected override DiffConfiguration GetBoundValue(BindingContext bindingContext) =>
+ new DiffConfiguration(
+ BeforeAssembliesFolderPath: bindingContext.ParseResult.GetValueForOption(_optionBeforeAssembliesFolderPath) ?? throw new NullReferenceException(Resources.NullBeforeAssembliesDirectory),
+ BeforeAssemblyReferencesFolderPath: bindingContext.ParseResult.GetValueForOption(_optionBeforeAssemblyReferencesFolderPath),
+ AfterAssembliesFolderPath: bindingContext.ParseResult.GetValueForOption(_optionAfterAssembliesFolderPath) ?? throw new NullReferenceException(Resources.NullAfterAssembliesDirectory),
+ AfterAssemblyReferencesFolderPath: bindingContext.ParseResult.GetValueForOption(_optionAfterAssemblyReferencesFolderPath),
+ OutputFolderPath: bindingContext.ParseResult.GetValueForOption(_optionOutputFolderPath) ?? throw new NullReferenceException(Resources.NullOutputDirectory),
+ TableOfContentsTitle: bindingContext.ParseResult.GetValueForOption(_optionTableOfContentsTitle) ?? throw new NullReferenceException(Resources.NullTableOfContentsTitle),
+ AttributesToExclude: bindingContext.ParseResult.GetValueForOption(_optionAttributesToExclude),
+ ApisToExclude: bindingContext.ParseResult.GetValueForOption(_optionApisToExclude),
+ AddPartialModifier: bindingContext.ParseResult.GetValueForOption(_optionAddPartialModifier),
+ HideImplicitDefaultConstructors: bindingContext.ParseResult.GetValueForOption(_optionHideImplicitDefaultConstructors),
+ Debug: bindingContext.ParseResult.GetValueForOption(_optionDebug)
+ );
+}
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff.Tool/Microsoft.DotNet.ApiDiff.Tool.csproj b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff.Tool/Microsoft.DotNet.ApiDiff.Tool.csproj
new file mode 100644
index 000000000000..9dabdcc14208
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff.Tool/Microsoft.DotNet.ApiDiff.Tool.csproj
@@ -0,0 +1,23 @@
+
+
+
+ $(NetToolMinimum)
+ Exe
+ true
+ true
+ apidiff
+ Tool to emit markdown diffs between sets of assemblies.
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff.Tool/Program.cs b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff.Tool/Program.cs
new file mode 100644
index 000000000000..bd4c8517deec
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff.Tool/Program.cs
@@ -0,0 +1,175 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.CommandLine;
+using System.Diagnostics;
+using Microsoft.DotNet.ApiSymbolExtensions.Logging;
+
+namespace Microsoft.DotNet.ApiDiff.Tool;
+
+///
+/// Entrypoint for the genapidiff tool, which generates a markdown diff of two
+/// different versions of the same assembly, using the specified command line options.
+///
+public static class Program
+{
+ public static async Task Main(string[] args)
+ {
+ RootCommand rootCommand = new("genapidiff");
+
+ Option optionBeforeAssembliesFolderPath = new(["--before", "-b"])
+ {
+ Description = "The path to the folder containing the old (before) assemblies.",
+ Arity = ArgumentArity.ExactlyOne,
+ IsRequired = true
+ };
+
+ Option optionBeforeRefAssembliesFolderPath = new(["--refbefore", "-rb"])
+ {
+ Description = "The path to the folder containing the old (before) reference assemblies.",
+ Arity = ArgumentArity.ExactlyOne,
+ IsRequired = false
+ };
+
+ Option optionAfterAssembliesFolderPath = new(["--after", "-a"])
+ {
+ Description = "The path to the folder containing the new (after) assemblies.",
+ Arity = ArgumentArity.ExactlyOne,
+ IsRequired = false
+ };
+
+ Option optionAfterRefAssembliesFolderPath = new(["--refafter", "-ra"])
+ {
+ Description = "The path to the folder containing the new (after) reference assemblies.",
+ Arity = ArgumentArity.ExactlyOne,
+ IsRequired = false
+ };
+
+ Option optionOutputFolderPath = new(["--output", "-o"])
+ {
+ Description = "The path to the output folder.",
+ Arity = ArgumentArity.ExactlyOne,
+ IsRequired = true
+ };
+
+ Option optionTableOfContentsTitle = new(["--tableOfContentsTitle", "-tc"])
+ {
+ Description = "The title of the markdown file that is placed in the output folder with a table of contents.",
+ Arity = ArgumentArity.ExactlyOne,
+ IsRequired = true
+ };
+
+ Option optionAttributesToExclude = new(["--attributesToExclude", "-eattrs"], () => null)
+ {
+ Description = "Attributes to exclude from the diff.",
+ Arity = ArgumentArity.ZeroOrMore,
+ IsRequired = false
+ };
+
+ Option optionApisToExclude = new(["--apisToExclude", "-eapis"], () => null)
+ {
+ Description = "APIs to exclude from the diff.",
+ Arity = ArgumentArity.ZeroOrMore,
+ IsRequired = false
+ };
+
+ Option optionAddPartialModifier = new(["--addPartialModifier", "-apm"], () => false)
+ {
+ Description = "Add the 'partial' modifier to types."
+ };
+
+ Option optionHideImplicitDefaultConstructors = new(["--hideImplicitDefaultConstructors", "-hidc"], () => false)
+ {
+ Description = "Hide implicit default constructors from types."
+ };
+
+ Option optionDebug = new(["--attachDebugger", "-d"], () => false)
+ {
+ Description = "Stops the tool at startup, prints the process ID and waits for a debugger to attach."
+ };
+
+ // Custom ordering for the help menu.
+ rootCommand.Add(optionBeforeAssembliesFolderPath);
+ rootCommand.Add(optionBeforeRefAssembliesFolderPath);
+ rootCommand.Add(optionAfterAssembliesFolderPath);
+ rootCommand.Add(optionAfterRefAssembliesFolderPath);
+ rootCommand.Add(optionOutputFolderPath);
+ rootCommand.Add(optionTableOfContentsTitle);
+ rootCommand.Add(optionAttributesToExclude);
+ rootCommand.Add(optionApisToExclude);
+ rootCommand.Add(optionAddPartialModifier);
+ rootCommand.Add(optionHideImplicitDefaultConstructors);
+ rootCommand.Add(optionDebug);
+
+ GenAPIDiffConfigurationBinder c = new(optionBeforeAssembliesFolderPath,
+ optionBeforeRefAssembliesFolderPath,
+ optionAfterAssembliesFolderPath,
+ optionAfterRefAssembliesFolderPath,
+ optionOutputFolderPath,
+ optionTableOfContentsTitle,
+ optionAttributesToExclude,
+ optionApisToExclude,
+ optionAddPartialModifier,
+ optionHideImplicitDefaultConstructors,
+ optionDebug);
+
+ rootCommand.SetHandler(HandleCommand, c);
+ await rootCommand.InvokeAsync(args);
+ }
+
+ private static void HandleCommand(DiffConfiguration diffConfig)
+ {
+ var log = new ConsoleLog(MessageImportance.Normal);
+
+ string attributesToExclude = diffConfig.AttributesToExclude != null ? string.Join(", ", diffConfig.AttributesToExclude) : string.Empty;
+ string apisToExclude = diffConfig.ApisToExclude != null ? string.Join(", ", diffConfig.ApisToExclude) : string.Empty;
+
+ // Custom ordering to match help menu.
+ log.LogMessage("Selected options:");
+ log.LogMessage($" - 'Before' source assemblies: {diffConfig.BeforeAssembliesFolderPath}");
+ log.LogMessage($" - 'After' source assemblies: {diffConfig.AfterAssembliesFolderPath}");
+ log.LogMessage($" - 'Before' reference assemblies: {diffConfig.BeforeAssemblyReferencesFolderPath}");
+ log.LogMessage($" - 'After' reference assemblies: {diffConfig.AfterAssemblyReferencesFolderPath}");
+ log.LogMessage($" - Output: {diffConfig.OutputFolderPath}");
+ log.LogMessage($" - Attributes to exclude: {attributesToExclude}");
+ log.LogMessage($" - APIs to exclude: {apisToExclude}");
+ log.LogMessage($" - Table of contents title: {diffConfig.TableOfContentsTitle}");
+ log.LogMessage($" - Add partial modifier to types: {diffConfig.AddPartialModifier}");
+ log.LogMessage($" - Hide implicit default constructors: {diffConfig.HideImplicitDefaultConstructors}");
+ log.LogMessage($" - Debug: {diffConfig.Debug}");
+ log.LogMessage("");
+
+ if (diffConfig.Debug)
+ {
+ WaitForDebugger();
+ }
+
+ IDiffGenerator diffGenerator = DiffGeneratorFactory.Create(log,
+ diffConfig.BeforeAssembliesFolderPath,
+ diffConfig.BeforeAssemblyReferencesFolderPath,
+ diffConfig.AfterAssembliesFolderPath,
+ diffConfig.AfterAssemblyReferencesFolderPath,
+ diffConfig.OutputFolderPath,
+ diffConfig.TableOfContentsTitle,
+ diffConfig.AttributesToExclude,
+ diffConfig.ApisToExclude,
+ diffConfig.AddPartialModifier,
+ diffConfig.HideImplicitDefaultConstructors,
+ writeToDisk: true,
+ diagnosticOptions: null // TODO: If needed, add CLI option to pass specific diagnostic options
+ );
+
+ diffGenerator.Run();
+ }
+
+ private static void WaitForDebugger()
+ {
+ while (!Debugger.IsAttached)
+ {
+ Console.WriteLine($"Attach to process {Environment.ProcessId}...");
+ Thread.Sleep(1000);
+ }
+ Console.WriteLine("Debugger attached!");
+ Debugger.Break();
+ }
+}
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/DiffConfiguration.cs b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/DiffConfiguration.cs
new file mode 100644
index 000000000000..11ccbe266f6c
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/DiffConfiguration.cs
@@ -0,0 +1,21 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.ApiDiff;
+
+///
+/// Defines the necessary configuration options for API diff.
+///
+public record DiffConfiguration(
+ string AfterAssembliesFolderPath,
+ string? AfterAssemblyReferencesFolderPath,
+ string BeforeAssembliesFolderPath,
+ string? BeforeAssemblyReferencesFolderPath,
+ string OutputFolderPath,
+ string TableOfContentsTitle,
+ string[]? AttributesToExclude,
+ string[]? ApisToExclude,
+ bool AddPartialModifier,
+ bool HideImplicitDefaultConstructors,
+ bool Debug
+);
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/DiffGeneratorFactory.cs b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/DiffGeneratorFactory.cs
new file mode 100644
index 000000000000..87cf93040eec
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/DiffGeneratorFactory.cs
@@ -0,0 +1,112 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.CodeAnalysis;
+using Microsoft.DotNet.ApiSymbolExtensions;
+using Microsoft.DotNet.ApiSymbolExtensions.Logging;
+
+namespace Microsoft.DotNet.ApiDiff;
+
+public static class DiffGeneratorFactory
+{
+ ///
+ /// The default attributes to exclude from the diff.
+ ///
+ public static readonly string[] DefaultAttributesToExclude = [
+ "T:System.AttributeUsageAttribute",
+ "T:System.ComponentModel.EditorBrowsableAttribute",
+ "T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute",
+ "T:System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute"
+ ];
+
+ ///
+ /// The default diagnostic options to use when generating the diff.
+ ///
+ public static readonly IEnumerable> DefaultDiagnosticOptions = [
+ new ("CS8019", ReportDiagnostic.Suppress), // CS8019: Unnecessary using directive.
+ new ("CS8597", ReportDiagnostic.Suppress), // CS8597: Thrown value may be null.
+ ];
+
+ ///
+ /// Creates a new instance of that writes the diff to disk.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// An optional list of attributes to avoid showing in the diff. If , the default list of attributes to exclude is used. If an empty list, no attributes are excluded.
+ /// An optional list of APIs to avoid showing in the diff.
+ ///
+ ///
+ /// If , when calling , the generated markdown files get written to disk, and no item is added to the dictionary. If , when calling , the generated markdown files get added to the dictionary (with the file path as the dictionary key) and none of them is written to disk. This is meant for testing purposes.
+ ///
+ ///
+ public static IDiffGenerator Create(ILog log,
+ string beforeAssembliesFolderPath,
+ string? beforeAssemblyReferencesFolderPath,
+ string afterAssembliesFolderPath,
+ string? afterAssemblyReferencesFolderPath,
+ string outputFolderPath,
+ string tableOfContentsTitle,
+ string[]? attributesToExclude,
+ string[]? apisToExclude,
+ bool addPartialModifier,
+ bool hideImplicitDefaultConstructors,
+ bool writeToDisk,
+ IEnumerable>? diagnosticOptions = null)
+ {
+ return new FileOutputDiffGenerator(log,
+ beforeAssembliesFolderPath,
+ beforeAssemblyReferencesFolderPath,
+ afterAssembliesFolderPath,
+ afterAssemblyReferencesFolderPath,
+ outputFolderPath,
+ tableOfContentsTitle,
+ attributesToExclude,
+ apisToExclude,
+ addPartialModifier,
+ hideImplicitDefaultConstructors,
+ writeToDisk,
+ diagnosticOptions);
+ }
+
+ ///
+ /// Creates a new instance of that writes the diff to memory.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// An optional list of attributes to avoid showing in the diff. If , the default list of attributes to exclude is used. If an empty list, no attributes are excluded.
+ /// An optional list of APIs to avoid showing in the diff.
+ ///
+ ///
+ ///
+ ///
+ public static IDiffGenerator Create(ILog log,
+ IAssemblySymbolLoader beforeLoader,
+ IAssemblySymbolLoader afterLoader,
+ Dictionary beforeAssemblySymbols,
+ Dictionary afterAssemblySymbols,
+ string[]? attributesToExclude,
+ string[]? apisToExclude,
+ bool addPartialModifier,
+ bool hideImplicitDefaultConstructors,
+ IEnumerable>? diagnosticOptions = null)
+ {
+ return new MemoryOutputDiffGenerator(log,
+ beforeLoader,
+ afterLoader,
+ beforeAssemblySymbols,
+ afterAssemblySymbols,
+ attributesToExclude,
+ apisToExclude,
+ addPartialModifier,
+ hideImplicitDefaultConstructors,
+ diagnosticOptions);
+ }
+}
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/FileOutputDiffGenerator.cs b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/FileOutputDiffGenerator.cs
new file mode 100644
index 000000000000..928dedc12089
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/FileOutputDiffGenerator.cs
@@ -0,0 +1,162 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the
+
+using Microsoft.CodeAnalysis;
+using Microsoft.DotNet.ApiSymbolExtensions.Logging;
+using Microsoft.DotNet.ApiSymbolExtensions;
+using System.Diagnostics;
+
+namespace Microsoft.DotNet.ApiDiff;
+
+///
+/// Generates a markdown diff of two different versions of the same assembly.
+///
+internal sealed class FileOutputDiffGenerator : IDiffGenerator
+{
+ private readonly ILog _log;
+ private readonly string[] _beforeAssembliesFolderPaths;
+ private readonly string[] _beforeAssemblyReferencesFolderPaths;
+ private readonly string[] _afterAssembliesFolderPaths;
+ private readonly string[] _afterAssemblyReferencesFolderPaths;
+ private readonly string _outputFolderPath;
+ private readonly string _tableOfContentsTitle;
+ private readonly string[] _attributesToExclude;
+ private readonly string[] _apisToExclude;
+ private readonly bool _addPartialModifier;
+ private readonly bool _hideImplicitDefaultConstructors;
+ private readonly bool _writeToDisk;
+ private readonly IEnumerable>? _diagnosticOptions;
+ private readonly Dictionary _results;
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// An optional list of attributes to avoid showing in the diff. If , the default list of attributes to exclude is used. If an empty list, no attributes are excluded.
+ /// An optional list of APIs to avoid showing in the diff.
+ ///
+ ///
+ /// If , when calling , the generated markdown files get written to disk, and no item is added to the dictionary. If , when calling , the generated markdown files get added to the dictionary (with the file path as the dictionary key) and none of them is written to disk. This is meant for testing purposes.
+ ///
+ internal FileOutputDiffGenerator(ILog log,
+ string beforeAssembliesFolderPath,
+ string? beforeAssemblyReferencesFolderPath,
+ string afterAssembliesFolderPath,
+ string? afterAssemblyReferencesFolderPath,
+ string outputFolderPath,
+ string tableOfContentsTitle,
+ string[]? attributesToExclude,
+ string[]? apisToExclude,
+ bool addPartialModifier,
+ bool hideImplicitDefaultConstructors,
+ bool writeToDisk,
+ IEnumerable>? diagnosticOptions = null)
+
+ {
+ _log = log;
+ _beforeAssembliesFolderPaths = [beforeAssembliesFolderPath];
+ _beforeAssemblyReferencesFolderPaths = beforeAssemblyReferencesFolderPath != null ? [beforeAssemblyReferencesFolderPath] : [];
+ _afterAssembliesFolderPaths = [afterAssembliesFolderPath];
+ _afterAssemblyReferencesFolderPaths = afterAssemblyReferencesFolderPath != null ? [afterAssemblyReferencesFolderPath] : [];
+ _outputFolderPath = outputFolderPath;
+ _tableOfContentsTitle = tableOfContentsTitle;
+ _attributesToExclude = attributesToExclude ?? DiffGeneratorFactory.DefaultAttributesToExclude;
+ _apisToExclude = apisToExclude ?? [];
+ _addPartialModifier = addPartialModifier;
+ _hideImplicitDefaultConstructors = hideImplicitDefaultConstructors;
+ _writeToDisk = writeToDisk;
+ _diagnosticOptions = diagnosticOptions ?? DiffGeneratorFactory.DefaultDiagnosticOptions;
+ _results = [];
+ }
+
+ ///
+ public IReadOnlyDictionary Results => _results.AsReadOnly();
+
+ ///
+ public void Run()
+ {
+ Debug.Assert(_beforeAssembliesFolderPaths.Length == 1);
+ Debug.Assert(_afterAssembliesFolderPaths.Length == 1);
+
+ (IAssemblySymbolLoader beforeLoader, Dictionary beforeAssemblySymbols) =
+ AssemblySymbolLoader.CreateFromFiles(
+ _log,
+ assembliesPaths: _beforeAssembliesFolderPaths,
+ assemblyReferencesPaths: _beforeAssemblyReferencesFolderPaths,
+ diagnosticOptions: _diagnosticOptions);
+
+ (IAssemblySymbolLoader afterLoader, Dictionary afterAssemblySymbols) =
+ AssemblySymbolLoader.CreateFromFiles(
+ _log,
+ assembliesPaths: _afterAssembliesFolderPaths,
+ assemblyReferencesPaths: _afterAssemblyReferencesFolderPaths,
+ diagnosticOptions: _diagnosticOptions);
+
+ MemoryOutputDiffGenerator generator = new(_log,
+ beforeLoader,
+ afterLoader,
+ beforeAssemblySymbols,
+ afterAssemblySymbols,
+ _attributesToExclude,
+ _apisToExclude,
+ _addPartialModifier,
+ _hideImplicitDefaultConstructors,
+ _diagnosticOptions);
+ generator.Run();
+
+ // If true, output is disk. Otherwise, it's the Results dictionary.
+ if (_writeToDisk)
+ {
+ Directory.CreateDirectory(_outputFolderPath);
+ }
+
+ string beforeFileName = Path.GetFileName(_beforeAssembliesFolderPaths[0]);
+ string afterFileName = Path.GetFileName(_afterAssembliesFolderPaths[0]);
+
+ StringBuilder tableOfContents = new();
+ tableOfContents.AppendLine($"# API difference between {beforeFileName} and {afterFileName}");
+ tableOfContents.AppendLine();
+ tableOfContents.AppendLine("API listing follows standard diff formatting.");
+ tableOfContents.AppendLine("Lines preceded by a '+' are additions and a '-' indicates removal.");
+ tableOfContents.AppendLine();
+
+ foreach ((string assemblyName, string text) in generator.Results)
+ {
+ string fileName = $"{_tableOfContentsTitle}_{assemblyName}.md";
+ tableOfContents.AppendLine($"* [{assemblyName}]({fileName})");
+
+ string filePath = Path.Combine(_outputFolderPath, fileName);
+ if (_writeToDisk)
+ {
+ File.WriteAllText(filePath, text);
+ }
+ else
+ {
+ _results.Add(filePath, text);
+ }
+
+ _log.LogMessage($"Wrote '{filePath}'.");
+ }
+
+ tableOfContents.AppendLine();
+
+ string tableOfContentsFilePath = Path.Combine(_outputFolderPath, $"{_tableOfContentsTitle}.md");
+
+ if (_writeToDisk)
+ {
+ File.WriteAllText(tableOfContentsFilePath, tableOfContents.ToString());
+ }
+ else
+ {
+ _results.Add(tableOfContentsFilePath, tableOfContents.ToString());
+ }
+
+ _log.LogMessage($"Wrote table of contents to '{tableOfContentsFilePath}'.");
+ }
+}
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/IDiffGenerator.cs b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/IDiffGenerator.cs
new file mode 100644
index 000000000000..276b8ef8be8d
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/IDiffGenerator.cs
@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.ApiDiff;
+
+public interface IDiffGenerator
+{
+ ///
+ /// Gets the results of the diff. The key is the assembly name and the value is the diff. This dictionary might get populated after calling , depending on the use case.
+ ///
+ IReadOnlyDictionary Results { get; }
+
+ ///
+ /// Runs the diff generator and may populate the dictionary depending on the use case.
+ ///
+ void Run();
+}
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/MemoryOutputDiffGenerator.cs b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/MemoryOutputDiffGenerator.cs
new file mode 100644
index 000000000000..ea03b1a16180
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/MemoryOutputDiffGenerator.cs
@@ -0,0 +1,547 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using DiffPlex.DiffBuilder;
+using DiffPlex.DiffBuilder.Model;
+using Microsoft.DotNet.ApiSymbolExtensions.Logging;
+using Microsoft.DotNet.ApiSymbolExtensions;
+using System.Diagnostics;
+using Microsoft.DotNet.ApiSymbolExtensions.Filtering;
+using Microsoft.DotNet.GenAPI;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Microsoft.DotNet.ApiDiff;
+
+///
+/// Generates a markdown diff of two different versions of the same assembly.
+///
+public class MemoryOutputDiffGenerator : IDiffGenerator
+{
+ private readonly ILog _log;
+ private readonly IAssemblySymbolLoader _beforeLoader;
+ private readonly IAssemblySymbolLoader _afterLoader;
+ private readonly Dictionary _beforeAssemblySymbols;
+ private readonly Dictionary _afterAssemblySymbols;
+ private readonly bool _addPartialModifier;
+ private readonly bool _hideImplicitDefaultConstructors;
+ private readonly ISymbolFilter _attributeSymbolFilter;
+ private readonly ISymbolFilter _symbolFilter;
+ private readonly SyntaxTriviaList _twoSpacesTrivia;
+ private readonly SyntaxList _emptyAttributeList;
+ private readonly IEnumerable> _diagnosticOptions;
+ private readonly Dictionary _results;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// An optional list of attributes to avoid showing in the diff. If , the default list of attributes to exclude is used. If an empty list, no attributes are excluded.
+ /// An optional list of APIs to avoid showing in the diff.
+ ///
+ ///
+ ///
+ internal MemoryOutputDiffGenerator(
+ ILog log,
+ IAssemblySymbolLoader beforeLoader,
+ IAssemblySymbolLoader afterLoader,
+ Dictionary beforeAssemblySymbols,
+ Dictionary afterAssemblySymbols,
+ string[]? attributesToExclude,
+ string[]? apisToExclude,
+ bool addPartialModifier,
+ bool hideImplicitDefaultConstructors,
+ IEnumerable>? diagnosticOptions = null)
+ {
+ _log = log;
+ _beforeLoader = beforeLoader;
+ _afterLoader = afterLoader;
+ _beforeAssemblySymbols = beforeAssemblySymbols;
+ _afterAssemblySymbols = afterAssemblySymbols;
+ _addPartialModifier = addPartialModifier;
+ _hideImplicitDefaultConstructors = hideImplicitDefaultConstructors;
+ _diagnosticOptions = diagnosticOptions ?? DiffGeneratorFactory.DefaultDiagnosticOptions;
+ _attributeSymbolFilter = SymbolFilterFactory.GetFilterFromList(attributesToExclude ?? DiffGeneratorFactory.DefaultAttributesToExclude, includeExplicitInterfaceImplementationSymbols: true);
+ _symbolFilter = SymbolFilterFactory.GetFilterFromList(apisToExclude ?? [], includeExplicitInterfaceImplementationSymbols: true);
+ _twoSpacesTrivia = SyntaxFactory.TriviaList(SyntaxFactory.Space, SyntaxFactory.Space);
+ _emptyAttributeList = SyntaxFactory.List();
+ _results = [];
+ }
+
+ ///
+ public IReadOnlyDictionary Results => _results.AsReadOnly();
+
+ ///
+ public void Run()
+ {
+ foreach ((string assemblyName, IAssemblySymbol beforeAssemblySymbol) in _beforeAssemblySymbols)
+ {
+ StringBuilder sb = new();
+
+ (SyntaxNode beforeAssemblyNode, SemanticModel beforeModel) = GetAssemblyRootNodeAndModel(_beforeLoader, beforeAssemblySymbol);
+
+ // See if an assembly with the same name can be found in the diff folder.
+ if (_afterAssemblySymbols.TryGetValue(assemblyName, out IAssemblySymbol? afterAssemblySymbol))
+ {
+ (SyntaxNode afterAssemblyNode, SemanticModel afterModel) = GetAssemblyRootNodeAndModel(_afterLoader, afterAssemblySymbol);
+ // We don't care about changed assembly attributes (for now).
+ sb.Append(VisitChildren(beforeAssemblyNode, afterAssemblyNode, beforeModel, afterModel, wereParentAttributesChanged: false));
+ // Remove the found ones. The remaining ones will be processed at the end because they're new.
+ _afterAssemblySymbols.Remove(assemblyName);
+ }
+ else
+ {
+ // The assembly was removed in the diff.
+ sb.Append(GenerateDeletedDiff(beforeAssemblyNode));
+ }
+
+ if (sb.Length > 0)
+ {
+ _results.Add(assemblyName, GetFinalAssemblyDiff(assemblyName, sb.ToString()));
+ }
+ }
+
+ // Process the remaining assemblies in the diff folder.
+ foreach ((string assemblyName, IAssemblySymbol afterAssemblySymbol) in _afterAssemblySymbols)
+ {
+ StringBuilder sb = new();
+ (SyntaxNode afterAssemblyNode, _) = GetAssemblyRootNodeAndModel(_afterLoader, afterAssemblySymbol);
+ sb.Append(GenerateAddedDiff(afterAssemblyNode));
+
+ if (sb.Length > 0)
+ {
+ _results.Add(assemblyName, GetFinalAssemblyDiff(assemblyName, sb.ToString()));
+ }
+ }
+ }
+
+ private static string GetFinalAssemblyDiff(string assemblyName, string diffText)
+ {
+ StringBuilder sbAssembly = new();
+ sbAssembly.AppendLine($"# {assemblyName}");
+ sbAssembly.AppendLine();
+ sbAssembly.AppendLine("```diff");
+ sbAssembly.Append(diffText.TrimEnd()); // Leading text stays, it's usually valid indentation.
+ sbAssembly.AppendLine();
+ sbAssembly.AppendLine("```");
+ return sbAssembly.ToString();
+ }
+
+ private string? VisitChildren(SyntaxNode beforeParentNode, SyntaxNode afterParentNode, SemanticModel beforeModel, SemanticModel afterModel, bool wereParentAttributesChanged)
+ {
+ Dictionary beforeChildrenNodes = CollectChildrenNodes(beforeParentNode, beforeModel);
+ Dictionary afterChildrenNodes = CollectChildrenNodes(afterParentNode, afterModel);
+
+ StringBuilder sb = new();
+ // Traverse all the elements found on the left side. This only visits unchanged, modified and deleted APIs.
+ // In other words, this loop excludes those that are new on the right. Those are handled later.
+ foreach ((string memberName, MemberDeclarationSyntax beforeMemberNode) in beforeChildrenNodes)
+ {
+ if (afterChildrenNodes.TryGetValue(memberName, out MemberDeclarationSyntax? afterMemberNode) &&
+ beforeMemberNode.Kind() == afterMemberNode.Kind())
+ {
+ if (beforeMemberNode is BaseTypeDeclarationSyntax && afterMemberNode is BaseTypeDeclarationSyntax ||
+ beforeMemberNode is BaseNamespaceDeclarationSyntax && afterMemberNode is BaseNamespaceDeclarationSyntax)
+ {
+ // At this point, the current API (which is a type) is considered unmodified in its signature.
+ // Before visiting its children, we need to check if the attributes have changed.
+ // The children visitation should take care of including the 'unmodified' parts of the parent type.
+ string? attributes = VisitAttributes(beforeMemberNode, afterMemberNode);
+ if (attributes != null)
+ {
+ sb.Append(attributes);
+ }
+ sb.Append(VisitChildren(beforeMemberNode, afterMemberNode, beforeModel, afterModel, wereParentAttributesChanged: attributes != null));
+ }
+ else
+ {
+ // This returns the current member (as changed) topped with its added/deleted/changed attributes.
+ sb.Append(VisitLeafNode(memberName, beforeMemberNode, afterMemberNode, ChangeType.Modified));
+ }
+ // Remove the found ones. The remaining ones will be processed at the end because they're new.
+ afterChildrenNodes.Remove(memberName);
+ }
+ else
+ {
+ // This returns the current member (as deleted) topped with its attributes as deleted.
+ sb.Append(VisitLeafNode(memberName, beforeMemberNode, afterNode: null, ChangeType.Deleted));
+ }
+ }
+
+ // Traverse all the elements that are new on the right side which were not found on the left. They are all treated as new APIs.
+ foreach ((string memberName, MemberDeclarationSyntax newMemberNode) in afterChildrenNodes)
+ {
+ // This returns the current member (as added) topped with its attributes as added.
+ sb.Append(VisitLeafNode(memberName, beforeNode: null, newMemberNode, ChangeType.Inserted));
+ }
+
+ if (sb.Length > 0 || wereParentAttributesChanged)
+ {
+ return GetCodeWrappedByParent(sb.ToString(), afterParentNode);
+ }
+
+ return null;
+ }
+
+ private static Dictionary CollectChildrenNodes(SyntaxNode parentNode, SemanticModel model)
+ {
+ Dictionary dictionary = new();
+
+ if (parentNode is BaseNamespaceDeclarationSyntax)
+ {
+ foreach (BaseTypeDeclarationSyntax typeNode in parentNode.ChildNodes().Where(n => n is BaseTypeDeclarationSyntax t && IsPublicOrProtected(t)))
+ {
+ dictionary.Add(GetDocId(typeNode, model), typeNode);
+ }
+ foreach (DelegateDeclarationSyntax delegateNode in parentNode.ChildNodes().Where(n => n is DelegateDeclarationSyntax d && IsPublicOrProtected(d)))
+ {
+ dictionary.Add(GetDocId(delegateNode, model), delegateNode);
+ }
+ }
+ else if (parentNode is BaseTypeDeclarationSyntax)
+ {
+ foreach (MemberDeclarationSyntax memberNode in parentNode.ChildNodes().Where(n => n is MemberDeclarationSyntax m && IsPublicOrProtected(m)))
+ {
+ dictionary.Add(GetDocId(memberNode, model), memberNode);
+ }
+ }
+ else if (parentNode is CompilationUnitSyntax)
+ {
+ foreach (BaseNamespaceDeclarationSyntax namespaceNode in parentNode.DescendantNodes().OfType())
+ {
+ dictionary.Add(GetDocId(namespaceNode, model), namespaceNode);
+ }
+ }
+ else
+ {
+ foreach (MemberDeclarationSyntax childNode in parentNode.ChildNodes().Where(n => n is MemberDeclarationSyntax m && IsPublicOrProtected(m)))
+ {
+ dictionary.Add(GetDocId(childNode, model), childNode);
+ }
+ }
+
+ return dictionary;
+ }
+
+ // Returns the specified leaf node as changed (type, member or namespace) topped with its added/deleted/changed attributes and the correct leading trivia.
+ private string? VisitLeafNode(string nodeName, MemberDeclarationSyntax? beforeNode, MemberDeclarationSyntax? afterNode, ChangeType changeType)
+ {
+ Debug.Assert(beforeNode != null || afterNode != null);
+
+ StringBuilder sb = new();
+
+ // If the leaf node was added or deleted, the visited attributes will also show as added or deleted.
+ string? attributes = VisitAttributes(beforeNode, afterNode);
+ if (attributes != null)
+ {
+ sb.Append(attributes);
+ }
+
+ // The string builder contains the attributes. Now append them on top of the member without their default attributes.
+ SyntaxNode? beforeNodeWithoutAttributes = GetNodeWithoutAttributes(beforeNode);
+ SyntaxNode? afterNodeWithoutAttributes = GetNodeWithoutAttributes(afterNode);
+
+ Debug.Assert(beforeNodeWithoutAttributes != null || afterNodeWithoutAttributes != null);
+
+ switch (changeType)
+ {
+ case ChangeType.Deleted:
+ Debug.Assert(beforeNodeWithoutAttributes != null);
+ sb.Append(GenerateDeletedDiff(beforeNodeWithoutAttributes));
+ break;
+ case ChangeType.Inserted:
+ Debug.Assert(afterNodeWithoutAttributes != null);
+ sb.Append(GenerateAddedDiff(afterNodeWithoutAttributes));
+ break;
+ case ChangeType.Modified:
+ Debug.Assert(beforeNode != null && afterNode != null);
+ string? changed = GenerateChangedDiff(beforeNodeWithoutAttributes!, afterNodeWithoutAttributes!);
+ // At this stage, the attributes that decorated this API have already been handled and printed.
+ // If the API itself also changed, then we can directly append this API's diff under the attributes (if any).
+ // Otherwise, we still need to show the API as unmodified, but only if the attributes also changed.
+ if (changed != null)
+ {
+ sb.Append(changed);
+ }
+ else if (attributes != null)
+ {
+ Debug.Assert(afterNodeWithoutAttributes != null);
+ sb.Append($" {afterNodeWithoutAttributes.ToFullString()}");
+ }
+ break;
+ default:
+ throw new NotSupportedException(string.Format(Resources.UnexpectedChangeTypeForNode, nodeName, changeType));
+ }
+
+ return sb.Length > 0 ? sb.ToString() : null;
+ }
+
+ [return: NotNullIfNotNull(nameof(node))]
+ private SyntaxNode? GetNodeWithoutAttributes(SyntaxNode? node)
+ {
+ if (node == null)
+ {
+ return null;
+ }
+
+ if (node is MemberDeclarationSyntax memberNode)
+ {
+ return memberNode.WithAttributeLists(_emptyAttributeList).WithLeadingTrivia(node.GetLeadingTrivia());
+ }
+ else if (node is BaseNamespaceDeclarationSyntax namespaceNode)
+ {
+ return namespaceNode.WithAttributeLists(_emptyAttributeList).WithLeadingTrivia(node.GetLeadingTrivia());
+ }
+
+ throw new InvalidOperationException(Resources.UnsupportedNodeForRemovingAttributes);
+ }
+
+ // Returns a non-null string if any attribute was changed (added, deleted or modified). Returns null if all attributes were the same before and after.
+ private static string? VisitAttributes(MemberDeclarationSyntax? beforeNode, MemberDeclarationSyntax? afterNode)
+ {
+ Dictionary? beforeAttributeNodes = beforeNode != null ? CollectAttributeNodes(beforeNode) : null;
+ Dictionary? afterAttributeNodes = afterNode != null ? CollectAttributeNodes(afterNode) : null;
+
+ StringBuilder sb = new();
+ if (beforeAttributeNodes != null)
+ {
+ foreach ((string attributeName, AttributeSyntax beforeAttributeNode) in beforeAttributeNodes)
+ {
+ // We found a before attribute.
+ if (afterAttributeNodes != null &&
+ afterAttributeNodes.TryGetValue(attributeName, out AttributeSyntax? afterAttributeNode))
+ {
+ AttributeListSyntax beforeAttributeList = GetAttributeAsAttributeList(beforeAttributeNode, beforeNode!);
+ AttributeListSyntax afterAttributeList = GetAttributeAsAttributeList(afterAttributeNode, afterNode!);
+
+ // We found the same after attribute. Retrieve the comparison string.
+ sb.Append(GenerateChangedDiff(beforeAttributeList, afterAttributeList));
+ // Remove the found ones. The remaining ones will be processed at the end because they're new.
+ afterAttributeNodes.Remove(attributeName);
+ }
+ else
+ {
+ // Retrieve the attribute string as removed.
+ AttributeListSyntax beforeAttributeList = GetAttributeAsAttributeList(beforeAttributeNode, beforeNode!);
+ sb.Append(GenerateDeletedDiff(beforeAttributeList));
+ }
+ }
+ }
+ // At this point, we may have found changed or deleted attributes (or none).
+ // Check now if there were any added attributes.
+ if (afterAttributeNodes != null)
+ {
+ foreach ((_, AttributeSyntax newAttributeNode) in afterAttributeNodes)
+ {
+ // Retrieve the attribute string as added.
+ AttributeListSyntax newAttributeList = GetAttributeAsAttributeList(newAttributeNode, afterNode!);
+ sb.Append(GenerateAddedDiff(newAttributeList));
+ }
+ }
+
+ return sb.Length > 0 ? sb.ToString() : null;
+ }
+
+ private (SyntaxNode rootNode, SemanticModel model) GetAssemblyRootNodeAndModel(IAssemblySymbolLoader loader, IAssemblySymbol assemblySymbol)
+ {
+ CSharpAssemblyDocumentGenerator docGenerator = new(_log,
+ loader,
+ _symbolFilter,
+ _attributeSymbolFilter,
+ exceptionMessage: null,
+ includeAssemblyAttributes: false,
+ loader.MetadataReferences,
+ diagnosticOptions: _diagnosticOptions,
+ addPartialModifier: _addPartialModifier,
+ hideImplicitDefaultConstructors: _hideImplicitDefaultConstructors);
+
+ // This is a workaround to get the root node and semantic model for a rewritten assembly root node.
+ Document oldDocument = docGenerator.GetDocumentForAssembly(assemblySymbol);
+ SyntaxNode oldRootNode = docGenerator.GetFormattedRootNodeForDocument(oldDocument); // This method rewrites the node and detaches it from the original document.
+ Document newDocument = oldDocument.WithSyntaxRoot(oldRootNode); // This links the rewritten node to the document and returns that document, but...
+ SyntaxNode newRootNode = newDocument.GetSyntaxRootAsync().Result!; // ... we need to retrieve the root node with the one linked to the document (it's a two way linking).
+ SemanticModel model = newDocument.GetSemanticModelAsync().Result!;
+
+ return (newRootNode, model);
+ }
+
+ // For types, members and namespaces.
+ private static Dictionary CollectAttributeNodes(MemberDeclarationSyntax memberNode)
+ {
+ Dictionary dictionary = new();
+
+ foreach (AttributeListSyntax attributeListNode in memberNode.AttributeLists)
+ {
+ foreach (AttributeSyntax attributeNode in attributeListNode.Attributes)
+ {
+ dictionary.Add(attributeNode.ToFullString(), attributeNode);
+ }
+ }
+
+ return dictionary;
+ }
+
+ private static AttributeListSyntax GetAttributeAsAttributeList(AttributeSyntax attributeNode, MemberDeclarationSyntax memberNode) =>
+ SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList([attributeNode])).WithLeadingTrivia(memberNode.GetLeadingTrivia());
+
+ private string GetCodeWrappedByParent(string childrenText, SyntaxNode parentNode)
+ {
+ if (parentNode is CompilationUnitSyntax) // Special case for an assembly
+ {
+ return childrenText;
+ }
+
+ StringBuilder sb = new();
+
+ SyntaxNode attributeLessNode = GetNodeWithoutAttributes(parentNode);
+ SyntaxNode childlessNode = GetChildlessNode(attributeLessNode);
+
+ sb.Append(GetCodeOfNodeOpening(childlessNode));
+ sb.Append(childrenText);
+ sb.Append(GetCodeOfNodeClosing(childlessNode));
+
+ return sb.ToString();
+ }
+
+ private static SyntaxNode GetChildlessNode(SyntaxNode node)
+ {
+ SyntaxNode childlessNode = node switch
+ {
+ BaseTypeDeclarationSyntax typeDecl => typeDecl
+ .RemoveNodes(typeDecl.ChildNodes()
+ .Where(c => c is MemberDeclarationSyntax),
+ SyntaxRemoveOptions.KeepNoTrivia)!,
+
+ NamespaceDeclarationSyntax namespaceDecl => namespaceDecl
+ .RemoveNodes(namespaceDecl.ChildNodes()
+ .Where(c => c is BaseTypeDeclarationSyntax or DelegateDeclarationSyntax),
+ SyntaxRemoveOptions.KeepNoTrivia)!,
+
+ _ => node
+ };
+
+ return childlessNode.WithLeadingTrivia(node.GetLeadingTrivia());
+ }
+
+ private string GetCodeOfNodeOpening(SyntaxNode childlessNode)
+ {
+ SyntaxToken openBrace = SyntaxFactory.Token(
+ leading: _twoSpacesTrivia.AddRange(childlessNode.GetLeadingTrivia()),
+ kind: SyntaxKind.OpenBraceToken,
+ trailing: SyntaxFactory.TriviaList(SyntaxFactory.CarriageReturnLineFeed));
+
+ SyntaxToken missingCloseBrace = SyntaxFactory.MissingToken(SyntaxKind.CloseBraceToken);
+
+ SyntaxNode unclosedNode = childlessNode switch
+ {
+ BaseTypeDeclarationSyntax typeDecl => typeDecl
+ .WithOpenBraceToken(openBrace)
+ .WithCloseBraceToken(missingCloseBrace),
+
+ NamespaceDeclarationSyntax nsDecl => nsDecl
+ .WithOpenBraceToken(openBrace)
+ .WithCloseBraceToken(missingCloseBrace),
+
+ _ => childlessNode
+ };
+
+ StringBuilder sb = new();
+
+ sb.Append(" ");
+ sb.Append(unclosedNode.GetLeadingTrivia().ToFullString());
+ sb.Append(unclosedNode.WithoutTrivia().ToString());
+
+ return sb.ToString();
+ }
+
+ private string GetCodeOfNodeClosing(SyntaxNode childlessNode)
+ {
+ SyntaxToken closeBrace = childlessNode switch
+ {
+ BaseTypeDeclarationSyntax typeDecl => typeDecl.CloseBraceToken
+ .WithLeadingTrivia(typeDecl.CloseBraceToken.LeadingTrivia.AddRange(_twoSpacesTrivia))
+ .WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed),
+
+ NamespaceDeclarationSyntax nsDecl => nsDecl.CloseBraceToken
+ .WithLeadingTrivia(nsDecl.CloseBraceToken.LeadingTrivia.AddRange(_twoSpacesTrivia))
+ .WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed),
+
+ _ => throw new InvalidOperationException(Resources.UnexpectedNodeType)
+ };
+
+ StringBuilder sb = new();
+
+ sb.Append(closeBrace.ToFullString());
+
+ return sb.ToString();
+ }
+
+ private static bool IsPublicOrProtected(MemberDeclarationSyntax m) =>
+ m.Modifiers.Any(SyntaxKind.PublicKeyword) || m.Modifiers.Any(SyntaxKind.ProtectedKeyword);
+
+ private static string GetDocId(SyntaxNode node, SemanticModel model)
+ {
+ if (node is FieldDeclarationSyntax fieldDeclaration)
+ {
+ foreach (var variable in fieldDeclaration.Declaration.Variables)
+ {
+ var fieldSymbol = model.GetDeclaredSymbol(variable) as IFieldSymbol;
+ if (fieldSymbol?.GetDocumentationCommentId() is string fieldDocId)
+ {
+ return fieldDocId;
+ }
+ }
+ }
+ else
+ {
+ var symbol = model.GetDeclaredSymbol(node);
+ if (symbol?.GetDocumentationCommentId() is string docId)
+ {
+ return docId;
+ }
+ }
+
+ throw new NullReferenceException(string.Format(Resources.CouldNotGetDocIdForNode, node));
+ }
+
+ private static string? GenerateAddedDiff(SyntaxNode afterNode) =>
+ GenerateDiff(InlineDiffBuilder.Diff(oldText: string.Empty, newText: afterNode.ToFullString()));
+
+ private static string? GenerateChangedDiff(SyntaxNode beforeNode, SyntaxNode afterNode) =>
+ GenerateDiff(InlineDiffBuilder.Diff(oldText: beforeNode.ToFullString(), newText: afterNode.ToFullString()));
+
+ private static string? GenerateDeletedDiff(SyntaxNode beforeNode) =>
+ GenerateDiff(InlineDiffBuilder.Diff(oldText: beforeNode.ToFullString(), newText: string.Empty));
+
+ private static string? GenerateDiff(DiffPaneModel diff)
+ {
+ StringBuilder sb = new();
+
+ foreach (var line in diff.Lines)
+ {
+ if (string.IsNullOrWhiteSpace(line.Text))
+ {
+ continue;
+ }
+ switch (line.Type)
+ {
+ case ChangeType.Inserted:
+ sb.AppendLine($"+ {line.Text}");
+ break;
+ case ChangeType.Deleted:
+ sb.AppendLine($"- {line.Text}");
+ break;
+ default:
+ break;
+ }
+ }
+
+ return sb.Length == 0 ? null : sb.ToString();
+ }
+}
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/Microsoft.DotNet.ApiDiff.csproj b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/Microsoft.DotNet.ApiDiff.csproj
new file mode 100644
index 000000000000..7dc8391ede44
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/Microsoft.DotNet.ApiDiff.csproj
@@ -0,0 +1,19 @@
+
+
+
+ $(NetToolMinimum)
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/Resources.resx b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/Resources.resx
new file mode 100644
index 000000000000..029af143a227
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/Resources.resx
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+ Could not get the DocID for node: {0}
+
+
+ Null after assemblies directory.
+
+
+ Null before assemblies directory.
+
+
+ Null output directory.
+
+
+ Null table of contents title.
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+ Unexpected change type for node {0}: {1}
+
+
+ Unsupported node for removing attributes.
+
+
+ Unexpected node type.
+
+
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.cs.xlf b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.cs.xlf
new file mode 100644
index 000000000000..8d502d807c7c
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.cs.xlf
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+
+ Could not get the DocID for node: {0}
+ Could not get the DocID for node: {0}
+
+
+
+ Null after assemblies directory.
+ Null after assemblies directory.
+
+
+
+ Null before assemblies directory.
+ Null before assemblies directory.
+
+
+
+ Null output directory.
+ Null output directory.
+
+
+
+ Null table of contents title.
+ Null table of contents title.
+
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+
+ Unexpected change type for node {0}: {1}
+ Unexpected change type for node {0}: {1}
+
+
+
+ Unexpected node type.
+ Unexpected node type.
+
+
+
+ Unsupported node for removing attributes.
+ Unsupported node for removing attributes.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.de.xlf b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.de.xlf
new file mode 100644
index 000000000000..a4931d239e65
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.de.xlf
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+
+ Could not get the DocID for node: {0}
+ Could not get the DocID for node: {0}
+
+
+
+ Null after assemblies directory.
+ Null after assemblies directory.
+
+
+
+ Null before assemblies directory.
+ Null before assemblies directory.
+
+
+
+ Null output directory.
+ Null output directory.
+
+
+
+ Null table of contents title.
+ Null table of contents title.
+
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+
+ Unexpected change type for node {0}: {1}
+ Unexpected change type for node {0}: {1}
+
+
+
+ Unexpected node type.
+ Unexpected node type.
+
+
+
+ Unsupported node for removing attributes.
+ Unsupported node for removing attributes.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.es.xlf b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.es.xlf
new file mode 100644
index 000000000000..4dce0e3709df
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.es.xlf
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+
+ Could not get the DocID for node: {0}
+ Could not get the DocID for node: {0}
+
+
+
+ Null after assemblies directory.
+ Null after assemblies directory.
+
+
+
+ Null before assemblies directory.
+ Null before assemblies directory.
+
+
+
+ Null output directory.
+ Null output directory.
+
+
+
+ Null table of contents title.
+ Null table of contents title.
+
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+
+ Unexpected change type for node {0}: {1}
+ Unexpected change type for node {0}: {1}
+
+
+
+ Unexpected node type.
+ Unexpected node type.
+
+
+
+ Unsupported node for removing attributes.
+ Unsupported node for removing attributes.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.fr.xlf b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.fr.xlf
new file mode 100644
index 000000000000..32b1eb87105f
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.fr.xlf
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+
+ Could not get the DocID for node: {0}
+ Could not get the DocID for node: {0}
+
+
+
+ Null after assemblies directory.
+ Null after assemblies directory.
+
+
+
+ Null before assemblies directory.
+ Null before assemblies directory.
+
+
+
+ Null output directory.
+ Null output directory.
+
+
+
+ Null table of contents title.
+ Null table of contents title.
+
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+
+ Unexpected change type for node {0}: {1}
+ Unexpected change type for node {0}: {1}
+
+
+
+ Unexpected node type.
+ Unexpected node type.
+
+
+
+ Unsupported node for removing attributes.
+ Unsupported node for removing attributes.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.it.xlf b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.it.xlf
new file mode 100644
index 000000000000..34274df59155
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.it.xlf
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+
+ Could not get the DocID for node: {0}
+ Could not get the DocID for node: {0}
+
+
+
+ Null after assemblies directory.
+ Null after assemblies directory.
+
+
+
+ Null before assemblies directory.
+ Null before assemblies directory.
+
+
+
+ Null output directory.
+ Null output directory.
+
+
+
+ Null table of contents title.
+ Null table of contents title.
+
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+
+ Unexpected change type for node {0}: {1}
+ Unexpected change type for node {0}: {1}
+
+
+
+ Unexpected node type.
+ Unexpected node type.
+
+
+
+ Unsupported node for removing attributes.
+ Unsupported node for removing attributes.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.ja.xlf b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.ja.xlf
new file mode 100644
index 000000000000..cad277f18a37
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.ja.xlf
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+
+ Could not get the DocID for node: {0}
+ Could not get the DocID for node: {0}
+
+
+
+ Null after assemblies directory.
+ Null after assemblies directory.
+
+
+
+ Null before assemblies directory.
+ Null before assemblies directory.
+
+
+
+ Null output directory.
+ Null output directory.
+
+
+
+ Null table of contents title.
+ Null table of contents title.
+
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+
+ Unexpected change type for node {0}: {1}
+ Unexpected change type for node {0}: {1}
+
+
+
+ Unexpected node type.
+ Unexpected node type.
+
+
+
+ Unsupported node for removing attributes.
+ Unsupported node for removing attributes.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.ko.xlf b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.ko.xlf
new file mode 100644
index 000000000000..739a24c7ff3d
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.ko.xlf
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+
+ Could not get the DocID for node: {0}
+ Could not get the DocID for node: {0}
+
+
+
+ Null after assemblies directory.
+ Null after assemblies directory.
+
+
+
+ Null before assemblies directory.
+ Null before assemblies directory.
+
+
+
+ Null output directory.
+ Null output directory.
+
+
+
+ Null table of contents title.
+ Null table of contents title.
+
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+
+ Unexpected change type for node {0}: {1}
+ Unexpected change type for node {0}: {1}
+
+
+
+ Unexpected node type.
+ Unexpected node type.
+
+
+
+ Unsupported node for removing attributes.
+ Unsupported node for removing attributes.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.pl.xlf b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.pl.xlf
new file mode 100644
index 000000000000..d777bb1f0366
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.pl.xlf
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+
+ Could not get the DocID for node: {0}
+ Could not get the DocID for node: {0}
+
+
+
+ Null after assemblies directory.
+ Null after assemblies directory.
+
+
+
+ Null before assemblies directory.
+ Null before assemblies directory.
+
+
+
+ Null output directory.
+ Null output directory.
+
+
+
+ Null table of contents title.
+ Null table of contents title.
+
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+
+ Unexpected change type for node {0}: {1}
+ Unexpected change type for node {0}: {1}
+
+
+
+ Unexpected node type.
+ Unexpected node type.
+
+
+
+ Unsupported node for removing attributes.
+ Unsupported node for removing attributes.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.pt-BR.xlf b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.pt-BR.xlf
new file mode 100644
index 000000000000..e806e3f6c535
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.pt-BR.xlf
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+
+ Could not get the DocID for node: {0}
+ Could not get the DocID for node: {0}
+
+
+
+ Null after assemblies directory.
+ Null after assemblies directory.
+
+
+
+ Null before assemblies directory.
+ Null before assemblies directory.
+
+
+
+ Null output directory.
+ Null output directory.
+
+
+
+ Null table of contents title.
+ Null table of contents title.
+
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+
+ Unexpected change type for node {0}: {1}
+ Unexpected change type for node {0}: {1}
+
+
+
+ Unexpected node type.
+ Unexpected node type.
+
+
+
+ Unsupported node for removing attributes.
+ Unsupported node for removing attributes.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.ru.xlf b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.ru.xlf
new file mode 100644
index 000000000000..f55f3efd9599
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.ru.xlf
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+
+ Could not get the DocID for node: {0}
+ Could not get the DocID for node: {0}
+
+
+
+ Null after assemblies directory.
+ Null after assemblies directory.
+
+
+
+ Null before assemblies directory.
+ Null before assemblies directory.
+
+
+
+ Null output directory.
+ Null output directory.
+
+
+
+ Null table of contents title.
+ Null table of contents title.
+
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+
+ Unexpected change type for node {0}: {1}
+ Unexpected change type for node {0}: {1}
+
+
+
+ Unexpected node type.
+ Unexpected node type.
+
+
+
+ Unsupported node for removing attributes.
+ Unsupported node for removing attributes.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.tr.xlf b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.tr.xlf
new file mode 100644
index 000000000000..d49d9ace0a00
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.tr.xlf
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+
+ Could not get the DocID for node: {0}
+ Could not get the DocID for node: {0}
+
+
+
+ Null after assemblies directory.
+ Null after assemblies directory.
+
+
+
+ Null before assemblies directory.
+ Null before assemblies directory.
+
+
+
+ Null output directory.
+ Null output directory.
+
+
+
+ Null table of contents title.
+ Null table of contents title.
+
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+
+ Unexpected change type for node {0}: {1}
+ Unexpected change type for node {0}: {1}
+
+
+
+ Unexpected node type.
+ Unexpected node type.
+
+
+
+ Unsupported node for removing attributes.
+ Unsupported node for removing attributes.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.zh-Hans.xlf b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.zh-Hans.xlf
new file mode 100644
index 000000000000..d5b1c0eee2ff
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.zh-Hans.xlf
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+
+ Could not get the DocID for node: {0}
+ Could not get the DocID for node: {0}
+
+
+
+ Null after assemblies directory.
+ Null after assemblies directory.
+
+
+
+ Null before assemblies directory.
+ Null before assemblies directory.
+
+
+
+ Null output directory.
+ Null output directory.
+
+
+
+ Null table of contents title.
+ Null table of contents title.
+
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+
+ Unexpected change type for node {0}: {1}
+ Unexpected change type for node {0}: {1}
+
+
+
+ Unexpected node type.
+ Unexpected node type.
+
+
+
+ Unsupported node for removing attributes.
+ Unsupported node for removing attributes.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.zh-Hant.xlf b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.zh-Hant.xlf
new file mode 100644
index 000000000000..94e28ced869f
--- /dev/null
+++ b/src/Compatibility/ApiDiff/Microsoft.DotNet.ApiDiff/xlf/Resources.zh-Hant.xlf
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+ Adding member '{0}' to the named type '{1}' failed with exception '{2}'.
+
+
+
+ Could not get the DocID for node: {0}
+ Could not get the DocID for node: {0}
+
+
+
+ Null after assemblies directory.
+ Null after assemblies directory.
+
+
+
+ Null before assemblies directory.
+ Null before assemblies directory.
+
+
+
+ Null output directory.
+ Null output directory.
+
+
+
+ Null table of contents title.
+ Null table of contents title.
+
+
+
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+ Could not resolve type '{0}' in containing assembly '{1}' via type forward. Make sure that the assembly is provided as a reference and contains the type.
+
+
+
+ Unexpected change type for node {0}: {1}
+ Unexpected change type for node {0}: {1}
+
+
+
+ Unexpected node type.
+ Unexpected node type.
+
+
+
+ Unsupported node for removing attributes.
+ Unsupported node for removing attributes.
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Compatibility/ApiDiff/apidiff.slnf b/src/Compatibility/ApiDiff/apidiff.slnf
new file mode 100644
index 000000000000..44b080591de5
--- /dev/null
+++ b/src/Compatibility/ApiDiff/apidiff.slnf
@@ -0,0 +1,11 @@
+{
+ "solution": {
+ "path": "..\\..\\..\\sdk.sln",
+ "projects": [
+ "src\\Compatibility\\ApiDiff\\Microsoft.DotNet.ApiDiff\\Microsoft.DotNet.ApiDiff.csproj",
+ "src\\Compatibility\\ApiDiff\\Microsoft.DotNet.ApiDiff.Tool\\Microsoft.DotNet.ApiDiff.Tool.csproj",
+ "src\\Compatibility\\Microsoft.DotNet.ApiSymbolExtensions\\Microsoft.DotNet.ApiSymbolExtensions.csproj",
+ "test\\Microsoft.DotNet.ApiDiff.Tests\\Microsoft.DotNet.ApiDiff.Tests.csproj"
+ ]
+ }
+}
diff --git a/src/Compatibility/Directory.Packages.props b/src/Compatibility/Directory.Packages.props
index 9898fda73ffd..be120d4cea62 100644
--- a/src/Compatibility/Directory.Packages.props
+++ b/src/Compatibility/Directory.Packages.props
@@ -8,8 +8,4 @@
-
-
-
-
diff --git a/src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/SyntaxGeneratorExtensions.cs b/src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/SyntaxGeneratorExtensions.cs
index 6618d47a20b1..d4938f265c35 100644
--- a/src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/SyntaxGeneratorExtensions.cs
+++ b/src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/SyntaxGeneratorExtensions.cs
@@ -105,7 +105,7 @@ public static SyntaxNode DeclarationExt(this SyntaxGenerator syntaxGenerator, IS
catch (ArgumentException ex)
{
// re-throw the ArgumentException with the symbol that caused it.
- throw new ArgumentException(ex.Message, symbol.ToDisplayString());
+ throw new ArgumentException(ex.Message, symbol.ToDisplayString(), innerException: ex);
}
}
diff --git a/src/Compatibility/compatibility.slnf b/src/Compatibility/compatibility.slnf
index ab10435bc0e9..3dde06cd30ce 100644
--- a/src/Compatibility/compatibility.slnf
+++ b/src/Compatibility/compatibility.slnf
@@ -9,6 +9,8 @@
"src\\Compatibility\\ApiCompat\\Microsoft.DotNet.ApiCompat.Tool\\Microsoft.DotNet.ApiCompat.Tool.csproj",
"src\\Compatibility\\ApiCompat\\Microsoft.DotNet.ApiCompatibility\\Microsoft.DotNet.ApiCompatibility.csproj",
"src\\Compatibility\\ApiCompat\\Microsoft.DotNet.PackageValidation\\Microsoft.DotNet.PackageValidation.csproj",
+ "src\\Compatibility\\ApiDiff\\Microsoft.DotNet.ApiDiff.Tool\\Microsoft.DotNet.ApiDiff.Tool.csproj",
+ "src\\Compatibility\\ApiDiff\\Microsoft.DotNet.ApiDiff\\Microsoft.DotNet.ApiDiff.csproj",
"src\\Compatibility\\GenAPI\\Microsoft.DotNet.GenAPI.Task\\Microsoft.DotNet.GenAPI.Task.csproj",
"src\\Compatibility\\GenAPI\\Microsoft.DotNet.GenAPI.Tool\\Microsoft.DotNet.GenAPI.Tool.csproj",
"src\\Compatibility\\GenAPI\\Microsoft.DotNet.GenAPI\\Microsoft.DotNet.GenAPI.csproj",
@@ -16,10 +18,11 @@
"test\\Microsoft.DotNet.ApiCompat.IntegrationTests\\Microsoft.DotNet.ApiCompat.IntegrationTests.csproj",
"test\\Microsoft.DotNet.ApiCompat.Tests\\Microsoft.DotNet.ApiCompat.Tests.csproj",
"test\\Microsoft.DotNet.ApiCompatibility.Tests\\Microsoft.DotNet.ApiCompatibility.Tests.csproj",
+ "test\\Microsoft.DotNet.ApiDiff.Tests\\Microsoft.DotNet.ApiDiff.Tests.csproj",
"test\\Microsoft.DotNet.ApiSymbolExtensions.Tests\\Microsoft.DotNet.ApiSymbolExtensions.Tests.csproj",
"test\\Microsoft.DotNet.GenAPI.Tests\\Microsoft.DotNet.GenAPI.Tests.csproj",
"test\\Microsoft.DotNet.PackageValidation.Tests\\Microsoft.DotNet.PackageValidation.Tests.csproj",
"test\\Microsoft.NET.TestFramework\\Microsoft.NET.TestFramework.csproj"
]
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Assembly.Tests.cs b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Assembly.Tests.cs
new file mode 100644
index 000000000000..85fb67c24bd0
--- /dev/null
+++ b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Assembly.Tests.cs
@@ -0,0 +1,94 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.ApiDiff.Tests;
+
+public class DiffAssemblyTests : DiffBaseTests
+{
+ [Fact]
+ public void TestAssemblyAdd()
+ {
+ RunTest(before: [],
+ after: [("MyAddedAssembly.dll", """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """)],
+ expected: new Dictionary() {
+ { "MyAddedAssembly", """
+ + namespace MyNamespace
+ + {
+ + public struct MyStruct
+ + {
+ + }
+ + }
+ """ }
+ });
+ }
+
+ [Fact]
+ public void TestAssemblyChange()
+ {
+ RunTest(before: [("MyBeforeAssembly.dll", """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """)],
+ after: [("MyAfterAssembly.dll", """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """)],
+ expected: new Dictionary() {
+ { "MyBeforeAssembly", """
+ - namespace MyNamespace
+ - {
+ - public struct MyStruct
+ - {
+ - }
+ - }
+ """ },
+ { "MyAfterAssembly", """
+ + namespace MyNamespace
+ + {
+ + public struct MyStruct
+ + {
+ + }
+ + }
+ """ }
+ });
+ }
+
+ [Fact]
+ public void TestAssemblyDelete()
+ {
+ RunTest(before: [("MyRemovedAssembly.dll", """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """)],
+ after: [],
+ expected: new Dictionary() {
+ { "MyRemovedAssembly", """
+ - namespace MyNamespace
+ - {
+ - public struct MyStruct
+ - {
+ - }
+ - }
+ """ }
+ });
+ }
+}
diff --git a/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Attribute.Tests.cs b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Attribute.Tests.cs
new file mode 100644
index 000000000000..0ab81f340ace
--- /dev/null
+++ b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Attribute.Tests.cs
@@ -0,0 +1,665 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.ApiDiff.Tests;
+
+public class DiffAttributeTests : DiffBaseTests
+{
+ #region Type attributes
+
+ [Fact]
+ public void TestTypeAttributeAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttributeAttribute : System.Attribute
+ {
+ public MyAttributeAttribute() { }
+ }
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttributeAttribute : System.Attribute
+ {
+ public MyAttributeAttribute() { }
+ }
+ [MyAttribute]
+ public class MyClass
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ + [MyAttribute]
+ public class MyClass
+ {
+ }
+ }
+ """, hideImplicitDefaultConstructors: true);
+ }
+
+ [Fact]
+ public void TestTypeAttributeDeleteAndAdd()
+ {
+ // Added APIs always show up at the end.
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute1Attribute : System.Attribute
+ {
+ public MyAttribute1Attribute() { }
+ }
+ [MyAttribute1]
+ public class MyClass
+ {
+ public MyClass() { }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute2Attribute : System.Attribute
+ {
+ public MyAttribute2Attribute() { }
+ }
+ [MyAttribute2]
+ public class MyClass
+ {
+ public MyClass() { }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - [System.AttributeUsage(System.AttributeTargets.All)]
+ - public class MyAttribute1Attribute : System.Attribute
+ - {
+ - public MyAttribute1Attribute() { }
+ - }
+ - [MyAttribute1]
+ + [MyAttribute2]
+ public class MyClass
+ {
+ }
+ + [System.AttributeUsage(System.AttributeTargets.All)]
+ + public class MyAttribute2Attribute : System.Attribute
+ + {
+ + public MyAttribute2Attribute() { }
+ + }
+ }
+ """,
+ attributesToExclude: []);
+ }
+
+ [Fact]
+ public void TestTypeAttributeSwitch()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute1Attribute : System.Attribute
+ {
+ public MyAttribute1Attribute() { }
+ }
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute2Attribute : System.Attribute
+ {
+ public MyAttribute2Attribute() { }
+ }
+ [MyAttribute1]
+ public class MyClass
+ {
+ public MyClass() { }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute1Attribute : System.Attribute
+ {
+ public MyAttribute1Attribute() { }
+ }
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute2Attribute : System.Attribute
+ {
+ public MyAttribute2Attribute() { }
+ }
+ [MyAttribute2]
+ public class MyClass
+ {
+ public MyClass() { }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - [MyAttribute1]
+ + [MyAttribute2]
+ public class MyClass
+ {
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestTypeChangeAndAttributeAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttributeAttribute : System.Attribute
+ {
+ public MyAttributeAttribute() { }
+ }
+ public class MyClass1
+ {
+ public MyClass1() { }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttributeAttribute : System.Attribute
+ {
+ public MyAttributeAttribute() { }
+ }
+ [MyAttribute]
+ public class MyClass2
+ {
+ public MyClass2() { }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - public class MyClass1
+ - {
+ - public MyClass1() { }
+ - }
+ + [MyAttribute]
+ + public class MyClass2
+ + {
+ + public MyClass2() { }
+ + }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestTypeChangeButAttributeStays()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttributeAttribute : System.Attribute
+ {
+ public MyAttributeAttribute() { }
+ }
+ [MyAttribute]
+ public class MyClass1
+ {
+ public MyClass1() { }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttributeAttribute : System.Attribute
+ {
+ public MyAttributeAttribute() { }
+ }
+ [MyAttribute]
+ public class MyClass2
+ {
+ public MyClass2() { }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - [MyAttribute]
+ - public class MyClass1
+ - {
+ - public MyClass1() { }
+ - }
+ + [MyAttribute]
+ + public class MyClass2
+ + {
+ + public MyClass2() { }
+ + }
+ }
+ """);
+ }
+
+ #endregion
+
+ #region Member attributes
+
+ #endregion
+
+ #region Parameter attributes
+
+ //[Fact]
+ [ActiveIssue("Parameter attributes are not showing up in the syntax tree.")]
+ internal void TestParameterAttributeAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.Parameter)]
+ public class MyAttributeAttribute : System.Attribute
+ {
+ public MyAttributeAttribute() { }
+ }
+ public class MyClass
+ {
+ public MyClass(int x) { }
+ public void MyMethod(int y) { }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.Parameter)]
+ public class MyAttributeAttribute : System.Attribute
+ {
+ public MyAttributeAttribute() { }
+ }
+ public class MyClass
+ {
+ public MyClass([MyAttribute] int x) { }
+ public void MyMethod([MyAttribute] int y) { }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public MyClass(int x) { }
+ + public MyClass([MyAttribute] int x) { }
+ - public void MyMethod(int y) { }
+ + public void MyMethod([MyAttribute] int y) { }
+ }
+ }
+ """, hideImplicitDefaultConstructors: true);
+ }
+
+ #endregion
+
+ #region Attribute list expansion
+
+ [Fact]
+ public void TestTypeAttributeListExpansion()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute1Attribute : System.Attribute
+ {
+ public MyAttribute1Attribute() { }
+ }
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute2Attribute : System.Attribute
+ {
+ public MyAttribute2Attribute() { }
+ }
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute1Attribute : System.Attribute
+ {
+ public MyAttribute1Attribute() { }
+ }
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute2Attribute : System.Attribute
+ {
+ public MyAttribute2Attribute() { }
+ }
+ [MyAttribute1, MyAttribute2]
+ public class MyClass
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ + [MyAttribute1]
+ + [MyAttribute2]
+ public class MyClass
+ {
+ }
+ }
+ """, hideImplicitDefaultConstructors: true);
+ }
+
+ [Fact]
+ public void TestMethodAttributeListExpansion()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute1Attribute : System.Attribute
+ {
+ public MyAttribute1Attribute() { }
+ }
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute2Attribute : System.Attribute
+ {
+ public MyAttribute2Attribute() { }
+ }
+ public class MyClass
+ {
+ public MyClass(int x) { }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute1Attribute : System.Attribute
+ {
+ public MyAttribute1Attribute() { }
+ }
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttribute2Attribute : System.Attribute
+ {
+ public MyAttribute2Attribute() { }
+ }
+ public class MyClass
+ {
+ [MyAttribute1, MyAttribute2]
+ public MyClass(int x) { }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + [MyAttribute1]
+ + [MyAttribute2]
+ public MyClass(int x) { }
+ }
+ }
+ """, hideImplicitDefaultConstructors: true);
+ }
+
+ //[Fact]
+ [ActiveIssue("Parameter attributes are not showing up in the syntax tree.")]
+ internal void TestParameterAttributeListNoExpansion()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.Parameter)]
+ public class MyAttribute1Attribute : System.Attribute
+ {
+ public MyAttribute1Attribute() { }
+ }
+ [System.AttributeUsage(System.AttributeTargets.Parameter)]
+ public class MyAttribute2Attribute : System.Attribute
+ {
+ public MyAttribute2Attribute() { }
+ }
+ public class MyClass
+ {
+ public MyClass(int x) { }
+ public void MyMethod(int y) { }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.Parameter)]
+ public class MyAttribute1Attribute : System.Attribute
+ {
+ public MyAttribute1Attribute() { }
+ }
+ [System.AttributeUsage(System.AttributeTargets.Parameter)]
+ public class MyAttribute2Attribute : System.Attribute
+ {
+ public MyAttribute2Attribute() { }
+ }
+ public class MyClass
+ {
+ public MyClass([MyAttribute1, MyAttribute2] int x) { }
+ public void MyMethod([MyAttribute1, MyAttribute2] int y) { }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public MyClass(int x) { }
+ + public MyClass([MyAttribute1, MyAttribute2] int x) { }
+ - public void MyMethod(int y) { }
+ + public void MyMethod([MyAttribute1, MyAttribute2] int y) { }
+ }
+ }
+ """, hideImplicitDefaultConstructors: true);
+ }
+
+ #endregion
+
+ #region Attribute exclusion
+
+ [Fact]
+ public void TestSuppressAllDefaultAttributes()
+ {
+ // The attributes that should get hidden in this test must all be part of
+ // the DiffGeneratorFactory.DefaultAttributesToExclude list.
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ using System;
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttributeAttribute : System.Attribute
+ {
+ public MyAttributeAttribute() { }
+ }
+ [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+ [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Text")]
+ [MyAttribute]
+ [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Text")]
+ public class MyClass
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ + [MyAttribute]
+ public class MyClass
+ {
+ }
+ + public class MyAttributeAttribute : System.Attribute
+ + {
+ + public MyAttributeAttribute() { }
+ + }
+ }
+ """,
+ attributesToExclude: null); // null forces using the default list
+ }
+
+ [Fact]
+ public void TestSuppressNone()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ using System;
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttributeAttribute : System.Attribute
+ {
+ public MyAttributeAttribute() { }
+ }
+ [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+ [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Text")]
+ [MyAttribute]
+ [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Text")]
+ public class MyClass
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+ + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Text")]
+ + [MyAttribute]
+ + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Text")]
+ public class MyClass
+ {
+ }
+ + [System.AttributeUsage(System.AttributeTargets.All)]
+ + public class MyAttributeAttribute : System.Attribute
+ + {
+ + public MyAttributeAttribute() { }
+ + }
+ }
+ """,
+ attributesToExclude: []); // empty list is respected as is
+ }
+
+ [Fact]
+ public void TestSuppressOnlyCustom()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ using System;
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttributeAttribute : System.Attribute
+ {
+ public MyAttributeAttribute() { }
+ }
+ [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+ [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Text")]
+ [MyAttribute]
+ [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Text")]
+ public class MyClass
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+ + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Text")]
+ + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Text")]
+ public class MyClass
+ {
+ }
+ + [System.AttributeUsage(System.AttributeTargets.All)]
+ + public class MyAttributeAttribute : System.Attribute
+ + {
+ + public MyAttributeAttribute() { }
+ + }
+ }
+ """,
+ attributesToExclude: ["T:MyNamespace.MyAttributeAttribute"]); // Overrides the default list
+ }
+
+ [Fact]
+ public void TestSuppressTypeAndAttributeUsage()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ [System.AttributeUsage(System.AttributeTargets.All)]
+ public class MyAttributeAttribute : System.Attribute
+ {
+ }
+ [MyAttribute]
+ public class MyClass
+ {
+ }
+ }
+ """,
+ expectedCode: "",
+ hideImplicitDefaultConstructors: true,
+ attributesToExclude: ["T:MyNamespace.MyAttributeAttribute"], // Exclude the attribute decorating other APIs
+ apisToExclude: ["T:MyNamespace.MyAttributeAttribute"]); // Excludes the type definition of the attribute itself
+ }
+
+ #endregion
+}
diff --git a/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Base.Tests.cs b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Base.Tests.cs
new file mode 100644
index 000000000000..e367abc1c3e0
--- /dev/null
+++ b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Base.Tests.cs
@@ -0,0 +1,88 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.CodeAnalysis;
+using Microsoft.DotNet.ApiSymbolExtensions;
+using Microsoft.DotNet.ApiSymbolExtensions.Logging;
+using Microsoft.DotNet.GenAPI.Tests;
+
+namespace Microsoft.DotNet.ApiDiff.Tests;
+
+public abstract class DiffBaseTests
+{
+ private readonly ConsoleLog _log = new(MessageImportance.Normal);
+ protected const string AssemblyName = "MyAssembly";
+
+ protected void RunTest(string beforeCode,
+ string afterCode,
+ string expectedCode,
+ string[]? attributesToExclude = null,
+ string[]? apisToExclude = null,
+ bool addPartialModifier = false,
+ bool hideImplicitDefaultConstructors = false)
+ => RunTest(before: [($"{AssemblyName}.dll", beforeCode)],
+ after: [($"{AssemblyName}.dll", afterCode)],
+ expected: new() { { AssemblyName, expectedCode } },
+ attributesToExclude,
+ apisToExclude,
+ addPartialModifier,
+ hideImplicitDefaultConstructors);
+
+ protected void RunTest((string, string)[] before,
+ (string, string)[] after,
+ Dictionary expected,
+ string[]? attributesToExclude = null,
+ string[]? apisToExclude = null,
+ bool addPartialModifier = false,
+ bool hideImplicitDefaultConstructors = false)
+ {
+ // CreateFromTexts will assert on any loader diagnostics via SyntaxFactory.
+ (IAssemblySymbolLoader beforeLoader, Dictionary beforeAssemblySymbols)
+ = TestAssemblyLoaderFactory.CreateFromTexts(_log, assemblyTexts: before, diagnosticOptions: DiffGeneratorFactory.DefaultDiagnosticOptions);
+ (IAssemblySymbolLoader afterLoader, Dictionary afterAssemblySymbols)
+ = TestAssemblyLoaderFactory.CreateFromTexts(_log, assemblyTexts: after, diagnosticOptions: DiffGeneratorFactory.DefaultDiagnosticOptions);
+
+ using MemoryStream outputStream = new();
+
+ IDiffGenerator generator = DiffGeneratorFactory.Create(
+ _log,
+ beforeLoader,
+ afterLoader,
+ beforeAssemblySymbols,
+ afterAssemblySymbols,
+ attributesToExclude,
+ apisToExclude,
+ addPartialModifier,
+ hideImplicitDefaultConstructors,
+ DiffGeneratorFactory.DefaultDiagnosticOptions);
+
+ generator.Run();
+
+ foreach ((string expectedAssemblyName, string expectedCode) in expected)
+ {
+ if (string.IsNullOrEmpty(expectedCode))
+ {
+ Assert.False(generator.Results.TryGetValue(expectedAssemblyName, out string? _), $"Assembly should've been absent among the results: {expectedAssemblyName}");
+ }
+ else
+ {
+ Assert.True(generator.Results.TryGetValue(expectedAssemblyName, out string? actualCode), $"Assembly should've been present among the results: {expectedAssemblyName}");
+ string fullExpectedCode = GetExpected(expectedCode, expectedAssemblyName);
+ Assert.Equal(fullExpectedCode, actualCode, ignoreLineEndingDifferences: true);
+ Assert.True(fullExpectedCode.Equals(actualCode), $"\nExpected:\n[{fullExpectedCode}]\nActual:\n[{actualCode}]");
+ }
+ }
+ }
+
+ private static string GetExpected(string expectedCode, string expectedAssemblyName)
+ {
+ return $"""
+ # {Path.GetFileNameWithoutExtension(expectedAssemblyName)}
+
+ ```diff
+ {expectedCode}
+ ```
+
+ """;
+ }
+}
diff --git a/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Disk.Tests.cs b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Disk.Tests.cs
new file mode 100644
index 000000000000..71e062a529e7
--- /dev/null
+++ b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Disk.Tests.cs
@@ -0,0 +1,267 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.Emit;
+using Microsoft.DotNet.ApiSymbolExtensions.Logging;
+using Microsoft.DotNet.ApiSymbolExtensions.Tests;
+using Moq;
+
+namespace Microsoft.DotNet.ApiDiff.Tests;
+
+public class DiffDiskTests
+{
+ private const string BeforeFolderName = "Before";
+ private const string AfterFolderName = "After";
+ private const string DefaultTableOfContentsTitle = "MyTitle";
+ private const string DefaultAssemblyName = "MyAssembly";
+
+ private const string ExpectedTableOfContents = $"""
+ # API difference between {BeforeFolderName} and {AfterFolderName}
+
+ API listing follows standard diff formatting.
+ Lines preceded by a '+' are additions and a '-' indicates removal.
+
+ * [{DefaultAssemblyName}]({DefaultTableOfContentsTitle}_{DefaultAssemblyName}.md)
+
+
+ """;
+
+ private const string BeforeCode = """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public MyClass() { }
+ }
+ }
+ """;
+
+ private const string AfterCode = """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public MyClass() { }
+ public void MyMethod() { }
+ }
+ }
+ """;
+ private const string DefaultExpectedMarkdown = $@"# {DefaultAssemblyName}
+
+```diff
+ namespace MyNamespace
+ {{
+ public class MyClass
+ {{
++ public void MyMethod() {{ }}
+ }}
+ }}
+```
+";
+
+ private readonly Dictionary DefaultBeforeAssemblyAndCodeFiles = new() { { DefaultAssemblyName, [BeforeCode] } };
+ private readonly Dictionary DefaultAfterAssemblyAndCodeFiles = new() { { DefaultAssemblyName, [AfterCode] } };
+ private readonly Dictionary DefaultExpectedAssemblyMarkdowns = new() { { DefaultAssemblyName, DefaultExpectedMarkdown } };
+
+ ///
+ /// This test reads two DLLs, where the only difference between the types in the assembly is one method that is added on the new type.
+ /// The output goes to disk.
+ ///
+ [Fact]
+ public void Test_DiskRead_DiskWrite()
+ {
+ using TempDirectory inputFolderPath = new();
+ using TempDirectory outputFolderPath = new();
+
+ IDiffGenerator generator = TestDiskShared(inputFolderPath.DirPath, DefaultTableOfContentsTitle, DefaultBeforeAssemblyAndCodeFiles, DefaultAfterAssemblyAndCodeFiles, outputFolderPath.DirPath, writeToDisk: true);
+ generator.Run();
+
+ VerifyDiskWrite(outputFolderPath.DirPath, DefaultTableOfContentsTitle, ExpectedTableOfContents, DefaultExpectedAssemblyMarkdowns);
+ }
+
+ ///
+ /// Many namespaces belonging to a single assembly should go into the same output markdown file for that assembly.
+ ///
+ [Fact]
+ public void Test_DiskRead_DiskWrite_MultiNamespaces()
+ {
+ using TempDirectory inputFolderPath = new();
+ using TempDirectory outputFolderPath = new();
+
+ string beforeCode1 = """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public MyClass() { }
+ }
+ }
+ """;
+
+ string beforeCode2 = """
+ namespace MyNamespace.MySubNamespace
+ {
+ public class MySubClass
+ {
+ public MySubClass() { }
+ }
+ }
+ """;
+
+ string afterCode1 = """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public MyClass() { }
+ public void MyMethod() { }
+ }
+ }
+ """;
+
+ string afterCode2 = """
+ namespace MyNamespace.MySubNamespace
+ {
+ public class MySubClass
+ {
+ public MySubClass() { }
+ public void MySubMethod() { }
+ }
+ }
+ """;
+
+ string expectedMarkdown = $@"# {DefaultAssemblyName}
+
+```diff
+ namespace MyNamespace
+ {{
+ public class MyClass
+ {{
++ public void MyMethod() {{ }}
+ }}
+ }}
+ namespace MyNamespace.MySubNamespace
+ {{
+ public class MySubClass
+ {{
++ public void MySubMethod() {{ }}
+ }}
+ }}
+```
+";
+
+ Dictionary beforeAssemblyAndCodeFiles = new() { { DefaultAssemblyName, [beforeCode1, beforeCode2] } };
+ Dictionary afterAssemblyAndCodeFiles = new() { { DefaultAssemblyName, [afterCode1, afterCode2] } };
+ Dictionary expectedAssemblyMarkdowns = new() { { DefaultAssemblyName, expectedMarkdown } };
+
+ IDiffGenerator generator = TestDiskShared(inputFolderPath.DirPath, DefaultTableOfContentsTitle, beforeAssemblyAndCodeFiles, afterAssemblyAndCodeFiles, outputFolderPath.DirPath, writeToDisk: true);
+ generator.Run();
+
+ VerifyDiskWrite(outputFolderPath.DirPath, DefaultTableOfContentsTitle, ExpectedTableOfContents, expectedAssemblyMarkdowns);
+ }
+
+ ///
+ /// This test reads two DLLs, where the only difference between the types in the assembly is one method that is added on the new type.
+ /// The output is the Results dictionary.
+ ///
+ [Fact]
+ public void Test_DiskRead_MemoryWrite()
+ {
+ using TempDirectory inputFolderPath = new();
+ using TempDirectory outputFolderPath = new();
+
+ IDiffGenerator generator = TestDiskShared(inputFolderPath.DirPath, DefaultTableOfContentsTitle, DefaultBeforeAssemblyAndCodeFiles, DefaultAfterAssemblyAndCodeFiles, outputFolderPath.DirPath, writeToDisk: false);
+ generator.Run();
+
+ string tableOfContentsMarkdownFilePath = Path.Join(outputFolderPath.DirPath, $"{DefaultTableOfContentsTitle}.md");
+ Assert.Contains(tableOfContentsMarkdownFilePath, generator.Results.Keys);
+
+ Assert.Equal(ExpectedTableOfContents, generator.Results[tableOfContentsMarkdownFilePath]);
+
+ string myAssemblyMarkdownFilePath = Path.Join(outputFolderPath.DirPath, $"{DefaultTableOfContentsTitle}_{DefaultAssemblyName}.md");
+ Assert.Contains(myAssemblyMarkdownFilePath, generator.Results.Keys);
+
+ Assert.Equal(DefaultExpectedMarkdown, generator.Results[myAssemblyMarkdownFilePath]);
+ }
+
+ private IDiffGenerator TestDiskShared(string inputFolderPath, string tableOfContentsTitle, Dictionary beforeAssemblyAndCodeFiles, Dictionary afterAssemblyAndCodeFiles, string outputFolderPath, bool writeToDisk)
+ {
+ string beforeAssembliesFolderPath = Path.Join(inputFolderPath, BeforeFolderName);
+ string afterAssembliesFolderPath = Path.Join(inputFolderPath, AfterFolderName);
+
+ Directory.CreateDirectory(beforeAssembliesFolderPath);
+ Directory.CreateDirectory(afterAssembliesFolderPath);
+
+ WriteCodeToAssemblyInDisk(beforeAssembliesFolderPath, beforeAssemblyAndCodeFiles);
+ WriteCodeToAssemblyInDisk(afterAssembliesFolderPath, afterAssemblyAndCodeFiles);
+
+ Mock log = new();
+
+ return DiffGeneratorFactory.Create(log.Object,
+ beforeAssembliesFolderPath,
+ beforeAssemblyReferencesFolderPath: null,
+ afterAssembliesFolderPath,
+ afterAssemblyReferencesFolderPath: null,
+ outputFolderPath,
+ tableOfContentsTitle,
+ attributesToExclude: null,
+ apisToExclude: null,
+ addPartialModifier: false,
+ hideImplicitDefaultConstructors: true,
+ writeToDisk,
+ DiffGeneratorFactory.DefaultDiagnosticOptions);
+ }
+
+ private void WriteCodeToAssemblyInDisk(string assemblyDirectoryPath, Dictionary assemblyAndCodeFiles)
+ {
+ foreach ((string assemblyName, string[] codeFiles) in assemblyAndCodeFiles)
+ {
+ List syntaxTrees = new();
+ foreach (string codeFile in codeFiles)
+ {
+ syntaxTrees.Add(CSharpSyntaxTree.ParseText(codeFile));
+ }
+
+ IEnumerable references = AppDomain.CurrentDomain.GetAssemblies()
+ .Where(a => !a.IsDynamic)
+ .Select(a => MetadataReference.CreateFromFile(a.Location))
+ .Cast();
+
+ CSharpCompilation compilation = CSharpCompilation.Create(
+ assemblyName,
+ syntaxTrees,
+ references,
+ new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
+
+ var assemblyPath = Path.Join(assemblyDirectoryPath, $"{assemblyName}.dll");
+ EmitResult result = compilation.Emit(assemblyPath);
+
+ if (!result.Success)
+ {
+ IEnumerable failures = result.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error);
+ string failureMessages = string.Join(Environment.NewLine, failures.Select(f => $"{f.Id}: {f.GetMessage()}"));
+ Assert.Fail($"Compilation failed: {failureMessages}");
+ }
+ }
+ }
+
+ private void VerifyDiskWrite(string outputFolderPath, string tableOfContentsTitle, string expectedTableOfContents, Dictionary expectedAssemblyMarkdowns)
+ {
+ string tableOfContentsMarkdownFilePath = Path.Join(outputFolderPath, $"{tableOfContentsTitle}.md");
+ Assert.True(File.Exists(tableOfContentsMarkdownFilePath), $"{tableOfContentsMarkdownFilePath} table of contents markdown file does not exist.");
+
+ string actualTableOfContentsText = File.ReadAllText(tableOfContentsMarkdownFilePath);
+ Assert.Equal(expectedTableOfContents, actualTableOfContentsText);
+
+ foreach ((string expectedAssembly, string expectedMarkdown) in expectedAssemblyMarkdowns)
+ {
+ string myAssemblyMarkdownFilePath = Path.Join(outputFolderPath, $"{tableOfContentsTitle}_{expectedAssembly}.md");
+ Assert.True(File.Exists(myAssemblyMarkdownFilePath), $"{myAssemblyMarkdownFilePath} assembly markdown file does not exist.");
+
+ string actualCode = File.ReadAllText(myAssemblyMarkdownFilePath);
+ Assert.Equal(expectedMarkdown, actualCode);
+ }
+ }
+}
diff --git a/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Method.Tests.cs b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Method.Tests.cs
new file mode 100644
index 000000000000..be5c49befb2e
--- /dev/null
+++ b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Method.Tests.cs
@@ -0,0 +1,412 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.ApiDiff.Tests;
+
+public class DiffMethodTests : DiffBaseTests
+{
+ #region Methods
+
+ [Fact]
+ public void TestMethodAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public void MyMethod()
+ {
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public void MyMethod() { }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestMethodChange()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public void MyBeforeMethod()
+ {
+ }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public void MyAfterMethod()
+ {
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public void MyBeforeMethod() { }
+ + public void MyAfterMethod() { }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestMethodDelete()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public void MyMethod()
+ {
+ }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public void MyMethod() { }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestMethodReturnChange()
+ {
+ // The DocID remains the same, but the return type changes
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public void MyMethod()
+ {
+ }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyMethod()
+ {
+ return 0;
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public void MyMethod() { }
+ + public int MyMethod() { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestMethodParametersChange()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public void MyMethod()
+ {
+ }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public void MyMethod(int x)
+ {
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public void MyMethod() { }
+ + public void MyMethod(int x) { }
+ }
+ }
+ """);
+ }
+
+ #endregion
+
+ #region Constructors
+
+ [Fact]
+ public void TestConstructorAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public MyClass(int x)
+ {
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public MyClass(int x) { }
+ }
+ }
+ """, hideImplicitDefaultConstructors: true);
+ }
+
+ [Fact]
+ public void TestConstructorDelete()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public MyClass(int x)
+ {
+ }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public MyClass(int x) { }
+ }
+ }
+ """, hideImplicitDefaultConstructors: true);
+ }
+
+ [Fact]
+ public void TestDefaultConstructorMakePrivate()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public MyClass()
+ {
+ }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ private MyClass()
+ {
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public MyClass() { }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestDefaultConstructorMakePublic()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ private MyClass()
+ {
+ }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public MyClass()
+ {
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public MyClass() { }
+ }
+ }
+ """);
+ }
+
+ #endregion
+
+ #region Exclusions
+
+ [Fact]
+ public void TestExcludeAddedMethod()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public void MyMethod() { }
+ }
+ }
+ """,
+ expectedCode: "",
+ hideImplicitDefaultConstructors: true,
+ apisToExclude: ["M:MyNamespace.MyClass.MyMethod"]);
+ }
+
+ [Fact]
+ public void TestExcludeModifiedMethod()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public void MyMethod1() { }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public void MyMethod2() { }
+ }
+ }
+ """,
+ expectedCode: "",
+ hideImplicitDefaultConstructors: true,
+ apisToExclude: ["M:MyNamespace.MyClass.MyMethod1", "M:MyNamespace.MyClass.MyMethod2"]);
+ }
+
+ [Fact]
+ public void TestExcludeRemovedMethod()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public void MyMethod() { }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ expectedCode: "",
+ hideImplicitDefaultConstructors: true,
+ apisToExclude: ["M:MyNamespace.MyClass.MyMethod"]);
+ }
+
+ #endregion
+}
diff --git a/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Namespace.Tests.cs b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Namespace.Tests.cs
new file mode 100644
index 000000000000..ae6e8b15eb28
--- /dev/null
+++ b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Namespace.Tests.cs
@@ -0,0 +1,275 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.ApiDiff.Tests;
+
+public class DiffNamespaceTests : DiffBaseTests
+{
+ #region Block-scoped namespaces
+
+ [Fact]
+ public void TestBlockScopedNamespaceAdd()
+ {
+ RunTest(beforeCode: "",
+ afterCode: """
+ namespace MyAddedNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ + namespace MyAddedNamespace
+ + {
+ + public struct MyStruct
+ + {
+ + }
+ + }
+ """);
+ }
+
+ [Fact]
+ public void TestBlockScopedNamespaceChange()
+ {
+ RunTest(beforeCode: """
+ namespace MyBeforeNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyAfterNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ - namespace MyBeforeNamespace
+ - {
+ - public struct MyStruct
+ - {
+ - }
+ - }
+ + namespace MyAfterNamespace
+ + {
+ + public struct MyStruct
+ + {
+ + }
+ + }
+ """);
+ }
+
+ [Fact]
+ public void TestBlockScopedNamespaceDelete()
+ {
+ RunTest(beforeCode: """
+ namespace MyDeletedNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """,
+ afterCode: "",
+ expectedCode: """
+ - namespace MyDeletedNamespace
+ - {
+ - public struct MyStruct
+ - {
+ - }
+ - }
+ """);
+ }
+
+ [Fact]
+ public void TestBlockScopedNamespaceSortAlphabetically()
+ {
+ // The output is block scoped
+ RunTest(beforeCode: "",
+ afterCode: """
+ namespace C
+ {
+ public struct CType
+ {
+ }
+ }
+ namespace B
+ {
+ public struct BType
+ {
+ }
+ }
+ namespace D
+ {
+ public struct DType
+ {
+ }
+ }
+ namespace A
+ {
+ public struct AType
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ + namespace A
+ + {
+ + public struct AType
+ + {
+ + }
+ + }
+ + namespace B
+ + {
+ + public struct BType
+ + {
+ + }
+ + }
+ + namespace C
+ + {
+ + public struct CType
+ + {
+ + }
+ + }
+ + namespace D
+ + {
+ + public struct DType
+ + {
+ + }
+ + }
+ """);
+ }
+
+ #endregion
+
+ #region File-scoped namespaces
+
+ [Fact]
+ public void TestFileScopedNamespaceAdd()
+ {
+ // The output is block scoped
+ RunTest(beforeCode: "",
+ afterCode: """
+ namespace MyAddedNamespace;
+ public struct MyStruct
+ {
+ }
+ """,
+ expectedCode: """
+ + namespace MyAddedNamespace
+ + {
+ + public struct MyStruct
+ + {
+ + }
+ + }
+ """);
+ }
+
+ [Fact]
+ public void TestFileScopedNamespaceChange()
+ {
+ // The output is block scoped
+ RunTest(beforeCode: """
+ namespace MyBeforeNamespace;
+ public struct MyStruct
+ {
+ }
+ """,
+ afterCode: """
+ namespace MyAfterNamespace;
+ public struct MyStruct
+ {
+ }
+ """,
+ expectedCode: """
+ - namespace MyBeforeNamespace
+ - {
+ - public struct MyStruct
+ - {
+ - }
+ - }
+ + namespace MyAfterNamespace
+ + {
+ + public struct MyStruct
+ + {
+ + }
+ + }
+ """);
+ }
+
+ [Fact]
+ public void TestFileScopedNamespaceDelete()
+ {
+ // The output is block scoped
+ RunTest(beforeCode: """
+ namespace MyDeletedNamespace;
+ public struct MyStruct
+ {
+ }
+ """,
+ afterCode: "",
+ expectedCode: """
+ - namespace MyDeletedNamespace
+ - {
+ - public struct MyStruct
+ - {
+ - }
+ - }
+ """);
+ }
+
+ #endregion
+
+ #region Exclusions
+
+ [Fact]
+ public void TestExcludeAddedNamespace()
+ {
+ RunTest(beforeCode: "",
+ afterCode: """
+ namespace MyNamespace
+ {
+ }
+ """,
+ expectedCode: "",
+ apisToExclude: ["N:MyNamespace.MyNamespace"]);
+ }
+
+ [Fact]
+ public void TestExcludeModifiedNamespace()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace1
+ {
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace2
+ {
+ }
+ """,
+ expectedCode: "",
+ apisToExclude: ["N:MyNamespace.MyNamespace1", "N:MyNamespace.MyNamespace2"]);
+ }
+
+ [Fact]
+ public void TestExcludeRemovedNamespace()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ }
+ """,
+ afterCode: "",
+ expectedCode: "",
+ apisToExclude: ["N:MyNamespace.MyNamespace"]);
+ }
+
+
+ #endregion
+}
diff --git a/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Operators.Tests.cs b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Operators.Tests.cs
new file mode 100644
index 000000000000..1a6834189e40
--- /dev/null
+++ b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Operators.Tests.cs
@@ -0,0 +1,756 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.ApiDiff.Tests;
+
+// Since operators are also methods, this class tests more basic things than the methods class.
+public class DiffOperatorsTests : DiffBaseTests
+{
+ [Fact]
+ public void TestEqualityOperators()
+ {
+ // The equality and inequality operators require also adding Equals and GetHashCode overrides
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator ==(MyClass a, MyClass b) { throw null; }
+ public static MyClass operator !=(MyClass a, MyClass b) { throw null; }
+ public override bool Equals(object? o) { throw null; }
+ public override int GetHashCode() { throw null; }
+ }
+ }
+ """,
+ // Note that the order of the methods is different in the expected code
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public override bool Equals(object? o) { throw null; }
+ + public override int GetHashCode() { throw null; }
+ + public static MyClass operator ==(MyClass a, MyClass b) { throw null; }
+ + public static MyClass operator !=(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestAdditionOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator +(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator +(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestSubtractionOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator -(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator -(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestMultiplicationOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator *(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator *(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestDivisionOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ // This would've thrown CS8597 but it's disabled by CSharpAssemblyDocumentGenerator
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator /(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator /(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestModulusOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator %(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator %(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestLessAndGreaterThanOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ // This would've thrown CS8597 but it's disabled by CSharpAssemblyDocumentGenerator
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static bool operator <(MyClass a, MyClass b) { throw null; }
+ public static bool operator >(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """,
+ // Note that the order of the operators is different in the expected code
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static bool operator >(MyClass a, MyClass b) { throw null; }
+ + public static bool operator <(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestLessAndGreaterThanOrEqualOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ // This would've thrown CS8597 but it's disabled by CSharpAssemblyDocumentGenerator
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static bool operator <=(MyClass a, MyClass b) { throw null; }
+ public static bool operator >=(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """,
+ // Note that the order of the operators is different in the expected code
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static bool operator >=(MyClass a, MyClass b) { throw null; }
+ + public static bool operator <=(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestIncrementOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator ++(MyClass a) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator ++(MyClass a) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestDecrementOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator --(MyClass a) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator --(MyClass a) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestLogicalNotOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator !(MyClass a) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator !(MyClass a) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestBitwiseNotOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator ~(MyClass a) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator ~(MyClass a) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestBitwiseAndOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator &(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator &(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestBitwiseOrOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ // This would've thrown CS8597 but it's disabled by CSharpAssemblyDocumentGenerator
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator |(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator |(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestBitwiseXorOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator ^(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator ^(MyClass a, MyClass b) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestLeftShiftOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator <<(MyClass a, int shift) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator <<(MyClass a, int shift) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestRightShiftOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static MyClass operator >>(MyClass a, int shift) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static MyClass operator >>(MyClass a, int shift) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestImplicitOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static implicit operator MyClass(int value) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static implicit operator MyClass(int value) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestExplicitOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static explicit operator int(MyClass value) { throw null; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static explicit operator int(MyClass value) { throw null; }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestExplicitCheckedOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static explicit operator byte(MyClass value) => (byte)(MyClass)value;
+ public static explicit operator checked byte(MyClass value) => checked((byte)(MyClass)value);
+ }
+ }
+ """, // Notice they get sorted
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public static explicit operator checked byte(MyClass value) { throw null; }
+ + public static explicit operator byte(MyClass value) { throw null; }
+ }
+ }
+ """);
+ }
+
+ #region Exclusions
+
+ [Fact]
+ public void TestExcludeAddedOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static explicit operator int(MyClass value) { throw null; }
+ }
+ }
+ """,
+ expectedCode: "",
+ hideImplicitDefaultConstructors: true,
+ apisToExclude: ["M:MyNamespace.MyClass.op_Explicit(MyNamespace.MyClass)~System.Int32"]);
+ }
+
+ [Fact]
+ public void TestExcludeModifiedOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static explicit operator int(MyClass value) { throw null; }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static explicit operator byte(MyClass value) { throw null; }
+ }
+ }
+ """,
+ expectedCode: "",
+ hideImplicitDefaultConstructors: true,
+ apisToExclude: ["M:MyNamespace.MyClass.op_Explicit(MyNamespace.MyClass)~System.Int32", "M:MyNamespace.MyClass.op_Explicit(MyNamespace.MyClass)~System.Byte"]);
+ }
+
+ [Fact]
+ public void TestExcludeRemovedOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static explicit operator int(MyClass value) { throw null; }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ expectedCode: "",
+ hideImplicitDefaultConstructors: true,
+ apisToExclude: ["M:MyNamespace.MyClass.op_Explicit(MyNamespace.MyClass)~System.Int32"]);
+ }
+
+ [Fact]
+ public void TestExcludeUnmodifiedOperator()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static explicit operator byte(MyClass value) => (byte)(MyClass)value;
+ public static explicit operator checked byte(MyClass value) => checked((byte)(MyClass)value);
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public static explicit operator byte(MyClass value) => (byte)(MyClass)value;
+ public static explicit operator checked byte(MyClass value) => checked((byte)(MyClass)value);
+ }
+ }
+ """,
+ expectedCode: "",
+ hideImplicitDefaultConstructors: true,
+ apisToExclude: ["M:MyNamespace.MyClass.op_Explicit(MyNamespace.MyClass)~System.Byte"]);
+ }
+
+ #endregion
+}
diff --git a/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Property.Tests.cs b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Property.Tests.cs
new file mode 100644
index 000000000000..fdecf8ee8a5f
--- /dev/null
+++ b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Property.Tests.cs
@@ -0,0 +1,413 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.ApiDiff.Tests;
+
+public class DiffPropertyTests : DiffBaseTests
+{
+ [Fact]
+ public void TestPropertyAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; set; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ + public int MyProperty { get { throw null; } set { } }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestPropertyChange()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyBeforeProperty { get; set; }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyAfterProperty { get; set; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public int MyBeforeProperty { get { throw null; } set { } }
+ + public int MyAfterProperty { get { throw null; } set { } }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestPropertyDelete()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; set; }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public int MyProperty { get { throw null; } set { } }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestPropertySetAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; set; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public int MyProperty { get { throw null; } }
+ + public int MyProperty { get { throw null; } set { } }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestPropertySetRemove()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; set; }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public int MyProperty { get { throw null; } set { } }
+ + public int MyProperty { get { throw null; } }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestPropertySetVisibilityProtected()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; set; }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; protected set; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public int MyProperty { get { throw null; } set { } }
+ + public int MyProperty { get { throw null; } protected set { } }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestPropertySetVisibilityPrivate()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; set; }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; private set; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public int MyProperty { get { throw null; } set { } }
+ + public int MyProperty { get { throw null; } }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestPropertyReturnChange()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; set; }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public float MyProperty { get; set; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public int MyProperty { get { throw null; } set { } }
+ + public float MyProperty { get { throw null; } set { } }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestPropertyNullabilityAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; set; }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int? MyProperty { get; set; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public int MyProperty { get { throw null; } set { } }
+ + public int? MyProperty { get { throw null; } set { } }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestPropertyNullabilityRemove()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int? MyProperty { get; set; }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; set; }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ - public int? MyProperty { get { throw null; } set { } }
+ + public int MyProperty { get { throw null; } set { } }
+ }
+ }
+ """);
+ }
+
+ #region Exclusions
+
+ [Fact]
+ public void TestExcludeAddedProperty()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; set; }
+ }
+ }
+ """,
+ expectedCode: "",
+ hideImplicitDefaultConstructors: true,
+ apisToExclude: ["P:MyNamespace.MyClass.MyProperty"]);
+ }
+
+ [Fact]
+ public void TestExcludeModifiedProperty()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty1 { get; set; }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty2 { get; set; }
+ }
+ }
+ """,
+ expectedCode: "",
+ hideImplicitDefaultConstructors: true,
+ apisToExclude: ["P:MyNamespace.MyClass.MyProperty1", "P:MyNamespace.MyClass.MyProperty2"]);
+ }
+
+ [Fact]
+ public void TestExcludeRemovedProperty()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public int MyProperty { get; set; }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ expectedCode: "",
+ hideImplicitDefaultConstructors: true,
+ apisToExclude: ["P:MyNamespace.MyClass.MyProperty"]);
+ }
+
+ #endregion
+}
diff --git a/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Type.Tests.cs b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Type.Tests.cs
new file mode 100644
index 000000000000..52e7ab91174a
--- /dev/null
+++ b/test/Microsoft.DotNet.ApiDiff.Tests/Diff.Type.Tests.cs
@@ -0,0 +1,1076 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.ApiDiff.Tests;
+
+public class DiffTypeTests : DiffBaseTests
+{
+ #region Classes
+
+ [Fact]
+ public void TestClassAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ public class MyAddedClass
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ + public class MyAddedClass
+ + {
+ + public MyAddedClass() { }
+ + }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestClassChange()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ public class MyBeforeClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ public class MyAfterClass
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - public class MyBeforeClass
+ - {
+ - public MyBeforeClass() { }
+ - }
+ + public class MyAfterClass
+ + {
+ + public MyAfterClass() { }
+ + }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestClassDelete()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ public class MyAddedClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - public class MyAddedClass
+ - {
+ - public MyAddedClass() { }
+ - }
+ }
+ """);
+ }
+
+ #endregion
+
+ #region Structs
+
+ [Fact]
+ public void TestStructAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ public struct MyAddedStruct
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ + public struct MyAddedStruct
+ + {
+ + }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestStructChange()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public struct MyBeforeStruct
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public struct MyAfterStruct
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - public struct MyBeforeStruct
+ - {
+ - }
+ + public struct MyAfterStruct
+ + {
+ + }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestStructDelete()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ public struct MyDeletedStruct
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - public struct MyDeletedStruct
+ - {
+ - }
+ }
+ """);
+ }
+
+ #endregion
+
+ #region Records
+
+ [Fact]
+ public void TestRecordAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public record MyStruct
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public record MyStruct
+ {
+ }
+ public record MyRecord(int a);
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ + public record MyRecord(int a)
+ + {
+ + }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestRecordChange()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public record MyBeforeRecord(int a);
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public record MyAfterRecord(int a);
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - public record MyBeforeRecord(int a)
+ - {
+ - }
+ + public record MyAfterRecord(int a)
+ + {
+ + }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestRecordDelete()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public record MyStruct
+ {
+ }
+ public record MyRecord(int a);
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public record MyStruct
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - public record MyRecord(int a)
+ - {
+ - }
+ }
+ """);
+ }
+
+ #endregion
+
+ #region Delegates
+
+ [Fact]
+ public void TestDelegateAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ public delegate void MyDelegate();
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ + public delegate void MyDelegate();
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestDelegateChange()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public delegate void MyBeforeDelegate();
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public delegate void MyAfterDelegate();
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - public delegate void MyBeforeDelegate();
+ + public delegate void MyAfterDelegate();
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestDelegateDelete()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ public delegate void MyDelegate();
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - public delegate void MyDelegate();
+ }
+ """);
+ }
+
+ #endregion
+
+ #region Interfaces
+
+ [Fact]
+ public void TestInterfaceAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ public interface IMyInterface
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ + public interface IMyInterface
+ + {
+ + }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestInterfaceChange()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public interface IMyBeforeInterface
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public interface IMyAfterInterface
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - public interface IMyBeforeInterface
+ - {
+ - }
+ + public interface IMyAfterInterface
+ + {
+ + }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestInterfaceDelete()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ public interface IMyInterface
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - public interface IMyInterface
+ - {
+ - }
+ }
+ """);
+ }
+
+ #endregion
+
+ #region Classes - Hide Default constructors
+
+ [Fact]
+ public void TestTypeAddHideImplicitDefaultConstructors()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public delegate void MyDelegate();
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public delegate void MyDelegate();
+ public class MyClass1
+ {
+ public MyClass1() { }
+ }
+ public class MyClass2
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ + public class MyClass1
+ + {
+ + }
+ + public class MyClass2
+ + {
+ + }
+ }
+ """,
+ hideImplicitDefaultConstructors: true);
+ }
+
+ [Fact]
+ public void TestTypeChangeHideImplicitDefaultConstructors()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyBeforeClass1
+ {
+ public MyBeforeClass1() { }
+ }
+ public class MyBeforeClass2
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyAfterClass1
+ {
+ public MyAfterClass1() { }
+ }
+ public class MyAfterClass2
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - public class MyBeforeClass1
+ - {
+ - }
+ - public class MyBeforeClass2
+ - {
+ - }
+ + public class MyAfterClass1
+ + {
+ + }
+ + public class MyAfterClass2
+ + {
+ + }
+ }
+ """,
+ hideImplicitDefaultConstructors: true);
+ }
+
+ [Fact]
+ public void TestNestedTypeAddHideImplicitDefaultConstructors()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public delegate void MyDelegate();
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public delegate void MyDelegate();
+ public class MyClass1
+ {
+ public class MyNestedClass1
+ {
+ public MyNestedClass1() { }
+ }
+ public class MyNestedClass2
+ {
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ + public class MyClass1
+ + {
+ + public class MyNestedClass1
+ + {
+ + }
+ + public class MyNestedClass2
+ + {
+ + }
+ + }
+ }
+ """,
+ hideImplicitDefaultConstructors: true);
+ }
+
+ [Fact]
+ public void TestNestedTypeChangeHideImplicitDefaultConstructors()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass1
+ {
+ public class MyBeforeNestedClass1
+ {
+ public MyBeforeNestedClass1() { }
+ }
+ public class MyBeforeNestedClass2
+ {
+ }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass1
+ {
+ public class MyAfterNestedClass1
+ {
+ public MyAfterNestedClass1() { }
+ }
+ public class MyAfterNestedClass2
+ {
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyClass1
+ {
+ - public class MyBeforeNestedClass1
+ - {
+ - }
+ - public class MyBeforeNestedClass2
+ - {
+ - }
+ + public class MyAfterNestedClass1
+ + {
+ + }
+ + public class MyAfterNestedClass2
+ + {
+ + }
+ }
+ }
+ """,
+ hideImplicitDefaultConstructors: true);
+ }
+
+ #endregion
+
+ #region Nested types
+
+ [Fact]
+ public void TestNestedTypeAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ public class MyNestedType
+ {
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ + public class MyNestedType
+ + {
+ + public MyNestedType() { }
+ + }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestNestedTypeChange()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ public class MyBeforeNestedType
+ {
+ }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ public class MyAfterNestedType
+ {
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ - public class MyBeforeNestedType
+ - {
+ - public MyBeforeNestedType() { }
+ - }
+ + public class MyAfterNestedType
+ + {
+ + public MyAfterNestedType() { }
+ + }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestNestedTypeRemove()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ public class MyNestedType
+ {
+ }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ - public class MyNestedType
+ - {
+ - public MyNestedType() { }
+ - }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestNestedTypeMemberAdd()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ public class MyNestedType
+ {
+ }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ public class MyNestedType
+ {
+ public void MyMethod() { }
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ public class MyNestedType
+ {
+ + public void MyMethod() { }
+ }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestNestedTypeMemberChange()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ public class MyNestedType
+ {
+ public void MyBeforeMethod() { }
+ }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ public class MyNestedType
+ {
+ public void MyAfterMethod() { }
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ public class MyNestedType
+ {
+ - public void MyBeforeMethod() { }
+ + public void MyAfterMethod() { }
+ }
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestNestedTypeMemberRemove()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ public class MyNestedType
+ {
+ public void MyMethod() { }
+ }
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ public class MyNestedType
+ {
+ }
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ public class MyNestedType
+ {
+ - public void MyMethod() { }
+ }
+ }
+ }
+ """);
+ }
+
+ #endregion
+
+ #region Exclusions
+
+ [Fact]
+ public void TestExcludeAddedType()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ public struct MyStruct
+ {
+ }
+ }
+ """,
+ expectedCode: "",
+ hideImplicitDefaultConstructors: true,
+ apisToExclude: ["T:MyNamespace.MyStruct"]);
+ }
+
+ [Fact]
+ public void TestExcludeModifiedType()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ public struct MyStruct1
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ }
+ public struct MyStruct2
+ {
+ }
+ }
+ """,
+ expectedCode: "",
+ hideImplicitDefaultConstructors: true,
+ apisToExclude: ["T:MyNamespace.MyStruct1", "T:MyNamespace.MyStruct2"]);
+ }
+
+ [Fact]
+ public void TestExcludeRemovedType()
+ {
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public struct MyStruct
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ }
+ """,
+ expectedCode: "", // The removal is not shown
+ hideImplicitDefaultConstructors: true,
+ apisToExclude: ["T:MyNamespace.MyStruct"]);
+ }
+
+ #endregion
+
+ #region General
+
+ [Fact]
+ public void TestTypeKindChange()
+ {
+ // Name remains the same (as well as DocID), but the kind changes
+ RunTest(beforeCode: """
+ namespace MyNamespace
+ {
+ public struct MyType
+ {
+ }
+ }
+ """,
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyType
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ namespace MyNamespace
+ {
+ - public struct MyType
+ - {
+ - }
+ + public class MyType
+ + {
+ + public MyType() { }
+ + }
+ }
+ """);
+ }
+
+ [Fact]
+ public void TestShowPartial()
+ {
+ RunTest(beforeCode: "",
+ afterCode: """
+ namespace MyNamespace
+ {
+ public class MyClass
+ {
+ public class MySubClass
+ {
+ }
+ }
+ public struct MyStruct
+ {
+ }
+ }
+ """,
+ expectedCode: """
+ + namespace MyNamespace
+ + {
+ + public partial class MyClass
+ + {
+ + public MyClass() { }
+ + public partial class MySubClass
+ + {
+ + public MySubClass() { }
+ + }
+ + }
+ + public partial struct MyStruct
+ + {
+ + }
+ + }
+ """,
+ addPartialModifier: true);
+ }
+
+ #endregion
+}
diff --git a/test/Microsoft.DotNet.ApiDiff.Tests/Microsoft.DotNet.ApiDiff.Tests.csproj b/test/Microsoft.DotNet.ApiDiff.Tests/Microsoft.DotNet.ApiDiff.Tests.csproj
new file mode 100644
index 000000000000..cbbb244af138
--- /dev/null
+++ b/test/Microsoft.DotNet.ApiDiff.Tests/Microsoft.DotNet.ApiDiff.Tests.csproj
@@ -0,0 +1,25 @@
+
+
+
+ $(ToolsetTargetFramework)
+ Exe
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Microsoft.DotNet.GenAPI.Tests/TestAssemblyLoaderFactory.cs b/test/Microsoft.DotNet.GenAPI.Tests/TestAssemblyLoaderFactory.cs
index 9bd062acf33a..10bb1a15a986 100644
--- a/test/Microsoft.DotNet.GenAPI.Tests/TestAssemblyLoaderFactory.cs
+++ b/test/Microsoft.DotNet.GenAPI.Tests/TestAssemblyLoaderFactory.cs
@@ -11,7 +11,7 @@ namespace Microsoft.DotNet.GenAPI.Tests;
public class TestAssemblyLoaderFactory
{
- public static (IAssemblySymbolLoader, Dictionary) CreateFromTexts(ILog log, (string, string)[] assemblyTexts, IEnumerable>? diagnosticOptions = null, bool respectInternals = false, bool allowUnsafe = false)
+ public static (IAssemblySymbolLoader, Dictionary) CreateFromTexts(ILog log, (string, string)[] assemblyTexts, bool respectInternals = false, bool allowUnsafe = false, IEnumerable>? diagnosticOptions = null)
{
if (assemblyTexts.Length == 0)
{
@@ -26,10 +26,11 @@ public static (IAssemblySymbolLoader, Dictionary) Creat
Dictionary assemblySymbols = new();
foreach ((string assemblyName, string assemblyText) in assemblyTexts)
{
+ string actualAssemblyName = assemblyName.Replace(".dll", string.Empty);
using Stream assemblyStream = SymbolFactory.EmitAssemblyStreamFromSyntax(assemblyText, diagnosticOptions, enableNullable: true, allowUnsafe: allowUnsafe, assemblyName: assemblyName);
- if (loader.LoadAssembly(assemblyName, assemblyStream) is IAssemblySymbol assemblySymbol)
+ if (loader.LoadAssembly(actualAssemblyName, assemblyStream) is IAssemblySymbol assemblySymbol)
{
- assemblySymbols.Add(assemblyName, assemblySymbol);
+ assemblySymbols.Add(actualAssemblyName, assemblySymbol);
}
}