class GenericQuestionReadOnlyViewModelPopulator implements QuestionReadOnlyViewModelPopulator<GenericQuestionReadOnlyViewModel> {

    @Override
    public GenericQuestionReadOnlyViewModel populate(CompetitionResource competition, QuestionResource question, ApplicationReadOnlyData data, ApplicationReadOnlySettings settings) {
        Collection<FormInputResource> formInputs = data.getQuestionIdToApplicationFormInputs().get(question.getId());
        Optional<FormInputResource> answerInput = formInputs.stream().filter(formInput -> formInput.getType().equals(TEXTAREA)
                || formInput.getType().equals(MULTIPLE_CHOICE))
                .findAny();

        Optional<FormInputResource> appendix = formInputs.stream().filter(formInput -> formInput.getType().equals(FILEUPLOAD))
                .findAny();

        Optional<FormInputResource> templateDocument = formInputs.stream().filter(formInput -> formInput.getType().equals(TEMPLATE_DOCUMENT))
                .findAny();

        Optional<FormInputResponseResource> textResponse = answerInput
                .map(input -> data.getFormInputIdToFormInputResponses().get(input.getId()));

        Optional<FormInputResponseResource> appendixResponse = appendix
                .map(input -> data.getFormInputIdToFormInputResponses().get(input.getId()));

        Optional<FormInputResponseResource> templateDocumentResponse = templateDocument
                .map(input -> data.getFormInputIdToFormInputResponses().get(input.getId()));

        return new GenericQuestionReadOnlyViewModel(data, question, questionName(question),
                question.getName(),
                answerInput.map(input -> input.getType().equals(FormInputType.MULTIPLE_CHOICE)
                        ? textResponse.map(FormInputResponseResource::getMultipleChoiceOptionText).orElse(null)
                        : textResponse.map(FormInputResponseResource::getValue).orElse(null)).orElse(null),
                appendixResponse.map(resp -> files(resp, question, data, settings)).orElse(Collections.emptyList()),
                templateDocumentResponse.flatMap(resp -> files(resp, question, data, settings).stream().findFirst()).orElse(null),
                templateDocument.map(FormInputResource::getDescription).orElse(null),
                allFeedback(data, question, settings),
                allScores(data, question, settings),
                inScope(data, settings),
                totalScope(data, settings),
                hasScope(data, question)
            );
    }

}