class GenericQuestionApplicationModelPopulator {

    public GenericQuestionApplicationViewModel populate(ApplicantQuestionResource applicantQuestion) {
        Map<FormInputType, ApplicantFormInputResource> formInputs = applicantQuestion.getApplicantFormInputs()
                .stream()
                .collect(toMap(input -> input.getFormInput().getType(), Function.identity()));
        QuestionResource question = applicantQuestion.getQuestion();
        ApplicationResource application = applicantQuestion.getApplication();
        CompetitionResource competition = applicantQuestion.getCompetition();

        GenericQuestionApplicationViewModelBuilder viewModelBuilder = aGenericQuestionApplicationViewModel();

        ofNullable(formInputs.get(FormInputType.TEXTAREA)).ifPresent(input -> buildTextAreaViewModel(viewModelBuilder, input));
        ofNullable(formInputs.get(FormInputType.MULTIPLE_CHOICE)).ifPresent(input -> buildMultipleChoiceOptionsViewModel(viewModelBuilder, input));
        ofNullable(formInputs.get(FormInputType.FILEUPLOAD)).ifPresent(input -> buildAppendixViewModel(viewModelBuilder, input));
        ofNullable(formInputs.get(FormInputType.TEMPLATE_DOCUMENT)).ifPresent(input -> buildTemplateDocumentViewModel(viewModelBuilder, input));

        applicantQuestion.getApplicantFormInputs()
                .stream()
                .flatMap(input -> input.getApplicantResponses().stream())
                .map(ApplicantFormInputResponseResource::getResponse)
                .max(Comparator.comparing(FormInputResponseResource::getUpdateDate))
                .ifPresent(response -> viewModelBuilder.withLastUpdated(toUkTimeZone(response.getUpdateDate()))
                                                       .withLastUpdatedBy(response.getUpdatedByUser())
                                                       .withLastUpdatedByName(response.getUpdatedByUserName()));

        return viewModelBuilder.withApplicationId(application.getId())
                .withCompetitionName(competition.getName())
                .withApplicationName(application.getName())
                .withCurrentUser(applicantQuestion.getCurrentUser().getId())
                .withQuestionId(question.getId())
                .withQuestionName(question.getShortName())
                .withQuestionSubtitle(question.getName())
                .withQuestionDescription(question.getDescription())
                .withQuestionNumber(question.getQuestionNumber())
                .withQuestionType(question.getQuestionSetupType())
                .withComplete(applicantQuestion.isCompleteByApplicant(applicantQuestion.getCurrentApplicant()))
                .withOpen(application.isOpen() && competition.isOpen())
                .withLeadApplicant(applicantQuestion.getCurrentApplicant().isLead())
                .withAssignButtonsViewModel(assignButtonsPopulator.populate(applicantQuestion, applicantQuestion, false))
                .build();
    }

}