public async Task <SendHostEmailResponse> EmailHostAsync(string accessCode, Guid sendingUserId)
        {
            var codeValidationResult = _validatorLocator.Validate <ProjectAccessCodeValidator>(accessCode);

            if (!codeValidationResult.IsValid)
            {
                throw new ValidationFailedException(codeValidationResult.Errors);
            }

            var getUserResponse = (await _userApi.GetBasicUserAsync(sendingUserId));
            var sendingUser     = getUserResponse.Payload;

            if (!getUserResponse.IsSuccess())
            {
                if (getUserResponse.ResponseCode == HttpStatusCode.NotFound)
                {
                    throw new NotFoundException($"User with id {sendingUserId} could not be found");
                }

                throw new InvalidOperationException();
            }

            var userSession = await _guestSessionRepository.CreateItemQuery()
                              .FirstOrDefaultAsync(x => x.UserId == sendingUserId && x.ProjectAccessCode == accessCode);

            if (userSession == null)
            {
                throw new NotFoundException($"User guest session with userId {sendingUserId} and project access code {accessCode} could not be found");
            }

            var project = (await _serviceToServiceProjectApi.GetProjectByAccessCodeAsync(accessCode)).Payload;

            if (project == null)
            {
                throw new NotFoundException($"Project with access code {accessCode} could not be found");
            }

            if (userSession.EmailedHostDateTime != null)
            {
                // This is not an error, but a no-op.
                return(new SendHostEmailResponse
                {
                    EmailSentDateTime = userSession.EmailedHostDateTime.Value,
                    SentBy = sendingUser.Email
                });
            }

            var invite = await _guestInviteRepository.CreateItemQuery()
                         .FirstOrDefaultAsync(x => x.UserId == sendingUserId && x.ProjectAccessCode == accessCode);

            var hostUser = invite == null
                ? (await _userApi.GetBasicUserAsync(project.OwnerId)).Payload
                : (await _userApi.GetBasicUserAsync(invite.InvitedBy)).Payload ?? (await _userApi.GetBasicUserAsync(project.OwnerId)).Payload;

            if (hostUser == null)
            {
                throw new InvalidOperationException($"Unable to find a host user for guest principal {sendingUserId} using access code {accessCode}");
            }

            var response = await _emailSendingService.SendNotifyHostEmailAsync(hostUser.Email, project.ProjectUri, project.Name, sendingUser.FullName, sendingUser.Email, sendingUser.FirstName);

            if (!response.IsSuccess())
            {
                throw new SendEmailException($"Notify host email could not be sent - {response.ResponseCode}, {response.ReasonPhrase}");
            }

            userSession.EmailedHostDateTime = DateTime.UtcNow;

            await _guestSessionRepository.UpdateItemAsync(userSession.Id, userSession);

            return(new SendHostEmailResponse()
            {
                EmailSentDateTime = DateTime.UtcNow,
                SentBy = sendingUser.Email
            });
        }