Add tests that are missing in upstream release, taken from upstream
git repository at version 0.5.6

diff --git a/src/tests/heapsize.rs b/src/tests/heapsize.rs
new file mode 100644
index 000000000..ec20ff5b2
--- /dev/null
+++ b/src/tests/heapsize.rs
@@ -0,0 +1,26 @@
+#![cfg(all(feature = "heapsize_impl", not(miri)))]
+
+extern crate heapsize;
+extern crate linked_hash_map;
+
+use heapsize::HeapSizeOf;
+use linked_hash_map::LinkedHashMap;
+
+#[test]
+fn empty() {
+    assert_eq!(
+        LinkedHashMap::<String, String>::new().heap_size_of_children(),
+        0
+    );
+}
+
+#[test]
+fn nonempty() {
+    let mut map = LinkedHashMap::new();
+    map.insert("hello".to_string(), "world".to_string());
+    map.insert("hola".to_string(), "mundo".to_string());
+    map.insert("bonjour".to_string(), "monde".to_string());
+    map.remove("hello");
+
+    assert!(map.heap_size_of_children() != 0);
+}
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
new file mode 100644
index 000000000..5e0e73afe
--- /dev/null
+++ b/src/tests/mod.rs
@@ -0,0 +1,880 @@
+#![allow(clippy::needless_collect)]
+#![allow(clippy::iter_cloned_collect)]
+
+use crate::{Entry, LinkedHashMap};
+
+fn assert_opt_eq<V: PartialEq>(opt: Option<&V>, v: V) {
+    assert!(opt.is_some());
+    assert!(opt.unwrap() == &v);
+}
+
+#[test]
+fn test_insert_and_get() {
+    let mut map = LinkedHashMap::new();
+    map.insert(1, 10);
+    map.insert(2, 20);
+    assert_opt_eq(map.get(&1), 10);
+    assert_opt_eq(map.get(&2), 20);
+    assert_eq!(map.len(), 2);
+}
+
+#[test]
+fn test_index() {
+    let mut map = LinkedHashMap::new();
+    map.insert(1, 10);
+    map.insert(2, 20);
+    assert_eq!(10, map[&1]);
+    map[&2] = 22;
+    assert_eq!(22, map[&2]);
+}
+
+#[test]
+fn test_insert_update() {
+    let mut map = LinkedHashMap::new();
+    map.insert("1".to_string(), vec![10, 10]);
+    map.insert("1".to_string(), vec![10, 19]);
+    assert_opt_eq(map.get(&"1".to_string()), vec![10, 19]);
+    assert_eq!(map.len(), 1);
+}
+
+#[test]
+fn test_entry_insert_vacant() {
+    let mut map = LinkedHashMap::new();
+    match map.entry("1".to_string()) {
+        Entry::Vacant(e) => {
+            assert_eq!(*e.insert(vec![10, 10]), vec![10, 10]);
+        }
+        _ => panic!("fail"),
+    }
+    assert!(map.contains_key("1"));
+    assert_eq!(map["1"], vec![10, 10]);
+
+    match map.entry("1".to_string()) {
+        Entry::Occupied(mut e) => {
+            assert_eq!(*e.get(), vec![10, 10]);
+            assert_eq!(e.insert(vec![10, 16]), vec![10, 10]);
+        }
+        _ => panic!("fail"),
+    }
+
+    assert!(map.contains_key("1"));
+    assert_eq!(map["1"], vec![10, 16]);
+
+    match map.entry("1".to_string()) {
+        Entry::Occupied(e) => {
+            assert_eq!(e.remove(), vec![10, 16]);
+        }
+        _ => panic!("fail"),
+    }
+}
+
+#[test]
+fn test_entry_or_default() {
+    let mut map = LinkedHashMap::<String, Vec<u32>>::new();
+    map.entry("hello".to_string()).or_default().push(4);
+    map.entry("hello".to_string()).or_default().push(5);
+    map.entry("hello".to_string()).or_default().push(8);
+
+    map.entry("bye".to_string()).or_default().push(9);
+
+    map.entry("there".to_string()).or_default();
+
+    assert_eq!(map["hello"], &[4, 5, 8]);
+    assert_eq!(map["bye"], &[9]);
+    assert_eq!(map["there"], &[]);
+}
+
+#[test]
+fn test_entry_and_modify() {
+    let mut map = LinkedHashMap::<String, Vec<u32>>::new();
+    map.entry("hello".to_string())
+        .and_modify(|v| v.push(3))
+        .or_default();
+    map.entry("hello".to_string())
+        .and_modify(|v| v.push(4))
+        .or_default();
+    map.entry("hello".to_string())
+        .and_modify(|v| v.push(5))
+        .or_default();
+
+    map.entry("bye".to_string()).or_default();
+
+    map.entry("bye".to_string())
+        .and_modify(|v| v.push(3))
+        .and_modify(|v| v.push(4))
+        .and_modify(|v| v.push(5));
+
+    map.entry("there".to_string()).and_modify(|v| v.push(3));
+
+    assert_eq!(map["hello"], &[4, 5]);
+    assert_eq!(map["bye"], &[3, 4, 5]);
+    assert_eq!(map.get("there"), None);
+}
+
+#[test]
+fn test_entries_replacing() {
+    let mut map = LinkedHashMap::new();
+    map.insert("a", 10);
+
+    {
+        let mut iter = map.entries();
+        let mut entry = iter.next().unwrap();
+        assert_eq!(entry.insert(20), 10);
+        assert!(iter.next().is_none());
+    }
+
+    assert_eq!(map["a"], 20);
+}
+
+#[test]
+fn test_entries_remove() {
+    let mut map = LinkedHashMap::new();
+    map.insert("a", 10);
+    map.insert("b", 20);
+    map.insert("c", 30);
+    map.insert("d", 40);
+
+    // remove middle
+    {
+        let mut iter = map.entries();
+        iter.next().unwrap();
+        let b = iter.next().unwrap();
+        assert_eq!(*b.key(), "b");
+        assert_eq!(b.remove(), 20);
+        assert_eq!(*iter.next().unwrap().key(), "c");
+    }
+
+    assert_eq!(map.len(), 3);
+    assert_eq!(map["a"], 10);
+    assert_eq!(map["c"], 30);
+    assert_eq!(map["d"], 40);
+
+    // remove first
+    {
+        let mut iter = map.entries();
+        let a = iter.next().unwrap();
+        assert_eq!(*a.key(), "a");
+        assert_eq!(a.remove(), 10);
+    }
+
+    assert_eq!(map.len(), 2);
+    assert_eq!(map["c"], 30);
+    assert_eq!(map["d"], 40);
+
+    // remove last
+    {
+        let mut iter = map.entries();
+        iter.next().unwrap();
+        let d = iter.next().unwrap();
+        assert_eq!(*d.key(), "d");
+        assert_eq!(d.remove(), 40);
+        assert!(iter.next().is_none());
+    }
+
+    assert_eq!(map.len(), 1);
+    assert_eq!(map["c"], 30);
+
+    // remove only
+    {
+        let mut iter = map.entries();
+        let c = iter.next().unwrap();
+        assert_eq!(*c.key(), "c");
+        assert_eq!(c.remove(), 30);
+    }
+
+    assert!(map.is_empty());
+}
+#[test]
+fn entries_insert() {
+    let mut map = LinkedHashMap::new();
+    map.insert(0, 0);
+    map.insert(1, 1);
+
+    let mut iter = map.entries();
+
+    iter.next().unwrap().insert(0);
+    iter.next().unwrap(); // 1
+    assert!(iter.next().is_none());
+}
+
+#[test]
+fn test_debug() {
+    let mut map = LinkedHashMap::new();
+    assert_eq!(format!("{:?}", map), "{}");
+    map.insert(1, 10);
+    map.insert(2, 20);
+    map.insert(3, 30);
+    assert_eq!(format!("{:?}", map), "{1: 10, 2: 20, 3: 30}");
+    map.insert(2, 22);
+    assert_eq!(format!("{:?}", map), "{1: 10, 3: 30, 2: 22}");
+    map.get(&3);
+    assert_eq!(format!("{:?}", map), "{1: 10, 3: 30, 2: 22}");
+    map.get_refresh(&3);
+    assert_eq!(format!("{:?}", map), "{1: 10, 2: 22, 3: 30}");
+    map.clear();
+    assert_eq!(format!("{:?}", map), "{}");
+}
+
+#[test]
+fn test_remove() {
+    let mut map = LinkedHashMap::new();
+    map.insert(1, 10);
+    map.insert(2, 20);
+    map.insert(3, 30);
+    map.insert(4, 40);
+    map.insert(5, 50);
+    map.remove(&3);
+    map.remove(&4);
+    assert!(map.get(&3).is_none());
+    assert!(map.get(&4).is_none());
+    map.insert(6, 60);
+    map.insert(7, 70);
+    map.insert(8, 80);
+    assert_opt_eq(map.get(&6), 60);
+    assert_opt_eq(map.get(&7), 70);
+    assert_opt_eq(map.get(&8), 80);
+}
+
+#[test]
+fn test_pop() {
+    let mut map = LinkedHashMap::new();
+    map.insert(1, 10);
+    map.insert(2, 20);
+    map.insert(3, 30);
+    map.insert(4, 40);
+    map.insert(5, 50);
+    assert_eq!(map.pop_front(), Some((1, 10)));
+    assert!(map.get(&1).is_none());
+    assert_eq!(map.pop_back(), Some((5, 50)));
+    assert!(map.get(&5).is_none());
+    map.insert(6, 60);
+    map.insert(7, 70);
+    map.insert(8, 80);
+    assert_eq!(map.pop_front(), Some((2, 20)));
+    assert!(map.get(&2).is_none());
+    assert_eq!(map.pop_back(), Some((8, 80)));
+    assert!(map.get(&8).is_none());
+    map.insert(3, 30);
+    assert_eq!(map.pop_front(), Some((4, 40)));
+    assert!(map.get(&4).is_none());
+    assert_eq!(map.pop_back(), Some((3, 30)));
+    assert!(map.get(&3).is_none());
+}
+
+#[test]
+fn test_clear() {
+    let mut map = LinkedHashMap::new();
+    map.insert(1, 10);
+    map.insert(2, 20);
+    map.clear();
+    assert!(map.get(&1).is_none());
+    assert!(map.get(&2).is_none());
+    assert_eq!(format!("{:?}", map), "{}");
+}
+
+#[test]
+fn test_iter() {
+    let mut map = LinkedHashMap::new();
+
+    // empty iter
+    assert_eq!(None, map.iter().next());
+
+    map.insert("a", 10);
+    map.insert("b", 20);
+    map.insert("c", 30);
+
+    // regular iter
+    let mut iter = map.iter();
+    assert_eq!((&"a", &10), iter.next().unwrap());
+    assert_eq!((&"b", &20), iter.next().unwrap());
+    assert_eq!((&"c", &30), iter.next().unwrap());
+    assert_eq!(None, iter.next());
+    assert_eq!(None, iter.next());
+
+    // reversed iter
+    let mut rev_iter = map.iter().rev();
+    assert_eq!((&"c", &30), rev_iter.next().unwrap());
+    assert_eq!((&"b", &20), rev_iter.next().unwrap());
+    assert_eq!((&"a", &10), rev_iter.next().unwrap());
+    assert_eq!(None, rev_iter.next());
+    assert_eq!(None, rev_iter.next());
+
+    // mixed
+    let mut mixed_iter = map.iter();
+    assert_eq!((&"a", &10), mixed_iter.next().unwrap());
+    assert_eq!((&"c", &30), mixed_iter.next_back().unwrap());
+    assert_eq!((&"b", &20), mixed_iter.next().unwrap());
+    assert_eq!(None, mixed_iter.next());
+    assert_eq!(None, mixed_iter.next_back());
+}
+
+#[test]
+fn test_iter_mut() {
+    let mut map = LinkedHashMap::new();
+    map.insert("a", 10);
+    map.insert("c", 30);
+    map.insert("b", 20);
+
+    {
+        let mut iter = map.iter_mut();
+        let entry = iter.next().unwrap();
+        assert_eq!(&"a", entry.0);
+        *entry.1 = 17;
+
+        // reverse iterator
+        let mut iter = iter.rev();
+        let entry = iter.next().unwrap();
+        assert_eq!(&"b", entry.0);
+        *entry.1 = 23;
+
+        let entry = iter.next().unwrap();
+        assert_eq!(&"c", entry.0);
+        assert_eq!(None, iter.next());
+        assert_eq!(None, iter.next());
+    }
+
+    assert_eq!(17, map[&"a"]);
+    assert_eq!(23, map[&"b"]);
+}
+
+#[test]
+fn test_consuming_iter() {
+    let map = {
+        let mut map = LinkedHashMap::new();
+        map.insert("a", 10);
+        map.insert("c", 30);
+        map.insert("b", 20);
+        map
+    };
+
+    let mut iter = map.into_iter();
+    assert_eq!(Some(("a", 10)), iter.next());
+
+    let clone = iter.clone();
+    for iter in &mut [iter, clone] {
+        assert_eq!(Some(("b", 20)), iter.next_back());
+        assert_eq!(1, iter.len());
+        assert_eq!(Some(("c", 30)), iter.next());
+        assert_eq!(None, iter.next());
+    }
+}
+
+#[test]
+fn test_consuming_iter_empty() {
+    let map = LinkedHashMap::<&str, i32>::new();
+    let mut iter = map.into_iter();
+    assert_eq!(None, iter.next());
+    let mut clone = iter.clone();
+    assert_eq!(None, clone.next());
+}
+
+#[test]
+fn test_consuming_iter_with_free_list() {
+    let mut map = LinkedHashMap::new();
+    map.insert("a", 10);
+    map.insert("c", 30);
+    map.insert("b", 20);
+    map.remove("a");
+    map.remove("b");
+
+    let mut iter = map.into_iter();
+    assert_eq!(Some(("c", 30)), iter.next());
+    assert_eq!(None, iter.next());
+}
+
+#[test]
+fn test_into_iter_drop() {
+    struct Counter<'a>(&'a mut usize);
+
+    impl<'a> Drop for Counter<'a> {
+        fn drop(&mut self) {
+            *self.0 += 1;
+        }
+    }
+
+    let mut a = 0;
+    let mut b = 0;
+    let mut c = 0;
+
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("a", Counter(&mut a));
+        map.insert("b", Counter(&mut b));
+        map.insert("c", Counter(&mut c));
+
+        let mut iter = map.into_iter();
+        iter.next();
+        iter.next_back();
+    }
+
+    assert_eq!(a, 1);
+    assert_eq!(b, 1);
+    assert_eq!(c, 1);
+}
+
+#[test]
+fn test_drain() {
+    let data = [("a", 1), ("b", 2), ("c", 3), ("d", 4)];
+
+    let mut map = data.iter().copied().collect::<LinkedHashMap<_, _>>();
+    assert_eq!(map.len(), 4);
+    let mut iter = map.drain();
+    assert_eq!(iter.size_hint(), (4, Some(4)));
+    assert_eq!(iter.next(), Some(("a", 1)));
+    assert_eq!(iter.size_hint(), (3, Some(3)));
+    assert_eq!(iter.next(), Some(("b", 2)));
+    assert_eq!(iter.size_hint(), (2, Some(2)));
+    assert_eq!(iter.next(), Some(("c", 3)));
+    assert_eq!(iter.size_hint(), (1, Some(1)));
+    assert_eq!(iter.next(), Some(("d", 4)));
+    assert_eq!(iter.size_hint(), (0, Some(0)));
+    assert_eq!(iter.next(), None);
+    assert_eq!(iter.size_hint(), (0, Some(0)));
+    assert_eq!(iter.next(), None);
+    assert_eq!(iter.size_hint(), (0, Some(0)));
+    assert_eq!(iter.next_back(), None);
+    assert_eq!(iter.size_hint(), (0, Some(0)));
+    drop(iter);
+    assert_eq!(map.len(), 0);
+
+    map.extend(data.iter().copied());
+    assert_eq!(map.len(), 4);
+    let mut iter = map.drain();
+    assert_eq!(iter.size_hint(), (4, Some(4)));
+    assert_eq!(iter.next_back(), Some(("d", 4)));
+    assert_eq!(iter.size_hint(), (3, Some(3)));
+    assert_eq!(iter.next_back(), Some(("c", 3)));
+    assert_eq!(iter.size_hint(), (2, Some(2)));
+    assert_eq!(iter.next_back(), Some(("b", 2)));
+    assert_eq!(iter.size_hint(), (1, Some(1)));
+    assert_eq!(iter.next_back(), Some(("a", 1)));
+    assert_eq!(iter.size_hint(), (0, Some(0)));
+    assert_eq!(iter.next_back(), None);
+    assert_eq!(iter.next_back(), None);
+    assert_eq!(iter.next(), None);
+    drop(iter);
+    assert_eq!(map.len(), 0);
+
+    map.extend(data.iter().rev().copied());
+    assert!(map.insert("e", 5).is_none());
+    assert!(map.insert("f", 6).is_none());
+    assert_eq!(map.len(), 6);
+    assert_eq!(map.remove("b"), Some(2));
+    assert!(map.get("b").is_none());
+    assert_eq!(map.len(), 5);
+    let mut iter = map.drain();
+    assert_eq!(iter.size_hint(), (5, Some(5)));
+    assert_eq!(iter.next(), Some(("d", 4)));
+    assert_eq!(iter.next(), Some(("c", 3)));
+    assert_eq!(iter.next_back(), Some(("f", 6)));
+    assert_eq!(iter.next(), Some(("a", 1)));
+    assert_eq!(iter.next(), Some(("e", 5)));
+    assert_eq!(iter.next(), None);
+    assert_eq!(iter.next(), None);
+    drop(iter);
+    assert_eq!(map.len(), 0);
+
+    map.insert("g", 2);
+    assert_eq!(map.get("g"), Some(&2));
+    assert_eq!(map.len(), 1);
+}
+
+#[test]
+fn test_drain_corners() {
+    {
+        let mut map = LinkedHashMap::<String, String>::new();
+        assert_eq!(map.len(), 0);
+        assert_eq!(map.drain().collect::<Vec<_>>(), vec![]);
+        assert_eq!(map.len(), 0);
+        assert!(map.is_empty());
+        assert!(map.iter().collect::<Vec<_>>().is_empty());
+    }
+    {
+        let mut map = LinkedHashMap::<String, String>::new();
+        assert_eq!(map.drain().rev().size_hint(), (0, Some(0)));
+        assert!(map.into_iter().collect::<Vec<_>>().is_empty());
+    }
+    {
+        let mut map = LinkedHashMap::<String, String>::new();
+        assert_eq!(map.drain().size_hint(), (0, Some(0)));
+        assert_eq!(map.len(), 0);
+        assert!(map.is_empty());
+        assert!(map.iter_mut().collect::<Vec<_>>().is_empty());
+    }
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("a", 1);
+        assert_eq!(map.len(), 1);
+        assert_eq!(map.drain().collect::<Vec<_>>(), vec![("a", 1)]);
+        assert_eq!(map.len(), 0);
+        assert!(map.get("a").is_none());
+    }
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("b", 2);
+        assert_eq!(map.len(), 1);
+        assert_eq!(map.drain().rev().collect::<Vec<_>>(), vec![("b", 2)]);
+        assert!(map.into_iter().rev().collect::<Vec<_>>().is_empty());
+    }
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("c", 3);
+        map.insert("d", 4);
+        assert_eq!(map.len(), 2);
+        assert_eq!(map.drain().collect::<Vec<_>>(), vec![("c", 3), ("d", 4)]);
+    }
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("e", 5);
+        map.insert("f", 6);
+        assert_eq!(map.len(), 2);
+        assert_eq!(
+            map.drain().rev().collect::<Vec<_>>(),
+            vec![("f", 6), ("e", 5)]
+        );
+    }
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("e", 5);
+        assert_eq!(map.remove("e"), Some(5));
+        assert_eq!(map.len(), 0);
+        let iter = map.drain();
+        assert_eq!(iter.size_hint(), (0, Some(0)));
+        assert_eq!(iter.collect::<Vec<_>>(), vec![]);
+        assert_eq!(map.len(), 0);
+        assert!(map.is_empty());
+        assert!(map.iter_mut().rev().collect::<Vec<_>>().is_empty());
+    }
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("e", 5);
+        assert_eq!(map.remove("e"), Some(5));
+        assert_eq!(map.len(), 0);
+        let iter = map.drain().rev();
+        assert_eq!(iter.size_hint(), (0, Some(0)));
+        assert_eq!(iter.collect::<Vec<_>>(), vec![]);
+        assert_eq!(map.len(), 0);
+        assert!(map.is_empty());
+        assert!(map.iter_mut().rev().collect::<Vec<_>>().is_empty());
+    }
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("e", 5);
+        assert_eq!(map.remove("e"), Some(5));
+        assert_eq!(map.len(), 0);
+        assert_eq!(map.drain().collect::<Vec<_>>(), vec![]);
+        assert_eq!(map.len(), 0);
+        assert!(map.into_iter().rev().collect::<Vec<_>>().is_empty());
+    }
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("e", 5);
+        assert_eq!(map.remove("e"), Some(5));
+        assert_eq!(map.len(), 0);
+        assert_eq!(map.drain().rev().collect::<Vec<_>>(), vec![]);
+        assert_eq!(map.len(), 0);
+        assert!(map.into_iter().collect::<Vec<_>>().is_empty());
+    }
+}
+
+#[test]
+fn test_drain_forget() {
+    let data = [("a", 1), ("b", 2), ("c", 3), ("d", 4)];
+
+    let mut map = data.iter().copied().collect::<LinkedHashMap<_, _>>();
+    assert_eq!(map.len(), 4);
+    let iter = map.drain();
+    std::mem::forget(iter);
+    assert_eq!(map.len(), 0);
+    assert!(map.get("a").is_none());
+    assert!(map.get("b").is_none());
+    assert!(map.iter().collect::<Vec<_>>().is_empty());
+    assert!(map.iter().rev().collect::<Vec<_>>().is_empty());
+
+    map.extend(data.iter().copied());
+    let mut iter = map.drain();
+    assert_eq!(iter.next(), Some(("a", 1)));
+    std::mem::forget(iter);
+    assert_eq!(map.len(), 0);
+    assert!(map.get("a").is_none());
+    assert!(map.get("b").is_none());
+    assert!(map.iter_mut().collect::<Vec<_>>().is_empty());
+    assert!(map.iter_mut().rev().collect::<Vec<_>>().is_empty());
+
+    map.extend(data.iter().rev().copied());
+    let mut iter = map.drain();
+    assert_eq!(iter.next_back(), Some(("a", 1)));
+    std::mem::forget(iter);
+    assert_eq!(map.len(), 0);
+    assert!(map.get("a").is_none());
+    assert!(map.get("b").is_none());
+    assert!(map.iter_mut().collect::<Vec<_>>().is_empty());
+    assert!(map.iter_mut().rev().collect::<Vec<_>>().is_empty());
+
+    map.extend(data.iter().rev().copied());
+    let mut iter = map.drain();
+    assert_eq!(
+        iter.by_ref().collect::<Vec<_>>(),
+        data.iter().rev().copied().collect::<Vec<_>>()
+    );
+    std::mem::forget(iter);
+    assert_eq!(map.len(), 0);
+    assert!(map.get("a").is_none());
+    assert!(map.get("b").is_none());
+    assert!(map.iter_mut().collect::<Vec<_>>().is_empty());
+    assert!(map.iter_mut().rev().collect::<Vec<_>>().is_empty());
+
+    map.extend(data.iter().rev().copied());
+    let mut iter = map.drain();
+    assert_eq!(
+        iter.by_ref().rev().collect::<Vec<_>>(),
+        data.iter().copied().collect::<Vec<_>>()
+    );
+    std::mem::forget(iter);
+    assert_eq!(map.len(), 0);
+    assert!(map.get("a").is_none());
+    assert!(map.get("b").is_none());
+    assert!(map.iter_mut().collect::<Vec<_>>().is_empty());
+    assert!(map.iter_mut().rev().collect::<Vec<_>>().is_empty());
+}
+
+#[test]
+fn test_drain_drop() {
+    struct Counter<'a>(&'a mut usize);
+
+    impl<'a> Drop for Counter<'a> {
+        fn drop(&mut self) {
+            *self.0 += 1;
+        }
+    }
+
+    let mut a = 0;
+    let mut b = 0;
+    let mut c = 0;
+
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("a", Counter(&mut a));
+        map.insert("b", Counter(&mut b));
+        map.insert("c", Counter(&mut c));
+
+        let mut iter = map.drain();
+        assert_eq!(iter.next().unwrap().0, "a");
+        assert_eq!(iter.next_back().unwrap().0, "c");
+    }
+
+    assert_eq!(a, 1);
+    assert_eq!(b, 1);
+    assert_eq!(c, 1);
+
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("a", Counter(&mut a));
+        map.insert("b", Counter(&mut b));
+        map.insert("c", Counter(&mut c));
+
+        let _iter = map.drain();
+    }
+
+    assert_eq!(a, 2);
+    assert_eq!(b, 2);
+    assert_eq!(c, 2);
+
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("a", Counter(&mut a));
+        map.insert("b", Counter(&mut b));
+        map.insert("c", Counter(&mut c));
+
+        let iter = map.drain();
+        std::mem::forget(iter);
+        assert_eq!(map.len(), 0);
+
+        assert!(map.is_empty());
+        let mut normal_iter = map.iter();
+        assert!(normal_iter.next().is_none());
+        assert!(normal_iter.next_back().is_none());
+    }
+
+    assert_eq!(a, 2);
+    assert_eq!(b, 2);
+    assert_eq!(c, 2);
+
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("a", Counter(&mut a));
+        map.insert("b", Counter(&mut b));
+        map.insert("c", Counter(&mut c));
+
+        let iter = map.drain();
+        std::mem::forget(iter);
+
+        assert_eq!(map.len(), 0);
+        let mut normal_iter = map.iter();
+        assert!(normal_iter.next().is_none());
+        assert!(normal_iter.next_back().is_none());
+    }
+
+    assert_eq!(a, 2);
+    assert_eq!(b, 2);
+    assert_eq!(c, 2);
+
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("a", Counter(&mut a));
+        map.insert("b", Counter(&mut b));
+        map.insert("c", Counter(&mut c));
+
+        let iter = map.drain();
+        for _ in iter {}
+    }
+
+    assert_eq!(a, 3);
+    assert_eq!(b, 3);
+    assert_eq!(c, 3);
+
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("a", Counter(&mut a));
+        map.insert("b", Counter(&mut b));
+        map.insert("c", Counter(&mut c));
+
+        let iter = map.drain();
+        for _ in iter.rev() {}
+    }
+
+    assert_eq!(a, 4);
+    assert_eq!(b, 4);
+    assert_eq!(c, 4);
+
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("a", Counter(&mut a));
+        map.insert("b", Counter(&mut b));
+        map.insert("c", Counter(&mut c));
+
+        let mut iter = map.drain();
+        assert!(iter.next().is_some());
+        std::mem::forget(iter);
+    }
+
+    assert_eq!(a, 5);
+    assert_eq!(b, 4);
+    assert_eq!(c, 4);
+
+    {
+        let mut map = LinkedHashMap::new();
+        map.insert("a", Counter(&mut a));
+        map.insert("b", Counter(&mut b));
+        map.insert("c", Counter(&mut c));
+
+        let mut iter = map.drain();
+        assert!(iter.next_back().is_some());
+        std::mem::forget(iter);
+    }
+
+    assert_eq!(a, 5);
+    assert_eq!(b, 4);
+    assert_eq!(c, 5);
+}
+
+#[test]
+fn test_borrow() {
+    #[derive(PartialEq, Eq, Hash)]
+    struct Foo(Bar);
+    #[derive(PartialEq, Eq, Hash)]
+    struct Bar(i32);
+
+    impl ::std::borrow::Borrow<Bar> for Foo {
+        fn borrow(&self) -> &Bar {
+            &self.0
+        }
+    }
+
+    let mut map = LinkedHashMap::new();
+    map.insert(Foo(Bar(1)), "a");
+    map.insert(Foo(Bar(2)), "b");
+
+    assert!(map.contains_key(&Bar(1)));
+    assert!(map.contains_key(&Bar(2)));
+    assert!(map.contains_key(&Foo(Bar(1))));
+    assert!(map.contains_key(&Foo(Bar(2))));
+
+    assert_eq!(map.get(&Bar(1)), Some(&"a"));
+    assert_eq!(map.get(&Bar(2)), Some(&"b"));
+    assert_eq!(map.get(&Foo(Bar(1))), Some(&"a"));
+    assert_eq!(map.get(&Foo(Bar(2))), Some(&"b"));
+
+    assert_eq!(map.get_refresh(&Bar(1)), Some(&mut "a"));
+    assert_eq!(map.get_refresh(&Bar(2)), Some(&mut "b"));
+    assert_eq!(map.get_refresh(&Foo(Bar(1))), Some(&mut "a"));
+    assert_eq!(map.get_refresh(&Foo(Bar(2))), Some(&mut "b"));
+
+    assert_eq!(map.get_mut(&Bar(1)), Some(&mut "a"));
+    assert_eq!(map.get_mut(&Bar(2)), Some(&mut "b"));
+    assert_eq!(map.get_mut(&Foo(Bar(1))), Some(&mut "a"));
+    assert_eq!(map.get_mut(&Foo(Bar(2))), Some(&mut "b"));
+
+    assert_eq!(map[&Bar(1)], "a");
+    assert_eq!(map[&Bar(2)], "b");
+    assert_eq!(map[&Foo(Bar(1))], "a");
+    assert_eq!(map[&Foo(Bar(2))], "b");
+
+    assert_eq!(map.remove(&Bar(1)), Some("a"));
+    assert_eq!(map.remove(&Bar(2)), Some("b"));
+    assert_eq!(map.remove(&Foo(Bar(1))), None);
+    assert_eq!(map.remove(&Foo(Bar(2))), None);
+}
+
+#[test]
+fn test_send_sync() {
+    fn is_send_sync<T: Send + Sync>() {}
+
+    is_send_sync::<LinkedHashMap<u32, i32>>();
+    is_send_sync::<crate::Iter<u32, i32>>();
+    is_send_sync::<crate::IterMut<u32, i32>>();
+    is_send_sync::<crate::IntoIter<u32, i32>>();
+    is_send_sync::<crate::Keys<u32, i32>>();
+    is_send_sync::<crate::Values<u32, i32>>();
+    is_send_sync::<crate::Drain<u32, i32>>();
+}
+
+#[cfg(all(feature = "nightly", test, not(miri)))]
+mod bench {
+    extern crate test;
+
+    use super::LinkedHashMap;
+
+    #[bench]
+    fn not_recycled_cycling(b: &mut test::Bencher) {
+        let mut hash_map = LinkedHashMap::with_capacity(1000);
+        for i in 0usize..1000 {
+            hash_map.insert(i, i);
+        }
+        b.iter(|| {
+            for i in 0usize..1000 {
+                hash_map.remove(&i);
+            }
+            hash_map.clear_free_list();
+            for i in 0usize..1000 {
+                hash_map.insert(i, i);
+            }
+        })
+    }
+
+    #[bench]
+    fn recycled_cycling(b: &mut test::Bencher) {
+        let mut hash_map = LinkedHashMap::with_capacity(1000);
+        for i in 0usize..1000 {
+            hash_map.insert(i, i);
+        }
+        b.iter(|| {
+            for i in 0usize..1000 {
+                hash_map.remove(&i);
+            }
+            for i in 0usize..1000 {
+                hash_map.insert(i, i);
+            }
+        })
+    }
+}
diff --git a/src/tests/serde.rs b/src/tests/serde.rs
new file mode 100644
index 000000000..a6dd46ce4
--- /dev/null
+++ b/src/tests/serde.rs
@@ -0,0 +1,36 @@
+#![cfg(feature = "serde_impl")]
+
+extern crate linked_hash_map;
+use linked_hash_map::LinkedHashMap;
+
+extern crate serde_test;
+use serde_test::{assert_tokens, Token};
+
+#[test]
+fn test_ser_de_empty() {
+    let map = LinkedHashMap::<char, u32>::new();
+
+    assert_tokens(&map, &[Token::Map { len: Some(0) }, Token::MapEnd]);
+}
+
+#[test]
+fn test_ser_de() {
+    let mut map = LinkedHashMap::new();
+    map.insert('b', 20);
+    map.insert('a', 10);
+    map.insert('c', 30);
+
+    assert_tokens(
+        &map,
+        &[
+            Token::Map { len: Some(3) },
+            Token::Char('b'),
+            Token::I32(20),
+            Token::Char('a'),
+            Token::I32(10),
+            Token::Char('c'),
+            Token::I32(30),
+            Token::MapEnd,
+        ],
+    );
+}
