void LinkedHashMapTest::testKeySetIterator() {

    LinkedHashMap<int, std::string> map;
    populateMap(map);

    int count = 0;
    Pointer< Iterator<int> > iterator(map.keySet().iterator());
    while (iterator->hasNext()) {
        int key = iterator->next();
        CPPUNIT_ASSERT_EQUAL(count, key);
        count++;
    }

    CPPUNIT_ASSERT_MESSAGE("Iterator didn't cover the expected range", count++ == MAP_SIZE);

    iterator.reset(map.keySet().iterator());
    CPPUNIT_ASSERT_THROW_MESSAGE(
        "Should throw an IllegalStateException",
        iterator->remove(),
        IllegalStateException);

    count = 0;
    while (iterator->hasNext()) {
        iterator->next();
        iterator->remove();
        count++;
    }

    CPPUNIT_ASSERT_MESSAGE("Iterator didn't remove the expected range", count++ == MAP_SIZE);
    CPPUNIT_ASSERT_THROW_MESSAGE(
        "Should throw an IllegalStateException",
        iterator->remove(),
        IllegalStateException);
}
void LinkedHashMapTest::testOrderedKeySet() {

    int i;
    int size = 100;

    {
        LinkedHashMap<int, std::string> map;
        populateMap(map, size);

        Set<int>& set = map.keySet();
        Pointer< Iterator<int> > iter(set.iterator());
        CPPUNIT_ASSERT_MESSAGE("Returned set of incorrect size 1", map.size() == set.size());
        for (i = 0; iter->hasNext(); i++) {
            int key = iter->next();
            CPPUNIT_ASSERT_MESSAGE("Returned incorrect key set 1", key == i);
        }
    }

    LinkedHashMap<int, std::string> map2(200, .75f, true);
    populateMap(map2, size);

    Set<int>& set = map2.keySet();
    Pointer< Iterator<int> > iter(set.iterator());
    CPPUNIT_ASSERT_MESSAGE("Returned set of incorrect size 2", map2.size() == set.size());
    for (i = 0; i < size && iter->hasNext(); i++) {
        int key = iter->next();
        CPPUNIT_ASSERT_MESSAGE("Returned incorrect key set 2", key == i);
    }

    /* fetch the even numbered entries to affect traversal order */
    int p = 0;
    for (i = 0; i < size; i += 2) {
        std::string ii = map2.get(i);
        p = p + Integer::parseInt(ii);
    }
    CPPUNIT_ASSERT_EQUAL_MESSAGE("invalid sum of even numbers", 2450, p);

    set = map2.keySet();
    iter.reset(set.iterator());
    CPPUNIT_ASSERT_MESSAGE("Returned set of incorrect size 3", map2.size() == set.size());
    for (i = 1; i < size && iter->hasNext(); i += 2) {
        int key = iter->next();
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Returned incorrect key set 3", key, i);
    }
    for (i = 0; i < size && iter->hasNext(); i += 2) {
        int key = iter->next();
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Returned incorrect key set 4", key, i);
    }
    CPPUNIT_ASSERT_MESSAGE("Entries left to iterate on", !iter->hasNext());
}
void LinkedHashMapTest::testPut() {

    {
        LinkedHashMap<std::string, std::string> hashMap(101);
        hashMap.put("KEY", "VALUE");
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to install key/value pair",
                                     std::string("VALUE"), hashMap.get("KEY"));
    }
    {
        // Check my actual key instance is returned
        LinkedHashMap<int, std::string> map;
        for (int i = -32767; i < 32768; i++) {
            map.put(i, "foobar");
        }
        int myKey = 0;
        // Put a new value at the old key position
        map.put(myKey, "myValue");
        CPPUNIT_ASSERT(map.containsKey(myKey));
        CPPUNIT_ASSERT_EQUAL(std::string("myValue"), map.get(myKey));
        bool found = false;
        Set<int>& intSet = map.keySet();
        Pointer< Iterator<int> > itr(intSet.iterator());
        while (itr->hasNext()) {
            int key = itr->next();
            found = (key == myKey);
            if (found) {
                break;
            }
        }
        CPPUNIT_ASSERT_MESSAGE("Should find new key instance in hashashMap", found);

        // Add a new key instance and check it is returned
        CPPUNIT_ASSERT_NO_THROW(map.remove(myKey));
        map.put(myKey, "myValue");
        CPPUNIT_ASSERT(map.containsKey(myKey));
        CPPUNIT_ASSERT_EQUAL(std::string("myValue"), map.get(myKey));
        itr.reset(intSet.iterator());
        while (itr->hasNext()) {
            int key = itr->next();
            found = (key == myKey);
            if (found) {
                break;
            }
        }
        CPPUNIT_ASSERT_MESSAGE("Did not find new key instance in hashashMap", found);
    }
    {
        // Ensure keys with identical hashcode are stored separately
        LinkedHashMap<MyKey, std::string> map;

        // Put non-equal object with same hashcode
        MyKey aKey;
        CPPUNIT_ASSERT(!map.containsKey(aKey));
        map.put(aKey, "value");
        MyKey aKey2;
        CPPUNIT_ASSERT_THROW_MESSAGE(
                "Should have thrown NoSuchElementException",
                map.remove(aKey2),
                NoSuchElementException);
        MyKey aKey3;
        map.put(aKey3, "foobar");
        CPPUNIT_ASSERT_EQUAL(std::string("foobar"), map.get(aKey3));
        CPPUNIT_ASSERT_EQUAL(std::string("value"), map.get(aKey));
    }
}
void LinkedHashMapTest::testKeySet() {

    LinkedHashMap<int, std::string> hashMap;
    populateMap(hashMap);
    Set<int>& set = hashMap.keySet();
    CPPUNIT_ASSERT_MESSAGE("Returned set of incorrect size()", set.size() == hashMap.size());
    for (int i = 0; i < MAP_SIZE; i++) {
        CPPUNIT_ASSERT_MESSAGE("Returned set does not contain all keys", set.contains(i));
    }

    {
        LinkedHashMap<int, std::string> localMap;
        localMap.put(0, "test");
        Set<int>& intSet = localMap.keySet();
        CPPUNIT_ASSERT_MESSAGE("Failed with zero key", intSet.contains(0));
    }
    {
        LinkedHashMap<int, std::string> localMap;
        localMap.put(1, "1");
        localMap.put(102, "102");
        localMap.put(203, "203");

        Set<int>& intSet = localMap.keySet();
        Pointer< Iterator<int> > it(intSet.iterator());
        int remove1 = it->next();
        it->hasNext();
        it->remove();
        int remove2 = it->next();
        it->remove();

        ArrayList<int> list;
        list.add(1);
        list.add(102);
        list.add(203);

        list.remove(remove1);
        list.remove(remove2);

        CPPUNIT_ASSERT_MESSAGE("Wrong result", it->next() == list.get(0));
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong size", 1, localMap.size());
        it.reset(intSet.iterator());
        CPPUNIT_ASSERT_MESSAGE("Wrong contents", it->next() == list.get(0));
    }
    {
        LinkedHashMap<int, std::string> map2(101);
        map2.put(1, "1");
        map2.put(4, "4");

        Set<int>& intSet = map2.keySet();
        Pointer< Iterator<int> > it2(intSet.iterator());

        int remove3 = it2->next();
        int next;

        if (remove3 == 1) {
            next = 4;
        } else {
            next = 1;
        }
        it2->hasNext();
        it2->remove();
        CPPUNIT_ASSERT_MESSAGE("Wrong result 2", it2->next() == next);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong size 2", 1, map2.size());
        it2.reset(intSet.iterator());
        CPPUNIT_ASSERT_MESSAGE("Wrong contents 2", it2->next() == next);
    }
}