diff --git a/AyCode.Core.Tests/Serialization/AcBinarySerializerChainReferenceTests.cs b/AyCode.Core.Tests/Serialization/AcBinarySerializerChainReferenceTests.cs
new file mode 100644
index 0000000..c86e5f3
--- /dev/null
+++ b/AyCode.Core.Tests/Serialization/AcBinarySerializerChainReferenceTests.cs
@@ -0,0 +1,233 @@
+using AyCode.Core.Extensions;
+using AyCode.Core.Tests.TestModels;
+
+namespace AyCode.Core.Tests.Serialization;
+
+///
+/// Tests for Chain API reference preservation with IId objects.
+/// This is the critical feature for DevExpress DXGrid GridCustomDataSource scenario.
+///
+[TestClass]
+public class AcBinarySerializerChainReferenceTests
+{
+ ///
+ /// CRITICAL TEST: DevExpress DXGrid scenario with Chain API.
+ /// Server returns List<Item> for grid display, but we also have internal cache List<Item>.
+ /// When using ThenPopulate, the grid's visible items MUST be the same object references
+ /// from the cache to ensure Blazor binding works correctly.
+ ///
+ [TestMethod]
+ public void ChainPopulate_IIdObjects_PreservesReferences()
+ {
+ // Setup: Create internal cache with 5 categories
+ var internalCache = new List
+ {
+ new() { Id = 1, Name = "Category1", SortOrder = 1 },
+ new() { Id = 2, Name = "Category2", SortOrder = 2 },
+ new() { Id = 3, Name = "Category3", SortOrder = 3 },
+ new() { Id = 4, Name = "Category4", SortOrder = 4 },
+ new() { Id = 5, Name = "Category5", SortOrder = 5 }
+ };
+
+ // Server returns subset of categories (like grid pagination - page 2: items 3-5)
+ var serverData = new List
+ {
+ new() { Id = 3, Name = "Category3_Updated", SortOrder = 33 },
+ new() { Id = 4, Name = "Category4_Updated", SortOrder = 44 },
+ new() { Id = 5, Name = "Category5_Updated", SortOrder = 55 }
+ };
+
+ // Serialize server response
+ var binary = serverData.ToBinary();
+
+ // Grid's visible list (empty initially)
+ var gridVisibleList = new List();
+
+ // CRITICAL: Use Chain API to parse once, populate both cache and grid
+ using var chain = binary.BinaryToChain>();
+
+ // First: Update internal cache (will become 3 items: 3-5 updated)
+ chain.ThenPopulate(internalCache);
+
+ // Second: Populate grid's visible list
+ chain.ThenPopulate(gridVisibleList);
+
+ // VERIFICATION: After ThenPopulate, internalCache contains the 3 items from server
+ Assert.AreEqual(3, gridVisibleList.Count);
+ Assert.AreEqual(3, internalCache.Count, "ThenPopulate replaces list contents with server data");
+
+ // CRITICAL ASSERTION: Grid items MUST be same object references as cache items!
+ Assert.AreSame(internalCache[0], gridVisibleList[0],
+ "Grid item MUST be same reference as cache item for Blazor binding!");
+ Assert.AreSame(internalCache[1], gridVisibleList[1],
+ "Grid item MUST be same reference as cache item for Blazor binding!");
+ Assert.AreSame(internalCache[2], gridVisibleList[2],
+ "Grid item MUST be same reference as cache item for Blazor binding!");
+
+ // Verify data was updated correctly
+ Assert.AreEqual(3, internalCache[0].Id);
+ Assert.AreEqual("Category3_Updated", internalCache[0].Name);
+ Assert.AreEqual(33, internalCache[0].SortOrder);
+ }
+
+ ///
+ /// Test JSON Chain API reference preservation.
+ ///
+ [TestMethod]
+ public void JsonChainPopulate_IIdObjects_PreservesReferences()
+ {
+ // Setup: Create internal cache
+ var internalCache = new List
+ {
+ new() { Id = 1, Name = "Category1", SortOrder = 1 },
+ new() { Id = 2, Name = "Category2", SortOrder = 2 },
+ new() { Id = 3, Name = "Category3", SortOrder = 3 }
+ };
+
+ // Server returns subset
+ var serverData = new List
+ {
+ new() { Id = 2, Name = "Category2_Updated", SortOrder = 22 },
+ new() { Id = 3, Name = "Category3_Updated", SortOrder = 33 }
+ };
+
+ // Serialize server response
+ var json = serverData.ToJson();
+
+ // Grid's visible list
+ var gridVisibleList = new List();
+
+ // Use JSON Chain API
+ using var chain = json.JsonToChain>();
+
+ // Update internal cache (will replace with 2 items)
+ chain.ThenPopulate(internalCache);
+
+ // Populate grid's visible list
+ chain.ThenPopulate(gridVisibleList);
+
+ // VERIFICATION
+ Assert.AreEqual(2, gridVisibleList.Count);
+ Assert.AreEqual(2, internalCache.Count, "ThenPopulate replaces list contents");
+
+ // CRITICAL: Same references!
+ Assert.AreSame(internalCache[0], gridVisibleList[0]);
+ Assert.AreSame(internalCache[1], gridVisibleList[1]);
+
+ // Verify updates
+ Assert.AreEqual(2, internalCache[0].Id);
+ Assert.AreEqual("Category2_Updated", internalCache[0].Name);
+ Assert.AreEqual(22, internalCache[0].SortOrder);
+ }
+
+ ///
+ /// Test with Guid-based IId implementation.
+ ///
+ [TestMethod]
+ public void ChainPopulate_GuidIId_PreservesReferences()
+ {
+ var cache = new List
+ {
+ new() { Id = Guid.NewGuid(), Code = "ORD-001", Count = 10 },
+ new() { Id = Guid.NewGuid(), Code = "ORD-002", Count = 20 }
+ };
+
+ var id1 = cache[0].Id;
+ var id2 = cache[1].Id;
+
+ var serverData = new List
+ {
+ new() { Id = id1, Code = "ORD-001-UPDATED", Count = 11 },
+ new() { Id = id2, Code = "ORD-002-UPDATED", Count = 22 }
+ };
+
+ var binary = serverData.ToBinary();
+ var gridList = new List();
+
+ using var chain = binary.BinaryToChain>();
+
+ chain.ThenPopulate(cache);
+ chain.ThenPopulate(gridList);
+
+ Assert.AreEqual(2, gridList.Count);
+ Assert.AreSame(cache[0], gridList[0], "Guid-based IId should also preserve references");
+ Assert.AreSame(cache[1], gridList[1]);
+ Assert.AreEqual("ORD-001-UPDATED", cache[0].Code);
+ }
+
+ ///
+ /// Test multiple chain operations with different subsets.
+ ///
+ [TestMethod]
+ public void ChainPopulate_MultipleSubsets_PreservesReferencesAcrossAll()
+ {
+ // Large internal cache
+ var internalCache = Enumerable.Range(1, 10)
+ .Select(i => new SharedCategory { Id = i, Name = $"Category{i}", SortOrder = i * 10 })
+ .ToList();
+
+ // Server returns items 3-7
+ var serverData = Enumerable.Range(3, 5)
+ .Select(i => new SharedCategory { Id = i, Name = $"Category{i}_Updated", SortOrder = i * 11 })
+ .ToList();
+
+ var binary = serverData.ToBinary();
+
+ // Three different grid pages/views
+ var gridPage1 = new List();
+ var gridPage2 = new List();
+ var gridPage3 = new List();
+
+ using var chain = binary.BinaryToChain>();
+
+ // Update cache first
+ chain.ThenPopulate(internalCache);
+
+ // Populate different grid pages
+ chain.ThenPopulate(gridPage1);
+ chain.ThenPopulate(gridPage2);
+ chain.ThenPopulate(gridPage3);
+
+ // All pages should have same references
+ Assert.AreEqual(5, gridPage1.Count);
+ Assert.AreEqual(5, gridPage2.Count);
+ Assert.AreEqual(5, gridPage3.Count);
+
+ // All three pages point to the SAME objects
+ for (int i = 0; i < 5; i++)
+ {
+ Assert.AreSame(gridPage1[i], gridPage2[i], $"Page1 and Page2 item {i} must be same reference");
+ Assert.AreSame(gridPage2[i], gridPage3[i], $"Page2 and Page3 item {i} must be same reference");
+ Assert.AreSame(internalCache[i], gridPage1[i], $"Cache and Page1 item {i} must be same reference");
+ }
+ }
+
+ ///
+ /// Simple debug test to verify chain reference tracking works.
+ ///
+ [TestMethod]
+ public void ChainPopulate_SimpleCase_Works()
+ {
+ var list1 = new List();
+ var list2 = new List();
+
+ var serverData = new List
+ {
+ new() { Id = 1, Name = "Cat1", SortOrder = 10 }
+ };
+
+ var binary = serverData.ToBinary();
+
+ using var chain = binary.BinaryToChain>();
+
+ // First populate
+ chain.ThenPopulate(list1);
+ Assert.AreEqual(1, list1.Count);
+ Assert.AreEqual(1, list1[0].Id);
+
+ // Second populate - should reuse same object
+ chain.ThenPopulate(list2);
+ Assert.AreEqual(1, list2.Count);
+ Assert.AreSame(list1[0], list2[0], "Should be same object reference!");
+ }
+}
diff --git a/AyCode.Core.Tests/Serialization/AcBinarySerializerChainTests.cs b/AyCode.Core.Tests/Serialization/AcBinarySerializerChainTests.cs
new file mode 100644
index 0000000..0547744
--- /dev/null
+++ b/AyCode.Core.Tests/Serialization/AcBinarySerializerChainTests.cs
@@ -0,0 +1,347 @@
+using AyCode.Core.Extensions;
+using AyCode.Core.Serializers.Binaries;
+using AyCode.Core.Tests.TestModels;
+using static AyCode.Core.Tests.TestModels.AcSerializerModels;
+
+namespace AyCode.Core.Tests.Serialization;
+
+///
+/// Tests for Binary Chain API (CreateDeserializeChain and CreatePopulateChain).
+///
+[TestClass]
+public class AcBinarySerializerChainTests
+{
+ [TestMethod]
+ public void DeserializeChain_SingleDeserialization_WorksCorrectly()
+ {
+ // Arrange
+ var original = new TestSimpleClass { Id = 42, Name = "John", Value = 3.14, IsActive = true };
+ var binary = original.ToBinary();
+
+ // Act
+ using var chain = binary.BinaryToChain();
+ var result = chain.Value;
+
+ // Assert
+ Assert.IsNotNull(result);
+ Assert.AreEqual(42, result.Id);
+ Assert.AreEqual("John", result.Name);
+ Assert.AreEqual(3.14, result.Value);
+ Assert.AreEqual(true, result.IsActive);
+ }
+
+ [TestMethod]
+ public void DeserializeChain_MultipleDeserializations_ParsesOnlyOnce()
+ {
+ // Arrange
+ var original = new TestSimpleClass { Id = 100, Name = "Test", Value = 99.9, IsActive = false };
+ var binary = original.ToBinary();
+
+ // Act
+ using var chain = binary.BinaryToChain();
+ var result1 = chain.Value;
+ var result2 = chain.ThenDeserialize();
+ var result3 = chain.ThenDeserialize();
+
+ // Assert - All three deserializations should work
+ Assert.IsNotNull(result1);
+ Assert.AreEqual(100, result1.Id);
+
+ Assert.IsNotNull(result2);
+ Assert.AreEqual(100, result2.Id);
+ Assert.AreEqual("Test", result2.Name);
+
+ Assert.IsNotNull(result3);
+ Assert.AreEqual(99.9, result3.Value);
+ Assert.AreEqual(false, result3.IsActive);
+ }
+
+ [TestMethod]
+ public void DeserializeChain_NestedObjects_WorksCorrectly()
+ {
+ // Arrange
+ var original = new TestNestedClass
+ {
+ Id = 1,
+ Name = "Parent",
+ Child = new TestSimpleClass { Id = 2, Name = "Child", Value = 10.5 }
+ };
+ var binary = original.ToBinary();
+
+ // Act
+ using var chain = binary.BinaryToChain();
+ var result1 = chain.Value;
+ var result2 = chain.ThenDeserialize();
+
+ // Assert
+ Assert.IsNotNull(result1);
+ Assert.AreEqual("Parent", result1.Name);
+ Assert.IsNotNull(result1.Child);
+ Assert.AreEqual("Child", result1.Child.Name);
+
+ Assert.IsNotNull(result2);
+ Assert.AreEqual(1, result2.Id);
+ Assert.IsNotNull(result2.Child);
+ Assert.AreEqual(10.5, result2.Child.Value);
+ }
+
+ [TestMethod]
+ public void DeserializeChain_WithList_WorksCorrectly()
+ {
+ // Arrange
+ var original = new TestClassWithList
+ {
+ Id = 5,
+ Items = new List { "Apple", "Banana", "Cherry" }
+ };
+ var binary = original.ToBinary();
+
+ // Act
+ using var chain = binary.BinaryToChain();
+ var result = chain.Value;
+
+ // Assert
+ Assert.IsNotNull(result);
+ Assert.AreEqual(5, result.Id);
+ Assert.AreEqual(3, result.Items.Count);
+ Assert.AreEqual("Apple", result.Items[0]);
+ Assert.AreEqual("Banana", result.Items[1]);
+ Assert.AreEqual("Cherry", result.Items[2]);
+ }
+
+ [TestMethod]
+ public void PopulateChain_SinglePopulate_UpdatesObject()
+ {
+ // Arrange
+ var original = new TestSimpleClass { Id = 99, Name = "Updated", Value = 123.45, IsActive = true };
+ var binary = original.ToBinary();
+ var target = new TestSimpleClass { Id = 1, Name = "Old", Value = 0, IsActive = false };
+
+ // Act
+ using var chain = binary.BinaryToChain(target);
+
+ // Assert
+ Assert.AreEqual(99, target.Id);
+ Assert.AreEqual("Updated", target.Name);
+ Assert.AreEqual(123.45, target.Value);
+ Assert.AreEqual(true, target.IsActive);
+ }
+
+ [TestMethod]
+ public void PopulateChain_MultiplePopulates_UpdatesAllObjects()
+ {
+ // Arrange
+ var original = new TestSimpleClass { Id = 100, Name = "Shared", Value = 50.0 };
+ var binary = original.ToBinary();
+ var target1 = new TestSimpleClass { Id = 1, Name = "Old1" };
+ var target2 = new TestSimpleClass { Id = 2, Name = "Old2" };
+ var target3 = new TestSimpleClass { Id = 3, Name = "Old3" };
+
+ // Act
+ using var chain = binary.BinaryToChain(target1);
+ chain.ThenPopulate(target2);
+ chain.ThenPopulate(target3);
+
+ // Assert
+ Assert.AreEqual(100, target1.Id);
+ Assert.AreEqual("Shared", target1.Name);
+ Assert.AreEqual(50.0, target1.Value);
+
+ Assert.AreEqual(100, target2.Id);
+ Assert.AreEqual("Shared", target2.Name);
+ Assert.AreEqual(50.0, target2.Value);
+
+ Assert.AreEqual(100, target3.Id);
+ Assert.AreEqual("Shared", target3.Name);
+ Assert.AreEqual(50.0, target3.Value);
+ }
+
+ [TestMethod]
+ public void PopulateChain_NestedObjects_MergesCorrectly()
+ {
+ // Arrange
+ var original = new TestNestedClass
+ {
+ Id = 10,
+ Name = "UpdatedParent",
+ Child = new TestSimpleClass { Id = 20, Name = "UpdatedChild", Value = 99.9 }
+ };
+ var binary = original.ToBinary();
+ var target = new TestNestedClass
+ {
+ Id = 1,
+ Name = "OldParent",
+ Child = new TestSimpleClass { Id = 2, Name = "OldChild", Value = 1.0 }
+ };
+
+ // Act
+ using var chain = binary.BinaryToChain(target);
+
+ // Assert
+ Assert.AreEqual(10, target.Id);
+ Assert.AreEqual("UpdatedParent", target.Name);
+ Assert.IsNotNull(target.Child);
+ Assert.AreEqual(20, target.Child.Id);
+ Assert.AreEqual("UpdatedChild", target.Child.Name);
+ Assert.AreEqual(99.9, target.Child.Value);
+ }
+
+ [TestMethod]
+ public void PopulateChain_WithList_UpdatesCollection()
+ {
+ // Arrange
+ var original = new TestClassWithList
+ {
+ Id = 7,
+ Items = new List { "New1", "New2", "New3" }
+ };
+ var binary = original.ToBinary();
+ var target = new TestClassWithList
+ {
+ Id = 1,
+ Items = new List { "Old1" }
+ };
+
+ // Act
+ using var chain = binary.BinaryToChain(target);
+
+ // Assert
+ Assert.AreEqual(7, target.Id);
+ Assert.AreEqual(3, target.Items.Count);
+ Assert.AreEqual("New1", target.Items[0]);
+ Assert.AreEqual("New2", target.Items[1]);
+ Assert.AreEqual("New3", target.Items[2]);
+ }
+
+ [TestMethod]
+ public void DeserializeChain_EmptyBinary_ReturnsEmpty()
+ {
+ // Arrange
+ var binary = Array.Empty();
+
+ // Act
+ using var chain = binary.BinaryToChain();
+
+ // Assert
+ Assert.IsNull(chain.Value);
+ }
+
+ [TestMethod]
+ public void PopulateChain_EmptyBinary_DoesNothing()
+ {
+ // Arrange
+ var binary = Array.Empty();
+ var target = new TestSimpleClass { Id = 42, Name = "Original" };
+
+ // Act
+ using var chain = binary.BinaryToChain(target);
+
+ // Assert - Should remain unchanged
+ Assert.AreEqual(42, target.Id);
+ Assert.AreEqual("Original", target.Name);
+ }
+
+ [TestMethod]
+ public void DeserializeChain_Dispose_CannotReuseAfterDispose()
+ {
+ // Arrange
+ var original = new TestSimpleClass { Id = 1, Name = "Test" };
+ var binary = original.ToBinary();
+ var chain = binary.BinaryToChain();
+ var value = chain.Value;
+
+ // Act
+ chain.Dispose();
+
+ // Assert
+ Assert.IsNotNull(value); // Value from before dispose should still exist
+ _ = Assert.ThrowsExactly(() => chain.ThenDeserialize());
+ }
+
+ [TestMethod]
+ public void PopulateChain_Dispose_CannotReuseAfterDispose()
+ {
+ // Arrange
+ var original = new TestSimpleClass { Id = 1, Name = "Test" };
+ var binary = original.ToBinary();
+ var target1 = new TestSimpleClass();
+ var chain = binary.BinaryToChain(target1);
+
+ // Act
+ chain.Dispose();
+
+ // Assert
+ var target2 = new TestSimpleClass();
+ _ = Assert.ThrowsExactly(() => chain.ThenPopulate(target2));
+ }
+
+ [TestMethod]
+ public void DeserializeChain_WithOptions_UsesCorrectOptions()
+ {
+ // Arrange
+ var original = new TestSimpleClass { Id = 1, Name = "Test", Value = 10.5 };
+ var binary = original.ToBinary();
+ var options = new AcBinarySerializerOptions();
+
+ // Act
+ using var chain = binary.BinaryToChain(options);
+ var result = chain.Value;
+
+ // Assert
+ Assert.IsNotNull(result);
+ Assert.AreEqual(1, result.Id);
+ Assert.AreEqual("Test", result.Name);
+ }
+
+ [TestMethod]
+ public void PopulateChain_WithOptions_UsesCorrectOptions()
+ {
+ // Arrange
+ var original = new TestSimpleClass { Id = 99, Name = "Updated" };
+ var binary = original.ToBinary();
+ var target = new TestSimpleClass { Id = 1, Name = "Old" };
+ var options = new AcBinarySerializerOptions();
+
+ // Act
+ using var chain = binary.BinaryToChain(target, options);
+
+ // Assert
+ Assert.AreEqual(99, target.Id);
+ Assert.AreEqual("Updated", target.Name);
+ }
+
+ [TestMethod]
+ public void DeserializeChain_ReadOnlyMemory_WorksCorrectly()
+ {
+ // Arrange
+ var original = new TestSimpleClass { Id = 42, Name = "Memory Test" };
+ var binary = original.ToBinary();
+ ReadOnlyMemory memory = binary;
+
+ // Act
+ using var chain = memory.BinaryToChain();
+ var result = chain.Value;
+
+ // Assert
+ Assert.IsNotNull(result);
+ Assert.AreEqual(42, result.Id);
+ Assert.AreEqual("Memory Test", result.Name);
+ }
+
+ [TestMethod]
+ public void PopulateChain_ReadOnlyMemory_WorksCorrectly()
+ {
+ // Arrange
+ var original = new TestSimpleClass { Id = 99, Name = "Memory Update" };
+ var binary = original.ToBinary();
+ ReadOnlyMemory memory = binary;
+ var target = new TestSimpleClass { Id = 1, Name = "Old" };
+
+ // Act
+ using var chain = memory.BinaryToChain(target);
+
+ // Assert
+ Assert.AreEqual(99, target.Id);
+ Assert.AreEqual("Memory Update", target.Name);
+ }
+}
diff --git a/AyCode.Core.Tests/Serialization/ChainReferenceDebugTest.cs b/AyCode.Core.Tests/Serialization/ChainReferenceDebugTest.cs
new file mode 100644
index 0000000..40d0084
--- /dev/null
+++ b/AyCode.Core.Tests/Serialization/ChainReferenceDebugTest.cs
@@ -0,0 +1,61 @@
+using AyCode.Core.Extensions;
+using AyCode.Core.Serializers;
+using AyCode.Core.Tests.TestModels;
+
+namespace AyCode.Core.Tests.Serialization;
+
+[TestClass]
+public class ChainReferenceDebugTest
+{
+ [TestMethod]
+ public void DebugChainReferences_DirectTest()
+ {
+ // Test ChainReferenceTracker directly
+ var tracker = new AcSerializerCommon.ChainReferenceTracker();
+
+ var category = new SharedCategory { Id = 100, Name = "TestCategory" };
+
+ // Register using reflection (like ThenPopulate does)
+ tracker.TryRegisterIIdObject(category);
+
+ // Try to retrieve using boxed int (like MergeIIdCollection does)
+ object id = 100; // Boxed int
+ var found = tracker.TryGetObject(id, out var retrievedCategory);
+
+ Console.WriteLine($"Found: {found}");
+ Console.WriteLine($"Same reference: {ReferenceEquals(category, retrievedCategory)}");
+
+ Assert.IsTrue(found, "Should find the category by ID");
+ Assert.AreSame(category, retrievedCategory, "Should be same object reference");
+ }
+
+ [TestMethod]
+ public void DebugSimpleChainPopulate()
+ {
+ var list1 = new List();
+ var list2 = new List();
+
+ var serverData = new List
+ {
+ new() { Id = 1, Name = "Cat1", SortOrder = 10 }
+ };
+
+ var binary = serverData.ToBinary();
+
+ using var chain = binary.BinaryToChain>();
+
+ // First populate
+ chain.ThenPopulate(list1);
+ Console.WriteLine($"List1 count: {list1.Count}, ID: {list1[0].Id}, Name: {list1[0].Name}");
+
+ // Second populate
+ chain.ThenPopulate(list2);
+ Console.WriteLine($"List2 count: {list2.Count}, ID: {list2[0].Id}, Name: {list2[0].Name}");
+
+ // Check if same reference
+ Console.WriteLine($"Same reference: {ReferenceEquals(list1[0], list2[0])}");
+ Console.WriteLine($"List1[0] hash: {list1[0].GetHashCode()}, List2[0] hash: {list2[0].GetHashCode()}");
+
+ Assert.AreSame(list1[0], list2[0], "Should be same object reference!");
+ }
+}
diff --git a/AyCode.Core/Extensions/SerializeObjectExtensions.cs b/AyCode.Core/Extensions/SerializeObjectExtensions.cs
index 72008ef..962875d 100644
--- a/AyCode.Core/Extensions/SerializeObjectExtensions.cs
+++ b/AyCode.Core/Extensions/SerializeObjectExtensions.cs
@@ -5,12 +5,13 @@ using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text;
using AyCode.Core.Interfaces;
+using AyCode.Core.Serializers;
using AyCode.Core.Serializers.Binaries;
using AyCode.Core.Serializers.Jsons;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using static AyCode.Core.Helpers.JsonUtilities;
-using ReferenceEqualityComparer = AyCode.Core.Serializers.Jsons.ReferenceEqualityComparer;
+using static AyCode.Core.Serializers.Binaries.AcBinaryDeserializer;
namespace AyCode.Core.Extensions;
@@ -74,7 +75,7 @@ public class HybridReferenceResolver : IReferenceResolver
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private Dictionary