public static void AssignPermissions(this SPSecurableObject securableObject, SPPrincipal principal, SPRoleDefinition roleDefinition, bool replaceAllDefinitions = false, bool copyRoleAssignments = false, bool clearSubscopes = true)
        {
            if (securableObject is SPWeb)
            {
                if (!securableObject.HasUniqueRoleAssignments)
                {
                    securableObject.BreakRoleInheritance(copyRoleAssignments, clearSubscopes);
                }
            }
            else
            {
                securableObject.BreakRoleInheritance(copyRoleAssignments, clearSubscopes);
            }

            SPRoleAssignment roleAssignment = GetAssignment(securableObject, principal);

            if (roleAssignment != null)
            {
                if (replaceAllDefinitions)
                {
                    roleAssignment.RoleDefinitionBindings.RemoveAll();
                    roleAssignment.RoleDefinitionBindings.Add(roleDefinition);

                }
                else
                {
                    if (!roleAssignment.RoleDefinitionBindings.Contains(roleDefinition))
                    {
                        roleAssignment.RoleDefinitionBindings.Add(roleDefinition);
                    }
                }

                try
                {
                    roleAssignment.Update();
                }
                catch (ArgumentException)
                {
                    //Note: fix for 'Cannot update a permission level assignment that is not part of a permission level assignment collection.'
                    securableObject.RoleAssignments.Add(roleAssignment);
                }
            }
            else
            {
                roleAssignment = new SPRoleAssignment(principal);

                if (!roleAssignment.RoleDefinitionBindings.Contains(roleDefinition))
                {
                    roleAssignment.RoleDefinitionBindings.Add(roleDefinition);
                }

                securableObject.RoleAssignments.Add(roleAssignment);
            }
        }
        public static void SetSecurity(this SecurableObject securable, TokenParser parser, ObjectSecurity security)
        {
            //using (var scope = new PnPMonitoredScope("Set Security"))
            //{

            var context = securable.Context as ClientContext;

            var groups = context.LoadQuery(context.Web.SiteGroups.Include(g => g.LoginName));
            var webRoleDefinitions = context.LoadQuery(context.Web.RoleDefinitions);

            context.ExecuteQueryRetry();

            securable.BreakRoleInheritance(security.CopyRoleAssignments, security.ClearSubscopes);

            foreach (var roleAssignment in security.RoleAssignments)
            {
                Principal principal = groups.FirstOrDefault(g => g.LoginName == parser.ParseString(roleAssignment.Principal));
                if (principal == null)
                {
                    principal = context.Web.EnsureUser(roleAssignment.Principal);
                }

                var roleDefinitionBindingCollection = new RoleDefinitionBindingCollection(context);

                var roleDefinition = webRoleDefinitions.FirstOrDefault(r => r.Name == roleAssignment.RoleDefinition);

                if (roleDefinition != null)
                {
                    roleDefinitionBindingCollection.Add(roleDefinition);
                }
                securable.RoleAssignments.Add(principal, roleDefinitionBindingCollection);
            }
            context.ExecuteQueryRetry();
            //}
        }