class IdpAuthnResponseTranslatorService {

    public InboundResponseFromIdpDto translate(SamlAuthnResponseTranslatorDto samlResponseDto) {
        Response response = stringToOpenSamlResponseTransformer.apply(samlResponseDto.getSamlResponse());
        MdcHelper.addContextToMdc(response);
        try {
            InboundResponseFromIdp idaResponseFromIdp = samlResponseToIdaResponseIssuedByIdpTransformer.apply(response);
            UnknownMethodAlgorithmLogger.probeResponseForMethodAlgorithm(idaResponseFromIdp);
            if (idaResponseFromIdp.getAuthnStatementAssertion().isPresent()) {
                Assertion authnStatementAssertion = stringToAssertionTransformer.apply(idaResponseFromIdp.getAuthnStatementAssertion().get().getUnderlyingAssertionBlob());
                logAnalytics(authnStatementAssertion, AUTHN_STATEMENT);
            }

            Assertion matchingDatasetAssertion = null;
            if (idaResponseFromIdp.getMatchingDatasetAssertion().isPresent()) {
                matchingDatasetAssertion = stringToAssertionTransformer.apply(idaResponseFromIdp.getMatchingDatasetAssertion().get().getUnderlyingAssertionBlob());
                logAnalytics(matchingDatasetAssertion, MATCHING_DATASET);

                final String matchingServiceEntityId = samlResponseDto.getMatchingServiceEntityId();
                if (transactionsConfigProxy.isProxyNodeEntityId(matchingServiceEntityId)) {
                    EidasAuthnResponseAttributesHashLogger.logEidasAttributesHash(matchingDatasetAssertion, response, matchingServiceEntityId);
                }
            }

            InboundResponseFromIdpData inboundResponseFromIdpData = inboundResponseFromIdpDataGenerator.generate(idaResponseFromIdp, samlResponseDto.getMatchingServiceEntityId());

            Optional<LevelOfAssurance> levelOfAssurance = Optional.empty();
            if (!Strings.isNullOrEmpty(inboundResponseFromIdpData.getLevelOfAssurance())) {
                levelOfAssurance = Optional.of(LevelOfAssurance.valueOf(inboundResponseFromIdpData.getLevelOfAssurance()));
            }

            logVerifiedAttributes(idaResponseFromIdp, matchingDatasetAssertion, levelOfAssurance);

            return new InboundResponseFromIdpDto(
                    inboundResponseFromIdpData.getStatus(),
                    inboundResponseFromIdpData.getStatusMessage(),
                    inboundResponseFromIdpData.getIssuer(),
                    inboundResponseFromIdpData.getEncryptedAuthnAssertion(),
                    inboundResponseFromIdpData.getEncryptedMatchingDatasetAssertion(),
                    inboundResponseFromIdpData.getPersistentId(),
                    inboundResponseFromIdpData.getPrincipalIpAddressAsSeenByIdp(),
                    levelOfAssurance,
                    inboundResponseFromIdpData.getIdpFraudEventId(),
                    inboundResponseFromIdpData.getFraudIndicator(),
                    inboundResponseFromIdpData.getNotOnOrAfter());
        } catch (SamlTransformationErrorException e) {
            throw new SamlContextException(response.getID(), response.getIssuer().getValue(), e);
        }
    }

    @Inject public  IdpAuthnResponseTranslatorService(StringToOpenSamlObjectTransformer<Response> stringToOpenSamlResponseTransformer,
                                             StringToOpenSamlObjectTransformer<Assertion> stringToAssertionTransformer,
                                             @Named("IdpSamlResponseTransformer") DecoratedSamlResponseToIdaResponseIssuedByIdpTransformer samlResponseToIdaResponseIssuedByIdpTransformer,
                                             InboundResponseFromIdpDataGenerator inboundResponseFromIdpDataGenerator,
                                             IdpAssertionMetricsCollector idpAssertionMetricsCollector,
                                             TransactionsConfigProxy transactionsConfigProxy);

}