Source:
<code>public IdentifierHolder createParticipant(Study study, StudyParticipant participant, boolean shouldSendVerification) { checkNotNull(study); checkNotNull(participant); if (study.getAccountLimit() > 0) { throwExceptionIfLimitMetOrExceeded(study); } StudyParticipantValidator validator = new StudyParticipantValidator(externalIdService, substudyService, study, true); Validate.entityThrowingException(validator, participant); Account account = accountDao.constructAccount(study, participant.getEmail(), participant.getPhone(), participant.getExternalId(), participant.getPassword()); updateAccountAndRoles(study, account, participant, true); account.setStatus(AccountStatus.UNVERIFIED); boolean sendEmailVerification = shouldSendVerification && study.isEmailVerificationEnabled(); if (participant.getEmail() != null && !sendEmailVerification) { account.setEmailVerified(true); account.setStatus(AccountStatus.ENABLED); } if (participant.getPhone() != null && !shouldSendVerification) { account.setPhoneVerified(true); account.setStatus(AccountStatus.ENABLED); } if (shouldEnableCompleteExternalIdAccount(participant)) { account.setStatus(AccountStatus.ENABLED); } final ExternalIdentifier externalId = externalIdService.beginAssignExternalId(account, participant.getExternalId()); try { accountDao.createAccount(study, account, (modifiedAccount) -> externalIdService.commitAssignExternalId(externalId)); } catch(Exception e) { if (externalId != null) { externalIdService.unassignExternalId(account, externalId.getIdentifier()); } <START> throw e; <END> } if (sendEmailVerification && !study.isAutoVerificationEmailSuppressed()) { accountWorkflowService.sendEmailVerificationToken(study, account.getId(), account.getEmail()); } Phone phone = account.getPhone(); if (phone != null) { smsService.optInPhoneNumber(account.getId(), phone); } if (shouldSendVerification && !study.isAutoVerificationPhoneSuppressed()) { accountWorkflowService.sendPhoneVerificationToken(study, account.getId(), phone); } return new IdentifierHolder(account.getId()); }</code><technical_language>Unit test for this rollback logic</technical_language>

Target:
public IdentifierHolder createParticipant(Study study, StudyParticipant participant, boolean shouldSendVerification) { checkNotNull(study); checkNotNull(participant); if (study.getAccountLimit() > 0) { throwExceptionIfLimitMetOrExceeded(study); } StudyParticipantValidator validator = new StudyParticipantValidator(externalIdService, substudyService, study, true); Validate.entityThrowingException(validator, participant); Account account = accountDao.constructAccount(study, participant.getEmail(), participant.getPhone(), participant.getExternalId(), participant.getPassword()); updateAccountAndRoles(study, account, participant, true); account.setStatus(AccountStatus.UNVERIFIED); boolean sendEmailVerification = shouldSendVerification && study.isEmailVerificationEnabled(); if (participant.getEmail() != null && !sendEmailVerification) { account.setEmailVerified(true); account.setStatus(AccountStatus.ENABLED); } if (participant.getPhone() != null && !shouldSendVerification) { account.setPhoneVerified(true); account.setStatus(AccountStatus.ENABLED); } if (shouldEnableCompleteExternalIdAccount(participant)) { account.setStatus(AccountStatus.ENABLED); } final ExternalIdentifier externalId = beginAssignExternalId(account, participant.getExternalId()); try { accountDao.createAccount(study, account, (modifiedAccount) -> externalIdService.commitAssignExternalId(externalId)); } catch(Exception e) { if (externalId != null) { externalIdService.unassignExternalId(account, externalId.getIdentifier()); } throw e; } if (sendEmailVerification && !study.isAutoVerificationEmailSuppressed()) { accountWorkflowService.sendEmailVerificationToken(study, account.getId(), account.getEmail()); } Phone phone = account.getPhone(); if (phone != null) { smsService.optInPhoneNumber(account.getId(), phone); } if (shouldSendVerification && !study.isAutoVerificationPhoneSuppressed()) { accountWorkflowService.sendPhoneVerificationToken(study, account.getId(), phone); } return new IdentifierHolder(account.getId()); }