diff --git a/Directory.Packages.props b/Directory.Packages.props
index 0ccaeaf..a187cc3 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -8,5 +8,6 @@
+
diff --git a/src/Csdsa/Algorithms/Search/Linear/LinearSSearch.IndexOf.cs b/src/Csdsa/Algorithms/Search/Linear/LinearSSearch.IndexOf.cs
new file mode 100644
index 0000000..2efb088
--- /dev/null
+++ b/src/Csdsa/Algorithms/Search/Linear/LinearSSearch.IndexOf.cs
@@ -0,0 +1,37 @@
+namespace Csdsa.Algorithms.Search.Linear;
+
+public static partial class LinearSearch
+{
+ ///
+ /// Returns the zero-based index of the first element in the sequence
+ /// that satisfies the specified predicate, or -1 if no such element exists.
+ ///
+ /// The element type of the sequence.
+ /// The sequence to search.
+ /// The predicate used to test each element.
+ ///
+ /// The zero-based index of the first matching element, or -1 if no match is found.
+ ///
+ ///
+ /// Thrown when or is .
+ ///
+ public static int IndexOf(this IEnumerable collection, Func match)
+ {
+ ArgumentNullException.ThrowIfNull(collection);
+ ArgumentNullException.ThrowIfNull(match);
+
+ int index = 0;
+
+ foreach (T item in collection)
+ {
+ if (match(item))
+ {
+ return index;
+ }
+
+ index++;
+ }
+
+ return -1;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Search/Linear/LinearSearch.AllMatch.cs b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.AllMatch.cs
new file mode 100644
index 0000000..c721612
--- /dev/null
+++ b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.AllMatch.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+
+namespace Csdsa.Algorithms.Search.Linear;
+
+public static partial class LinearSearch
+{
+ ///
+ /// Determines whether all elements in the sequence satisfy the specified predicate.
+ ///
+ /// The element type of the sequence.
+ /// The sequence to test.
+ /// The predicate used to test each element.
+ ///
+ /// if all elements satisfy ;
+ /// otherwise, .
+ ///
+ ///
+ /// Thrown when or is .
+ ///
+ public static bool AllMatch(this IEnumerable collection, Func match)
+ {
+ ArgumentNullException.ThrowIfNull(collection);
+ ArgumentNullException.ThrowIfNull(match);
+
+ foreach (T item in collection)
+ {
+ if (!match(item))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Search/Linear/LinearSearch.AnyMatch.cs b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.AnyMatch.cs
new file mode 100644
index 0000000..cd0ae66
--- /dev/null
+++ b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.AnyMatch.cs
@@ -0,0 +1,33 @@
+namespace Csdsa.Algorithms.Search.Linear;
+
+public static partial class LinearSearch
+{
+ ///
+ /// Determines whether any element in the sequence satisfies the specified predicate.
+ ///
+ /// The element type of the sequence.
+ /// The sequence to test.
+ /// The predicate used to test each element.
+ ///
+ /// if any element satisfies ;
+ /// otherwise, .
+ ///
+ ///
+ /// Thrown when or is .
+ ///
+ public static bool AnyMatch(this IEnumerable collection, Func match)
+ {
+ ArgumentNullException.ThrowIfNull(collection);
+ ArgumentNullException.ThrowIfNull(match);
+
+ foreach (T item in collection)
+ {
+ if (match(item))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Search/Linear/LinearSearch.ContainsMatch.cs b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.ContainsMatch.cs
new file mode 100644
index 0000000..22c8f04
--- /dev/null
+++ b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.ContainsMatch.cs
@@ -0,0 +1,25 @@
+namespace Csdsa.Algorithms.Search.Linear;
+
+public static partial class LinearSearch
+{
+ ///
+ /// Determines whether any element in the sequence satisfies the specified predicate.
+ ///
+ /// The element type of the sequence.
+ /// The sequence to search.
+ /// The predicate used to test each element.
+ ///
+ /// if any element satisfies ;
+ /// otherwise, .
+ ///
+ ///
+ /// Thrown when or is .
+ ///
+ public static bool ContainsMatch(this IEnumerable collection, Func match)
+ {
+ ArgumentNullException.ThrowIfNull(collection);
+ ArgumentNullException.ThrowIfNull(match);
+
+ return collection.IndexOf(match) != -1;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Search/Linear/LinearSearch.CountMatches.cs b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.CountMatches.cs
new file mode 100644
index 0000000..1bd9b04
--- /dev/null
+++ b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.CountMatches.cs
@@ -0,0 +1,32 @@
+namespace Csdsa.Algorithms.Search.Linear;
+
+public static partial class LinearSearch
+{
+ ///
+ /// Counts the number of elements in the sequence that satisfy the specified predicate.
+ ///
+ /// The element type of the sequence.
+ /// The sequence to search.
+ /// The predicate used to test each element.
+ /// The number of elements satisfying .
+ ///
+ /// Thrown when or is .
+ ///
+ public static int CountMatches(this IEnumerable collection, Func match)
+ {
+ ArgumentNullException.ThrowIfNull(collection);
+ ArgumentNullException.ThrowIfNull(match);
+
+ int count = 0;
+
+ foreach (T item in collection)
+ {
+ if (match(item))
+ {
+ count++;
+ }
+ }
+
+ return count;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Search/Linear/LinearSearch.FindAllAlias.cs b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.FindAllAlias.cs
new file mode 100644
index 0000000..aae0783
--- /dev/null
+++ b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.FindAllAlias.cs
@@ -0,0 +1,19 @@
+namespace Csdsa.Algorithms.Search.Linear;
+
+public static partial class LinearSearch
+{
+ ///
+ /// Returns a list of all elements in the sequence that satisfy the specified predicate.
+ /// This is an alias for .
+ ///
+ /// The element type of the sequence.
+ /// The sequence to search.
+ /// The predicate used to test each element.
+ ///
+ /// A read-only list containing all elements that satisfy .
+ ///
+ public static IReadOnlyList FindAll(this IEnumerable collection, Func match)
+ {
+ return FindAllMatches(collection, match);
+ }
+}
diff --git a/src/Csdsa/Algorithms/Search/Linear/LinearSearch.FindAllMatches.cs b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.FindAllMatches.cs
new file mode 100644
index 0000000..e605096
--- /dev/null
+++ b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.FindAllMatches.cs
@@ -0,0 +1,34 @@
+namespace Csdsa.Algorithms.Search.Linear;
+
+public static partial class LinearSearch
+{
+ ///
+ /// Returns a list of all elements in the sequence that satisfy the specified predicate.
+ ///
+ /// The element type of the sequence.
+ /// The sequence to search.
+ /// The predicate used to test each element.
+ ///
+ /// A read-only list containing all elements that satisfy .
+ ///
+ ///
+ /// Thrown when or is .
+ ///
+ public static IReadOnlyList FindAllMatches(this IEnumerable collection, Func match)
+ {
+ ArgumentNullException.ThrowIfNull(collection);
+ ArgumentNullException.ThrowIfNull(match);
+
+ List result = new List();
+
+ foreach (T item in collection)
+ {
+ if (match(item))
+ {
+ result.Add(item);
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Search/Linear/LinearSearch.FirstOrDefaultMatch.cs b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.FirstOrDefaultMatch.cs
new file mode 100644
index 0000000..f943bbe
--- /dev/null
+++ b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.FirstOrDefaultMatch.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+
+namespace Csdsa.Algorithms.Search.Linear;
+
+public static partial class LinearSearch
+{
+ ///
+ /// Returns the first element in the sequence that satisfies the specified predicate,
+ /// or the default value of if no such element is found.
+ ///
+ /// The element type of the sequence.
+ /// The sequence to search.
+ /// The predicate used to test each element.
+ ///
+ /// The first matching element, or default(T) if no match is found.
+ ///
+ ///
+ /// Thrown when or is .
+ ///
+ public static T FirstOrDefaultMatch(this IEnumerable collection, Func match)
+ {
+ ArgumentNullException.ThrowIfNull(collection);
+ ArgumentNullException.ThrowIfNull(match);
+
+ foreach (T item in collection)
+ {
+ if (match(item))
+ {
+ return item;
+ }
+ }
+
+ return default;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Search/Linear/LinearSearch.LastIndexOf.cs b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.LastIndexOf.cs
new file mode 100644
index 0000000..ef51259
--- /dev/null
+++ b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.LastIndexOf.cs
@@ -0,0 +1,38 @@
+namespace Csdsa.Algorithms.Search.Linear;
+
+public static partial class LinearSearch
+{
+ ///
+ /// Returns the zero-based index of the last element in the sequence that
+ /// satisfies the specified predicate, or -1 if no such element exists.
+ ///
+ /// The element type of the sequence.
+ /// The sequence to search.
+ /// The predicate used to test each element.
+ ///
+ /// The zero-based index of the last matching element, or -1 if no match is found.
+ ///
+ ///
+ /// Thrown when or is .
+ ///
+ public static int LastIndexOf(this IEnumerable collection, Func match)
+ {
+ ArgumentNullException.ThrowIfNull(collection);
+ ArgumentNullException.ThrowIfNull(match);
+
+ int lastIndex = -1;
+ int index = 0;
+
+ foreach (T item in collection)
+ {
+ if (match(item))
+ {
+ lastIndex = index;
+ }
+
+ index++;
+ }
+
+ return lastIndex;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Search/Linear/LinearSearch.RemoveAllMatches.cs b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.RemoveAllMatches.cs
new file mode 100644
index 0000000..8dbdb3b
--- /dev/null
+++ b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.RemoveAllMatches.cs
@@ -0,0 +1,34 @@
+namespace Csdsa.Algorithms.Search.Linear;
+
+public static partial class LinearSearch
+{
+ ///
+ /// Removes all elements from the list that satisfy the specified predicate
+ /// and returns the number of removed elements.
+ ///
+ /// The element type of the list.
+ /// The list to modify.
+ /// The predicate used to test each element.
+ /// The number of elements removed from .
+ ///
+ /// Thrown when or is .
+ ///
+ public static int RemoveAllMatches(this List collection, Func match)
+ {
+ ArgumentNullException.ThrowIfNull(collection);
+ ArgumentNullException.ThrowIfNull(match);
+
+ int removed = 0;
+
+ for (int i = collection.Count - 1; i >= 0; i--)
+ {
+ if (match(collection[i]))
+ {
+ collection.RemoveAt(i);
+ removed++;
+ }
+ }
+
+ return removed;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Search/Linear/LinearSearch.SingleOrDefaultMatch.cs b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.SingleOrDefaultMatch.cs
new file mode 100644
index 0000000..cb84f8f
--- /dev/null
+++ b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.SingleOrDefaultMatch.cs
@@ -0,0 +1,45 @@
+namespace Csdsa.Algorithms.Search.Linear;
+
+public static partial class LinearSearch
+{
+ ///
+ /// Returns the single element in the sequence that satisfies the specified
+ /// predicate, or the default value of if no such
+ /// element is found or if more than one matching element exists.
+ ///
+ /// The element type of the sequence.
+ /// The sequence to search.
+ /// The predicate used to test each element.
+ ///
+ /// The single matching element, or default(T) if zero or multiple matches are found.
+ ///
+ ///
+ /// Thrown when or is .
+ ///
+ public static T SingleOrDefaultMatch(this IEnumerable collection, Func match)
+ {
+ ArgumentNullException.ThrowIfNull(collection);
+ ArgumentNullException.ThrowIfNull(match);
+
+ T matchItem = default;
+ int count = 0;
+
+ foreach (T item in collection)
+ {
+ if (!match(item))
+ {
+ continue;
+ }
+
+ matchItem = item;
+ count++;
+
+ if (count > 1)
+ {
+ return default;
+ }
+ }
+
+ return matchItem;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Search/Linear/LinearSearch.cs b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.cs
new file mode 100644
index 0000000..bc09f90
--- /dev/null
+++ b/src/Csdsa/Algorithms/Search/Linear/LinearSearch.cs
@@ -0,0 +1,53 @@
+namespace Csdsa.Algorithms.Search.Linear;
+
+///
+/// Provides linear search (O(n)) extension methods over .
+///
+/// Concepts:
+///
+///
+/// -
+///
+/// Generics (T) to enable reusable algorithms across different collection types.
+///
+///
+/// -
+///
+/// Extension methods for enhancing existing types without modifying their original definitions.
+///
+///
+/// -
+///
+/// Higher-order functions () for flexible match criteria.
+///
+///
+/// -
+///
+/// Algorithm complexity of linear search and its O(n) performance characteristics.
+///
+///
+///
+///
+/// Key practices:
+///
+///
+/// -
+/// Implementing extension methods to enhance functionality.
+///
+/// -
+/// Designing generic algorithms for maximum code reuse.
+///
+/// -
+///
+/// Staying type-safe by employing predicates
+/// instead of ad-hoc casting.
+///
+///
+/// -
+/// Maintaining clear semantics for "first", "last", "single", and "all/any" matches.
+///
+///
+///
+public static partial class LinearSearch
+{
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Base64/SerializationUtils.Base64.cs b/src/Csdsa/Algorithms/Serialization/Base64/SerializationUtils.Base64.cs
new file mode 100644
index 0000000..9c77b12
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Base64/SerializationUtils.Base64.cs
@@ -0,0 +1,36 @@
+namespace Csdsa.Algorithms.Serialization.Json;
+
+///
+/// Provides helpers for Base64-encoding and decoding JSON-based payloads.
+///
+public static partial class SerializationUtils
+{
+ ///
+ /// Serializes the specified value to a Base64-encoded UTF-8 JSON string.
+ ///
+ /// The type of the value.
+ /// The value to serialize.
+ /// A Base64-encoded JSON payload.
+ public static string SerializeToBase64(T data)
+ {
+ byte[] bytes = SerializeToBytes(data);
+ return Convert.ToBase64String(bytes);
+ }
+
+ ///
+ /// Deserializes a Base64-encoded UTF-8 JSON string into an instance of .
+ ///
+ /// The target type.
+ /// The Base64-encoded JSON payload.
+ /// An instance of .
+ ///
+ /// Thrown when is .
+ ///
+ public static T DeserializeFromBase64(string base64)
+ {
+ ArgumentNullException.ThrowIfNull(base64);
+
+ byte[] bytes = Convert.FromBase64String(base64);
+ return DeserializeFromBytes(bytes);
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Base64/SerializationUtils.SerializeIgnoreNullsToBase64.cs b/src/Csdsa/Algorithms/Serialization/Base64/SerializationUtils.SerializeIgnoreNullsToBase64.cs
new file mode 100644
index 0000000..fc0373d
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Base64/SerializationUtils.SerializeIgnoreNullsToBase64.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Text;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Serializes the specified value to JSON while ignoring null properties and
+ /// then encodes the JSON as a Base64 UTF-8 string.
+ ///
+ /// The type of the value.
+ /// The value to serialize.
+ ///
+ /// A Base64-encoded JSON string with null properties omitted.
+ ///
+ public static string SerializeIgnoreNullsToBase64(T data)
+ {
+ string json = SerializeIgnoreNulls(data);
+ byte[] bytes = Encoding.UTF8.GetBytes(json);
+ return Convert.ToBase64String(bytes);
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.DeserializeFromBytes.cs b/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.DeserializeFromBytes.cs
new file mode 100644
index 0000000..a71d3d3
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.DeserializeFromBytes.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Text;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Deserializes a UTF-8 encoded JSON byte array into an instance of .
+ ///
+ /// The target type.
+ /// The UTF-8 encoded JSON bytes.
+ /// An instance of .
+ ///
+ /// Thrown when is .
+ ///
+ public static T DeserializeFromBytes(byte[] bytes)
+ {
+ ArgumentNullException.ThrowIfNull(bytes);
+
+ string json = Encoding.UTF8.GetString(bytes);
+ return DeserializeFromJson(json);
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.SerializeToBytes.cs b/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.SerializeToBytes.cs
new file mode 100644
index 0000000..c4ae32d
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.SerializeToBytes.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Text;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Serializes the specified value to a UTF-8 encoded JSON byte array.
+ ///
+ /// The type of the value.
+ /// The value to serialize.
+ /// A UTF-8 encoded JSON byte array.
+ public static byte[] SerializeToBytes(T data)
+ {
+ string json = SerializeToJson(data);
+ return Encoding.UTF8.GetBytes(json);
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.SerializeWithNamingPolicy.cs b/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.SerializeWithNamingPolicy.cs
new file mode 100644
index 0000000..70d42e4
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.SerializeWithNamingPolicy.cs
@@ -0,0 +1,34 @@
+using System.Text.Json;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Serializes the specified value to JSON using a custom naming policy.
+ /// Currently supports ; other policies
+ /// will result in a .
+ ///
+ /// The type of the value.
+ /// The value to serialize.
+ /// The property naming policy to apply.
+ /// The JSON representation of .
+ ///
+ /// Thrown when is .
+ ///
+ ///
+ /// Thrown when is not supported.
+ ///
+ public static string SerializeWithNamingPolicy(T data, JsonNamingPolicy namingPolicy)
+ {
+ ArgumentNullException.ThrowIfNull(namingPolicy);
+
+ if (ReferenceEquals(namingPolicy, JsonNamingPolicy.CamelCase))
+ {
+ return System.Text.Json.JsonSerializer.Serialize(data, CamelCaseJsonOptions);
+ }
+
+ throw new NotSupportedException(
+ "Only JsonNamingPolicy.CamelCase is supported by SerializeWithNamingPolicy.");
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.TryDeserializeOrDefault.cs b/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.TryDeserializeOrDefault.cs
new file mode 100644
index 0000000..aae4a2a
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.TryDeserializeOrDefault.cs
@@ -0,0 +1,33 @@
+using System.Text.Json;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Attempts to deserialize the specified JSON string into an instance of .
+ /// Returns the provided fallback value if deserialization fails due to JSON parsing errors
+ /// or unsupported types.
+ ///
+ /// The target type.
+ /// The JSON payload.
+ /// The value to return if deserialization fails.
+ ///
+ /// The deserialized value, or if deserialization fails.
+ ///
+ public static T TryDeserializeOrDefault(string json, T fallback = default)
+ {
+ try
+ {
+ return DeserializeFromJson(json);
+ }
+ catch (JsonException)
+ {
+ return fallback;
+ }
+ catch (NotSupportedException)
+ {
+ return fallback;
+ }
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.Xml.cs b/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.Xml.cs
new file mode 100644
index 0000000..e9155f8
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Convert/SerializationUtils.Xml.cs
@@ -0,0 +1,50 @@
+using System.Text;
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Serializes the specified value to an XML string using .
+ ///
+ /// The type of the value.
+ /// The value to serialize.
+ /// An XML representation of .
+ public static string SerializeToXml(T data)
+ {
+ XmlSerializer serializer = new XmlSerializer(typeof(T));
+ using MemoryStream memory = new MemoryStream();
+ serializer.Serialize(memory, data);
+ return Encoding.UTF8.GetString(memory.ToArray());
+ }
+
+ ///
+ /// Deserializes the specified XML string into an instance of ,
+ /// using an with DTD processing disabled and no resolver.
+ ///
+ /// The target type.
+ /// The XML payload.
+ /// An instance of .
+ ///
+ /// Thrown when is .
+ ///
+ public static T DeserializeFromXml(string xml)
+ {
+ ArgumentNullException.ThrowIfNull(xml);
+
+ XmlSerializer serializer = new XmlSerializer(typeof(T));
+
+ using StringReader stringReader = new StringReader(xml);
+ XmlReaderSettings settings = new XmlReaderSettings
+ {
+ DtdProcessing = DtdProcessing.Prohibit,
+ XmlResolver = null,
+ };
+
+ using XmlReader reader = XmlReader.Create(stringReader, settings);
+ object result = serializer.Deserialize(reader);
+ return (T)result!;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/File/SerializationUtils.DeserializeFromFile.cs b/src/Csdsa/Algorithms/Serialization/File/SerializationUtils.DeserializeFromFile.cs
new file mode 100644
index 0000000..c1f6ee6
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/File/SerializationUtils.DeserializeFromFile.cs
@@ -0,0 +1,24 @@
+using System;
+using System.IO;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Deserializes JSON from the specified file into an instance of .
+ ///
+ /// The target type.
+ /// The path of the file to read.
+ /// An instance of .
+ ///
+ /// Thrown when is .
+ ///
+ public static T DeserializeFromFile(string filePath)
+ {
+ ArgumentNullException.ThrowIfNull(filePath);
+
+ string json = File.ReadAllText(filePath);
+ return DeserializeFromJson(json);
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/File/SerializationUtils.SerializeToFile.cs b/src/Csdsa/Algorithms/Serialization/File/SerializationUtils.SerializeToFile.cs
new file mode 100644
index 0000000..b27d070
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/File/SerializationUtils.SerializeToFile.cs
@@ -0,0 +1,24 @@
+using System;
+using System.IO;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Serializes the specified value to a JSON file.
+ ///
+ /// The type of the value.
+ /// The value to serialize.
+ /// The file path to write to.
+ ///
+ /// Thrown when is .
+ ///
+ public static void SerializeToFile(T data, string filePath)
+ {
+ ArgumentNullException.ThrowIfNull(filePath);
+
+ string json = SerializeToJson(data);
+ File.WriteAllText(filePath, json);
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.DeserializeFromJson.cs b/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.DeserializeFromJson.cs
new file mode 100644
index 0000000..f77ed4d
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.DeserializeFromJson.cs
@@ -0,0 +1,32 @@
+using System.Text.Json;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Deserializes the specified JSON string to an instance of
+ /// using .
+ ///
+ /// The target type.
+ /// The JSON string to deserialize.
+ /// An instance of .
+ ///
+ /// Thrown when is .
+ ///
+ ///
+ /// Thrown when deserialization returns .
+ ///
+ public static T DeserializeFromJson(string json)
+ {
+ ArgumentNullException.ThrowIfNull(json);
+
+ T result = JsonSerializer.Deserialize(json, DefaultJsonOptions);
+ if (result == null)
+ {
+ throw new InvalidOperationException("Deserialization produced a null result.");
+ }
+
+ return result;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.DeserializeWithConverters.cs b/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.DeserializeWithConverters.cs
new file mode 100644
index 0000000..24192a6
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.DeserializeWithConverters.cs
@@ -0,0 +1,47 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Deserializes the specified JSON string to an instance of
+ /// using the provided JSON converters.
+ ///
+ /// The target type.
+ /// The JSON payload.
+ /// The converters to register in the options.
+ /// An instance of .
+ ///
+ /// Thrown when or is .
+ ///
+ ///
+ /// Thrown when deserialization returns .
+ ///
+ public static T DeserializeWithConverters(
+ string json,
+ IEnumerable converters)
+ {
+ ArgumentNullException.ThrowIfNull(json);
+ ArgumentNullException.ThrowIfNull(converters);
+
+ JsonSerializerOptions options = new JsonSerializerOptions
+ {
+ WriteIndented = true,
+ };
+
+ foreach (JsonConverter converter in converters)
+ {
+ options.Converters.Add(converter);
+ }
+
+ T result = JsonSerializer.Deserialize(json, options);
+ if (result == null)
+ {
+ throw new InvalidOperationException("Deserialization produced a null result.");
+ }
+
+ return result;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.IsValidJson.cs b/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.IsValidJson.cs
new file mode 100644
index 0000000..fa25386
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.IsValidJson.cs
@@ -0,0 +1,33 @@
+using System.Text.Json;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Determines whether the specified string is valid JSON.
+ ///
+ /// The JSON string to validate.
+ ///
+ /// if is non-empty and valid JSON;
+ /// otherwise, .
+ ///
+ public static bool IsValidJson(string json)
+ {
+ if (string.IsNullOrWhiteSpace(json))
+ {
+ return false;
+ }
+
+ try
+ {
+ using JsonDocument document = JsonDocument.Parse(json);
+ _ = document.RootElement;
+ return true;
+ }
+ catch (JsonException)
+ {
+ return false;
+ }
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.SerializeIgnoreNulls.cs b/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.SerializeIgnoreNulls.cs
new file mode 100644
index 0000000..9d6cfa7
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.SerializeIgnoreNulls.cs
@@ -0,0 +1,17 @@
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Serializes the specified value to a JSON string, ignoring properties with null values.
+ ///
+ /// The type of the value.
+ /// The value to serialize.
+ ///
+ /// A JSON representation of where null-valued properties are omitted.
+ ///
+ public static string SerializeIgnoreNulls(T data)
+ {
+ return System.Text.Json.JsonSerializer.Serialize(data, IgnoreNullsJsonOptions);
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.SerializeToJson.cs b/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.SerializeToJson.cs
new file mode 100644
index 0000000..3373dfc
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.SerializeToJson.cs
@@ -0,0 +1,26 @@
+using System.Text.Json;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Serializes the specified value to a JSON string using .
+ ///
+ /// The type of the value to serialize.
+ /// The value to serialize.
+ /// The JSON representation of .
+ ///
+ /// Thrown when the serialization unexpectedly returns .
+ ///
+ public static string SerializeToJson(T data)
+ {
+ string json = JsonSerializer.Serialize(data, DefaultJsonOptions);
+ if (json == null)
+ {
+ throw new InvalidOperationException("Serialization produced a null result.");
+ }
+
+ return json;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.SerializeWithConverters.cs b/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.SerializeWithConverters.cs
new file mode 100644
index 0000000..40c8c35
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Json/SerializationUtils.SerializeWithConverters.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Serializes the specified value using the provided JSON converters.
+ ///
+ /// The type of the value.
+ /// The value to serialize.
+ /// The converters to register in the options.
+ /// The JSON representation of .
+ ///
+ /// Thrown when is .
+ ///
+ public static string SerializeWithConverters(
+ T data,
+ IEnumerable converters)
+ {
+ ArgumentNullException.ThrowIfNull(converters);
+
+ JsonSerializerOptions options = new JsonSerializerOptions
+ {
+ WriteIndented = true,
+ };
+
+ foreach (JsonConverter converter in converters)
+ {
+ options.Converters.Add(converter);
+ }
+
+ return JsonSerializer.Serialize(data, options);
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Polymorphic/SerializationUtils.DeepClone.cs b/src/Csdsa/Algorithms/Serialization/Polymorphic/SerializationUtils.DeepClone.cs
new file mode 100644
index 0000000..e3d3807
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Polymorphic/SerializationUtils.DeepClone.cs
@@ -0,0 +1,19 @@
+using Newtonsoft.Json;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Creates a deep clone of the specified object by serializing and deserializing it
+ /// using Newtonsoft.Json with default settings.
+ ///
+ /// The type of the object to clone.
+ /// The object to clone.
+ /// A deep clone of .
+ public static T DeepClone(T data)
+ {
+ string json = JsonConvert.SerializeObject(data);
+ return JsonConvert.DeserializeObject(json)!;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Polymorphic/SerializationUtils.Polymorphic.cs b/src/Csdsa/Algorithms/Serialization/Polymorphic/SerializationUtils.Polymorphic.cs
new file mode 100644
index 0000000..3c75d63
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Polymorphic/SerializationUtils.Polymorphic.cs
@@ -0,0 +1,27 @@
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Serializes the specified polymorphic value to JSON using .
+ ///
+ /// The static type of the value to serialize.
+ /// The value to serialize.
+ /// The JSON representation of .
+ public static string SerializePolymorphic(T baseObject)
+ {
+ return SerializeToJson(baseObject);
+ }
+
+ ///
+ /// Deserializes the specified JSON string into a polymorphic instance of
+ /// using .
+ ///
+ /// The target base type.
+ /// The JSON payload.
+ /// An instance of .
+ public static T DeserializePolymorphic(string json)
+ {
+ return DeserializeFromJson(json);
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Polymorphic/SerializationUtils.SerializeIncludingPrivate.cs b/src/Csdsa/Algorithms/Serialization/Polymorphic/SerializationUtils.SerializeIncludingPrivate.cs
new file mode 100644
index 0000000..68b1f9c
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Polymorphic/SerializationUtils.SerializeIncludingPrivate.cs
@@ -0,0 +1,21 @@
+using Newtonsoft.Json;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Serializes the specified value to JSON using Newtonsoft.Json,
+ /// including private and compiler-generated members for diagnostics.
+ ///
+ /// The type of the value.
+ /// The value to serialize.
+ ///
+ /// A JSON representation of that includes
+ /// private and compiler-generated members.
+ ///
+ public static string SerializeIncludingPrivate(T data)
+ {
+ return JsonConvert.SerializeObject(data, NewtonsoftPrivateSerializerSettings);
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/SerializationUtils.Options.cs b/src/Csdsa/Algorithms/Serialization/SerializationUtils.Options.cs
new file mode 100644
index 0000000..da7fb68
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/SerializationUtils.Options.cs
@@ -0,0 +1,50 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Gets the default JSON serialization options used by this module.
+ /// Includes fields and writes indented JSON.
+ ///
+ public static JsonSerializerOptions DefaultJsonOptions { get; } =
+ new JsonSerializerOptions { WriteIndented = true, IncludeFields = true };
+
+ ///
+ /// Gets the JSON serialization options that ignore null values when writing.
+ ///
+ public static JsonSerializerOptions IgnoreNullsJsonOptions { get; } =
+ new JsonSerializerOptions
+ {
+ WriteIndented = true,
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
+ };
+
+ ///
+ /// Gets JSON serialization options that use camelCase property naming.
+ ///
+ public static JsonSerializerOptions CamelCaseJsonOptions { get; } =
+ new JsonSerializerOptions
+ {
+ WriteIndented = true,
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
+ };
+
+ ///
+ /// Gets Newtonsoft.Json serializer settings configured to include
+ /// private and compiler-generated members for diagnostics and deep cloning.
+ ///
+ public static JsonSerializerSettings NewtonsoftPrivateSerializerSettings { get; } =
+ new JsonSerializerSettings
+ {
+ Formatting = Formatting.Indented,
+ ContractResolver = new DefaultContractResolver
+ {
+ SerializeCompilerGeneratedMembers = true,
+ },
+ };
+}
diff --git a/src/Csdsa/Algorithms/Serialization/SerializationUtils.cs b/src/Csdsa/Algorithms/Serialization/SerializationUtils.cs
new file mode 100644
index 0000000..ee8b95d
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/SerializationUtils.cs
@@ -0,0 +1,42 @@
+namespace Csdsa.Algorithms.Serialization;
+
+///
+/// Provides JSON, Base64, XML, and network-oriented serialization helpers.
+///
+/// Concepts:
+///
+///
+/// -
+/// JSON, Base64, and XML serialization for arbitrary object graphs.
+///
+/// -
+/// Deep cloning via serialization-based round-tripping.
+///
+/// -
+/// Custom converters and naming policies for JSON payloads.
+///
+/// -
+/// Ignoring null values and providing robust fallback strategies.
+///
+///
+///
+/// Key practices:
+///
+///
+/// -
+/// Centralized (de)serialization to keep calling code clean and consistent.
+///
+/// -
+/// Forward-thinking design for network, file, stream, and Base64 scenarios.
+///
+/// -
+/// Robust fallbacks via TryDeserializeOrDefault-style helpers.
+///
+/// -
+/// Diagnostics support via serialization that includes private and compiler-generated members.
+///
+///
+///
+public static partial class SerializationUtils
+{
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Stream/SerializationUtils.DeserializeFromStream.cs b/src/Csdsa/Algorithms/Serialization/Stream/SerializationUtils.DeserializeFromStream.cs
new file mode 100644
index 0000000..5d7d4ff
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Stream/SerializationUtils.DeserializeFromStream.cs
@@ -0,0 +1,31 @@
+using System.Text.Json;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Deserializes JSON from the specified stream to an instance of .
+ ///
+ /// The target type.
+ /// The source stream.
+ /// An instance of .
+ ///
+ /// Thrown when is .
+ ///
+ ///
+ /// Thrown when deserialization returns .
+ ///
+ public static T DeserializeFromStream(Stream stream)
+ {
+ ArgumentNullException.ThrowIfNull(stream);
+
+ T result = JsonSerializer.Deserialize(stream, DefaultJsonOptions);
+ if (result == null)
+ {
+ throw new InvalidOperationException("Deserialization produced a null result.");
+ }
+
+ return result;
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Stream/SerializationUtils.Network.cs b/src/Csdsa/Algorithms/Serialization/Stream/SerializationUtils.Network.cs
new file mode 100644
index 0000000..9fe28e5
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Stream/SerializationUtils.Network.cs
@@ -0,0 +1,37 @@
+using System;
+using System.IO;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Serializes the specified value to a network stream as JSON.
+ ///
+ /// The type of the value.
+ /// The value to serialize.
+ /// The network stream to write to.
+ ///
+ /// Thrown when is .
+ ///
+ public static void SerializeToNetwork(T data, Stream networkStream)
+ {
+ ArgumentNullException.ThrowIfNull(networkStream);
+ SerializeToStream(data, networkStream);
+ }
+
+ ///
+ /// Deserializes JSON from the specified network stream into an instance of .
+ ///
+ /// The target type.
+ /// The network stream to read from.
+ /// An instance of .
+ ///
+ /// Thrown when is .
+ ///
+ public static T DeserializeFromNetwork(Stream networkStream)
+ {
+ ArgumentNullException.ThrowIfNull(networkStream);
+ return DeserializeFromStream(networkStream);
+ }
+}
diff --git a/src/Csdsa/Algorithms/Serialization/Stream/SerializationUtils.SerializeToStream.cs b/src/Csdsa/Algorithms/Serialization/Stream/SerializationUtils.SerializeToStream.cs
new file mode 100644
index 0000000..c2bffe8
--- /dev/null
+++ b/src/Csdsa/Algorithms/Serialization/Stream/SerializationUtils.SerializeToStream.cs
@@ -0,0 +1,22 @@
+using System.Text.Json;
+
+namespace Csdsa.Algorithms.Serialization.Json;
+
+public static partial class SerializationUtils
+{
+ ///
+ /// Serializes the specified value to the provided stream as JSON.
+ ///
+ /// The type of the value.
+ /// The value to serialize.
+ /// The target stream.
+ ///
+ /// Thrown when is .
+ ///
+ public static void SerializeToStream(T data, Stream stream)
+ {
+ ArgumentNullException.ThrowIfNull(stream);
+
+ JsonSerializer.Serialize(stream, data, DefaultJsonOptions);
+ }
+}
diff --git a/src/Csdsa/Csdsa.csproj b/src/Csdsa/Csdsa.csproj
index 46165a4..00e1c5f 100644
--- a/src/Csdsa/Csdsa.csproj
+++ b/src/Csdsa/Csdsa.csproj
@@ -14,6 +14,7 @@
+
diff --git a/tests/Csdsa.Tests/Algorithms/Bfs/Bfs.AllPathBfs.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.AllPathBfs.Tests.cs
similarity index 100%
rename from tests/Csdsa.Tests/Algorithms/Bfs/Bfs.AllPathBfs.Tests.cs
rename to tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.AllPathBfs.Tests.cs
diff --git a/tests/Csdsa.Tests/Algorithms/Bfs/Bfs.BfsWithPredicate.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.BfsWithPredicate.Tests.cs
similarity index 100%
rename from tests/Csdsa.Tests/Algorithms/Bfs/Bfs.BfsWithPredicate.Tests.cs
rename to tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.BfsWithPredicate.Tests.cs
diff --git a/tests/Csdsa.Tests/Algorithms/Bfs/Bfs.ConnectedComponents.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.ConnectedComponents.Tests.cs
similarity index 100%
rename from tests/Csdsa.Tests/Algorithms/Bfs/Bfs.ConnectedComponents.Tests.cs
rename to tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.ConnectedComponents.Tests.cs
diff --git a/tests/Csdsa.Tests/Algorithms/Bfs/Bfs.DetectCycleUnidirected.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.DetectCycleUnidirected.Tests.cs
similarity index 100%
rename from tests/Csdsa.Tests/Algorithms/Bfs/Bfs.DetectCycleUnidirected.Tests.cs
rename to tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.DetectCycleUnidirected.Tests.cs
diff --git a/tests/Csdsa.Tests/Algorithms/Bfs/Bfs.DistanceFromSource.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.DistanceFromSource.Tests.cs
similarity index 100%
rename from tests/Csdsa.Tests/Algorithms/Bfs/Bfs.DistanceFromSource.Tests.cs
rename to tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.DistanceFromSource.Tests.cs
diff --git a/tests/Csdsa.Tests/Algorithms/Bfs/Bfs.GraphExtensions.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.GraphExtensions.Tests.cs
similarity index 100%
rename from tests/Csdsa.Tests/Algorithms/Bfs/Bfs.GraphExtensions.Tests.cs
rename to tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.GraphExtensions.Tests.cs
diff --git a/tests/Csdsa.Tests/Algorithms/Bfs/Bfs.KnightPath.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.KnightPath.Tests.cs
similarity index 100%
rename from tests/Csdsa.Tests/Algorithms/Bfs/Bfs.KnightPath.Tests.cs
rename to tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.KnightPath.Tests.cs
diff --git a/tests/Csdsa.Tests/Algorithms/Bfs/Bfs.MultiSourceBfs.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.MultiSourceBfs.Tests.cs
similarity index 100%
rename from tests/Csdsa.Tests/Algorithms/Bfs/Bfs.MultiSourceBfs.Tests.cs
rename to tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.MultiSourceBfs.Tests.cs
diff --git a/tests/Csdsa.Tests/Algorithms/Bfs/Bfs.NumberOfIslands.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.NumberOfIslands.Tests.cs
similarity index 100%
rename from tests/Csdsa.Tests/Algorithms/Bfs/Bfs.NumberOfIslands.Tests.cs
rename to tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.NumberOfIslands.Tests.cs
diff --git a/tests/Csdsa.Tests/Algorithms/Bfs/Bfs.ShortestPathInGrid.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.ShortestPathInGrid.Tests.cs
similarity index 100%
rename from tests/Csdsa.Tests/Algorithms/Bfs/Bfs.ShortestPathInGrid.Tests.cs
rename to tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.ShortestPathInGrid.Tests.cs
diff --git a/tests/Csdsa.Tests/Algorithms/Bfs/Bfs.TopologicalSortKahn.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.TopologicalSortKahn.Tests.cs
similarity index 100%
rename from tests/Csdsa.Tests/Algorithms/Bfs/Bfs.TopologicalSortKahn.Tests.cs
rename to tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.TopologicalSortKahn.Tests.cs
diff --git a/tests/Csdsa.Tests/Algorithms/Bfs/Bfs.WordLadder.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.WordLadder.Tests.cs
similarity index 100%
rename from tests/Csdsa.Tests/Algorithms/Bfs/Bfs.WordLadder.Tests.cs
rename to tests/Csdsa.Tests/Algorithms/GraphTraversals/Bfs.WordLadder.Tests.cs
diff --git a/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.AllPathsDfs.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.AllPathsDfs.Tests.cs
new file mode 100644
index 0000000..b53e035
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.AllPathsDfs.Tests.cs
@@ -0,0 +1,43 @@
+using System.Collections.Generic;
+using System.Linq;
+
+using Csdsa.Algorithms.GraphTraversal;
+using Csdsa.DataStructures.Graphs;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.GraphTraversal;
+
+public sealed partial class DfsTests
+{
+ [Fact]
+ public void AllPathsDfs_FindsAllSimplePaths_InDag()
+ {
+ Graph graph = CreateDag();
+
+ IReadOnlyList> paths = Dfs.AllPathsDFS(graph, 0, 3, maxDepth: 4);
+
+ Assert.Equal(2, paths.Count);
+
+ List[] expectedPaths =
+ {
+ new List { 0, 1, 3 },
+ new List { 0, 2, 3 },
+ };
+
+ Assert.All(
+ expectedPaths,
+ expected => Assert.Contains(paths, p => p.SequenceEqual(expected)));
+ }
+
+ [Fact]
+ public void AllPathsDfs_RespectsMaxDepth()
+ {
+ Graph graph = CreateDag();
+
+ // With maxDepth = 2, no path from 0 to 3 fits (paths are length 3).
+ IReadOnlyList> paths = Dfs.AllPathsDFS(graph, 0, 3, maxDepth: 2);
+
+ Assert.Empty(paths);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.ConnectedComponents.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.ConnectedComponents.Tests.cs
new file mode 100644
index 0000000..c1e3199
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.ConnectedComponents.Tests.cs
@@ -0,0 +1,26 @@
+using System.Collections.Generic;
+using System.Linq;
+
+using Csdsa.Algorithms.GraphTraversal;
+using Csdsa.DataStructures.Graphs;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.GraphTraversal;
+
+public sealed partial class DfsTests
+{
+ [Fact]
+ public void ConnectedComponents_FindsAllComponents()
+ {
+ Graph graph = new Graph(isDirected: false);
+ graph.AddEdge(0, 1);
+ graph.AddEdge(2, 3);
+
+ IReadOnlyList> components = Dfs.ConnectedComponents(graph);
+
+ Assert.Equal(2, components.Count);
+ Assert.Contains(components, c => c.Contains(0) && c.Contains(1));
+ Assert.Contains(components, c => c.Contains(2) && c.Contains(3));
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.DfsOrder.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.DfsOrder.Tests.cs
new file mode 100644
index 0000000..b8deeab
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.DfsOrder.Tests.cs
@@ -0,0 +1,62 @@
+using System.Collections.Generic;
+
+using Csdsa.Algorithms.GraphTraversal;
+using Csdsa.DataStructures.Graphs;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.GraphTraversal;
+
+public sealed partial class DfsTests
+{
+ private static Graph CreateSimpleGraph()
+ {
+ // 0 -- 1 -- 2
+ // | |
+ // +----3----+
+ Graph graph = new Graph(isDirected: false);
+ graph.AddEdge(0, 1);
+ graph.AddEdge(1, 2);
+ graph.AddEdge(0, 3);
+ graph.AddEdge(3, 2);
+ return graph;
+ }
+
+ private static Graph CreateDag()
+ {
+ // 0 -> 1 -> 3
+ // \> 2 -/
+ Graph graph = new Graph(isDirected: true);
+ graph.AddEdge(0, 1);
+ graph.AddEdge(1, 3);
+ graph.AddEdge(0, 2);
+ graph.AddEdge(2, 3);
+ return graph;
+ }
+
+ [Fact]
+ public void DfsOrder_Works_OnSimpleGraph()
+ {
+ Graph graph = CreateSimpleGraph();
+
+ IReadOnlyList order = Dfs.DfsOrder(graph, 0);
+
+ Assert.Equal(4, order.Count);
+ Assert.Equal(0, order[0]);
+ Assert.Contains(1, order);
+ Assert.Contains(2, order);
+ Assert.Contains(3, order);
+ }
+
+ [Fact]
+ public void DfsOrder_Works_OnSingleVertex()
+ {
+ Graph graph = new Graph(isDirected: false);
+ graph.AddVertex(0);
+
+ IReadOnlyList order = Dfs.DfsOrder(graph, 0);
+
+ Assert.Single(order);
+ Assert.Equal(0, order[0]);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.DfsWithPredicate.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.DfsWithPredicate.Tests.cs
new file mode 100644
index 0000000..dcf062b
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.DfsWithPredicate.Tests.cs
@@ -0,0 +1,30 @@
+using Csdsa.Algorithms.GraphTraversal;
+using Csdsa.DataStructures.Graphs;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.GraphTraversal;
+
+public sealed partial class DfsTests
+{
+ [Fact]
+ public void DfsWithPredicate_ReturnsDepth_WhenMatchExists()
+ {
+ Graph graph = CreateSimpleGraph();
+
+ int depth = Dfs.DFSWithPredicate(graph, 0, u => u == 2);
+
+ // In the simple graph, a DFS from 0 will reach 2 with depth 2.
+ Assert.Equal(2, depth);
+ }
+
+ [Fact]
+ public void DfsWithPredicate_ReturnsMinusOne_WhenNoMatchExists()
+ {
+ Graph graph = CreateSimpleGraph();
+
+ int depth = Dfs.DFSWithPredicate(graph, 0, u => u == 99);
+
+ Assert.Equal(-1, depth);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.HasCycleDirected.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.HasCycleDirected.Tests.cs
new file mode 100644
index 0000000..612ba91
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.HasCycleDirected.Tests.cs
@@ -0,0 +1,32 @@
+using Csdsa.Algorithms.GraphTraversal;
+using Csdsa.DataStructures.Graphs;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.GraphTraversal;
+
+public sealed partial class DfsTests
+{
+ [Fact]
+ public void HasCycleDirected_ReturnsFalse_ForAcyclicDirectedGraph()
+ {
+ Graph graph = CreateDag();
+
+ bool hasCycle = Dfs.HasCycleDirected(graph);
+
+ Assert.False(hasCycle);
+ }
+
+ [Fact]
+ public void HasCycleDirected_ReturnsTrue_ForDirectedCycle()
+ {
+ Graph graph = new Graph(isDirected: true);
+ graph.AddEdge(0, 1);
+ graph.AddEdge(1, 2);
+ graph.AddEdge(2, 0);
+
+ bool hasCycle = Dfs.HasCycleDirected(graph);
+
+ Assert.True(hasCycle);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.HasCycleUnidirected.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.HasCycleUnidirected.Tests.cs
new file mode 100644
index 0000000..6c15ddd
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.HasCycleUnidirected.Tests.cs
@@ -0,0 +1,31 @@
+using Csdsa.Algorithms.GraphTraversal;
+using Csdsa.DataStructures.Graphs;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.GraphTraversal;
+
+public sealed partial class DfsTests
+{
+ [Fact]
+ public void HasCycleUnidirected_ReturnsFalse_ForAcyclicUndirectedGraph()
+ {
+ Graph graph = new Graph(isDirected: false);
+ graph.AddEdge(0, 1);
+ graph.AddEdge(1, 2);
+
+ bool hasCycle = Dfs.HasCycleUndirected(graph);
+
+ Assert.False(hasCycle);
+ }
+
+ [Fact]
+ public void HasCycleUnidirected_ReturnsTrue_ForUndirectedCycle()
+ {
+ Graph graph = CreateSimpleGraph();
+
+ bool hasCycle = Dfs.HasCycleUndirected(graph);
+
+ Assert.True(hasCycle);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.HasPath.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.HasPath.Tests.cs
new file mode 100644
index 0000000..eebc3db
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.HasPath.Tests.cs
@@ -0,0 +1,29 @@
+using Csdsa.Algorithms.GraphTraversal;
+using Csdsa.DataStructures.Graphs;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.GraphTraversal;
+
+public sealed partial class DfsTests
+{
+ [Fact]
+ public void HasPath_ReturnsTrue_WhenPathExists()
+ {
+ Graph graph = CreateSimpleGraph();
+
+ bool hasPath = Dfs.HasPath(graph, 0, 2);
+
+ Assert.True(hasPath);
+ }
+
+ [Fact]
+ public void HasPath_ReturnsFalse_WhenPathDoesNotExist()
+ {
+ Graph graph = CreateSimpleGraph();
+
+ bool hasPath = Dfs.HasPath(graph, 0, 99);
+
+ Assert.False(hasPath);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.TopologicalSortDfs.Tests.cs b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.TopologicalSortDfs.Tests.cs
new file mode 100644
index 0000000..ab2fb68
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/GraphTraversals/Dfs.TopologicalSortDfs.Tests.cs
@@ -0,0 +1,25 @@
+using System.Collections.Generic;
+
+using Csdsa.Algorithms.GraphTraversal;
+using Csdsa.DataStructures.Graphs;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.GraphTraversal;
+
+public sealed partial class DfsTests
+{
+ [Fact]
+ public void TopologicalSortDfs_Works_OnDag()
+ {
+ Graph graph = CreateDag();
+
+ IReadOnlyList topo = Dfs.TopologicalSortDFS(graph);
+
+ Assert.Equal(4, topo.Count);
+ Assert.True(topo.IndexOf(0) < topo.IndexOf(1));
+ Assert.True(topo.IndexOf(0) < topo.IndexOf(2));
+ Assert.True(topo.IndexOf(1) < topo.IndexOf(3));
+ Assert.True(topo.IndexOf(2) < topo.IndexOf(3));
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSSearch.RemoveAllMatches.Tests.cs b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSSearch.RemoveAllMatches.Tests.cs
new file mode 100644
index 0000000..9c39ad6
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSSearch.RemoveAllMatches.Tests.cs
@@ -0,0 +1,32 @@
+using System.Collections.Generic;
+
+using Csdsa.Algorithms.Search.Linear;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Search.Linear;
+
+public sealed partial class LinearSearchTests
+{
+ [Fact]
+ public void RemoveAllMatches_RemovesCorrectNumber()
+ {
+ List collection = new List { 1, 2, 3, 2 };
+
+ int removed = collection.RemoveAllMatches(x => x == 2);
+
+ Assert.Equal(2, removed);
+ Assert.DoesNotContain(2, collection);
+ }
+
+ [Fact]
+ public void RemoveAllMatches_RemovesNone_WhenNoMatch()
+ {
+ List collection = new List { 1, 2, 3 };
+
+ int removed = collection.RemoveAllMatches(x => x == 99);
+
+ Assert.Equal(0, removed);
+ Assert.Equal(new[] { 1, 2, 3 }, collection);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.AllMatch.Tests.cs b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.AllMatch.Tests.cs
new file mode 100644
index 0000000..dd3884f
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.AllMatch.Tests.cs
@@ -0,0 +1,28 @@
+using Csdsa.Algorithms.Search.Linear;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Search.Linear;
+
+public sealed partial class LinearSearchTests
+{
+ [Fact]
+ public void AllMatch_ReturnsTrue_WhenAllElementsMatch()
+ {
+ int[] collection = { 2, 4, 6 };
+
+ bool result = collection.AllMatch(x => x % 2 == 0);
+
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void AllMatch_ReturnsFalse_WhenAnyElementDoesNotMatch()
+ {
+ int[] collection = { 2, 3, 4 };
+
+ bool result = collection.AllMatch(x => x % 2 == 0);
+
+ Assert.False(result);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.AnyMatch.Tests.cs b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.AnyMatch.Tests.cs
new file mode 100644
index 0000000..bb757ab
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.AnyMatch.Tests.cs
@@ -0,0 +1,28 @@
+using Csdsa.Algorithms.Search.Linear;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Search.Linear;
+
+public sealed partial class LinearSearchTests
+{
+ [Fact]
+ public void AnyMatch_ReturnsTrue_WhenAnyElementMatches()
+ {
+ int[] collection = { 1, 2, 3 };
+
+ bool result = collection.AnyMatch(x => x == 2);
+
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void AnyMatch_ReturnsFalse_WhenNoElementMatches()
+ {
+ int[] collection = { 1, 2, 3 };
+
+ bool result = collection.AnyMatch(x => x == 99);
+
+ Assert.False(result);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.ContainsMatch.Tests.cs b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.ContainsMatch.Tests.cs
new file mode 100644
index 0000000..2d4d8a6
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.ContainsMatch.Tests.cs
@@ -0,0 +1,28 @@
+using Csdsa.Algorithms.Search.Linear;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Search.Linear;
+
+public sealed partial class LinearSearchTests
+{
+ [Fact]
+ public void ContainsMatch_ReturnsTrue_IfMatchExists()
+ {
+ string[] collection = { "foo", "bar" };
+
+ bool result = collection.ContainsMatch(s => s == "foo");
+
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void ContainsMatch_ReturnsFalse_IfNoMatchExists()
+ {
+ string[] collection = { "foo", "bar" };
+
+ bool result = collection.ContainsMatch(s => s == "baz");
+
+ Assert.False(result);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.CountMatches.Tests.cs b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.CountMatches.Tests.cs
new file mode 100644
index 0000000..22cf707
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.CountMatches.Tests.cs
@@ -0,0 +1,28 @@
+using Csdsa.Algorithms.Search.Linear;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Search.Linear;
+
+public sealed partial class LinearSearchTests
+{
+ [Fact]
+ public void CountMatches_CountsCorrectly()
+ {
+ int[] collection = { 1, 2, 2, 3 };
+
+ int count = collection.CountMatches(x => x == 2);
+
+ Assert.Equal(2, count);
+ }
+
+ [Fact]
+ public void CountMatches_ReturnsZero_WhenNoMatch()
+ {
+ int[] collection = { 1, 2, 3 };
+
+ int count = collection.CountMatches(x => x == 99);
+
+ Assert.Equal(0, count);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.FindAllAlias.Tests.cs b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.FindAllAlias.Tests.cs
new file mode 100644
index 0000000..8c048d6
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.FindAllAlias.Tests.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+
+using Csdsa.Algorithms.Search.Linear;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Search.Linear;
+
+public sealed partial class LinearSearchTests
+{
+ [Fact]
+ public void FindAll_Alias_ReturnsAllMatches()
+ {
+ int[] collection = { 1, 2, 2, 3 };
+
+ IReadOnlyList all = collection.FindAll(x => x == 2);
+
+ Assert.Equal(2, all.Count);
+ Assert.All(all, item => Assert.Equal(2, item));
+ }
+
+ [Fact]
+ public void FindAll_Alias_ReturnsEmpty_WhenNoMatches()
+ {
+ int[] collection = { 1, 2, 3 };
+
+ IReadOnlyList all = collection.FindAll(x => x == 99);
+
+ Assert.Empty(all);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.FindAllMatches.Tests.cs b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.FindAllMatches.Tests.cs
new file mode 100644
index 0000000..9477a84
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.FindAllMatches.Tests.cs
@@ -0,0 +1,32 @@
+using System.Collections.Generic;
+
+using Csdsa.Algorithms.Search.Linear;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Search.Linear;
+
+public sealed partial class LinearSearchTests
+{
+ [Fact]
+ public void FindAllMatches_FindsAllMatchingElements()
+ {
+ int[] collection = { 1, 2, 3, 4, 5 };
+
+ IReadOnlyList matches = LinearSearch.FindAllMatches(collection, x => x % 2 == 0);
+
+ Assert.Equal(2, matches.Count);
+ Assert.Contains(2, matches);
+ Assert.Contains(4, matches);
+ }
+
+ [Fact]
+ public void FindAllMatches_ReturnsEmpty_WhenNoMatches()
+ {
+ int[] collection = { 1, 3, 5 };
+
+ IReadOnlyList matches = LinearSearch.FindAllMatches(collection, x => x % 2 == 0);
+
+ Assert.Empty(matches);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.FirstOrDefaultMatch.Tests.cs b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.FirstOrDefaultMatch.Tests.cs
new file mode 100644
index 0000000..11e607b
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.FirstOrDefaultMatch.Tests.cs
@@ -0,0 +1,28 @@
+using Csdsa.Algorithms.Search.Linear;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Search.Linear;
+
+public sealed partial class LinearSearchTests
+{
+ [Fact]
+ public void FirstOrDefaultMatch_FindsFirstMatch()
+ {
+ int[] collection = { 1, 2, 3 };
+
+ int first = collection.FirstOrDefaultMatch(x => x > 1);
+
+ Assert.Equal(2, first);
+ }
+
+ [Fact]
+ public void FirstOrDefaultMatch_ReturnsDefault_WhenNoMatch()
+ {
+ int[] collection = { 1, 2, 3 };
+
+ int first = collection.FirstOrDefaultMatch(x => x == 99);
+
+ Assert.Equal(0, first);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.IndexOf.Tests.cs b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.IndexOf.Tests.cs
new file mode 100644
index 0000000..dc7605c
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.IndexOf.Tests.cs
@@ -0,0 +1,28 @@
+using Csdsa.Algorithms.Search.Linear;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Search.Linear;
+
+public sealed partial class LinearSearchTests
+{
+ [Fact]
+ public void IndexOf_FindsFirstMatch()
+ {
+ int[] collection = { 1, 2, 3, 4, 5 };
+
+ int index = collection.IndexOf(x => x == 4);
+
+ Assert.Equal(3, index);
+ }
+
+ [Fact]
+ public void IndexOf_ReturnsMinusOne_IfNotFound()
+ {
+ int[] collection = { 1, 2, 3 };
+
+ int index = collection.IndexOf(x => x == 10);
+
+ Assert.Equal(-1, index);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.LastIndexOf.Tests.cs b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.LastIndexOf.Tests.cs
new file mode 100644
index 0000000..084998d
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.LastIndexOf.Tests.cs
@@ -0,0 +1,28 @@
+using Csdsa.Algorithms.Search.Linear;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Search.Linear;
+
+public sealed partial class LinearSearchTests
+{
+ [Fact]
+ public void LastIndexOf_FindsLastMatch()
+ {
+ int[] collection = { 1, 2, 2, 4 };
+
+ int lastIndex = collection.LastIndexOf(x => x == 2);
+
+ Assert.Equal(2, lastIndex);
+ }
+
+ [Fact]
+ public void LastIndexOf_ReturnsMinusOne_WhenNoMatch()
+ {
+ int[] collection = { 1, 2, 3 };
+
+ int lastIndex = collection.LastIndexOf(x => x == 99);
+
+ Assert.Equal(-1, lastIndex);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.SingleOrDefaultMatch.Tests.cs b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.SingleOrDefaultMatch.Tests.cs
new file mode 100644
index 0000000..434dd2c
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.SingleOrDefaultMatch.Tests.cs
@@ -0,0 +1,38 @@
+using Csdsa.Algorithms.Search.Linear;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Search.Linear;
+
+public sealed partial class LinearSearchTests
+{
+ [Fact]
+ public void SingleOrDefaultMatch_ReturnsSingleMatch()
+ {
+ int[] collection = { 1, 2, 3 };
+
+ int match = collection.SingleOrDefaultMatch(x => x == 2);
+
+ Assert.Equal(2, match);
+ }
+
+ [Fact]
+ public void SingleOrDefaultMatch_ReturnsDefault_WhenMultipleMatches()
+ {
+ int[] collection = { 1, 2, 2 };
+
+ int match = collection.SingleOrDefaultMatch(x => x == 2);
+
+ Assert.Equal(0, match);
+ }
+
+ [Fact]
+ public void SingleOrDefaultMatch_ReturnsDefault_WhenNoMatch()
+ {
+ int[] collection = { 1, 2, 3 };
+
+ int match = collection.SingleOrDefaultMatch(x => x == 99);
+
+ Assert.Equal(0, match);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.Tests.cs b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.Tests.cs
new file mode 100644
index 0000000..2284f34
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Search/Linear/LinearSearch.Tests.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+
+using Csdsa.Algorithms.Search.Linear;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Search.Linear;
+
+public sealed partial class LinearSearchTests
+{
+ [Fact]
+ public void LinearSearch_Integration_WorksAcrossCommonOperations()
+ {
+ int[] data = { 1, 2, 2, 3, 4 };
+
+ int firstIndex = data.IndexOf(x => x == 2);
+ int lastIndex = data.LastIndexOf(x => x == 2);
+ int count = data.CountMatches(x => x == 2);
+ bool any = data.AnyMatch(x => x == 2);
+ bool all = data.AllMatch(x => x > 0);
+
+ Assert.Equal(1, firstIndex);
+ Assert.Equal(2, lastIndex);
+ Assert.Equal(2, count);
+ Assert.True(any);
+ Assert.True(all);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Base64.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Base64.Tests.cs
new file mode 100644
index 0000000..2ea5aa3
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Base64.Tests.cs
@@ -0,0 +1,20 @@
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void SerializeToBase64_And_DeserializeFromBase64_Works()
+ {
+ Person person = new Person { Name = "Kendrick", Age = 37 };
+
+ string base64 = SerializationUtils.SerializeToBase64(person);
+ Person deserialized = SerializationUtils.DeserializeFromBase64(base64);
+
+ Assert.Equal("Kendrick", deserialized.Name);
+ Assert.Equal(37, deserialized.Age);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.DeepClone.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.DeepClone.Tests.cs
new file mode 100644
index 0000000..dd6aaca
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.DeepClone.Tests.cs
@@ -0,0 +1,20 @@
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void DeepClone_CreatesNewObject_WithSameValues()
+ {
+ Person person = new Person { Name = "Lelland", Age = 31 };
+
+ Person clone = SerializationUtils.DeepClone(person);
+
+ Assert.NotSame(person, clone);
+ Assert.Equal("Lelland", clone.Name);
+ Assert.Equal(31, clone.Age);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.DeserializeWithConverters.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.DeserializeWithConverters.Tests.cs
new file mode 100644
index 0000000..b2727d4
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.DeserializeWithConverters.Tests.cs
@@ -0,0 +1,30 @@
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void DeserializeWithConverters_UsesCustomConverter()
+ {
+ const string json = """
+ {
+ "Name": "lowercase",
+ "Age": 20
+ }
+ """;
+
+ Person result = SerializationUtils.DeserializeWithConverters(
+ json,
+ new JsonConverter[] { new UppercaseNameConverter() });
+
+ Assert.Equal("LOWERCASE", result.Name);
+ Assert.Equal(20, result.Age);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Helpers.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Helpers.Tests.cs
new file mode 100644
index 0000000..59b24d2
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Helpers.Tests.cs
@@ -0,0 +1,13 @@
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ public sealed class Person
+ {
+ public string Name { get; set; } = "mavantgarderc";
+
+ public int Age { get; set; } = 22;
+
+ public string? Nickname { get; set; }
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.IsValidJson.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.IsValidJson.Tests.cs
new file mode 100644
index 0000000..20d39b9
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.IsValidJson.Tests.cs
@@ -0,0 +1,19 @@
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void IsValidJson_ReturnsTrueForValidJson_AndFalseForInvalid()
+ {
+ Person person = new Person { Name = "Nayvadius", Age = 41 };
+
+ string json = SerializationUtils.SerializeToJson(person);
+
+ Assert.True(SerializationUtils.IsValidJson(json));
+ Assert.False(SerializationUtils.IsValidJson("Invalid JSON"));
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Network.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Network.Tests.cs
new file mode 100644
index 0000000..2487612
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Network.Tests.cs
@@ -0,0 +1,31 @@
+using System.IO;
+
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void SerializeToAndFromNetwork_Works()
+ {
+ Person person = new Person
+ {
+ Name = "NetworkTest",
+ Age = 99,
+ };
+
+ using MemoryStream networkStream = new MemoryStream();
+
+ SerializationUtils.SerializeToNetwork(person, networkStream);
+
+ networkStream.Position = 0;
+
+ Person deserialized = SerializationUtils.DeserializeFromNetwork(networkStream);
+
+ Assert.Equal("NetworkTest", deserialized.Name);
+ Assert.Equal(99, deserialized.Age);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Polymorphic.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Polymorphic.Tests.cs
new file mode 100644
index 0000000..74c9e21
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Polymorphic.Tests.cs
@@ -0,0 +1,34 @@
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ private abstract class Animal
+ {
+ public string Name { get; set; } = string.Empty;
+ }
+
+ private sealed class Dog : Animal
+ {
+ public int Age { get; set; }
+ }
+
+ [Fact]
+ public void SerializePolymorphic_And_DeserializePolymorphic_Works()
+ {
+ Dog dog = new Dog
+ {
+ Name = "Snoopy",
+ Age = 5,
+ };
+
+ string json = SerializationUtils.SerializePolymorphic(dog);
+ Dog deserialized = SerializationUtils.DeserializePolymorphic(json);
+
+ Assert.Equal("Snoopy", deserialized.Name);
+ Assert.Equal(5, deserialized.Age);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeIgnoreNulls.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeIgnoreNulls.Tests.cs
new file mode 100644
index 0000000..7dc815b
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeIgnoreNulls.Tests.cs
@@ -0,0 +1,18 @@
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void SerializeIgnoreNulls_OmitsNullProperties()
+ {
+ Person person = new Person { Name = "Aubrey", Age = 38 };
+
+ string json = SerializationUtils.SerializeIgnoreNulls(person);
+
+ Assert.DoesNotContain("Nickname", json);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeIgnoreNullsToBase64.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeIgnoreNullsToBase64.Tests.cs
new file mode 100644
index 0000000..674a8d8
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeIgnoreNullsToBase64.Tests.cs
@@ -0,0 +1,29 @@
+using System.Text;
+
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void SerializeIgnoreNullsToBase64_OmitsNullPropertiesInDecodedJson()
+ {
+ Person person = new Person
+ {
+ Name = "Base64Test",
+ Age = 10,
+ Nickname = null,
+ };
+
+ string base64 = SerializationUtils.SerializeIgnoreNullsToBase64(person);
+
+ byte[] bytes = Convert.FromBase64String(base64);
+ string json = Encoding.UTF8.GetString(bytes);
+
+ Assert.Contains("Base64Test", json);
+ Assert.DoesNotContain("Nickname", json);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeIncludingPrivate.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeIncludingPrivate.Tests.cs
new file mode 100644
index 0000000..485e426
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeIncludingPrivate.Tests.cs
@@ -0,0 +1,29 @@
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ private sealed class PrivatePerson
+ {
+ public string Name { get; set; } = string.Empty;
+
+ private string Secret { get; set; } = "top-secret";
+ }
+
+ [Fact]
+ public void SerializeIncludingPrivate_ProducesJson()
+ {
+ PrivatePerson person = new PrivatePerson
+ {
+ Name = "Test",
+ };
+
+ string json = SerializationUtils.SerializeIncludingPrivate(person);
+
+ Assert.False(string.IsNullOrWhiteSpace(json));
+ Assert.Contains("Test", json);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeToBytes.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeToBytes.Tests.cs
new file mode 100644
index 0000000..963550f
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeToBytes.Tests.cs
@@ -0,0 +1,20 @@
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void SerializeToAndFromBytes_Works()
+ {
+ Person person = new Person { Name = "Ye", Age = 48 };
+
+ byte[] bytes = SerializationUtils.SerializeToBytes(person);
+ Person deserialized = SerializationUtils.DeserializeFromBytes(bytes);
+
+ Assert.Equal("Ye", deserialized.Name);
+ Assert.Equal(48, deserialized.Age);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeToFile.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeToFile.Tests.cs
new file mode 100644
index 0000000..cc84aba
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeToFile.Tests.cs
@@ -0,0 +1,25 @@
+using System.IO;
+
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void SerializeToAndFromFile_Works()
+ {
+ Person person = new Person { Name = "Shawn", Age = 55 };
+ const string path = "temp-test.json";
+
+ SerializationUtils.SerializeToFile(person, path);
+ Person deserialized = SerializationUtils.DeserializeFromFile(path);
+
+ File.Delete(path);
+
+ Assert.Equal("Shawn", deserialized.Name);
+ Assert.Equal(55, deserialized.Age);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeToJson.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeToJson.Tests.cs
new file mode 100644
index 0000000..2c9d8ec
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeToJson.Tests.cs
@@ -0,0 +1,20 @@
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void SerializeAndDeserialize_ReturnsEqualObject()
+ {
+ Person person = new Person { Name = "Jermaine", Age = 40 };
+
+ string json = SerializationUtils.SerializeToJson(person);
+ Person deserialized = SerializationUtils.DeserializeFromJson(json);
+
+ Assert.Equal(person.Name, deserialized.Name);
+ Assert.Equal(person.Age, deserialized.Age);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeToStream.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeToStream.Tests.cs
new file mode 100644
index 0000000..a53cb9a
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeToStream.Tests.cs
@@ -0,0 +1,26 @@
+using System.IO;
+
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void SerializeToAndFromStream_Works()
+ {
+ Person person = new Person { Name = "Dwayne", Age = 42 };
+
+ using MemoryStream stream = new MemoryStream();
+
+ SerializationUtils.SerializeToStream(person, stream);
+ stream.Position = 0;
+
+ Person deserialized = SerializationUtils.DeserializeFromStream(stream);
+
+ Assert.Equal("Dwayne", deserialized.Name);
+ Assert.Equal(42, deserialized.Age);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeWithConverters.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeWithConverters.Tests.cs
new file mode 100644
index 0000000..e0336c1
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeWithConverters.Tests.cs
@@ -0,0 +1,54 @@
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ private sealed class UppercaseNameConverter : JsonConverter
+ {
+ public override Person Read(ref Utf8JsonReader reader, System.Type typeToConvert, JsonSerializerOptions options)
+ {
+ // Minimal read implementation: delegate to default, then adjust.
+ Person? person = JsonSerializer.Deserialize(ref reader, options);
+ if (person is null)
+ {
+ return new Person();
+ }
+
+ person.Name = person.Name.ToUpperInvariant();
+ return person;
+ }
+
+ public override void Write(Utf8JsonWriter writer, Person value, JsonSerializerOptions options)
+ {
+ writer.WriteStartObject();
+ writer.WriteString(nameof(Person.Name), value.Name.ToUpperInvariant());
+ writer.WriteNumber(nameof(Person.Age), value.Age);
+ if (value.Nickname is not null)
+ {
+ writer.WriteString(nameof(Person.Nickname), value.Nickname);
+ }
+
+ writer.WriteEndObject();
+ }
+ }
+
+ [Fact]
+ public void SerializeWithConverters_UsesCustomConverter()
+ {
+ Person person = new Person { Name = "Jayce", Age = 25 };
+
+ string json = SerializationUtils.SerializeWithConverters(
+ person,
+ new JsonConverter[] { new UppercaseNameConverter() });
+
+ Assert.Contains("JAYCE", json);
+ Assert.DoesNotContain("Jayce", json);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeWithNamingPolicy.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeWithNamingPolicy.Tests.cs
new file mode 100644
index 0000000..d1ba56a
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.SerializeWithNamingPolicy.Tests.cs
@@ -0,0 +1,21 @@
+using System.Text.Json;
+
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void SerializeWithNamingPolicy_CamelCase_UsesCamelCasePropertyNames()
+ {
+ Person person = new Person { Name = "Webster", Age = 34 };
+
+ string json = SerializationUtils.SerializeWithNamingPolicy(person, JsonNamingPolicy.CamelCase);
+
+ Assert.Contains("name", json);
+ Assert.Contains("age", json);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Xml.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Xml.Tests.cs
new file mode 100644
index 0000000..22cebb0
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/SerializationUtils.Xml.Tests.cs
@@ -0,0 +1,20 @@
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void SerializeToAndFromXml_Works()
+ {
+ Person person = new Person { Name = "Curtis", Age = 49 };
+
+ string xml = SerializationUtils.SerializeToXml(person);
+ Person deserialized = SerializationUtils.DeserializeFromXml(xml);
+
+ Assert.Equal("Curtis", deserialized.Name);
+ Assert.Equal(49, deserialized.Age);
+ }
+}
diff --git a/tests/Csdsa.Tests/Algorithms/Serialization/Serializationutils.TryDeserializeOrDefault.Tests.cs b/tests/Csdsa.Tests/Algorithms/Serialization/Serializationutils.TryDeserializeOrDefault.Tests.cs
new file mode 100644
index 0000000..60a104a
--- /dev/null
+++ b/tests/Csdsa.Tests/Algorithms/Serialization/Serializationutils.TryDeserializeOrDefault.Tests.cs
@@ -0,0 +1,21 @@
+using Csdsa.Algorithms.Serialization.Json;
+
+using Xunit;
+
+namespace Csdsa.Tests.Algorithms.Serialization.Json;
+
+public sealed partial class SerializationUtilsTests
+{
+ [Fact]
+ public void TryDeserializeOrDefault_ReturnsFallback_OnInvalidJson()
+ {
+ const string invalidJson = "{ invalid json }";
+
+ Person fallback = new Person { Name = "Fallback", Age = 0 };
+
+ Person result = SerializationUtils.TryDeserializeOrDefault(invalidJson, fallback);
+
+ Assert.Equal("Fallback", result.Name);
+ Assert.Equal(0, result.Age);
+ }
+}