diff --git a/back/src/Kyoo.Abstractions/Utility/EnumerableExtensions.cs b/back/src/Kyoo.Abstractions/Utility/EnumerableExtensions.cs
deleted file mode 100644
index 4c3b72b0..00000000
--- a/back/src/Kyoo.Abstractions/Utility/EnumerableExtensions.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-// Kyoo - A portable and vast media library solution.
-// Copyright (c) Kyoo.
-//
-// See AUTHORS.md and LICENSE file in the project root for full license information.
-//
-// Kyoo is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// any later version.
-//
-// Kyoo is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Kyoo. If not, see .
-
-using System;
-using System.Collections.Generic;
-
-namespace Kyoo.Utils;
-
-///
-/// A set of extensions class for enumerable.
-///
-public static class EnumerableExtensions
-{
- ///
- /// If the enumerable is empty, execute an action.
- ///
- /// The enumerable to check
- /// The action to execute is the list is empty
- /// The type of items inside the list
- /// The iterator proxied, there is no dual iterations.
- public static IEnumerable IfEmpty(this IEnumerable self, Action action)
- {
- static IEnumerable Generator(IEnumerable self, Action action)
- {
- using IEnumerator enumerator = self.GetEnumerator();
-
- if (!enumerator.MoveNext())
- {
- action();
- yield break;
- }
-
- do
- {
- yield return enumerator.Current;
- } while (enumerator.MoveNext());
- }
-
- return Generator(self, action);
- }
-
- ///
- /// A foreach used as a function with a little specificity: the list can be null.
- ///
- /// The list to enumerate. If this is null, the function result in a no-op
- /// The action to execute for each arguments
- /// The type of items in the list
- public static void ForEach(this IEnumerable? self, Action action)
- {
- if (self == null)
- return;
- foreach (T i in self)
- action(i);
- }
-}
diff --git a/back/src/Kyoo.Abstractions/Utility/Merger.cs b/back/src/Kyoo.Abstractions/Utility/Merger.cs
deleted file mode 100644
index a97530ef..00000000
--- a/back/src/Kyoo.Abstractions/Utility/Merger.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-// Kyoo - A portable and vast media library solution.
-// Copyright (c) Kyoo.
-//
-// See AUTHORS.md and LICENSE file in the project root for full license information.
-//
-// Kyoo is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// any later version.
-//
-// Kyoo is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Kyoo. If not, see .
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using Kyoo.Abstractions.Models.Attributes;
-
-namespace Kyoo.Utils;
-
-///
-/// A class containing helper methods to merge objects.
-///
-public static class Merger
-{
- ///
- /// Merge two dictionary, if the same key is found on both dictionary, the values of the second one is kept.
- ///
- /// The first dictionary to merge
- /// The second dictionary to merge
- ///
- /// true if a new items has been added to the dictionary, false otherwise.
- ///
- /// The type of the keys in dictionaries
- /// The type of values in the dictionaries
- ///
- /// A dictionary with the missing elements of
- /// set to those of .
- ///
- public static IDictionary? CompleteDictionaries(
- IDictionary? first,
- IDictionary? second,
- out bool hasChanged
- )
- {
- if (first == null)
- {
- hasChanged = true;
- return second;
- }
-
- hasChanged = false;
- if (second == null)
- return first;
- hasChanged = second.Any(x =>
- !first.ContainsKey(x.Key) || x.Value?.Equals(first[x.Key]) == false
- );
- foreach ((T key, T2 value) in first)
- second.TryAdd(key, value);
- return second;
- }
-
- ///
- /// Set every non-default values of seconds to the corresponding property of second.
- /// Dictionaries are handled like anonymous objects with a property per key/pair value
- /// At the end, the OnMerge method of first will be called if first is a
- ///
- ///
- /// {id: 0, slug: "test"}, {id: 4, slug: "foo"} -> {id: 4, slug: "foo"}
- ///
- ///
- /// The object to complete
- ///
- ///
- /// Missing fields of first will be completed by fields of this item. If second is null, the function no-op.
- ///
- ///
- /// Filter fields that will be merged
- ///
- /// Fields of T will be completed
- ///
- public static T Complete(T first, T? second, Func? where = null)
- {
- if (second == null)
- return first;
-
- Type type = typeof(T);
- IEnumerable properties = type.GetProperties()
- .Where(x =>
- x is { CanRead: true, CanWrite: true }
- && Attribute.GetCustomAttribute(x, typeof(NotMergeableAttribute)) == null
- );
-
- if (where != null)
- properties = properties.Where(where);
-
- foreach (PropertyInfo property in properties)
- {
- object? value = property.GetValue(second);
-
- if (value?.Equals(property.GetValue(first)) == true)
- continue;
-
- if (Utility.IsOfGenericType(property.PropertyType, typeof(IDictionary<,>)))
- {
- Type[] dictionaryTypes = Utility
- .GetGenericDefinition(property.PropertyType, typeof(IDictionary<,>))!
- .GenericTypeArguments;
- object?[] parameters = { property.GetValue(first), value, false };
- object newDictionary = Utility.RunGenericMethod