diff --git a/Tests/NFUnitTestGC/NFUnitTestGC.nfproj b/Tests/NFUnitTestGC/NFUnitTestGC.nfproj
new file mode 100644
index 00000000..31f73663
--- /dev/null
+++ b/Tests/NFUnitTestGC/NFUnitTestGC.nfproj
@@ -0,0 +1,49 @@
+
+
+
+ $(MSBuildExtensionsPath)\nanoFramework\v1.0\
+
+
+
+
+
+
+ Debug
+ AnyCPU
+ {11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 768be3b6-41c6-4dfb-8a2d-443b2113f5ad
+ Library
+ Properties
+ 512
+ NFUnitTestGC
+ NFUnitTest
+ False
+ true
+ UnitTest
+ v1.0
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\..\packages\nanoFramework.CoreLibrary.1.14.2\lib\mscorlib.dll
+
+
+ ..\..\packages\nanoFramework.TestFramework.2.1.85\lib\nanoFramework.TestFramework.dll
+
+
+ ..\..\packages\nanoFramework.TestFramework.2.1.85\lib\nanoFramework.UnitTestLauncher.exe
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Tests/NFUnitTestGC/Properties/AssemblyInfo.cs b/Tests/NFUnitTestGC/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..a3735af6
--- /dev/null
+++ b/Tests/NFUnitTestGC/Properties/AssemblyInfo.cs
@@ -0,0 +1,31 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyCopyright("Copyright (c) 2021 nanoFramework contributors")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Tests/NFUnitTestGC/TestGC.cs b/Tests/NFUnitTestGC/TestGC.cs
new file mode 100644
index 00000000..0ea02bba
--- /dev/null
+++ b/Tests/NFUnitTestGC/TestGC.cs
@@ -0,0 +1,48 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// Portions Copyright (c) Microsoft Corporation. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+
+
+using nanoFramework.TestFramework;
+using System;
+
+namespace NFUnitTestGC
+{
+ [TestClass]
+ public class TestGC
+ {
+ [TestMethod]
+ public void TestGCStress()
+ {
+ int maxArraySize = 1024 * 32;
+ object[] arrays = new object[600];
+
+ OutputHelper.WriteLine("Starting TestGCStress");
+
+ for (int loop = 0; loop < 100; loop++)
+ {
+ OutputHelper.WriteLine($"Running iteration {loop}");
+
+ for (int i = 0; i < arrays.Length - 1;)
+ {
+ OutputHelper.WriteLine($"Alloc array of {maxArraySize} bytes @ pos {i}");
+ arrays[i++] = new byte[maxArraySize]; ;
+
+ OutputHelper.WriteLine($"Alloc array of 64 bytes @ pos {i}");
+ arrays[i++] = new byte[64];
+ }
+
+ arrays[0] = new byte[maxArraySize];
+
+ for (int i = 0; i < arrays.Length; i++)
+ {
+ arrays[i] = null;
+ }
+ }
+
+ OutputHelper.WriteLine("Completed TestGCStress");
+ }
+ }
+}
diff --git a/Tests/NFUnitTestGC/TestGCWithByteArrays.cs b/Tests/NFUnitTestGC/TestGCWithByteArrays.cs
new file mode 100644
index 00000000..579d7ca8
--- /dev/null
+++ b/Tests/NFUnitTestGC/TestGCWithByteArrays.cs
@@ -0,0 +1,89 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// Portions Copyright (c) Microsoft Corporation. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+
+using nanoFramework.TestFramework;
+using System;
+
+namespace NFUnitTestGC
+{
+ [TestClass]
+ public class TestGCWithByteArrays
+ {
+ [TestMethod]
+ public void TestCompactionForNotFixedArray()
+ {
+ OutputHelper.WriteLine("Starting TestCompactionForNotFixedArray");
+
+ for (int loop = 0; loop < 10; loop++)
+ {
+ OutputHelper.WriteLine($"Starting iteration {loop}");
+
+ // First we create byte and holes that keeps some space that could be used by compaction
+
+ // Small count so compaction does not happen
+ byte[] arrayOfArrays = new byte[10];
+
+ RunAllocations(arrayOfArrays);
+
+ // This is the array that we expect to move in during compaction.
+ byte[] testNativeBuffer = new byte[100];
+
+ // Fill it, so it is not optimized out
+ Random random = new();
+ var baseValue = random.Next(2);
+
+ for (int i = 0; i < testNativeBuffer.Length; i++)
+ {
+ testNativeBuffer[i] = (byte)(i * baseValue);
+ }
+
+ // trigger compaction
+ InitiateCompaction();
+
+ int index = 0;
+
+ // Check that array content is not corrupted
+ foreach (var item in testNativeBuffer)
+ {
+ Assert.AreEqual(index * baseValue, item, $"Array content comparison failed at position {index}. Expecting {(index * baseValue)}, found {item}");
+ index++;
+ }
+
+ OutputHelper.WriteLine("No corruption detected in array");
+ }
+
+ OutputHelper.WriteLine("Completed TestCompactionForNotFixedArray");
+ }
+
+ void RunAllocations(byte[] arrObj)
+ {
+ for (int i = 1; i < arrObj.Length; i++)
+ {
+ // Creates referenced byte, which stays in memory until InitiateCompaction exits
+ arrObj[i] = new byte();
+
+ // Tries to create larger object that would be later hole .
+ // This object could be garbage collected on each "i" cycle.
+ byte[] arr = new byte[50 * i];
+
+ // Creates some usage for arr, so it is not optimized out.
+ arr[0] = 1;
+ arr[1] = 2;
+
+ OutputHelper.WriteLine($"On Cycle {i:D3} Array of {arr[1]} was allocated");
+ }
+ }
+
+ // This method causes compaction to occur.
+ // It is not so trivial as it need to fragment heap with referenced byte array.
+ void InitiateCompaction()
+ {
+ // large count, so compaction happens during call to RunAllocations
+ byte[] arrayOfArrays = new byte[1500];
+ RunAllocations(arrayOfArrays);
+ }
+ }
+}
diff --git a/Tests/NFUnitTestGC/TestGCWithDateTimeArrays.cs b/Tests/NFUnitTestGC/TestGCWithDateTimeArrays.cs
new file mode 100644
index 00000000..e78cd0c5
--- /dev/null
+++ b/Tests/NFUnitTestGC/TestGCWithDateTimeArrays.cs
@@ -0,0 +1,214 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// Portions Copyright (c) Microsoft Corporation. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+
+using nanoFramework.TestFramework;
+using System;
+
+namespace NFUnitTestGC
+{
+ [TestClass]
+ public class TestGCWithDateTimeArrays
+ {
+ [TestMethod]
+ public void TestCompactionForNotFixedDateTimeArray()
+ {
+ OutputHelper.WriteLine("Starting TestCompactionForNotFixedDateTimeArray");
+
+ for (int loop = 0; loop < 10; loop++)
+ {
+ OutputHelper.WriteLine($"Starting iteration {loop}");
+ // First we create objects and holes that keeps some space that could be used by compaction.
+ // Small count so compaction does not happen.
+ HolderForDateTime[] arrayOfArrays = new HolderForDateTime[10];
+ RunDateTimeAllocations(arrayOfArrays);
+
+ // This is the array that we expect to move in during compaction.
+ HolderForDateTime[] testNativeBuffer = new HolderForDateTime[100];
+ // Fill it, so it is not optimized out
+ for (int i = 0; i < testNativeBuffer.Length; i++)
+ {
+ testNativeBuffer[i] = new HolderForDateTime(GetRandomDateTime());
+ }
+
+ OutputHelper.WriteLine("Large HolderForDateTime array created");
+ OutputHelper.WriteLine("Forcing compaction to occurr");
+
+ // Causes compaction
+ InitiateDateTimeCompaction();
+
+ OutputHelper.WriteLine("Compaction occurred");
+ OutputHelper.WriteLine("Checking arrays for corrupted data...");
+
+ int index = 0;
+
+ // Check that array content is not corrupted
+ foreach (HolderForDateTime holder in testNativeBuffer)
+ {
+ Assert.AreEqual(holder.StoredTicks, holder.DtValue.Ticks, $"Array content comparison failed at position {index}. Expecting {holder.StoredTicks}, found {holder.DtValue.Ticks}");
+ index++;
+ }
+
+ OutputHelper.WriteLine("No corruption detected in array");
+ }
+
+ OutputHelper.WriteLine("Completed TestCompactionForNotFixedArray");
+ }
+
+ // This function cause compaction to occur.
+ // It is not so trivial as it need to fragment heap with referenced objects.
+ void InitiateDateTimeCompaction()
+ {
+ // Large count, so compaction happens during RunAllocations.
+ HolderForDateTime[] arrayOfArrays = new HolderForDateTime[500];
+ RunDateTimeAllocations(arrayOfArrays);
+ }
+
+ private void RunDateTimeAllocations(HolderForDateTime[] arrObj)
+ {
+ for (int i = 1; i < arrObj.Length; i++)
+ {
+ // Creates referenced object, which stays in memory until InitiateCompaction exits
+ arrObj[i] = new HolderForDateTime(DateTime_btwn_1801_And_2801());
+
+ // Tries to create larger object that would be later hole
+ // This object could be garbage collected on each "i" cycle
+ HolderForDateTime[] arr = new HolderForDateTime[50 * i];
+
+ // Creates some usage for array elements, so it is not optimized out
+ arr[0] = new HolderForDateTime(DateTime.MinValue);
+ arr[1] = new HolderForDateTime(DateTime.MaxValue);
+
+ Console.WriteLine($"On Cycle {i:D3} DateTime holder allocated");
+ }
+ }
+
+ private class HolderForDateTime
+ {
+ public long StoredTicks { get; }
+ public DateTime DtValue { get; }
+
+ public HolderForDateTime(DateTime dt)
+ {
+ StoredTicks = dt.Ticks;
+ DtValue = dt;
+ }
+ }
+
+ static int year, month, day, hour, minute, second, millisec;
+ static long ticks;
+
+ static int[] leapYear = new int[] {2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, 2044, 2048,
+ 2052, 2056, 2060, 2064, 2068, 2072, 2076, 2080, 2084, 2088, 2092, 2096};
+
+ // computing our constants here, as these are not accessible
+ // equivalent to DateTime.TicksPerSecond
+ const int _TicksPerSecond = 10000 * 1000;
+
+ private DateTime[] Get_ArrayOfRandomDateTimes()
+ {
+ OutputHelper.WriteLine(DateTime_btwn_1801_And_2801().ToString());
+ OutputHelper.WriteLine(GetLeapYearDateTime().ToString());
+ DateTime[] _dateTimeArr = new DateTime[] {DateTime.UtcNow,
+ DateTime_btwn_1801_And_2801(), DateTime_btwn_1801_And_2801(), DateTime_btwn_1801_And_2801(),
+ GetLeapYearDateTime(), GetLeapYearDateTime() , GetLeapYearDateTime(),
+ DateTime_btwn_1801_And_2801(), DateTime_btwn_1801_And_2801(), DateTime_btwn_1801_And_2801(),
+ GetLeapYearDateTime(), GetLeapYearDateTime(), GetLeapYearDateTime()};
+
+ return _dateTimeArr;
+ }
+
+ private DateTime DateTime_btwn_1801_And_2801()
+ {
+ //Generates random DateTime b/n 1000 and 9000
+ Random random = new Random();
+ year = random.Next(999) + 1801;
+ month = random.Next(12) + 1;
+ if (month == 2 && IsLeapYear(year))
+ day = random.Next(29) + 1;
+ else if (month == 2 && (!IsLeapYear(year)))
+ day = random.Next(28) + 1;
+ else if (((month <= 7) && ((month + 1) % 2 == 0)) ||
+ ((month > 7) && ((month % 2) == 0)))
+ day = random.Next(31) + 1;
+ else
+ day = random.Next(30) + 1;
+ hour = random.Next(24);
+ minute = random.Next(60);
+ second = random.Next(60);
+ millisec = random.Next(1000);
+
+ return new DateTime(year, month, day, hour, minute, second, millisec);
+ }
+
+ private DateTime GetRandomDateTime()
+ {
+ //Generates random DateTime
+ Random random = new Random();
+ year = random.Next(1399) + 1601;
+ month = random.Next(12) + 1;
+
+ if (month == 2 && IsLeapYear(year))
+ {
+ day = random.Next(29) + 1;
+ }
+ else if (month == 2 && (!IsLeapYear(year)))
+ {
+ day = random.Next(28) + 1;
+ }
+ else if (((month <= 7) && ((month + 1) % 2 == 0))
+ || ((month > 7) && ((month % 2) == 0)))
+ {
+ day = random.Next(31) + 1;
+ }
+ else
+ {
+ day = random.Next(30) + 1;
+ }
+
+ hour = random.Next(24);
+ minute = random.Next(60);
+ second = random.Next(60);
+ millisec = random.Next(1000);
+
+ DateTime dt = new(year, month, day, hour, minute, second, millisec);
+
+ // fill in random ticks value so we can have a fully filled ticks value
+ ticks = dt.Ticks + random.Next(1000_000);
+
+ dt = new(ticks);
+
+ // need to update minutesm, millisec and second because it could have changed with new ticks value
+ millisec = dt.Millisecond;
+ second = dt.Second;
+ minute = dt.Minute;
+
+ return dt;
+ }
+
+ private DateTime GetLeapYearDateTime()
+ {
+ Random random = new Random();
+ year = leapYear[random.Next(leapYear.Length)];
+ month = random.Next(12) + 1;
+ day = random.Next(29) + 1;
+ hour = random.Next(24);
+ minute = random.Next(60);
+ second = random.Next(60);
+ millisec = random.Next(1000);
+ OutputHelper.WriteLine($"{year} {month} {day} {hour} {minute} {second} {millisec}");
+ return new DateTime(year, month, day, hour, minute, second, millisec);
+ }
+
+ private bool IsLeapYear(int yr)
+ {
+ if ((yr % 400 == 0) || ((yr % 100 != 0) && (yr % 4 == 0)))
+ return true;
+ else
+ return false;
+ }
+
+ }
+}
diff --git a/Tests/NFUnitTestGC/TestGCWithObjectArrays.cs b/Tests/NFUnitTestGC/TestGCWithObjectArrays.cs
new file mode 100644
index 00000000..df0b9a3d
--- /dev/null
+++ b/Tests/NFUnitTestGC/TestGCWithObjectArrays.cs
@@ -0,0 +1,89 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// Portions Copyright (c) Microsoft Corporation. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+
+using nanoFramework.TestFramework;
+using System;
+
+namespace NFUnitTestGC
+{
+ [TestClass]
+ public class TestGCWithObjectArrays
+ {
+ [TestMethod]
+ public void TestCompactionForNotFixedArray()
+ {
+ OutputHelper.WriteLine("Starting TestCompactionForNotFixedArray");
+
+ for (int loop = 0; loop < 10; loop++)
+ {
+ OutputHelper.WriteLine($"Starting iteration {loop}");
+
+ // First we create objects and holes that keeps some space that could be used by compaction
+
+ // Small count so compaction does not happen
+ object[] arrayOfArrays = new object[10];
+
+ RunAllocations(arrayOfArrays);
+
+ // This is the array that we expect to move in during compaction.
+ int[] testNativeBuffer = new int[100];
+
+ // Fill it, so it is not optimized out
+ Random random = new Random();
+ var baseValue = random.Next();
+
+ for (int i = 0; i < testNativeBuffer.Length; i++)
+ {
+ testNativeBuffer[i] = i * baseValue;
+ }
+
+ // trigger compaction
+ InitiateCompaction();
+
+ int index = 0;
+
+ // Check that array content is not corrupted
+ foreach (var item in testNativeBuffer)
+ {
+ Assert.AreEqual(index * baseValue, item, $"Array content comparison failed at position {index}. Expecting {(index * baseValue)}, found {item}");
+ index++;
+ }
+
+ OutputHelper.WriteLine("No corruption detected in array");
+ }
+
+ OutputHelper.WriteLine("Completed TestCompactionForNotFixedArray");
+ }
+
+ void RunAllocations(object[] arrObj)
+ {
+ for (int i = 1; i < arrObj.Length; i++)
+ {
+ // Creates referenced interger object, which stays in memory until InitiateCompaction exits
+ arrObj[i] = new int();
+
+ // Tries to create larger object that would be later hole .
+ // This object could be garbage collected on each "i" cycle.
+ int[] arr = new int[50 * i];
+
+ // Creates some usage for arr, so it is not optimized out.
+ arr[0] = i;
+ arr[1] = 50 * i;
+
+ OutputHelper.WriteLine($"On Cycle {i:D3} Array of {arr[1]} was allocated");
+ }
+ }
+
+ // This method causes compaction to occur.
+ // It is not so trivial as it need to fragment heap with referenced objects.
+ void InitiateCompaction()
+ {
+ // large count, so compaction happens during call to RunAllocations
+ object[] arrayOfArrays = new object[1500];
+ RunAllocations(arrayOfArrays);
+ }
+ }
+}
diff --git a/Tests/NFUnitTestGC/TestGCWithTimeSpanArrays.cs b/Tests/NFUnitTestGC/TestGCWithTimeSpanArrays.cs
new file mode 100644
index 00000000..1294deda
--- /dev/null
+++ b/Tests/NFUnitTestGC/TestGCWithTimeSpanArrays.cs
@@ -0,0 +1,109 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// Portions Copyright (c) Microsoft Corporation. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+
+using nanoFramework.TestFramework;
+using System;
+
+namespace NFUnitTestGC
+{
+ [TestClass]
+ public class TestGCWithTimeSpanArrays
+ {
+ [TestMethod]
+ public void TestCompactionForNotFixedTimeSpanArray()
+ {
+ OutputHelper.WriteLine("Starting TestCompactionForNotFixedTimeSpanArray");
+
+ for (int loop = 0; loop < 10; loop++)
+ {
+ OutputHelper.WriteLine($"Starting iteration {loop}");
+
+ // First we create objects and holes that keeps some space that could be used by compaction.
+ // Small count so compaction does not happen.
+ HolderForTimeSpan[] arrayOfArrays = new HolderForTimeSpan[10];
+ RunTimeSpanAllocations(arrayOfArrays);
+
+ // This is the array that we expect to move in during compaction.
+ HolderForTimeSpan[] testNativeBuffer = new HolderForTimeSpan[100];
+ // Fill it, so it is not optimized out
+ for (int i = 0; i < testNativeBuffer.Length; i++)
+ {
+ testNativeBuffer[i] = new HolderForTimeSpan(GetRandomTimeSpan());
+ }
+
+ OutputHelper.WriteLine("Large HolderForTimeSpan array created");
+ OutputHelper.WriteLine("Forcing compaction to occurr");
+
+ // Causes compaction
+ InitiateTimeSpanCompaction();
+
+ OutputHelper.WriteLine("Compaction occurred");
+ OutputHelper.WriteLine("Checking arrays for corrupted data...");
+
+ int index = 0;
+
+ // Check that array content is not corrupted
+ foreach (HolderForTimeSpan holder in testNativeBuffer)
+ {
+ Assert.AreEqual(holder.StoredTicks, holder.TsValue.Ticks, $"Array content comparison failed at position {index}. Expecting {holder.StoredTicks}, found {holder.TsValue.Ticks}");
+ index++;
+ }
+
+ OutputHelper.WriteLine("No corruption detected in array");
+ }
+
+ OutputHelper.WriteLine("Completed TestCompactionForNotFixedArray");
+ }
+
+ private TimeSpan GetRandomTimeSpan()
+ {
+ Random rand = new();
+
+ return TimeSpan.FromTicks(rand.Next() * 1000_000);
+ }
+
+ // This function cause compaction to occur.
+ // It is not so trivial as it need to fragment heap with referenced objects.
+ void InitiateTimeSpanCompaction()
+ {
+ // Large count, so compaction happens during RunAllocations.
+ HolderForTimeSpan[] arrayOfArrays = new HolderForTimeSpan[500];
+ RunTimeSpanAllocations(arrayOfArrays);
+ }
+
+ private void RunTimeSpanAllocations(HolderForTimeSpan[] arrObj)
+ {
+
+ for (int i = 1; i < arrObj.Length; i++)
+ {
+ // Creates referenced object, which stays in memory until InitiateCompaction exits
+ arrObj[i] = new HolderForTimeSpan(GetRandomTimeSpan());
+
+ // Tries to create larger object that would be later hole
+ // This object could be garbage collected on each "i" cycle
+ HolderForTimeSpan[] arr = new HolderForTimeSpan[50 * i];
+
+ // Creates some usage for array elements, so it is not optimized out
+ arr[0] = new HolderForTimeSpan(TimeSpan.MinValue);
+ arr[1] = new HolderForTimeSpan(TimeSpan.MaxValue);
+
+ Console.WriteLine($"On Cycle {i:D3} DateTime holder allocated");
+ }
+ }
+
+ private class HolderForTimeSpan
+ {
+ public long StoredTicks { get; }
+ public TimeSpan TsValue { get; }
+
+ public HolderForTimeSpan(TimeSpan ts)
+ {
+ StoredTicks = ts.Ticks;
+ TsValue = ts;
+ }
+ }
+ }
+}
diff --git a/Tests/NFUnitTestGC/packages.config b/Tests/NFUnitTestGC/packages.config
new file mode 100644
index 00000000..7704bd8d
--- /dev/null
+++ b/Tests/NFUnitTestGC/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/nanoFramework.CoreLibrary.sln b/nanoFramework.CoreLibrary.sln
index a2a1bbe7..9e41b209 100644
--- a/nanoFramework.CoreLibrary.sln
+++ b/nanoFramework.CoreLibrary.sln
@@ -67,6 +67,8 @@ Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "NFUnitTestRecords", "Tests\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "nanoFramework.TestAdapter", "nanoFramework.TestFramework\source\TestAdapter\nanoFramework.TestAdapter.csproj", "{6D740F0A-D435-4ACF-AD27-D702A599F229}"
EndProject
+Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "NFUnitTestGC", "Tests\NFUnitTestGC\NFUnitTestGC.nfproj", "{768BE3B6-41C6-4DFB-8A2D-443B2113F5AD}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -221,6 +223,12 @@ Global
{6D740F0A-D435-4ACF-AD27-D702A599F229}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6D740F0A-D435-4ACF-AD27-D702A599F229}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6D740F0A-D435-4ACF-AD27-D702A599F229}.Release|Any CPU.Build.0 = Release|Any CPU
+ {768BE3B6-41C6-4DFB-8A2D-443B2113F5AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {768BE3B6-41C6-4DFB-8A2D-443B2113F5AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {768BE3B6-41C6-4DFB-8A2D-443B2113F5AD}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {768BE3B6-41C6-4DFB-8A2D-443B2113F5AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {768BE3B6-41C6-4DFB-8A2D-443B2113F5AD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {768BE3B6-41C6-4DFB-8A2D-443B2113F5AD}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -250,6 +258,7 @@ Global
{55F048B5-6739-43C5-A93D-DB61DB8E912F} = {0BAE286A-5434-4F56-A9F1-41B72056170E}
{0BE498D1-CB3E-4D1E-BA4C-2C49AE30432D} = {0BAE286A-5434-4F56-A9F1-41B72056170E}
{6D740F0A-D435-4ACF-AD27-D702A599F229} = {0BAE286A-5434-4F56-A9F1-41B72056170E}
+ {768BE3B6-41C6-4DFB-8A2D-443B2113F5AD} = {0BAE286A-5434-4F56-A9F1-41B72056170E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8DE44407-9B41-4459-97D2-FCE54B1F4300}