class GrantOfferLetterTemplatePopulator {

    public GrantOfferLetterTemplateViewModel populate(long projectId) {

        ProjectResource projectResource = projectRestService.getProjectById(projectId).getSuccess();
        String projectName = projectResource.getName();
        long applicationId = projectResource.getApplication();
        CompetitionResource competitionResource = competitionRestService.getCompetitionById(projectResource.getCompetition()).getSuccess();
        ProjectUserResource projectUserResource = projectService.getProjectManager(projectId).get();
        OrganisationResource leadOrg = organisationRestService.getOrganisationById(projectUserResource.getOrganisation()).getSuccess();
        String leadOrgName = leadOrg.getName();
        UserResource user = userRestService.retrieveUserById(projectUserResource.getUser()).getSuccess();
        String projectManagerFirstName = user.getFirstName();
        String projectManagerLastName = user.getLastName();
        List<ProjectFinanceResource> allProjectFinances = projectFinanceRestService.getProjectFinances(projectResource.getId()).getSuccess();
        List<NoteResource> allProjectNotes = new ArrayList<>();
        allProjectFinances.forEach(projectFinance ->
                                           projectFinanceNotesRestService.findAll(projectFinance.getId())
                                                   .ifSuccessful(allProjectNotes::addAll)
        );

        Map<OrganisationResource, ProjectFinanceResource> financesForOrgs = getFinancesForOrgs(projectResource, allProjectFinances);
        IndustrialFinanceTableModel industrialFinanceTableModel = industrialFinanceTableModelPopulator.createTable(financesForOrgs, competitionResource);
        AcademicFinanceTableModel academicFinanceTableModel = academicFinanceTableModelPopulator.createTable(financesForOrgs, competitionResource);
        SummaryFinanceTableModel summaryFinanceTableModel = summaryFinanceTableModelPopulator.createTable(financesForOrgs, competitionResource);

        return new GrantOfferLetterTemplateViewModel(applicationId,
                                                     projectManagerFirstName,
                                                     projectManagerLastName,
                                                     getAddressLines(projectResource),
                                                     projectResource.getCompetitionName(),
                                                     projectName,
                                                     leadOrgName,
                                                     allProjectNotes,
                                                     competitionResource.getTermsAndConditions().getTemplate(),
                                                     industrialFinanceTableModel,
                                                     academicFinanceTableModel,
                                                     summaryFinanceTableModel,
                                                     competitionResource.isProcurement());
    }

    @Autowired public  GrantOfferLetterTemplatePopulator(
            ProjectRestService projectRestService,
            CompetitionRestService competitionRestService,
            ProjectService projectService,
            OrganisationRestService organisationRestService,
            UserRestService userRestService,
            ProjectFinanceRestService projectFinanceRestService,
            ProjectFinanceNotesRestService projectFinanceNotesRestService,
            IndustrialFinanceTableModelPopulator industrialFinanceTableModelPopulator,
            AcademicFinanceTableModelPopulator academicFinanceTableModelPopulator,
            SummaryFinanceTableModelPopulator summaryFinanceTableModelPopulator
    );

}