Source:
<code>private void testHandlerProcessMessage(Vertx from, Vertx to, int expectedLocalCount) { FakeEventBusMetrics metrics = FakeMetricsBase.getMetrics(to.eventBus()); CountDownLatch latch1 = new CountDownLatch(1); CountDownLatch latch2 = new CountDownLatch(1); to.runOnContext(v -> { to.eventBus().consumer(ADDRESS1, msg -> { HandlerMetric registration = assertRegistration(metrics); assertEquals(ADDRESS1, registration.address); assertEquals(null, registration.repliedAddress); assertEquals(1, registration.scheduleCount.get()); assertEquals(1, registration.beginCount.get()); assertEquals(0, registration.endCount.get()); assertEquals(0, registration.failureCount.get()); assertEquals(expectedLocalCount, registration.localCount.get()); msg.reply("pong"); }).completionHandler(onSuccess(v2 -> { to.runOnContext(v3 -> { latch1.countDown(); try { <START> awaitLatch(latch2); <END> } catch (InterruptedException e) { fail(e); } }); })); }); try { awaitLatch(latch1); } catch (InterruptedException e) { fail(e); return; } HandlerMetric registration = assertRegistration(metrics); assertEquals(ADDRESS1, registration.address); assertEquals(null, registration.repliedAddress); from.eventBus().send(ADDRESS1, "ping", reply -> { assertEquals(1, registration.scheduleCount.get()); assertEquals(1, registration.beginCount.get()); waitUntil(() -> 1 == registration.endCount.get()); assertEquals(0, registration.failureCount.get()); assertEquals(expectedLocalCount, registration.localCount.get()); testComplete(); }); waitUntil(() -> registration.scheduleCount.get() == 1); assertEquals(0, registration.beginCount.get()); latch2.countDown(); await(); }</code><technical_language>I understand need wait here. explain</technical_language>

Target:
private void testHandlerProcessMessage(Vertx from, Vertx to, int expectedLocalCount) { FakeEventBusMetrics metrics = FakeMetricsBase.getMetrics(to.eventBus()); CountDownLatch latch1 = new CountDownLatch(1); CountDownLatch latch2 = new CountDownLatch(1); to.runOnContext(v -> { to.eventBus().consumer(ADDRESS1, msg -> { HandlerMetric registration = assertRegistration(metrics); assertEquals(ADDRESS1, registration.address); assertEquals(null, registration.repliedAddress); assertEquals(1, registration.scheduleCount.get()); assertEquals(expectedLocalCount, registration.localScheduleCount.get()); assertEquals(1, registration.beginCount.get()); assertEquals(0, registration.endCount.get()); assertEquals(0, registration.failureCount.get()); assertEquals(expectedLocalCount, registration.localBeginCount.get()); msg.reply("pong"); }).completionHandler(onSuccess(v2 -> { to.runOnContext(v3 -> { latch1.countDown(); try { awaitLatch(latch2); } catch (InterruptedException e) { fail(e); } }); })); }); try { awaitLatch(latch1); } catch (InterruptedException e) { fail(e); return; } HandlerMetric registration = assertRegistration(metrics); assertEquals(ADDRESS1, registration.address); assertEquals(null, registration.repliedAddress); from.eventBus().send(ADDRESS1, "ping", reply -> { assertEquals(1, registration.scheduleCount.get()); assertEquals(1, registration.beginCount.get()); waitUntil(() -> 1 == registration.endCount.get()); assertEquals(0, registration.failureCount.get()); assertEquals(expectedLocalCount, registration.localBeginCount.get()); testComplete(); }); waitUntil(() -> registration.scheduleCount.get() == 1); assertEquals(0, registration.beginCount.get()); latch2.countDown(); await(); }