@Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {

            private Iterator<Map.Entry<E, List<E>>> mapIterator = map.entrySet().iterator();
            private Iterator<E> listIterator;
            private E currentElement = null;
            private int expectedModCount = modCount;

            @Override
            public boolean hasNext() {
                if (listIterator == null) {
                    if (!mapIterator.hasNext()) {
                        return false;
                    }
                    listIterator = mapIterator.next().getValue().iterator();
                }
                return listIterator.hasNext() || mapIterator.hasNext();
            }

            @Override
            public E next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                if (listIterator.hasNext()) {
                    currentElement = listIterator.next();
                    return currentElement;
                }
                listIterator = mapIterator.next().getValue().iterator();
                currentElement = listIterator.next();
                return currentElement;
            }

            @Override
            public void remove() {
                if (modCount != expectedModCount) {
                    throw new ConcurrentModificationException();
                }
                if (currentElement == null) {
                    throw new IllegalStateException();
                }
                List<E> list = HashMapBag.this.map.get(currentElement);
                if (list.size() > 1) {
                    listIterator.remove();
                } else {
                    mapIterator.remove();
                }
                HashMapBag.this.size--;
                currentElement = null;
            }
        };
    }