/// <summary>
        /// TODO Documentation comment
        /// </summary>
        /// <param name="member"></param>
        /// <param name="requestedPublicity"></param>
        /// <param name="requestedRegion"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public bool CheckPermission(DiscordMember member, string name, ChannelPublicity requestedPublicity, VoiceRegion requestedRegion, out string error)
        {
            VoiceChannelCreationPermissions highestPrecedencePermissions = null;
            int existingChannels = (CreatedChannels.ContainsKey(member) ? CreatedChannels[member]?.Count : 0) ?? 0;

            int         highestRolePosition = -1;
            DiscordRole highestRole         = null;

            foreach (DiscordRole role in member.Roles)
            {
                if (highestRolePosition < role.Position)
                {
                    highestRole         = role;
                    highestRolePosition = role.Position;
                }
            }

            if (RolewisePermissions.ContainsKey(highestRole))
            {
                highestPrecedencePermissions = RolewisePermissions[highestRole];
            }

            if (MemberwisePermissions.ContainsKey(member))
            {
                highestPrecedencePermissions = MemberwisePermissions[member];
            }

            return((highestPrecedencePermissions ?? EveryonePermission).ValidateChannelCreationAuthority(!((name is null) || name == string.Empty), requestedPublicity, existingChannels, requestedRegion, out error));
        }
        /// <summary>
        /// Updates all provided existing permissions, removes keys whos values are null, adds keys whos values are not null and don't exist in the current dictionary
        /// </summary>
        /// <param name="everyonePermission">Updated everyone permission. Set null to ignore</param>
        /// <param name="rolewisePermissions">Updated rolewise permissions. Set null to ignore, set value to null to remove coresponding key from dictionary, set key and value to update existing or add new value repsectively</param>
        /// <param name="memberwisePermissions">Updated memberwise permissions. Set null to ignore, set value to null to remove coresponding key from dictionary, set key and value to update existing or add new value repsectively</param>
        public void UpdatePermissions(VoiceChannelCreationPermissions everyonePermission, IEnumerable <KeyValuePair <DiscordRole, VoiceChannelCreationPermissions> > rolewisePermissions, IEnumerable <KeyValuePair <DiscordMember, VoiceChannelCreationPermissions> > memberwisePermissions)
        {
            if (!(everyonePermission is null))
            {
                EveryonePermission = everyonePermission;
            }

            if (!(rolewisePermissions is null) && rolewisePermissions.Count() > 0)
            {
                foreach (var kvp in rolewisePermissions)
                {
                    if (kvp.Key is null)
                    {
                        continue;
                    }

                    if (this.RolewisePermissions.ContainsKey(kvp.Key))
                    {
                        if (kvp.Value is null)
                        {
                            this.RolewisePermissions.Remove(kvp.Key);
                            continue;
                        }

                        this.RolewisePermissions[kvp.Key] = kvp.Value;
                        continue;
                    }

                    if (kvp.Value is null)
                    {
                        continue;
                    }

                    this.RolewisePermissions.Add(kvp.Key, kvp.Value);
                }
            }

            if (!(memberwisePermissions is null) && memberwisePermissions.Count() > 0)
            {
                foreach (var kvp in memberwisePermissions)
                {
                    if (kvp.Key is null)
                    {
                        continue;
                    }

                    if (this.MemberwisePermissions.ContainsKey(kvp.Key))
                    {
                        if (kvp.Value is null)
                        {
                            this.MemberwisePermissions.Remove(kvp.Key);
                            continue;
                        }

                        this.MemberwisePermissions[kvp.Key] = kvp.Value;
                    }

                    if (kvp.Value is null)
                    {
                        continue;
                    }

                    this.MemberwisePermissions.Add(kvp.Key, kvp.Value);
                }
            }
        }
 /// <summary>
 /// TODO
 /// </summary>
 /// <param name="parentCategory"></param>
 /// <param name="waitingRoomVc"></param>
 /// <param name="commandListenChannel"></param>
 /// <param name="memberRole"></param>
 /// <param name="mutedRole"></param>
 /// <param name="botManagerRole"></param>
 /// <param name="everyonePermission"></param>
 /// <param name="rolewisePermissions"></param>
 /// <param name="memberwisePermissions"></param>
 /// <param name="createdChannels"></param>
 internal GuildData(DiscordChannel parentCategory, DiscordChannel waitingRoomVc, DiscordChannel commandListenChannel, DiscordRole memberRole, DiscordRole mutedRole, DiscordRole botManagerRole, VoiceChannelCreationPermissions everyonePermission, IEnumerable <KeyValuePair <DiscordRole, VoiceChannelCreationPermissions> > rolewisePermissions, IEnumerable <KeyValuePair <DiscordMember, VoiceChannelCreationPermissions> > memberwisePermissions, IEnumerable <KeyValuePair <DiscordMember, List <DiscordChannel> > > createdChannels) : this(parentCategory, waitingRoomVc, commandListenChannel, memberRole, mutedRole, botManagerRole, everyonePermission, rolewisePermissions, memberwisePermissions)
 {
     CreatedChannels = new Dictionary <DiscordMember, List <DiscordChannel> >(createdChannels);
 }
 /// <summary>
 /// TODO Documentation comment
 /// </summary>
 /// <param name="everyonePermission"></param>
 /// <param name="rolewisePermissions"></param>
 /// <param name="memberwisePermissions"></param>
 public void InitializePermissions(VoiceChannelCreationPermissions everyonePermission, IEnumerable <KeyValuePair <DiscordRole, VoiceChannelCreationPermissions> > rolewisePermissions, IEnumerable <KeyValuePair <DiscordMember, VoiceChannelCreationPermissions> > memberwisePermissions)
 {
     this.EveryonePermission    = everyonePermission ?? new VoiceChannelCreationPermissions();
     this.RolewisePermissions   = new Dictionary <DiscordRole, VoiceChannelCreationPermissions>(rolewisePermissions ?? new KeyValuePair <DiscordRole, VoiceChannelCreationPermissions>[] { });
     this.MemberwisePermissions = new Dictionary <DiscordMember, VoiceChannelCreationPermissions>(memberwisePermissions ?? new KeyValuePair <DiscordMember, VoiceChannelCreationPermissions>[] { });
 }
 /// <summary>
 /// TODO
 /// </summary>
 /// <param name="parentCategory"></param>
 /// <param name="waitingRoomVc"></param>
 /// <param name="commandListenChannel"></param>
 /// <param name="memberRole"></param>
 /// <param name="mutedRole"></param>
 /// <param name="everyonePermission"></param>
 /// <param name="rolewisePermissions"></param>
 /// <param name="memberwisePermissions"></param>
 public GuildData(DiscordChannel parentCategory, DiscordChannel waitingRoomVc, DiscordChannel commandListenChannel, DiscordRole memberRole, DiscordRole mutedRole, DiscordRole botManagerRole, VoiceChannelCreationPermissions everyonePermission, IEnumerable <KeyValuePair <DiscordRole, VoiceChannelCreationPermissions> > rolewisePermissions, IEnumerable <KeyValuePair <DiscordMember, VoiceChannelCreationPermissions> > memberwisePermissions) : this(parentCategory, waitingRoomVc, commandListenChannel, memberRole, mutedRole, botManagerRole)
 {
     InitializePermissions(everyonePermission, rolewisePermissions, memberwisePermissions);
 }