class SetupStatusViewModelPopulator extends AsyncAdaptor {

    public SetupStatusViewModel populateViewModel(long projectId,
                                                  UserResource loggedInUser) {
        ProjectResource project = projectService.getById(projectId);
        boolean monitoringOfficer = monitoringOfficerService.isMonitoringOfficerOnProject(projectId, loggedInUser.getId()).getSuccess();

        CompetitionResource competition = competitionRestService.getCompetitionById(project.getCompetition()).getSuccess();

        RestResult<OrganisationResource> organisationResult = projectRestService.getOrganisationByProjectAndUser(project.getId(), loggedInUser.getId());
        ProjectTeamStatusResource teamStatus = statusService.getProjectTeamStatus(project.getId(), Optional.of(loggedInUser.getId()));

        CompletableFuture<ProjectTeamStatusResource> teamStatusRequest = async(() -> statusService.getProjectTeamStatus(project.getId(), Optional.empty()));
        CompletableFuture<OrganisationResource> organisationRequest = async(() -> monitoringOfficer ?
                projectService.getLeadOrganisation(project.getId()) :
                projectRestService.getOrganisationByProjectAndUser(project.getId(), loggedInUser.getId()).getSuccess());

        List<SetupStatusStageViewModel> stages = competition.getProjectSetupStages().stream()
                .filter(stage -> (ProjectSetupStage.BANK_DETAILS != stage) || showBankDetails(organisationResult, teamStatus))
                .map(stage -> toStageViewModel(stage, project, competition, loggedInUser, monitoringOfficer, teamStatusRequest, organisationRequest))
                .collect(toList());

        boolean isInvestorPartnership = FundingType.INVESTOR_PARTNERSHIPS == competition.getFundingType();

        RestResult<CompetitionPostAwardServiceResource> competitionPostAwardServiceResource = competitionSetupPostAwardServiceRestService.getPostAwardService(project.getCompetition());

        boolean isProjectManager = projectService.isProjectManager(loggedInUser.getId(), projectId);
        boolean isProjectFinanceContact = projectService.isProjectFinanceContact(loggedInUser.getId(), projectId);

        return new SetupStatusViewModel(
                project,
                monitoringOfficer,
                stages,
                competition.isLoan(),
                showApplicationSummaryLink(project, loggedInUser, monitoringOfficer),
                isInvestorPartnership,
                isProjectManager,
                isProjectFinanceContact,
                competitionPostAwardServiceResource.getSuccess().getPostAwardService(),
                navigationUtils.getLiveProjectsLandingPageUrl());
    }

}