private static void ApplyGroupMemberChanges(ApplicationTask task, SecurityGroupChange securityGroup, IdentityDescriptor groupDescriptor, IIdentityManagementService ims, IList <TeamFoundationIdentity> existingMembers)
        {
            var existingMemberAccountNames = existingMembers.Select(m => GetAccountName(m));

            // Remove requested members.
            if (securityGroup.RemoveAllUsers)
            {
                foreach (var member in existingMembers)
                {
                    ims.RemoveMemberFromApplicationGroup(groupDescriptor, member.Descriptor);
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(securityGroup.UsersToRemove))
                {
                    foreach (var userToRemove in securityGroup.UsersToRemove.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(u => u.Trim()))
                    {
                        if (existingMemberAccountNames.Any(m => string.Equals(m, userToRemove, StringComparison.OrdinalIgnoreCase)))
                        {
                            PerformUserAction(task, ims, userToRemove, identityToRemove => ims.RemoveMemberFromApplicationGroup(groupDescriptor, identityToRemove.Descriptor));
                        }
                    }
                }
            }

            // Add requested members.
            if (!string.IsNullOrEmpty(securityGroup.UsersToAdd))
            {
                foreach (var userToAdd in securityGroup.UsersToAdd.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(u => u.Trim()))
                {
                    if (!existingMemberAccountNames.Any(m => string.Equals(m, userToAdd, StringComparison.OrdinalIgnoreCase)))
                    {
                        PerformUserAction(task, ims, userToAdd, identityToAdd => ims.AddMemberToApplicationGroup(groupDescriptor, identityToAdd.Descriptor));
                    }
                }
            }
        }
        public static void Apply(ApplicationTask task, TfsTeamProjectCollection tfs, TfsMajorVersion tfsVersion, string teamProjectName, SecurityGroupChange securityGroup)
        {
            var ims               = tfs.GetService <IIdentityManagementService>();
            var css               = tfs.GetService <ICommonStructureService>();
            var teamProject       = css.GetProjectFromName(teamProjectName);
            var groupIdentityName = string.Format(CultureInfo.InvariantCulture, @"[{0}]\{1}", teamProjectName, securityGroup.Name);

            // Create the group if needed.
            var existingGroup = ims.ListApplicationGroups(teamProject.Uri, ReadIdentityOptions.IncludeReadFromSource).FirstOrDefault(g => string.Equals(g.DisplayName, groupIdentityName, StringComparison.OrdinalIgnoreCase));
            var members       = new List <TeamFoundationIdentity>();
            IdentityDescriptor groupDescriptor;

            if (existingGroup == null)
            {
                // There is no existing group with the same name, create one.
                task.Status     = "Creating new \"{0}\" security group".FormatCurrent(groupIdentityName);
                groupDescriptor = ims.CreateApplicationGroup(teamProject.Uri, securityGroup.Name, securityGroup.Description);
            }
            else
            {
                // We have an existing group with the same name, update the description.
                task.Status     = "Updating existing \"{0}\" security group".FormatCurrent(groupIdentityName);
                groupDescriptor = existingGroup.Descriptor;
                var applicationGroupWithMembers = ims.ReadIdentity(groupDescriptor, MembershipQuery.Direct, ReadIdentityOptions.None);
                if (applicationGroupWithMembers.Members != null && applicationGroupWithMembers.Members.Any())
                {
                    members.AddRange(ims.ReadIdentities(applicationGroupWithMembers.Members, MembershipQuery.Direct, ReadIdentityOptions.None).Where(m => m != null));
                }
                if (!string.IsNullOrEmpty(securityGroup.Description))
                {
                    ims.UpdateApplicationGroup(groupDescriptor, GroupProperty.Description, securityGroup.Description);
                }
            }

            // Set permissions.
            if (securityGroup.PermissionGroupChanges.SelectMany(g => g.PermissionChanges).Any(p => p.Action != PermissionChangeAction.None))
            {
                var securityNamespaces = tfs.GetService <ISecurityService>().GetSecurityNamespaces();
                foreach (var groupChange in securityGroup.PermissionGroupChanges.Where(g => g.PermissionChanges.Any(c => c.Action != PermissionChangeAction.None)))
                {
                    foreach (var securityNamespace in securityNamespaces)
                    {
                        var factory = permissionGroupFactories.FirstOrDefault(f => f.AppliesTo(securityNamespace.Description.NamespaceId, groupChange.PermissionGroup.Scope));
                        if (factory != null)
                        {
                            var tokens = factory.GetObjectTokens(tfs, tfsVersion, teamProject.Name, teamProject.Uri);
                            if (tokens != null)
                            {
                                foreach (var token in tokens)
                                {
                                    ApplySecurityNamespacePermissions(token, groupDescriptor, securityNamespace, groupChange.PermissionChanges);
                                }
                            }
                        }
                    }
                }
                task.Status = "Applied security permissions";
            }

            // Set members.
            if (securityGroup.RemoveAllUsers || !string.IsNullOrEmpty(securityGroup.UsersToAdd) || !string.IsNullOrEmpty(securityGroup.UsersToRemove))
            {
                ApplyGroupMemberChanges(task, securityGroup, groupDescriptor, ims, members);
                task.Status = "Applied group member changes";
            }
        }