@Override
  public void log(Level logLevel, String message) {
    if (!messageConsumers.containsKey(logLevel)) {
      return;
    }
    Consumer<String> messageConsumer = messageConsumers.get(logLevel);

    singleThreadedExecutor.execute(
        () -> {
          boolean didErase = eraseFooter();
          // If a previous footer was erased, the message needs to go up a line.
          if (didErase) {
            if (enableTwoCursorUpJump) {
              messageConsumer.accept(String.format(CURSOR_UP_SEQUENCE_TEMPLATE, 2));
              messageConsumer.accept(message);
            } else {
              messageConsumer.accept(CURSOR_UP_SEQUENCE + message);
            }
          } else {
            messageConsumer.accept(message);
          }

          printInBold(footerLines);
        });
  }
@Test
  public void testLog_ignoreIfNoMessageConsumer() {
    AnsiLoggerWithFooter testAnsiLoggerWithFooter =
        new AnsiLoggerWithFooter(
            ImmutableMap.of(Level.LIFECYCLE, createMessageConsumer(Level.LIFECYCLE)),
            singleThreadedExecutor,
            false);

    testAnsiLoggerWithFooter.log(Level.LIFECYCLE, "lifecycle");
    testAnsiLoggerWithFooter.log(Level.PROGRESS, "progress");
    testAnsiLoggerWithFooter.log(Level.INFO, "info");
    testAnsiLoggerWithFooter.log(Level.DEBUG, "debug");
    testAnsiLoggerWithFooter.log(Level.WARN, "warn");
    testAnsiLoggerWithFooter.log(Level.ERROR, "error");

    singleThreadedExecutor.shutDownAndAwaitTermination(SHUTDOWN_TIMEOUT);

    Assert.assertEquals(Collections.singletonList("lifecycle"), messages);
    Assert.assertEquals(Collections.singletonList(Level.LIFECYCLE), levels);
  }