class SubjectMatterExpertDaoImpl implements SubjectMatterExpertDao {

    @Override
    public SubjectMatterExpertContactDetails getSubjectMatterExpertByKey(SubjectMatterExpertKey subjectMatterExpertKey)
    {
        // Get LDAP specific configuration settings.
        final String ldapUrl = configurationHelper.getProperty(ConfigurationValue.LDAP_URL);
        final String ldapBase = configurationHelper.getProperty(ConfigurationValue.LDAP_BASE);
        final String ldapUserDn = configurationHelper.getProperty(ConfigurationValue.LDAP_USER_DN);
        final String credStashEncryptionContext = configurationHelper.getProperty(ConfigurationValue.CREDSTASH_HERD_ENCRYPTION_CONTEXT);
        final String ldapUserCredentialName = configurationHelper.getProperty(ConfigurationValue.LDAP_USER_CREDENTIAL_NAME);

        // Log configuration values being used to create LDAP context source.
        LOGGER.info("Creating LDAP context source using the following parameters: {}=\"{}\" {}=\"{}\" {}=\"{}\" {}=\"{}\" {}=\"{}\"...",
            ConfigurationValue.LDAP_URL.getKey(), ldapUrl, ConfigurationValue.LDAP_BASE.getKey(), ldapBase, ConfigurationValue.LDAP_USER_DN.getKey(),
            ldapUserDn, ConfigurationValue.CREDSTASH_HERD_ENCRYPTION_CONTEXT.getKey(), credStashEncryptionContext,
            ConfigurationValue.LDAP_USER_CREDENTIAL_NAME.getKey(), ldapUserCredentialName);

        // Retrieve LDAP user password from the credstash.
        String ldapUserPassword;
        try
        {
            ldapUserPassword = credStashHelper.getCredentialFromCredStash(credStashEncryptionContext, ldapUserCredentialName);
        }
        catch (CredStashGetCredentialFailedException e)
        {
            throw new IllegalStateException(e);
        }

        // Create and initialize an LDAP context source.
        LdapContextSource contextSource = new LdapContextSource();
        contextSource.setUrl(ldapUrl);
        contextSource.setBase(ldapBase);
        contextSource.setUserDn(ldapUserDn);
        contextSource.setPassword(ldapUserPassword);
        contextSource.afterPropertiesSet();

        // Create an LDAP template.
        LdapTemplate ldapTemplate = new LdapTemplate(contextSource);

        // Create an LDAP query.
        LdapQuery ldapQuery = query().where(configurationHelper.getProperty(ConfigurationValue.LDAP_ATTRIBUTE_USER_ID)).is(subjectMatterExpertKey.getUserId());

        // Create a subject matter expert contact details mapper.
        SubjectMatterExpertContactDetailsMapper subjectMatterExpertContactDetailsMapper =
            new SubjectMatterExpertContactDetailsMapper(configurationHelper.getProperty(ConfigurationValue.LDAP_ATTRIBUTE_USER_FULL_NAME),
                configurationHelper.getProperty(ConfigurationValue.LDAP_ATTRIBUTE_USER_JOB_TITLE),
                configurationHelper.getProperty(ConfigurationValue.LDAP_ATTRIBUTE_USER_EMAIL_ADDRESS),
                configurationHelper.getProperty(ConfigurationValue.LDAP_ATTRIBUTE_USER_TELEPHONE_NUMBER));

        // Gets information for the specified subject matter expert.
        List<SubjectMatterExpertContactDetails> subjectMatterExpertContactDetailsList =
            ldapOperations.search(ldapTemplate, ldapQuery, subjectMatterExpertContactDetailsMapper);

        // Return the results.
        return CollectionUtils.isNotEmpty(subjectMatterExpertContactDetailsList) ? subjectMatterExpertContactDetailsList.get(0) : null;
    }

}