@Override
  public boolean equals(Object o) {
    if (!(o instanceof Map)) return false;

    try {
      Map m = (Map) o;
      for (Entry<K, V> e : entrySet()) {
        K key = e.getKey();
        V value = e.getValue();
        if (value == null) {
          if (!(m.get(key) == null && m.containsKey(key)))
            return false;
        } else {
          if (!value.equals(m.get(key)))
            return false;
        }
      }
    } catch (ClassCastException unused) {
      return false;
    } catch (NullPointerException unused) {
      return false;
    }

    return true;
  }