/// <summary>
        /// Registers a new member.
        /// </summary>
        /// <param name="model">Register member model.</param>
        /// <param name="logMemberIn">Flag for whether to log the member in upon successful registration.</param>
        /// <returns>Result of registration operation.</returns>
        private async Task <IdentityResult> RegisterMemberAsync(RegisterModel model, bool logMemberIn = true)
        {
            using ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true);

            // U4-10762 Server error with "Register Member" snippet (Cannot save member with empty name)
            // If name field is empty, add the email address instead.
            if (string.IsNullOrEmpty(model.Name) && string.IsNullOrEmpty(model.Email) == false)
            {
                model.Name = model.Email;
            }

            model.Username = (model.UsernameIsEmail || model.Username == null) ? model.Email : model.Username;

            var            identityUser   = MemberIdentityUser.CreateNew(model.Username, model.Email, model.MemberTypeAlias, true, model.Name);
            IdentityResult identityResult = await _memberManager.CreateAsync(
                identityUser,
                model.Password);

            if (identityResult.Succeeded)
            {
                // Update the custom properties
                // TODO: See TODO in MembersIdentityUser, Should we support custom member properties for persistence/retrieval?
                IMember?member = _memberService.GetByKey(identityUser.Key);
                if (member == null)
                {
                    // should never happen
                    throw new InvalidOperationException($"Could not find a member with key: {member?.Key}.");
                }

                if (model.MemberProperties != null)
                {
                    foreach (MemberPropertyModel property in model.MemberProperties.Where(p => p.Value != null)
                             .Where(property => member.Properties.Contains(property.Alias)))
                    {
                        member.Properties[property.Alias]?.SetValue(property.Value);
                    }
                }
                _memberService.Save(member);

                if (logMemberIn)
                {
                    await _memberSignInManager.SignInAsync(identityUser, false);
                }
            }

            return(identityResult);
        }
        /// <summary>
        /// Create a member from the supplied member content data
        ///
        /// All member password processing and creation is done via the identity manager
        /// </summary>
        /// <param name="contentItem">Member content data</param>
        /// <returns>The identity result of the created member</returns>
        private async Task <ActionResult <bool> > CreateMemberAsync(MemberSave contentItem)
        {
            IMemberType?memberType = _memberTypeService.Get(contentItem.ContentTypeAlias);

            if (memberType == null)
            {
                throw new InvalidOperationException($"No member type found with alias {contentItem.ContentTypeAlias}");
            }

            var identityMember = MemberIdentityUser.CreateNew(
                contentItem.Username,
                contentItem.Email,
                memberType.Alias,
                contentItem.IsApproved,
                contentItem.Name);

            IdentityResult created = await _memberManager.CreateAsync(identityMember, contentItem.Password?.NewPassword);

            if (created.Succeeded == false)
            {
                MemberDisplay?forDisplay = _umbracoMapper.Map <MemberDisplay>(contentItem.PersistedContent);
                foreach (IdentityError error in created.Errors)
                {
                    switch (error.Code)
                    {
                    case nameof(IdentityErrorDescriber.InvalidUserName):
                        ModelState.AddPropertyError(
                            new ValidationResult(error.Description, new[] { "value" }),
                            string.Format("{0}login", Constants.PropertyEditors.InternalGenericPropertiesPrefix));
                        break;

                    case nameof(IdentityErrorDescriber.PasswordMismatch):
                    case nameof(IdentityErrorDescriber.PasswordRequiresDigit):
                    case nameof(IdentityErrorDescriber.PasswordRequiresLower):
                    case nameof(IdentityErrorDescriber.PasswordRequiresNonAlphanumeric):
                    case nameof(IdentityErrorDescriber.PasswordRequiresUniqueChars):
                    case nameof(IdentityErrorDescriber.PasswordRequiresUpper):
                    case nameof(IdentityErrorDescriber.PasswordTooShort):
                        ModelState.AddPropertyError(
                            new ValidationResult(error.Description, new[] { "value" }),
                            string.Format("{0}password", Constants.PropertyEditors.InternalGenericPropertiesPrefix));
                        break;

                    case nameof(IdentityErrorDescriber.InvalidEmail):
                        ModelState.AddPropertyError(
                            new ValidationResult(error.Description, new[] { "value" }),
                            string.Format("{0}email", Constants.PropertyEditors.InternalGenericPropertiesPrefix));
                        break;

                    case nameof(IdentityErrorDescriber.DuplicateUserName):
                        ModelState.AddPropertyError(
                            new ValidationResult(error.Description, new[] { "value" }),
                            string.Format("{0}login", Constants.PropertyEditors.InternalGenericPropertiesPrefix));
                        break;

                    case nameof(IdentityErrorDescriber.DuplicateEmail):
                        ModelState.AddPropertyError(
                            new ValidationResult(error.Description, new[] { "value" }),
                            string.Format("{0}email", Constants.PropertyEditors.InternalGenericPropertiesPrefix));
                        break;
                    }
                }
                return(ValidationProblem(forDisplay, ModelState));
            }

            // now re-look up the member, which will now exist
            IMember?member = _memberService.GetByEmail(contentItem.Email);

            if (member is null)
            {
                return(false);
            }

            // map the save info over onto the user
            member = _umbracoMapper.Map <MemberSave, IMember>(contentItem, member);

            int creatorId = _backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Id ?? -1;

            member.CreatorId = creatorId;

            // assign the mapped property values that are not part of the identity properties
            string[] builtInAliases = ConventionsHelper.GetStandardPropertyTypeStubs(_shortStringHelper).Select(x => x.Key).ToArray();
            foreach (ContentPropertyBasic property in contentItem.Properties)
            {
                if (builtInAliases.Contains(property.Alias) == false)
                {
                    member.Properties[property.Alias]?.SetValue(property.Value);
                }
            }

            // now the member has been saved via identity, resave the member with mapped content properties
            _memberService.Save(member);
            contentItem.PersistedContent = member;

            ActionResult <bool> rolesChanged = await AddOrUpdateRoles(contentItem.Groups, identityMember);

            if (!rolesChanged.Value && rolesChanged.Result != null)
            {
                return(rolesChanged.Result);
            }

            return(true);
        }