private CompletableFuture<Collection<IMessageSession>> getMessageSessionsAsync(Date lastUpdatedTime, int lastReceivedSkip, String lastSessionId) { TRACE_LOGGER.debug("Getting '{}' browsable sessions from entity '{}', lastUpdatedTime '{}', lastReceivedSkip '{}', lastSessionId '{}'", PAGESIZE, this.entityPath, lastUpdatedTime, lastReceivedSkip, lastSessionId); return this.miscRequestResponseHandler.getMessageSessionsAsync(lastUpdatedTime, lastReceivedSkip, PAGESIZE, lastSessionId).thenComposeAsync((p) -> { int newLastReceivedSkip = p.getSecondItem(); String[] sessionIds = p.getFirstItem(); ArrayList<IMessageSession> sessionsList = new ArrayList<>(); if (sessionIds != null && sessionIds.length > 0) { TRACE_LOGGER.debug("Got '{}' browsable sessions from entity '{}', receivedSkip '{}'", sessionIds.length, this.entityPath, newLastReceivedSkip); CompletableFuture[] initFutures = new CompletableFuture[sessionIds.length]; int initFutureIndex = 0; String newLastSessionId = sessionIds[sessionIds.length - 1]; for (String sessionId : sessionIds) { BrowsableMessageSession browsableSession = new BrowsableMessageSession(sessionId, this.messagingFactory, this.entityPath, this.entityType); sessionsList.add(browsableSession); initFutures[initFutureIndex++] = browsableSession.initializeAsync(); } CompletableFuture<Void> allInitFuture = CompletableFuture.allOf(initFutures); return allInitFuture.thenComposeAsync((v) -> getMessageSessionsAsync(lastUpdatedTime, newLastReceivedSkip, newLastSessionId), MessagingFactory.INTERNAL_THREAD_POOL).thenApply((c) -> { sessionsList.addAll(c); return sessionsList; }); } else { TRACE_LOGGER.debug("Got no browsable sessions from entity '{}'", this.entityPath); return CompletableFuture.completedFuture(sessionsList); } }, MessagingFactory.INTERNAL_THREAD_POOL); } }