@Test
  @MongoDbAvailable
  public void testMessageGroupIterator() throws Exception {
    MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
    MongoDbMessageStore store1 = new MongoDbMessageStore(mongoDbFactory);
    MongoDbMessageStore store2 = new MongoDbMessageStore(mongoDbFactory);

    Message<?> message = new GenericMessage<String>("1");
    store2.addMessageToGroup(1, message);
    store1.addMessageToGroup(2, new GenericMessage<String>("2"));
    store2.addMessageToGroup(3, new GenericMessage<String>("3"));

    MongoDbMessageStore store3 = new MongoDbMessageStore(mongoDbFactory);

    Iterator<MessageGroup> iterator = store3.iterator();
    int counter = 0;
    while (iterator.hasNext()) {
      iterator.next();
      counter++;
    }
    assertEquals(3, counter);

    store2.removeMessageFromGroup(1, message);

    iterator = store3.iterator();
    counter = 0;
    while (iterator.hasNext()) {
      iterator.next();
      counter++;
    }
    assertEquals(2, counter);
  }
  @Test
  @MongoDbAvailable
  public void testNonExistingEmptyMessageGroup() throws Exception {
    MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
    MongoDbMessageStore store = new MongoDbMessageStore(mongoDbFactory);

    MessageGroup messageGroup = store.getMessageGroup(1);
    assertNotNull(messageGroup);
    assertTrue(messageGroup instanceof SimpleMessageGroup);
    assertEquals(0, messageGroup.size());
  }
  @Test
  @MongoDbAvailable
  public void testLastReleasedSequenceNumber() throws Exception {
    MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
    MongoDbMessageStore store = new MongoDbMessageStore(mongoDbFactory);

    MessageGroup messageGroup = store.getMessageGroup(1);
    Message<?> message = new GenericMessage<String>("Hello");
    store.addMessageToGroup(messageGroup.getGroupId(), message);
    store.setLastReleasedSequenceNumberForGroup(messageGroup.getGroupId(), 5);
    messageGroup = store.getMessageGroup(1);
    assertEquals(5, messageGroup.getLastReleasedMessageSequenceNumber());
  }
  @Test
  @MongoDbAvailable
  public void testCompleteMessageGroup() throws Exception {
    MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
    MongoDbMessageStore store = new MongoDbMessageStore(mongoDbFactory);

    MessageGroup messageGroup = store.getMessageGroup(1);
    Message<?> message = new GenericMessage<String>("Hello");
    store.addMessageToGroup(messageGroup.getGroupId(), message);
    store.completeGroup(messageGroup.getGroupId());
    messageGroup = store.getMessageGroup(1);
    assertTrue(messageGroup.isComplete());
  }
  @Test
  @MongoDbAvailable
  public void testMessageGroupWithAddedMessage() throws Exception {
    MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
    MongoDbMessageStore store = new MongoDbMessageStore(mongoDbFactory);

    MessageGroup messageGroup = store.getMessageGroup(1);
    Message<?> messageA = new GenericMessage<String>("A");
    Message<?> messageB = new GenericMessage<String>("B");
    store.addMessageToGroup(1, messageA);
    messageGroup = store.addMessageToGroup(1, messageB);
    assertEquals(2, messageGroup.size());
    Message<?> retrievedMessage = store.getMessage(messageA.getHeaders().getId());
    assertNotNull(retrievedMessage);
    assertEquals(retrievedMessage.getHeaders().getId(), messageA.getHeaders().getId());
    // ensure that 'message_group' header that is only used internally is not propagated
    assertNull(retrievedMessage.getHeaders().get("message_group"));
  }
  @Test
  @MongoDbAvailable
  public void testMessageGroupMarkingMessage() throws Exception {
    MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
    MongoDbMessageStore store = new MongoDbMessageStore(mongoDbFactory);

    MessageGroup messageGroup = store.getMessageGroup(1);
    Message<?> messageA = new GenericMessage<String>("A");
    Message<?> messageB = new GenericMessage<String>("B");
    store.addMessageToGroup(1, messageA);
    messageGroup = store.addMessageToGroup(1, messageB);
    assertEquals(0, messageGroup.getMarked().size());
    assertEquals(2, messageGroup.getUnmarked().size());

    messageGroup = store.markMessageFromGroup(1, messageA);
    assertEquals(1, messageGroup.getMarked().size());
    assertEquals(1, messageGroup.getUnmarked().size());

    // validate that the updates were propagated to Mongo as well
    store = new MongoDbMessageStore(mongoDbFactory);

    messageGroup = store.getMessageGroup(1);
    assertEquals(1, messageGroup.getMarked().size());
    assertEquals(1, messageGroup.getUnmarked().size());
  }
  @Test
  @MongoDbAvailable
  public void testMarkAllMessagesInMessageGroup() throws Exception {
    MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
    MongoDbMessageStore store = new MongoDbMessageStore(mongoDbFactory);

    MessageGroup messageGroup = store.getMessageGroup(1);

    store.addMessageToGroup(1, new GenericMessage<String>("1"));
    store.addMessageToGroup(1, new GenericMessage<String>("2"));
    messageGroup = store.addMessageToGroup(1, new GenericMessage<String>("3"));

    assertEquals(3, messageGroup.getUnmarked().size());
    assertEquals(0, messageGroup.getMarked().size());

    messageGroup = store.markMessageGroup(messageGroup);

    assertEquals(0, messageGroup.getUnmarked().size());
    assertEquals(3, messageGroup.getMarked().size());

    store = new MongoDbMessageStore(mongoDbFactory);

    messageGroup = store.getMessageGroup(1);
    assertEquals(0, messageGroup.getUnmarked().size());
    assertEquals(3, messageGroup.getMarked().size());
  }
  @Test
  @MongoDbAvailable
  public void testMultipleMessageStores() throws Exception {
    MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
    MongoDbMessageStore store1 = new MongoDbMessageStore(mongoDbFactory);
    MongoDbMessageStore store2 = new MongoDbMessageStore(mongoDbFactory);

    Message<?> message = new GenericMessage<String>("1");
    store1.addMessageToGroup(1, message);
    store2.addMessageToGroup(1, new GenericMessage<String>("2"));
    store1.addMessageToGroup(1, new GenericMessage<String>("3"));

    MongoDbMessageStore store3 = new MongoDbMessageStore(mongoDbFactory);

    MessageGroup messageGroup = store3.getMessageGroup(1);

    assertEquals(3, messageGroup.getUnmarked().size());

    store3.removeMessageFromGroup(1, message);

    messageGroup = store2.getMessageGroup(1);
    assertEquals(2, messageGroup.getUnmarked().size());
  }
  @Test
  @MongoDbAvailable
  public void testRemoveMessageGroup() throws Exception {
    MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
    MongoDbMessageStore store = new MongoDbMessageStore(mongoDbFactory);

    MessageGroup messageGroup = store.getMessageGroup(1);
    Message<?> message = new GenericMessage<String>("Hello");
    UUID id = message.getHeaders().getId();
    messageGroup = store.addMessageToGroup(1, message);
    assertEquals(1, messageGroup.size());
    message = store.getMessage(id);
    assertNotNull(message);

    store.removeMessageGroup(1);
    MessageGroup messageGroupA = store.getMessageGroup(1);
    assertEquals(0, messageGroupA.size());
    assertFalse(messageGroupA.equals(messageGroup));
  }