@Test
  public void testAddThenRemoveSameKey() {
    final RelatedObject relatedObject1 = new RelatedObject();
    relatedObject1.setRelatedIntValue(1);

    SimpleObject simpleObject = new SimpleObject();
    simpleObject.setRelatedObjectMap(
        new HashMap<String, RelatedObject>() {
          {
            put("first", relatedObject1);
          }
        });

    simpleObjectDAO.save(simpleObject);

    SimpleObject resultSimpleObject = simpleObjectDAO.findById(simpleObject.getId());

    RelatedObject relatedObject2 = new RelatedObject();
    relatedObject2.setRelatedIntValue(2);

    resultSimpleObject.getRelatedObjectMap().put("second", relatedObject2);
    resultSimpleObject.getRelatedObjectMap().remove("second");

    simpleObjectDAO.save(resultSimpleObject);

    resultSimpleObject = simpleObjectDAO.findById(simpleObject.getId());

    Assert.assertEquals(1, resultSimpleObject.getRelatedObjectMap().size());
    Assert.assertTrue(resultSimpleObject.getRelatedObjectMap().containsKey("first"));
    Assert.assertEquals(
        1, resultSimpleObject.getRelatedObjectMap().get("first").getRelatedIntValue());
  }
  @Test
  public void testUpdateRelatedObjectInList() throws NoSuchItemException {
    RelatedObject relatedObject = new RelatedObject();
    relatedObject.setRelatedIntValue(999);

    SimpleObject simpleObject = new SimpleObject();
    simpleObject.addRelatedObject(relatedObject);

    simpleObjectDAO.save(simpleObject);

    SimpleObject resultSimpleObject = simpleObjectDAO.findById(simpleObject.getId());
    RelatedObject resultRelatedObject = resultSimpleObject.getRelatedObjects().get(0);

    resultRelatedObject.setRelatedIntValue(123);

    //noinspection unchecked
    assertKeys(
        ((DirtyableDBObject) resultSimpleObject).getDirtyKeys(),
        new HashSet(Collections.singleton("relatedObjects")));

    simpleObjectDAO.save(resultSimpleObject);

    Assert.assertEquals(
        123,
        simpleObjectDAO
            .findById(simpleObject.getId())
            .getRelatedObjects()
            .get(0)
            .getRelatedIntValue());
  }
  @Test
  public void testCollectionsEquals() {
    RelatedObject relatedObject1 = new RelatedObject();
    relatedObject1.setRelatedIntValue(1);
    RelatedObject relatedObject2 = new RelatedObject();
    relatedObject2.setRelatedIntValue(2);

    SimpleObject simpleObject = new SimpleObject();
    simpleObject.addRelatedObject(relatedObject1);
    simpleObject.addRelatedObject(relatedObject2);
    simpleObject.addToRelatedObjectSet(relatedObject1);
    simpleObject.addToRelatedObjectSet(relatedObject2);
    simpleObject.addRelatedObject("one", relatedObject1);
    simpleObject.addRelatedObject("two", relatedObject2);

    simpleObjectDAO.save(simpleObject);

    SimpleObject resultSimpleObject1 = simpleObjectDAO.findById(simpleObject.getId());

    Assert.assertTrue(
        simpleObject.getRelatedObjects().equals(resultSimpleObject1.getRelatedObjects()));
    Assert.assertTrue(
        resultSimpleObject1.getRelatedObjects().equals(simpleObject.getRelatedObjects()));
    Assert.assertTrue(
        simpleObject.getRelatedObjectSet().equals(resultSimpleObject1.getRelatedObjectSet()));
    Assert.assertTrue(
        resultSimpleObject1.getRelatedObjectSet().equals(simpleObject.getRelatedObjectSet()));
    Assert.assertTrue(
        simpleObject.getRelatedObjectMap().equals(resultSimpleObject1.getRelatedObjectMap()));
    Assert.assertTrue(
        resultSimpleObject1.getRelatedObjectMap().equals(simpleObject.getRelatedObjectMap()));

    SimpleObject resultSimpleObject2 = simpleObjectDAO.findById(simpleObject.getId());

    Assert.assertTrue(
        resultSimpleObject2.getRelatedObjects().equals(resultSimpleObject1.getRelatedObjects()));
    Assert.assertTrue(
        resultSimpleObject1.getRelatedObjects().equals(resultSimpleObject2.getRelatedObjects()));
    Assert.assertTrue(
        resultSimpleObject2
            .getRelatedObjectSet()
            .equals(resultSimpleObject1.getRelatedObjectSet()));
    Assert.assertTrue(
        resultSimpleObject1
            .getRelatedObjectSet()
            .equals(resultSimpleObject2.getRelatedObjectSet()));
    Assert.assertTrue(
        resultSimpleObject2
            .getRelatedObjectMap()
            .equals(resultSimpleObject1.getRelatedObjectMap()));
    Assert.assertTrue(
        resultSimpleObject1
            .getRelatedObjectMap()
            .equals(resultSimpleObject2.getRelatedObjectMap()));
  }
  @Test
  public void testSetInIterator() throws NoSuchItemException {
    RelatedObject relatedObject = new RelatedObject();
    relatedObject.setRelatedIntValue(999);

    RelatedObject relatedObject2 = new RelatedObject();
    relatedObject2.setRelatedIntValue(123);

    SimpleObject simpleObject = new SimpleObject();
    simpleObject.addRelatedObject(relatedObject);
    simpleObject.addRelatedObject(relatedObject2);

    simpleObjectDAO.save(simpleObject);

    SimpleObject resultSimpleObject = simpleObjectDAO.findById(simpleObject.getId());

    int iteratedItemCount = 0;
    for (ListIterator<RelatedObject> roIterator =
            resultSimpleObject.getRelatedObjects().listIterator();
        roIterator.hasNext(); ) {
      iteratedItemCount++;
      RelatedObject ro = roIterator.next();

      if (ro.getRelatedIntValue() < 500) {
        RelatedObject relatedObject3 = new RelatedObject();
        relatedObject3.setRelatedIntValue(ro.getRelatedIntValue() + 1);

        roIterator.set(relatedObject3);
      }
    }

    Assert.assertEquals(2, iteratedItemCount);

    //noinspection unchecked
    assertKeys(
        ((DirtyableDBObject) resultSimpleObject).getDirtyKeys(),
        new HashSet(Collections.singleton("relatedObjects")));

    simpleObjectDAO.save(resultSimpleObject);

    List<RelatedObject> relatedObjectList =
        simpleObjectDAO.findById(simpleObject.getId()).getRelatedObjects();

    Assert.assertEquals(2, relatedObjectList.size());
    Assert.assertEquals(999, relatedObjectList.get(0).getRelatedIntValue());
    Assert.assertEquals(124, relatedObjectList.get(1).getRelatedIntValue());
  }