Fix Map HashCode Collision (#44)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index eb48144..aaf52d9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 1.0.1
+
+- Fix `hashCode` collisions with `Map` properties ([#43](https://github.com/felangel/equatable/issues/43)).
+
 # 1.0.0
 
 - Update hashCode implementation to use `Jenkins Hash` ([#39](https://github.com/felangel/equatable/issues/39)).
diff --git a/lib/src/equatable_utils.dart b/lib/src/equatable_utils.dart
index 778ab4f..cf1f21f 100644
--- a/lib/src/equatable_utils.dart
+++ b/lib/src/equatable_utils.dart
@@ -15,7 +15,7 @@
     final unit1 = list1[i];
     final unit2 = list2[i];
 
-    if (unit1 is Iterable || unit1 is List || unit1 is Map || unit1 is Set) {
+    if (unit1 is Iterable || unit1 is Map) {
       if (!_equality.equals(unit1, unit2)) return false;
     } else if (unit1?.runtimeType != unit2?.runtimeType) {
       return false;
@@ -31,13 +31,11 @@
 int _combine(int hash, dynamic object) {
   if (object is Map) {
     object.forEach((key, value) {
-      hash = _combine(hash, [key, value]);
+      hash = hash ^ _combine(hash, [key, value]);
     });
     return hash;
   }
-  if (object is Iterable) {
-    return mapPropsToHashCode(object);
-  }
+  if (object is Iterable) return mapPropsToHashCode(object);
   hash = 0x1fffffff & (hash + object.hashCode);
   hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
   return hash ^ (hash >> 6);
diff --git a/pubspec.yaml b/pubspec.yaml
index f17a414..ef62f79 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
 name: equatable
 description: An abstract class that helps to implement equality without needing to explicitly override == and hashCode.
-version: 1.0.0
+version: 1.0.1
 author: Felix Angelov <felangelov@gmail.com>
 homepage: https://github.com/felangel/equatable
 
diff --git a/test/equatable_test.dart b/test/equatable_test.dart
index a35b302..2eeac97 100644
--- a/test/equatable_test.dart
+++ b/test/equatable_test.dart
@@ -442,6 +442,38 @@
       );
       expect(instanceA == instanceB, false);
     });
+
+    test('should return false when values only differ in list', () {
+      final instanceA = ComplexEquatable(
+        name: 'Joe',
+        age: 40,
+        hairColor: Color.black,
+        children: ['Bob'],
+      );
+      final instanceB = ComplexEquatable(
+        name: 'Joe',
+        age: 40,
+        hairColor: Color.black,
+        children: ['Bobby'],
+      );
+      expect(instanceA == instanceB, false);
+    });
+
+    test('should return false when values only differ in single property', () {
+      final instanceA = ComplexEquatable(
+        name: 'Joe',
+        age: 40,
+        hairColor: Color.black,
+        children: ['Bob'],
+      );
+      final instanceB = ComplexEquatable(
+        name: 'Joe',
+        age: 41,
+        hairColor: Color.black,
+        children: ['Bob'],
+      );
+      expect(instanceA == instanceB, false);
+    });
   });
 
   group('Json Equatable', () {
@@ -592,29 +624,71 @@
         expect(instanceA == instanceB, true);
         expect(instanceA.hashCode == instanceB.hashCode, true);
       });
+
+      test(
+          'should return different hashCode when instance properties are different',
+          () {
+        final instanceA = SimpleEquatable<List>(["A", "B"]);
+        final instanceB = SimpleEquatable<List>(["B"]);
+
+        expect(instanceA != instanceB, true);
+        expect(instanceA.hashCode != instanceB.hashCode, true);
+      });
+
+      test(
+          'should return different hashCode when instance properties are modified',
+          () {
+        final list = ["A", "B"];
+        final instanceA = SimpleEquatable<List>(list);
+        final hashCodeA = instanceA.hashCode;
+        list.removeLast();
+        final hashCodeB = instanceA.hashCode;
+        expect(hashCodeA != hashCodeB, true);
+      });
     });
 
     group('Map Equatable', () {
-      test('should return when values are same', () {
+      test('should return true when values are same', () {
         final instanceA = SimpleEquatable<Map>({1: "A", 2: "B"});
         final instanceB = SimpleEquatable<Map>({1: "A", 2: "B"});
         expect(instanceA == instanceB, true);
         expect(instanceA.hashCode == instanceB.hashCode, true);
       });
 
-      test('should return when values are different', () {
+      test('should return false when values are different', () {
         final instanceA = SimpleEquatable<Map>({1: "A", 2: "B"});
         final instanceB = SimpleEquatable<Map>({1: "a", 2: "b"});
         expect(instanceA != instanceB, true);
         expect(instanceA.hashCode != instanceB.hashCode, true);
       });
 
-      test('should return when values are different', () {
+      test('should return false when values are different', () {
         final instanceA = SimpleEquatable<Map>({1: "A", 2: "B"});
         final instanceB = SimpleEquatable<Map>({1: "C", 2: "D"});
         expect(instanceA != instanceB, true);
         expect(instanceA.hashCode != instanceB.hashCode, true);
       });
+
+      test(
+          'should return different hashCode when instance properties are different',
+          () {
+        final instanceA = SimpleEquatable<Map>({1: "A", 2: "B"});
+        final instanceB = SimpleEquatable<Map>({2: "B"});
+
+        expect(instanceA != instanceB, true);
+        expect(instanceA.hashCode != instanceB.hashCode, true);
+      });
+
+      test(
+          'should return different hashCode when instance properties are modified',
+          () {
+        final map = {1: "A", 2: "B"};
+        final instanceA = SimpleEquatable<Map>(map);
+        final hashCodeA = instanceA.hashCode;
+        map.remove(1);
+        final hashCodeB = instanceA.hashCode;
+        expect(hashCodeA != hashCodeB, true);
+      });
     });
 
     group('Set Equatable', () {