public async Task PublishUpdateMessagesAsync(User user, UpdateEmailAndUsernameResult updateResult)
        {
            await _messageAggregator.PublishAsync(new UserUpdatedMessage()
            {
                UserAreaCode = user.UserAreaCode,
                UserId       = user.UserId
            });

            if (updateResult.HasEmailChanged)
            {
                await _messageAggregator.PublishAsync(new UserEmailUpdatedMessage()
                {
                    UserAreaCode = user.UserAreaCode,
                    UserId       = user.UserId
                });
            }

            if (updateResult.HasUsernameChanged)
            {
                await _messageAggregator.PublishAsync(new UserUsernameUpdatedMessage()
                {
                    UserAreaCode = user.UserAreaCode,
                    UserId       = user.UserId
                });
            }
        }
        private async Task <UpdateEmailAndUsernameResult> UpdateEmailAsync(
            IUserAreaDefinition userArea,
            string email,
            string username,
            User user,
            IExecutionContext executionContext
            )
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }
            if (executionContext == null)
            {
                throw new ArgumentNullException(nameof(executionContext));
            }

            if (userArea.UseEmailAsUsername && !string.IsNullOrEmpty(username))
            {
                throw ValidationErrorException.CreateWithProperties("Username field should be empty becuase the specified user area uses the email as the username.", USERNAME_PROPERTY);
            }

            var result         = new UpdateEmailAndUsernameResult();
            var isEmailDefined = !string.IsNullOrWhiteSpace(email);

            if (!isEmailDefined && (userArea.UseEmailAsUsername || userArea.AllowPasswordSignIn))
            {
                throw ValidationErrorException.CreateWithProperties("Email field is required.", EMAIL_PROPERTY);
            }
            else if (!isEmailDefined && !string.IsNullOrWhiteSpace(user.Email))
            {
                user.Email         = null;
                user.UniqueEmail   = null;
                user.EmailDomainId = null;

                result.HasEmailChanged = true;
                return(result);
            }
            else if (!isEmailDefined)
            {
                return(result);
            }

            var emailFormatResult = _userDataFormatter.FormatEmailAddress(userArea, email);

            if (emailFormatResult == null)
            {
                throw ValidationErrorException.CreateWithProperties("Email is in an invalid format.", EMAIL_PROPERTY);
            }

            result.HasEmailChanged = user.Email != emailFormatResult.NormalizedEmailAddress || user.UniqueEmail != emailFormatResult.UniqueEmailAddress;
            if (!result.HasEmailChanged)
            {
                return(result);
            }

            await ValidateNewEmailAsync(userArea, emailFormatResult, user, executionContext);

            user.EmailDomainId = await GetEmailDomainIdAsync(emailFormatResult, executionContext);

            user.Email       = emailFormatResult.NormalizedEmailAddress;
            user.UniqueEmail = emailFormatResult.UniqueEmailAddress;

            if (userArea.UseEmailAsUsername)
            {
                var usernameFormatterResult = _userDataFormatter.FormatUsername(userArea, emailFormatResult);
                if (usernameFormatterResult == null)
                {
                    // This shouldn't happen unless a custom email uniquifier is misbehaving
                    throw ValidationErrorException.CreateWithProperties("Email is invalid as a username.", EMAIL_PROPERTY);
                }

                result.HasUsernameChanged = await UpdateUsernameAsync(userArea, usernameFormatterResult, user, executionContext);
            }

            return(result);
        }