using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ExtensionMethods {
  public static class IEquatableExtensions {
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    public static bool Eq(this IEquatable? item1, T? item2) {
      if ((item1 == null && item2 != null) || (item1 != null && item2 == null))
        return false;
      if (item1 == null && item2 == null)
        return true;
      if (item1 != null && item2 != null) {
        var result = item1.Equals(item2);
        return result;
      }
      return false;
    }
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    public static bool EnumerableEq(this IEnumerable>? list1, IEnumerable>? list2) {
      if ((list1 == null && list2 != null) || (list1 != null && list2 == null))
        return false;
      if (list1 == null && list2 == null)
        return true;
      if (list1 != null && list2 != null && list1.Count() == list2.Count()) {
        var diffDic = list2.GroupBy(x => x.GetHashCode()).ToDictionary(g => g.Key, g => g.Count());
        for (int i = 0; i < list1.Count(); i++) {
          var obj = (T)list1.ElementAt(i);
          var objHash = obj.GetHashCode();
          if (diffDic.ContainsKey(objHash))
            diffDic[objHash] = diffDic[objHash] - 1;
          else
            diffDic.Add(objHash, -1);
        }
        return !diffDic.Any(x => x.Value != 0);
      }
      return false;
    }
  }
}