/**
   * Hedwig Console
   *
   * @param args arguments
   * @throws IOException
   * @throws InterruptedException
   */
  public HedwigConsole(String[] args) throws IOException, InterruptedException {
    // Setup Terminal
    terminal = Terminal.setupTerminal();
    HedwigCommands.init();
    cl.parseOptions(args);

    if (cl.getCommand() == null) {
      inConsole = true;
    } else {
      inConsole = false;
    }

    org.apache.bookkeeper.conf.ClientConfiguration bkClientConf =
        new org.apache.bookkeeper.conf.ClientConfiguration();
    ServerConfiguration hubServerConf = new ServerConfiguration();
    String serverCfgFile = cl.getOption("server-cfg");
    if (serverCfgFile != null) {
      try {
        hubServerConf.loadConf(new File(serverCfgFile).toURI().toURL());
      } catch (ConfigurationException e) {
        throw new IOException(e);
      }
      try {
        bkClientConf.loadConf(new File(serverCfgFile).toURI().toURL());
      } catch (ConfigurationException e) {
        throw new IOException(e);
      }
    }

    ClientConfiguration hubClientCfg = new ClientConfiguration();
    String clientCfgFile = cl.getOption("client-cfg");
    if (clientCfgFile != null) {
      try {
        hubClientCfg.loadConf(new File(clientCfgFile).toURI().toURL());
      } catch (ConfigurationException e) {
        throw new IOException(e);
      }
    }

    printMessage("Connecting to zookeeper/bookkeeper using HedwigAdmin");
    try {
      admin = new HedwigAdmin(bkClientConf, hubServerConf);
      admin.getZkHandle().register(new MyWatcher());
    } catch (Exception e) {
      throw new IOException(e);
    }

    printMessage("Connecting to default hub server " + hubClientCfg.getDefaultServerHost());
    hubClient = new HedwigClient(hubClientCfg);
    publisher = hubClient.getPublisher();
    subscriber = hubClient.getSubscriber();
    subscriber.addSubscriptionListener(new ConsoleSubscriptionListener());

    // other parameters
    myRegion = hubServerConf.getMyRegion();
  }
    void receiveNumModM(
        final ByteString topic, final ByteString subid, final int start, final int num, final int M)
        throws Exception {
      org.apache.hedwig.filter.ServerMessageFilter filter =
          new org.apache.hedwig.filter.ServerMessageFilter() {

            @Override
            public org.apache.hedwig.filter.ServerMessageFilter initialize(Configuration conf) {
              // do nothing
              return this;
            }

            @Override
            public void uninitialize() {
              // do nothing;
            }

            @Override
            public org.apache.hedwig.filter.MessageFilterBase setSubscriptionPreferences(
                ByteString topic,
                ByteString subscriberId,
                org.apache.hedwig.protocol.PubSubProtocol.SubscriptionPreferences preferences) {
              // do nothing;
              return this;
            }

            @Override
            public boolean testMessage(org.apache.hedwig.protocol.PubSubProtocol.Message msg) {
              int value = Integer.valueOf(msg.getBody().toStringUtf8());
              return 0 == value % M;
            }
          };
      filter.initialize(conf.getConf());

      org.apache.hedwig.protocol.PubSubProtocol.SubscriptionOptions opts =
          org.apache.hedwig.protocol.PubSubProtocol.SubscriptionOptions.newBuilder()
              .setCreateOrAttach(
                  org.apache.hedwig.protocol.PubSubProtocol.SubscribeRequest.CreateOrAttach.ATTACH)
              .build();
      subscriber.subscribe(topic, subid, opts);
      final int base = start + M - start % M;
      final AtomicInteger expected = new AtomicInteger(base);
      final CountDownLatch latch = new CountDownLatch(1);
      subscriber.startDeliveryWithFilter(
          topic,
          subid,
          new org.apache.hedwig.client.api.MessageHandler() {
            public synchronized void deliver(
                ByteString topic,
                ByteString subscriberId,
                org.apache.hedwig.protocol.PubSubProtocol.Message msg,
                org.apache.hedwig.util.Callback<Void> callback,
                Object context) {
              try {
                int value = Integer.valueOf(msg.getBody().toStringUtf8());
                // duplicated messages received, ignore them
                if (value > start) {
                  if (value == expected.get()) {
                    expected.addAndGet(M);
                  } else {
                    logger.error(
                        "Did not receive expected value, expected {}, got {}",
                        expected.get(),
                        value);
                    expected.set(0);
                    latch.countDown();
                  }
                  if (expected.get() == (base + num * M)) {
                    latch.countDown();
                  }
                }
                callback.operationFinished(context, null);
              } catch (Exception e) {
                logger.error("Received bad message", e);
                latch.countDown();
              }
            }
          },
          (org.apache.hedwig.filter.ClientMessageFilter) filter);
      assertTrue(
          "Timed out waiting for messages mod " + M + " expected is " + expected.get(),
          latch.await(10, TimeUnit.SECONDS));
      assertEquals(
          "Should be expected message with " + (base + num * M), (base + num * M), expected.get());
      subscriber.stopDelivery(topic, subid);
      filter.uninitialize();
      subscriber.closeSubscription(topic, subid);
    }