public async Task <ActionResult> Edit(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }

            //var user = UserManager.Users.FirstOrDefault(u => u.Id == id);
            var user = await UserManager.FindByIdAsync(id);

            if (user == null)
            {
                ViewBag.ErrorMessage = $"User with Id = {id} cannot be found";
                return(View("NotFound"));
                //return HttpNotFound();
            }

            var userRoles = await UserManager.GetRolesAsync(user.Id);

            var userClaims = await UserManager.GetClaimsAsync(user.Id);

            // All Roles List, with True False for Selected/Unselected Role list
            var viewModel = new EditUserFormViewModel()
            {
                Id                = user.Id,
                Email             = user.Email,
                DrivingLicense    = user.DrivingLicense,
                Phone             = user.Phone,
                SelectedRolesList = RoleManager.Roles.ToList().Select(x => new SelectListItem()
                {
                    Selected = userRoles.Contains(x.Name),
                    Text     = x.Name,
                    Value    = x.Name
                }).ToList(),
                SelectedClaimsList = ClaimsStore.AllClaims.Select(x => new SelectListItem()
                {
                    Selected = userClaims.Any(uc => uc.Value == x.Value),
                    Text     = x.Type,
                    Value    = x.Value
                }).ToList()
            };


            return(View("EditUserForm", viewModel));
        }
        public async Task <ActionResult> Edit(EditUserFormViewModel viewModel, string[] selectedRoles, string[] selectedClaims)
        {
            // selectedRole is the name of the checkbox list on the html form

            // HERE WE ARE USING SAME FORM & VIEWMODEL FOR ADD & EDIT
            // BUT BOTH SCENARIOS ARE DIFFERENT,
            // ADD NEED PASSWORD & CONFIRM PASSWORD IN VIEW & VIEWMODEL & THEY ARE MANDATORY
            // WITH THEM MODEL WILL BE NOT VALIDATED
            // EDIT DO NOT NEED PASSWORD & CONFIRM PASSWORD IN VIEW & VIEWMODEL
            // MODEL VALIDATION WILL STOP US FROM EDITING USER AND WILL ASK FOR PASSWORKD & CONFIRM PASSWORD
            // SPLIT VIEWS & VIEWMODELS FOR ADD & EDIT

            IdentityResult result = null;

            //var user = UserManager.Users.FirstOrDefault(u => u.Id == viewModel.Id);

            ApplicationUser user = await UserManager.FindByIdAsync(viewModel.Id);

            IList <string> userRoles = await UserManager.GetRolesAsync(viewModel.Id);

            IList <Claim> userClaims = await UserManager.GetClaimsAsync(viewModel.Id);

            // If SelectedRoles is null, then add Empty String
            selectedRoles = selectedRoles ?? new string[] { };

            selectedClaims = selectedClaims ?? new string[] { };

            IEnumerable <SelectListItem> SelectedRolesList = RoleManager.Roles.ToList().Select(x => new SelectListItem()
            {
                Selected = userRoles.Contains(x.Name),
                Text     = x.Name,
                Value    = x.Name
            });

            IEnumerable <SelectListItem> SelectedClaimsList = ClaimsStore.AllClaims.Select(x => new SelectListItem()
            {
                Selected = userClaims.Any(uc => uc.Value == x.Value),
                Text     = x.Type,
                Value    = x.Value
            });

            // User is to be Edited


            if (!ModelState.IsValid)
            {
                // Add Error
                ModelState.AddModelError("", "Something failed.");

                return(View("EditUserForm", new EditUserFormViewModel()
                {
                    Id = user.Id,
                    Email = user.Email,
                    DrivingLicense = user.DrivingLicense,
                    Phone = user.Phone,
                    SelectedRolesList = SelectedRolesList,
                    SelectedClaimsList = SelectedClaimsList
                }));
            }


            if (user == null)
            {
                ViewBag.ErrorMessage = $"User with Id = {viewModel.Email} cannot be found";
                return(View("NotFound"));
                //return HttpNotFound();
            }

            user.UserName       = viewModel.Email;
            user.Email          = viewModel.Email;
            user.DrivingLicense = viewModel.DrivingLicense;
            user.Phone          = viewModel.Phone;

            result = await UserManager.UpdateAsync(user);

            // Error Occurs While Updating User, no need to add Roles & Claims
            if (!result.Succeeded)
            {
                ViewBag.Message = "Error occurred while updating Record(s)";
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError("", error);
                }

                // show view
                return(View("EditUserForm", new EditUserFormViewModel()
                {
                    Id = user.Id,
                    Email = user.Email,
                    DrivingLicense = user.DrivingLicense,
                    Phone = user.Phone,
                    SelectedRolesList = SelectedRolesList,
                    SelectedClaimsList = SelectedClaimsList
                }));
            }

            // Only add newly added roles, do not add already added roles.
            result = await UserManager.AddToRolesAsync(user.Id, selectedRoles.Except(userRoles).ToArray <string>());


            // Error occurs while adding roles array, but user edited
            if (!result.Succeeded)
            {
                // Add error
                ViewBag.Message = "Error occurred while adding Record(s)";
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError("", error);
                }

                // Show view
                return(View("EditUserForm", new EditUserFormViewModel()
                {
                    Id = user.Id,
                    Email = user.Email,
                    DrivingLicense = user.DrivingLicense,
                    Phone = user.Phone,
                    SelectedRolesList = SelectedRolesList,
                    SelectedClaimsList = SelectedClaimsList
                }));
            }

            // Remove all roles other than selected roles.
            result = await UserManager.RemoveFromRolesAsync(user.Id, userRoles.Except(selectedRoles).ToArray <string>());

            // Error occurs while removing roles, but user edited, role added, not removed
            if (!result.Succeeded)
            {
                ViewBag.Message = "Error occurred while updating Record(s)";
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError("", error);
                }

                return(View("EditUserForm", new EditUserFormViewModel()
                {
                    Id = user.Id,
                    Email = user.Email,
                    DrivingLicense = user.DrivingLicense,
                    Phone = user.Phone,
                    SelectedRolesList = SelectedRolesList,
                    SelectedClaimsList = SelectedClaimsList
                }));
            }

            // Removing Claim Array
            foreach (var claim in userClaims)
            {
                result = await UserManager.RemoveClaimAsync(user.Id, claim);
            }


            if (!result.Succeeded)
            {
                ViewBag.Message = "Error occurred while updating Record(s)";
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError("", error);
                }

                return(View("EditUserForm", new EditUserFormViewModel()
                {
                    Id = user.Id,
                    Email = user.Email,
                    DrivingLicense = user.DrivingLicense,
                    Phone = user.Phone,
                    SelectedRolesList = SelectedRolesList,
                    SelectedClaimsList = SelectedClaimsList
                }));
            }

            //IList<Claim> selectedClaimsOnForm = new List<Claim>();

            List <Claim> selectedClaimsOnForm = ClaimsStore.AllClaims.Where(c => selectedClaims.Contains(c.Value)).ToList();

            // Adding Claim Array
            foreach (var claim in selectedClaimsOnForm)
            {
                result = await UserManager.AddClaimAsync(user.Id, claim);
            }


            if (!result.Succeeded)
            {
                ViewBag.Message = "Error occurred while updating Record(s)";
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError("", error);
                }

                return(View("EditUserForm", new EditUserFormViewModel()
                {
                    Id = user.Id,
                    Email = user.Email,
                    DrivingLicense = user.DrivingLicense,
                    Phone = user.Phone,
                    SelectedRolesList = SelectedRolesList,
                    SelectedClaimsList = SelectedClaimsList
                }));
            }

            // User Added, Role Added, Role Removed Successfully. Show List Role
            ViewBag.Message = "Record(s) updated successfully.";
            return(List());
        }