/// <summary>
        /// Returns role assignments for the current sharepoint objects
        /// </summary>
        /// <param name="context"></param>
        /// <param name="CurrentWeb"></param>
        /// <param name="Object"></param>
        /// <param name="childSecurableObject"></param>
        private static void GetRoleAssignments(ClientContext context, Web CurrentWeb, object Object, SPSecurableObject childSecurableObject)
        {
            try
            {
                string objectDetails = string.Empty;
                childSecurableObject.RoleAssignments = new List <SPRoleAssignment>();
                RoleAssignmentCollection roleAssignments = null;

                Type spObjectType = Object.GetType();

                switch (spObjectType.Name)
                {
                case "Web":
                    Web web = Object as Web;
                    objectDetails   = web.ServerRelativeUrl;
                    roleAssignments = web.RoleAssignments;
                    break;

                case "List":
                    List list = Object as List;
                    objectDetails   = "List " + list.Title;
                    roleAssignments = list.RoleAssignments;
                    break;

                case "ListItem":
                    ListItem listItem = Object as ListItem;
                    objectDetails   = "List Item ID " + listItem.Id;
                    roleAssignments = listItem.RoleAssignments;
                    break;
                }

                context.Load(roleAssignments);
                context.ExecuteQuery();

                foreach (RoleAssignment roleAssignment in roleAssignments)
                {
                    SPRoleAssignment spRoleAssignment = new SPRoleAssignment();
                    spRoleAssignment.Member          = new SPMember();
                    spRoleAssignment.RoleDefBindings = new SPRoleDefBindings();

                    context.Load(roleAssignment);
                    context.Load(roleAssignment.Member);
                    context.ExecuteQuery();

                    Principal roleMember = roleAssignment.Member;

                    if (roleMember.PrincipalType == Microsoft.SharePoint.Client.Utilities.PrincipalType.SharePointGroup)
                    {
                        spRoleAssignment.PrincipalType = PrincipalType.Group;
                        spRoleAssignment.Member.Group  = new SPGroup();

                        var     query = from g in spSiteGroups.SiteGroups where g.GroupName == roleMember.LoginName select g;
                        SPGroup group = query.First();

                        spRoleAssignment.Member.Group.GroupName = group.GroupName;
                        spRoleAssignment.Member.Group.Users     = new List <SPUser>();

                        foreach (SPUser usr in group.Users)
                        {
                            SPUser spUser = new SPUser
                            {
                                DisplayName = usr.DisplayName,
                                Email       = usr.Email,
                                LoginId     = usr.LoginId
                            };

                            spRoleAssignment.Member.Group.Users.Add(spUser);
                        }
                    }
                    else if (roleMember.PrincipalType == Microsoft.SharePoint.Client.Utilities.PrincipalType.User)
                    {
                        spRoleAssignment.PrincipalType = PrincipalType.User;
                        spRoleAssignment.Member.User   = new SPUser
                        {
                            DisplayName = roleMember.Title,
                            LoginId     = roleMember.LoginName
                        };
                    }

                    context.Load(roleAssignment, r => r.RoleDefinitionBindings);
                    context.ExecuteQuery();

                    spRoleAssignment.RoleDefBindings.Permissions = new List <SPBasePermissions>();

                    foreach (RoleDefinition roleDef in roleAssignment.RoleDefinitionBindings)
                    {
                        if (string.IsNullOrEmpty(spRoleAssignment.RoleDefBindings.RoleName))
                        {
                            spRoleAssignment.RoleDefBindings.RoleName = roleDef.Name;
                        }
                        else
                        {
                            spRoleAssignment.RoleDefBindings.RoleName = spRoleAssignment.RoleDefBindings.RoleName + ", " + roleDef.Name;
                        }

                        //enumerate the enum and check each permission
                        //type to see if the perm is included
                        string[] keys = Enum.GetNames(typeof(PermissionKind));

                        context.Load(roleDef, r => r.BasePermissions);
                        context.ExecuteQuery();

                        //get a reference to the base permissions
                        //in this RoleDefinition
                        BasePermissions bp = roleDef.BasePermissions;

                        //enumerate the enum
                        foreach (string key in keys)
                        {
                            if (bp.Has((PermissionKind)Enum.Parse(typeof(PermissionKind), key)))
                            {
                                SPBasePermissions spBasePermission = new SPBasePermissions {
                                    PermissionName = key
                                };
                                spRoleAssignment.RoleDefBindings.Permissions.Add(spBasePermission);
                            }
                        }
                    }

                    childSecurableObject.RoleAssignments.Add(spRoleAssignment);
                }
            }
            catch (Exception ex)
            {
                RaiseStatusUpdate("ERROR: " + CurrentWeb.ServerRelativeUrl + ". Stack Trace: " + ex.Message, UpdateType.StatusUpdateOnly);
            }
        }
        /// <summary>
        /// Preloads site groups and users
        /// </summary>
        /// <param name="Context">Client context</param>
        private static void LoadSiteGroups(ClientContext Context)
        {
            RaiseStatusUpdate("Preloading: Initiating", UpdateType.StatusUpdateOnly);
            spSiteGroups            = new SPSiteGroups();
            spSiteGroups.SiteGroups = new List <SPGroup>();

            spSiteUsers           = new SPSiteUsers();
            spSiteUsers.SiteUsers = new List <SPUser>();

            Site            site       = Context.Site;
            Web             web        = site.RootWeb;
            GroupCollection siteGroups = web.SiteGroups;

            Context.Load(site);
            Context.Load(web);
            Context.Load(siteGroups);
            Context.ExecuteQuery();

            RaiseStatusUpdate("Preloading: Site Groups", UpdateType.StatusUpdateOnly);

            // Populate spSiteGroups object with all site groups
            foreach (Group group in siteGroups)
            {
                Context.Load(group);
                Context.Load(group.Users);
                Context.ExecuteQuery();

                SPGroup spGroup = new SPGroup();
                spGroup.GroupName = group.Title;
                spGroup.Users     = new List <SPUser>();

                RaiseStatusUpdate("Preloading: Group " + group.LoginName, UpdateType.StatusUpdateOnly);

                foreach (User usr in group.Users)
                {
                    SPUser spUser = new SPUser
                    {
                        DisplayName = usr.Title,
                        Email       = usr.Email,
                        LoginId     = usr.LoginName
                    };

                    spGroup.Users.Add(spUser);
                }
                spSiteGroups.SiteGroups.Add(spGroup);
                RaiseStatusUpdate("Preloading: Finished", UpdateType.StatusUpdateOnly);
            }

            RaiseStatusUpdate("Preloading: Finished Loading Site Groups", UpdateType.StatusUpdateOnly);
            RaiseStatusUpdate("Preloading: Site Users", UpdateType.StatusUpdateOnly);

            // Populate spSiteUsers object with all site users
            List userList = web.SiteUserInfoList;

            Context.Load(userList);

            CamlQuery query = new CamlQuery();

            query.ViewXml = "<View><Query><Where><Eq><FieldRef Name='ContentType'/><Value Type='Text'>Person</Value></Eq></Where></Query></View>";

            ListItemCollection collection = userList.GetItems(query);

            Context.Load(collection, pj => pj.Include(
                             p => p["Name"],
                             p => p["Title"],
                             p => p["EMail"],
                             p => p["IsSiteAdmin"],
                             p => p["IsActive"]));

            Context.ExecuteQuery();

            foreach (ListItem item in collection)
            {
                string loginId     = (item["Name"] != null) ? item["Name"].ToString() : string.Empty;
                string displayName = (item["Title"] != null) ? item["Title"].ToString() : loginId;
                string email       = (item["EMail"] != null) ? item["EMail"].ToString() : string.Empty;

                SPUser usr = new SPUser {
                    DisplayName = displayName, Email = email, LoginId = loginId
                };
                spSiteUsers.SiteUsers.Add(usr);
            }

            RaiseStatusUpdate("Preloading: Finished Loading Site Users", UpdateType.StatusUpdateOnly);
            RaiseStatusUpdate("Preloading Finished, Initiating main processing", UpdateType.StatusUpdateOnly);
        }