/// <summary>
 /// Constructs a new <see cref="BaseSocketClientAbstraction"/> around an existing <see cref="WebSocket.BaseSocketClient"/>.
 /// </summary>
 /// <param name="baseSocketClient">The value to use for <see cref="WebSocket.BaseSocketClient"/>.</param>
 /// <exception cref="ArgumentNullException">Throws for <paramref name="baseSocketClient"/>.</exception>
 protected BaseSocketClientAbstraction(BaseSocketClient baseSocketClient)
     : base(baseSocketClient)
 {
     baseSocketClient.ChannelCreated         += x => ChannelCreated?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.ChannelDestroyed       += x => ChannelDestroyed?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.ChannelUpdated         += (x, y) => ChannelUpdated?.InvokeAsync(x.Abstract(), y.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.CurrentUserUpdated     += (x, y) => CurrentUserUpdated?.InvokeAsync(x.Abstract(), y.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.GuildAvailable         += x => GuildAvailable?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.GuildMembersDownloaded += x => GuildMembersDownloaded?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.GuildMemberUpdated     += (x, y) => GuildMemberUpdated?.InvokeAsync(x.Abstract(), y.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.GuildUnavailable       += x => GuildUnavailable?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.GuildUpdated           += (x, y) => GuildUpdated?.InvokeAsync(x.Abstract(), y.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.JoinedGuild            += x => JoinedGuild?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.LeftGuild             += x => LeftGuild?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.MessageReceived       += x => MessageReceived?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.MessageUpdated        += (x, y, z) => MessageUpdated?.InvokeAsync(x.Abstract(), y.Abstract(), z.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.MessageDeleted        += (x, y) => MessageDeleted?.InvokeAsync(x.Abstract(), y.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.ReactionAdded         += (x, y, z) => ReactionAdded?.InvokeAsync(x.Abstract(), y.Abstract(), z.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.ReactionRemoved       += (x, y, z) => ReactionRemoved?.InvokeAsync(x.Abstract(), y.Abstract(), z.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.ReactionsCleared      += (x, y) => ReactionsCleared?.InvokeAsync(x.Abstract(), y.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.RecipientAdded        += x => RecipientAdded?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.RecipientRemoved      += x => RecipientRemoved?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.RoleCreated           += x => RoleCreated?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.RoleDeleted           += x => RoleDeleted?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.RoleUpdated           += (x, y) => RoleUpdated?.InvokeAsync(x.Abstract(), y.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.UserBanned            += (x, y) => UserBanned?.InvokeAsync(x.Abstract(), y.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.UserIsTyping          += (x, y) => UserIsTyping?.InvokeAsync(x.Abstract(), y.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.UserJoined            += x => UserJoined?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.UserLeft              += x => UserLeft?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.UserUnbanned          += (x, y) => UserUnbanned?.InvokeAsync(x.Abstract(), y.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.UserUpdated           += (x, y) => UserUpdated?.InvokeAsync(x.Abstract(), y.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.UserVoiceStateUpdated += (x, y, z) => UserVoiceStateUpdated?.InvokeAsync(x.Abstract(), y.Abstract(), z.Abstract()) ?? Task.CompletedTask;
     baseSocketClient.VoiceServerUpdated    += x => VoiceServerUpdated?.InvokeAsync(x.Abstract()) ?? Task.CompletedTask;
 }
        public IRestVoiceRegion GetVoiceRegion(string id)
        {
            var restVoiceRegion = BaseSocketClient.GetVoiceRegion(id);

            return((restVoiceRegion is null)
                ? null
                : RestVoiceRegionAbstractionExtensions.Abstract(restVoiceRegion));
        }
        /// <inheritdoc />
        new public async Task <IRestInviteMetadata> GetInviteAsync(string inviteId, RequestOptions options)
        {
            var restInviteMetadata = await BaseSocketClient.GetInviteAsync(inviteId, options);

            return((restInviteMetadata is null)
                ? null
                : RestInviteMetadataAbstractionExtensions.Abstract(restInviteMetadata));
        }
 /// <summary>
 /// Converts an existing <see cref="BaseSocketClient"/> to an abstracted <see cref="IBaseSocketClient"/> value.
 /// </summary>
 /// <param name="baseSocketClient">The existing <see cref="BaseSocketClient"/> to be abstracted.</param>
 /// <exception cref="ArgumentNullException">Throws for <paramref name="baseSocketClient"/>.</exception>
 /// <returns>An <see cref="IBaseSocketClient"/> that abstracts <paramref name="baseSocketClient"/>.</returns>
 public static IBaseSocketClient Abstract(this BaseSocketClient baseSocketClient)
 => baseSocketClient switch
 {
     null
     => throw new ArgumentNullException(nameof(baseSocketClient)),
 /// <inheritdoc />
 public Task SetStatusAsync(UserStatus status)
 => BaseSocketClient.SetStatusAsync(status);
 /// <inheritdoc />
 public Task SetGameAsync(string name, string streamUrl = null, ActivityType type = ActivityType.Playing)
 => BaseSocketClient.SetGameAsync(name, streamUrl, type);
 /// <inheritdoc />
 public Task SetActivityAsync(IActivity activity)
 => BaseSocketClient.SetActivityAsync(activity);
 /// <inheritdoc />
 public ISocketUser GetUser(string username, string discriminator)
 => BaseSocketClient.GetUser(username, discriminator)
 ?.Abstract();
 /// <inheritdoc />
 public ISocketUser GetUser(ulong id)
 => BaseSocketClient.GetUser(id)
 ?.Abstract();
 /// <inheritdoc />
 public ISocketGuild GetGuild(ulong id)
 => BaseSocketClient.GetGuild(id)
 ?.Abstract();
 /// <inheritdoc />
 public ISocketChannel GetChannel(ulong id)
 => BaseSocketClient.GetChannel(id)
 ?.Abstract();
 /// <inheritdoc />
 new public async Task <IRestApplication> GetApplicationInfoAsync(RequestOptions options)
 => RestApplicationAbstractionExtensions.Abstract(
     await BaseSocketClient.GetApplicationInfoAsync(options));
 /// <inheritdoc />
 public Task DownloadUsersAsync(IEnumerable <IGuild> guilds)
 => BaseSocketClient.DownloadUsersAsync(guilds);
 /// <inheritdoc />
 new public async Task <IRestGuild> CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon, RequestOptions options)
 => RestGuildAbstractionExtensions.Abstract(
     await BaseSocketClient.CreateGuildAsync(name, region, jpegIcon, options));
 public static async Task DeleteAsync(ISocketInvite invite, BaseSocketClient client,
                                      RequestOptions options)
 {
     await client.ApiClient.DeleteInviteAsync(invite.Code, options).ConfigureAwait(false);
 }