@Override
    public void messageReceived(DoveMQMessage message) {

      byte[] body = message.getPayload();
      String bString = new String(body);

      if ("TOPIC_TEST_DONE".equalsIgnoreCase(bString)) {
        shutdown = true;
      } else {
        messageReceivedCount.incrementAndGet();
      }
    }
  public static void main(String[] args) throws InterruptedException, FileNotFoundException {
    brokerIP = args[0];
    numIterations = Integer.parseInt(args[1]);
    endpointName = "TestPubSub";

    ConnectionFactory.initialize(endpointName);
    numSubscribers = topicHierarchies.length;
    ExecutorService executor = Executors.newFixedThreadPool(numSubscribers);
    CountDownLatch startSignal = new CountDownLatch(1);
    CountDownLatch doneSignal = new CountDownLatch(numSubscribers);

    TestSubscriber[] subscribers = new TestSubscriber[numSubscribers];
    for (int i = 0; i < numSubscribers; i++) {
      TestSubscriber subscriber = new TestSubscriber(startSignal, doneSignal, i);
      subscribers[i] = subscriber;
      executor.submit(subscriber);
    }

    startSignal.countDown();

    Thread.sleep(10000);

    Session session = ConnectionFactory.createSession(brokerIP);
    Publisher publisher = session.createHierarchicalTopicPublisher("root");
    final AtomicInteger messageAckCount = new AtomicInteger(0);
    publisher.registerMessageAckReceiver(
        new DoveMQMessageAckReceiver() {

          @Override
          public void messageAcknowledged(DoveMQMessage message) {
            messageAckCount.incrementAndGet();
          }
        });

    System.out.println("created publisher");
    int messagesSent = 0;

    Random randomGenerator = new Random();
    for (int iter = 0; iter < numIterations; iter++) {

      for (String hierarchy : publishTopicHierarchies) {
        DoveMQMessage message = EndpointTestUtils.createEncodedMessage(randomGenerator, true);
        message.setTopicPublishHierarchy(hierarchy);
        publisher.publishMessage(message);
        messagesSent++;

        if (messagesSent % 10000 == 0) {
          System.out.println("Sent message count: " + messagesSent);
        }
      }
    }

    for (String hierarchy : shutdownMessageHierarchies) {
      DoveMQMessage message = MessageFactory.createMessage();
      message.addPayload("TOPIC_TEST_DONE".getBytes());
      message.setTopicPublishHierarchy(hierarchy);
      publisher.publishMessage(message);
      messagesSent++;
    }

    while (messageAckCount.get() < messagesSent) {
      try {
        Thread.sleep(5000);
        System.out.println("publisher waiting: " + messagesSent + " " + messageAckCount.get());
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      }
    }

    doneSignal.await();

    assertTrue(subscribers[0].numMessagesReceived() == 14 * numIterations);
    assertTrue(subscribers[1].numMessagesReceived() == 7 * numIterations);
    assertTrue(subscribers[2].numMessagesReceived() == 4 * numIterations);
    assertTrue(subscribers[3].numMessagesReceived() == 2 * numIterations);
    assertTrue(subscribers[4].numMessagesReceived() == 2 * numIterations);
    assertTrue(subscribers[5].numMessagesReceived() == 6 * numIterations);
    assertTrue(subscribers[6].numMessagesReceived() == 2 * numIterations);
    assertTrue(subscribers[7].numMessagesReceived() == 2 * numIterations);
    assertTrue(subscribers[8].numMessagesReceived() == 1 * numIterations);

    Thread.sleep(2000);
    executor.shutdown();

    ConnectionFactory.shutdown();
  }