<?xml version="1.0"?>
<doc>
    <assembly>
        <name>slskd</name>
    </assembly>
    <members>
        <member name="F:slskd.Application.DefaultGroup">
            <summary>
                The name of the default user group.
            </summary>
        </member>
        <member name="F:slskd.Application.PrivilegedGroup">
            <summary>
                The name of the privileged user group.
            </summary>
        </member>
        <member name="F:slskd.Application.LeecherGroup">
            <summary>
                The name of the leecher user group.
            </summary>
        </member>
        <member name="F:slskd.Application.BlacklistedGroup">
            <summary>
                The name of the blacklisted user group.
            </summary>
        </member>
        <member name="P:slskd.Application.IsShuttingDown">
            <summary>
                Gets a value indicating whether the application is in the process of shutting down.
            </summary>
        </member>
        <member name="M:slskd.Application.CheckVersionAsync">
            <summary>
                Gets the version of the latest application release.
            </summary>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Application.BrowseResponseResolver(System.String,System.Net.IPEndPoint)">
            <summary>
                Creates and returns an instances of <see cref="T:Soulseek.BrowseResponse"/> in response to a remote request.
            </summary>
            <param name="username">The username of the requesting user.</param>
            <param name="endpoint">The IP endpoint of the requesting user.</param>
            <returns>A Task resolving an IEnumerable of Soulseek.Directory.</returns>
        </member>
        <member name="M:slskd.Application.DirectoryContentsResponseResolver(System.String,System.Net.IPEndPoint,System.Int32,System.String)">
            <summary>
                Creates and returns a <see cref="T:Soulseek.Directory"/> in response to a remote request.
            </summary>
            <param name="username">The username of the requesting user.</param>
            <param name="endpoint">The IP endpoint of the requesting user.</param>
            <param name="token">The unique token for the request, supplied by the requesting user.</param>
            <param name="directory">The requested directory.</param>
            <returns>A Task resolving an instance of Soulseek.Directory containing the contents of the requested directory.</returns>
        </member>
        <member name="M:slskd.Application.SearchResponseResolver(System.String,System.Int32,Soulseek.SearchQuery)">
            <summary>
                Creates and returns a <see cref="T:slskd.Search.Response"/> in response to the given <paramref name="query"/>.
            </summary>
            <param name="username">The username of the requesting user.</param>
            <param name="token">The search token.</param>
            <param name="query">The search query.</param>
            <returns>A Task resolving a SearchResponse, or null.</returns>
        </member>
        <member name="M:slskd.Application.UserInfoResolver(System.String,System.Net.IPEndPoint)">
            <summary>
                Creates and returns a <see cref="T:Soulseek.UserInfo"/> object in response to a remote request.
            </summary>
            <param name="username">The username of the requesting user.</param>
            <param name="endpoint">The IP endpoint of the requesting user.</param>
            <returns>A Task resolving the UserInfo instance.</returns>
        </member>
        <member name="T:slskd.Authentication.ApiKeyAuthentication">
            <summary>
                API key authentication.
            </summary>
        </member>
        <member name="P:slskd.Authentication.ApiKeyAuthentication.AuthenticationScheme">
            <summary>
                Gets the API key authentication scheme name.
            </summary>
        </member>
        <member name="T:slskd.Authentication.ApiKeyAuthenticationHandler">
            <summary>
                Handles API key authentication.
            </summary>
        </member>
        <member name="M:slskd.Authentication.ApiKeyAuthenticationHandler.#ctor(Microsoft.Extensions.Options.IOptionsMonitor{slskd.Authentication.ApiKeyAuthenticationOptions},slskd.ISecurityService,Microsoft.Extensions.Logging.ILoggerFactory,System.Text.Encodings.Web.UrlEncoder)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Authentication.ApiKeyAuthenticationHandler"/> class.
            </summary>
            <param name="apiKeyOptionsMonitor">An options monitor.</param>
            <param name="securityService">The security service.</param>
            <param name="logger">A logger factory.</param>
            <param name="urlEncoder">A url encoder.</param>
        </member>
        <member name="M:slskd.Authentication.ApiKeyAuthenticationHandler.HandleAuthenticateAsync">
            <summary>
                Authenticates via API key.
            </summary>
            <returns>A successful authentication result containing a ticket for the API key.</returns>
        </member>
        <member name="T:slskd.Authentication.ApiKeyAuthenticationOptions">
            <summary>
                API key authentication options.
            </summary>
        </member>
        <member name="T:slskd.Authentication.PassthroughAuthentication">
            <summary>
                Passthrough authentication.
            </summary>
        </member>
        <member name="P:slskd.Authentication.PassthroughAuthentication.AuthenticationScheme">
            <summary>
                Gets the Passthrough authentication scheme name.
            </summary>
        </member>
        <member name="T:slskd.Authentication.PassthroughAuthenticationHandler">
            <summary>
                Handles passthrough authentication.
            </summary>
        </member>
        <member name="M:slskd.Authentication.PassthroughAuthenticationHandler.#ctor(Microsoft.Extensions.Options.IOptionsMonitor{slskd.Authentication.PassthroughAuthenticationOptions},Microsoft.Extensions.Logging.ILoggerFactory,System.Text.Encodings.Web.UrlEncoder)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Authentication.PassthroughAuthenticationHandler"/> class.
            </summary>
            <param name="optionsMonitor">An options monitor.</param>
            <param name="logger">A logger factory.</param>
            <param name="urlEncoder">A url encoder.</param>
        </member>
        <member name="M:slskd.Authentication.PassthroughAuthenticationHandler.HandleAuthenticateAsync">
            <summary>
                Authenticates using the configured <see cref="P:slskd.Authentication.PassthroughAuthenticationOptions.Username"/> and <see cref="P:slskd.Authentication.PassthroughAuthenticationOptions.Role"/>.
            </summary>
            <returns>A successful authentication result containing a default ticket.</returns>
        </member>
        <member name="T:slskd.Authentication.PassthroughAuthenticationOptions">
            <summary>
                Passthrough authentication options.
            </summary>
        </member>
        <member name="M:slskd.Authentication.PassthroughAuthenticationOptions.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Authentication.PassthroughAuthenticationOptions"/> class.
            </summary>
        </member>
        <member name="P:slskd.Authentication.PassthroughAuthenticationOptions.Username">
            <summary>
                Gets or sets the username for the passed-through authentication ticket.
            </summary>
        </member>
        <member name="P:slskd.Authentication.PassthroughAuthenticationOptions.Role">
            <summary>
                Gets or sets the role for the passed-through authentication ticket.
            </summary>
        </member>
        <member name="T:slskd.AuthPolicy">
            <summary>
                Authentication policies.
            </summary>
        </member>
        <member name="T:slskd.AuthRole">
            <summary>
                Authentication roles.
            </summary>
            <remarks>
                For use in the <see cref="T:Microsoft.AspNetCore.Authorization.AuthorizeAttribute"/> attribute, specifically.
            </remarks>
        </member>
        <member name="M:slskd.Base62Extensions.ToBase62(System.Int16,System.Boolean)">
            <summary>
            Encode a 2-byte number with Base62
            </summary>
            <param name="original">String</param>
            <param name="inverted">Use inverted character set</param>
            <returns>Base62 string</returns>
        </member>
        <member name="M:slskd.Base62Extensions.ToBase62(System.Int32,System.Boolean)">
            <summary>
            Encode a 4-byte number with Base62
            </summary>
            <param name="original">String</param>
            <param name="inverted">Use inverted character set</param>
            <returns>Base62 string</returns>
        </member>
        <member name="M:slskd.Base62Extensions.ToBase62(System.Int64,System.Boolean)">
            <summary>
            Encode a 8-byte number with Base62
            </summary>
            <param name="original">String</param>
            <param name="inverted">Use inverted character set</param>
            <returns>Base62 string</returns>
        </member>
        <member name="M:slskd.Base62Extensions.ToBase62(System.String,System.Boolean)">
            <summary>
            Encode a string with Base62
            </summary>
            <param name="original">String</param>
            <param name="inverted">Use inverted character set</param>
            <returns>Base62 string</returns>
        </member>
        <member name="M:slskd.Base62Extensions.ToBase62(System.Byte[],System.Boolean)">
            <summary>
            Encode a byte array with Base62
            </summary>
            <param name="original">Byte array</param>
            <param name="inverted">Use inverted character set</param>
            <returns>Base62 string</returns>
        </member>
        <member name="M:slskd.Base62Extensions.FromBase62``1(System.String,System.Boolean)">
            <summary>
            Decode a base62-encoded string
            </summary>
            <param name="base62">Base62 string</param>
            <param name="inverted">Use inverted character set</param>
            <returns>Byte array</returns>
        </member>
        <member name="M:slskd.Base62Extensions.FromBase62(System.String,System.Boolean)">
            <summary>
            Decode a base62-encoded string
            </summary>
            <param name="base62">Base62 string</param>
            <param name="inverted">Use inverted character set</param>
            <returns>Byte array</returns>
        </member>
        <member name="T:slskd.Base64Extensions">
            <summary>
                Base 64 extensions.
            </summary>
        </member>
        <member name="M:slskd.Base64Extensions.ToBase64(System.String)">
            <summary>
                Encode this string in Base 64.
            </summary>
            <param name="str">The string to encode.</param>
            <returns>The encoded string.</returns>
        </member>
        <member name="M:slskd.Base64Extensions.FromBase64(System.String)">
            <summary>
                Decode this string from Base 64.
            </summary>
            <param name="str">The string to decode.</param>
            <returns>The decoded string.</returns>
        </member>
        <member name="T:slskd.Shares.IChannelReader">
            <summary>
                Reads and handles items from a channel.
            </summary>
        </member>
        <member name="P:slskd.Shares.IChannelReader.Completed">
            <summary>
                Gets the <see cref="T:System.Threading.Tasks.Task"/> that completes when the reader has read all available items from the channel.
            </summary>
        </member>
        <member name="P:slskd.Shares.IChannelReader.Started">
            <summary>
                Gets a value indicating whether the reader has started reading.
            </summary>
        </member>
        <member name="M:slskd.Shares.IChannelReader.Start">
            <summary>
                Starts the reader.
            </summary>
        </member>
        <member name="T:slskd.Shares.ChannelReader`1">
            <summary>
                Shared file cache worker.
            </summary>
            <typeparam name="T">The type of the underlying channel.</typeparam>
        </member>
        <member name="M:slskd.Shares.ChannelReader`1.#ctor(System.Threading.Channels.Channel{`0},System.Action{`0},System.Action{System.Exception},System.Boolean,System.Threading.CancellationToken)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Shares.ChannelReader`1"/> class.
            </summary>
            <param name="channel">The channel from which the reader will read.</param>
            <param name="handler">An <see cref="T:System.Action"/> to be invoked for each item read from the channel.</param>
            <param name="exceptionHandler">An optional <see cref="T:System.Action"/> to be invoked if the reader encounters an <see cref="T:System.Exception"/>.</param>
            <param name="automaticallyStart">An optional value indicating whether to automatically start the reader.</param>
            <param name="cancellationToken">An optional <see cref="P:slskd.Shares.ChannelReader`1.CancellationToken"/> to monitor for cancellation.</param>
        </member>
        <member name="P:slskd.Shares.ChannelReader`1.Completed">
            <summary>
                Gets the <see cref="T:System.Threading.Tasks.Task"/> that completes when the worker has completed all of its work.
            </summary>
        </member>
        <member name="P:slskd.Shares.ChannelReader`1.Started">
            <summary>
                Gets a value indicating whether the reader has started reading.
            </summary>
        </member>
        <member name="M:slskd.Shares.ChannelReader`1.Start">
            <summary>
                Starts the reader.
            </summary>
        </member>
        <member name="T:slskd.Shares.API.SharesController">
            <summary>
                Shares.
            </summary>
        </member>
        <member name="M:slskd.Shares.API.SharesController.#ctor(slskd.Shares.IShareService)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Shares.API.SharesController"/> class.
            </summary>
            <param name="shareService"></param>
        </member>
        <member name="M:slskd.Shares.API.SharesController.List">
            <summary>
                Gets the current list of shares.
            </summary>
            <response code="200">The request completed successfully.</response>
            <returns></returns>
        </member>
        <member name="M:slskd.Shares.API.SharesController.Get(System.String)">
            <summary>
                Gets the share associated with the specified <see paramref="id"/>.
            </summary>
            <param name="id">The id of the share.</param>
            <response code="200">The request completed successfully.</response>
            <response code="404">The requested share could not be found.</response>
            <returns></returns>
        </member>
        <member name="M:slskd.Shares.API.SharesController.BrowseAll">
            <summary>
                Returns a list of all shared directories and files.
            </summary>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
        </member>
        <member name="M:slskd.Shares.API.SharesController.BrowseShare(System.String)">
            <summary>
                Gets the contents of the share associated with the specified <see paramref="id"/>.
            </summary>
            <param name="id">The id of the share.</param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="404">The requested share could not be found.</response>
        </member>
        <member name="M:slskd.Shares.API.SharesController.RescanSharesAsync">
            <summary>
                Initiates a scan of the configured shares.
            </summary>
            <returns></returns>
            <response code="204">The request completed successfully.</response>
            <response code="409">A share scan is already in progress.</response>
        </member>
        <member name="M:slskd.Shares.API.SharesController.CancelShareScan">
            <summary>
                Cancels a share scan, if one is running.
            </summary>
            <returns></returns>
            <response code="204">The request completed successfully.</response>
            <response code="409">A share scan was not in progress.</response>
        </member>
        <member name="T:slskd.Shares.IShareRepository">
            <summary>
                Persistent storage of shared files and metadata.
            </summary>
        </member>
        <member name="P:slskd.Shares.IShareRepository.ConnectionString">
            <summary>
                Gets the connection string for this repository.
            </summary>
        </member>
        <member name="M:slskd.Shares.IShareRepository.BackupTo(slskd.Shares.IShareRepository)">
            <summary>
                Backs the current database up to the database at the specified <paramref name="repository"/>.
            </summary>
            <param name="repository">The destination repository.</param>
        </member>
        <member name="M:slskd.Shares.IShareRepository.CountDirectories(System.String)">
            <summary>
                Counts the number of directories in the database.
            </summary>
            <param name="parentDirectory">The optional directory prefix used for counting subdirectories.</param>
            <returns>The number of directories.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepository.CountFiles(System.String)">
            <summary>
                Counts the number of files in the database.
            </summary>
            <param name="parentDirectory">The optional directory prefix used for counting files in a subdirectory.</param>
            <returns>The number of files.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepository.Create(System.Boolean)">
            <summary>
                Creates a new database.
            </summary>
            <remarks>
                Creates tables using 'IF NOT EXISTS', so this is idempotent unless 'discardExisting` is specified, in which case
                tables are explicitly dropped prior to creation.
            </remarks>
            <param name="discardExisting">An optional value that determines whether the existing database should be discarded.</param>
        </member>
        <member name="M:slskd.Shares.IShareRepository.DumpTo(System.String)">
            <summary>
                Dumps the contents of the database to a file.
            </summary>
            <param name="filename">The destination file.</param>
        </member>
        <member name="M:slskd.Shares.IShareRepository.EnableKeepalive(System.Boolean)">
            <summary>
                Enable connection keepalive.
            </summary>
            <param name="enable">A value indicating whether the keepalive logic should be executed.</param>
        </member>
        <member name="M:slskd.Shares.IShareRepository.FindFileInfo(System.String)">
            <summary>
                Finds the filename and length of the file matching the specified <paramref name="maskedFilename"/>.
            </summary>
            <param name="maskedFilename">The fully qualified remote path of the file.</param>
            <returns>The filename, if found.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepository.FindLatestScan">
            <summary>
                Finds and returns the most recent scan record.
            </summary>
            <returns>The most recent scan record, or default if no scan was found.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepository.FlagLatestScanAsSuspect">
            <summary>
                Flags the latest scan as suspect, indicating that the cached contents may have diverged from physical storage.
            </summary>
        </member>
        <member name="M:slskd.Shares.IShareRepository.InsertDirectory(System.String,System.Int64)">
            <summary>
                Inserts a directory.
            </summary>
            <param name="name">The fully qualified local name of the directory.</param>
            <param name="timestamp">The timestamp to assign to the record.</param>
        </member>
        <member name="M:slskd.Shares.IShareRepository.InsertFile(System.String,System.String,System.DateTime,Soulseek.File,System.Int64)">
            <summary>
                Inserts a file.
            </summary>
            <param name="maskedFilename">The fully qualified remote path of the file.</param>
            <param name="originalFilename">The fully qualified local path of the file.</param>
            <param name="touchedAt">The timestamp at which the file was last modified, according to the host OS.</param>
            <param name="file">The Soulseek.File instance representing the file.</param>
            <param name="timestamp">The timestamp to assign to the record.</param>
        </member>
        <member name="M:slskd.Shares.IShareRepository.InsertScan(System.Int64,slskd.Options.SharesOptions)">
            <summary>
                Inserts a scan record at the specified <paramref name="timestamp"/>.
            </summary>
            <param name="timestamp">The timestamp associated with the scan.</param>
            <param name="options">The options snapshot at the start of the scan.</param>
        </member>
        <member name="M:slskd.Shares.IShareRepository.ListDirectories(System.String)">
            <summary>
                Lists all directories.
            </summary>
            <param name="parentDirectory">The optional directory prefix used for listing subdirectories.</param>
            <returns>The list of directories.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepository.ListFiles(System.String,System.Boolean)">
            <summary>
                Lists all files.
            </summary>
            <param name="parentDirectory">The optional parent directory.</param>
            <param name="includeFullPath">A value indicating whether the fully qualified path should be returned.</param>
            <returns>The list of files.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepository.ListScans(System.Int64)">
            <summary>
                Returns the list of all <see cref="T:slskd.Shares.Scan"/> started at or after the specified <paramref name="startedAtOrAfter"/>
                unix timestamp.
            </summary>
            <param name="startedAtOrAfter">A unix timestamp that serves as the lower bound of the time-based listing.</param>
            <returns>The operation context, including the list of found scans.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepository.PruneDirectories(System.Int64)">
            <summary>
                Deletes directory records with a timestamp prior to the specified <paramref name="olderThanTimestamp"/>.
            </summary>
            <param name="olderThanTimestamp">The timestamp before which to delete directories.</param>
            <returns>The number of records deleted.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepository.PruneFiles(System.Int64)">
            <summary>
                Deletes file records with a timestamp prior to the specified <paramref name="olderThanTimestamp"/>.
            </summary>
            <param name="olderThanTimestamp">The timestamp before which to delete files.</param>
            <returns>The number of records deleted.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepository.RebuildFilenameIndex">
            <summary>
                Rebuilds the filename index table using the data in the files table.
            </summary>
        </member>
        <member name="M:slskd.Shares.IShareRepository.RestoreFrom(slskd.Shares.IShareRepository)">
            <summary>
                Restores the current database from the database at the specified <paramref name="repository"/>.
            </summary>
            <param name="repository">The destination repository.</param>
        </member>
        <member name="M:slskd.Shares.IShareRepository.Search(Soulseek.SearchQuery)">
            <summary>
                Searches the database for files matching the specified <paramref name="query"/>.
            </summary>
            <param name="query">The search query.</param>
            <returns>The list of matching files.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepository.TryValidate">
            <summary>
                Attempts to validate the backing database.
            </summary>
            <returns>A value indicating whether the database is valid.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepository.TryValidate(System.Collections.Generic.IEnumerable{System.String}@)">
            <summary>
                Attempts to validate the backing database.
            </summary>
            <param name="problems">The list of problems, if the database is invalid.</param>
            <returns>A value indicating whether the database is valid.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepository.UpdateScan(System.Int64,System.Int64)">
            <summary>
                Updates the scan started at the specified <paramref name="timestamp"/> to set the <paramref name="end"/>.
            </summary>
            <param name="timestamp">The timestamp associated with the scan.</param>
            <param name="end">The timestamp at the conclusion of the scan.</param>
        </member>
        <member name="M:slskd.Shares.IShareRepository.Vacuum">
            <summary>
                Reclaims unused space.
            </summary>
        </member>
        <member name="T:slskd.Shares.IShareRepositoryFactory">
            <summary>
                Persistent storage of a shared file cache.
            </summary>
        </member>
        <member name="M:slskd.Shares.IShareRepositoryFactory.CreateFromHost(System.String)">
            <summary>
                Create a repository for the specified <paramref name="name"/>.
            </summary>
            <param name="name">The name of the agent.</param>
            <returns>The created repository.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepositoryFactory.CreateFromHostBackup(System.String)">
            <summary>
                Create a repository backup for the specified <paramref name="name"/>.
            </summary>
            <param name="name">The name of the agent.</param>
            <returns>The created repository.</returns>
        </member>
        <member name="M:slskd.Shares.IShareRepositoryFactory.CreateFromFile(System.String,System.Boolean)">
            <summary>
                Create a repository for the specified <paramref name="filename"/>.
            </summary>
            <param name="filename">The fully qualified path of the filename.</param>
            <param name="pooling">A value indicating whether pooling should be enabled.</param>
            <returns>The created repository.</returns>
        </member>
        <member name="T:slskd.Shares.IShareService">
            <summary>
                Provides control and interactions with configured shares and shared files.
            </summary>
        </member>
        <member name="P:slskd.Shares.IShareService.Hosts">
            <summary>
                Gets the list of share hosts.
            </summary>
        </member>
        <member name="P:slskd.Shares.IShareService.LocalHost">
            <summary>
                Gets the local share host.
            </summary>
        </member>
        <member name="P:slskd.Shares.IShareService.StateMonitor">
            <summary>
                Gets the state monitor for the service.
            </summary>
        </member>
        <member name="M:slskd.Shares.IShareService.AddOrUpdateHost(slskd.Shares.Host)">
            <summary>
                Adds a new, or updates an existing, share host.
            </summary>
            <param name="host">The host to add or update.</param>
        </member>
        <member name="M:slskd.Shares.IShareService.BrowseAsync(slskd.Shares.Share)">
            <summary>
                Returns the entire contents of the share.
            </summary>
            <returns>The entire contents of the share.</returns>
        </member>
        <member name="M:slskd.Shares.IShareService.DumpAsync(System.String)">
            <summary>
                Dumps the local share cache to a file.
            </summary>
            <param name="filename">The destination file.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Shares.IShareService.InitializeAsync(System.Boolean)">
            <summary>
                Initializes the service and shares.
            </summary>
            <param name="forceRescan">A value indicating whether a full re-scan of shares should be performed.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Shares.IShareService.ListDirectoryAsync(System.String)">
            <summary>
                Returns the contents of the specified <paramref name="directory"/>.
            </summary>
            <param name="directory">The directory for which the contents are to be listed.</param>
            <returns>The contents of the directory.</returns>
        </member>
        <member name="M:slskd.Shares.IShareService.ListScansAsync(System.Int64)">
            <summary>
                Returns the list of all <see cref="T:slskd.Shares.Scan"/>  started at or after the specified <paramref name="startedAtOrAfter"/>
                unix timestamp.
            </summary>
            <param name="startedAtOrAfter">A unix timestamp that serves as the lower bound of the time-based listing.</param>
            <returns>The operation context, including the list of found scans.</returns>
        </member>
        <member name="M:slskd.Shares.IShareService.RequestScan">
            <summary>
                Requests that a share scan is performed.
            </summary>
        </member>
        <member name="M:slskd.Shares.IShareService.ResolveFileAsync(System.String)">
            <summary>
                Resolves the local filename and size of the specified <paramref name="remoteFilename"/>, if the mask is associated with a
                configured share.
            </summary>
            <param name="remoteFilename">The fully qualified filename to resolve.</param>
            <returns>The resolved host and filename.</returns>
            <exception cref="T:slskd.NotFoundException">
                Thrown when the specified remote filename can not be associated with a configured share.
            </exception>
        </member>
        <member name="M:slskd.Shares.IShareService.ScanAsync">
            <summary>
                Scans the configured shares on the local host.
            </summary>
            <returns>The operation context.</returns>
            <exception cref="T:slskd.ShareScanInProgressException">Thrown when a scan is already in progress.</exception>
        </member>
        <member name="M:slskd.Shares.IShareService.SearchAsync(Soulseek.SearchQuery)">
            <summary>
                Searches the cache for the specified <paramref name="query"/> and returns the matching files.
            </summary>
            <param name="query">The query for which to search.</param>
            <returns>The matching files.</returns>
        </member>
        <member name="M:slskd.Shares.IShareService.TryCancelScan">
            <summary>
                Cancels the currently running scan on the local host, if one is running.
            </summary>
            <returns>A value indicating whether a scan was cancelled.</returns>
        </member>
        <member name="M:slskd.Shares.IShareService.TryGetHost(System.String,slskd.Shares.Host@)">
            <summary>
                Returns the share host with the specified <paramref name="name"/>.
            </summary>
            <param name="name">The name of the host.</param>
            <param name="host">The host, if found.</param>
            <returns>A value indicating whether the host was found.</returns>
        </member>
        <member name="M:slskd.Shares.IShareService.TryRemoveHost(System.String)">
            <summary>
                Removes the share host with the specified <paramref name="name"/>.
            </summary>
            <param name="name">The name of the host.</param>
            <returns>A value indicating whether the host was removed.</returns>
        </member>
        <member name="T:slskd.Shares.SqliteShareRepositoryFactory">
            <summary>
                Persistent storage of a shared file cache.
            </summary>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepositoryFactory.#ctor(slskd.OptionsAtStartup)">
            <summary>
            Initializes a new instance of the <see cref="T:slskd.Shares.SqliteShareRepositoryFactory"/> class.
            </summary>
            <param name="optionsAtStartup"></param>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepositoryFactory.CreateFromHost(System.String)">
            <summary>
                Create a repository for the specified <paramref name="name"/>.
            </summary>
            <param name="name">The name of the agent.</param>
            <returns>The created repository.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepositoryFactory.CreateFromHostBackup(System.String)">
            <summary>
                Create a repository backup for the specified <paramref name="name"/>.
            </summary>
            <param name="name">The name of the agent.</param>
            <returns>The created repository.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepositoryFactory.CreateFromFile(System.String,System.Boolean)">
            <summary>
                Create a repository for the specified <paramref name="filename"/>.
            </summary>
            <param name="filename">The fully qualified path of the filename.</param>
            <param name="pooling">A value indicating whether pooling should be enabled.</param>
            <returns>The created repository.</returns>
        </member>
        <member name="T:slskd.Shares.IShareScanner">
            <summary>
                Shared file cache.
            </summary>
        </member>
        <member name="P:slskd.Shares.IShareScanner.StateMonitor">
            <summary>
                Gets the cache state monitor.
            </summary>
        </member>
        <member name="M:slskd.Shares.IShareScanner.ScanAsync(System.Collections.Generic.IEnumerable{slskd.Shares.Share},slskd.Options.SharesOptions,slskd.Shares.IShareRepository)">
            <summary>
                Scans the configured shares and fills the cache.
            </summary>
            <param name="shares">The list of shares from which to fill the cache.</param>
            <param name="options">The current options snapshot.</param>
            <param name="repository">The repository to update.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Shares.IShareScanner.TryCancelScan">
            <summary>
                Cancels the currently running fill operation, if one is running.
            </summary>
            <returns>A value indicating whether a fill operation was cancelled.</returns>
        </member>
        <member name="T:slskd.Shares.ShareScanner">
            <summary>
                Shared file cache.
            </summary>
        </member>
        <member name="M:slskd.Shares.ShareScanner.#ctor(System.Int32,slskd.Files.FileService,slskd.Shares.ISoulseekFileFactory)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Shares.ShareScanner"/> class.
            </summary>
            <param name="workerCount"></param>
            <param name="fileService"></param>
            <param name="soulseekFileFactory"></param>
        </member>
        <member name="P:slskd.Shares.ShareScanner.StateMonitor">
            <summary>
                Gets the cache state monitor.
            </summary>
        </member>
        <member name="M:slskd.Shares.ShareScanner.ScanAsync(System.Collections.Generic.IEnumerable{slskd.Shares.Share},slskd.Options.SharesOptions,slskd.Shares.IShareRepository)">
            <summary>
                Scans the configured shares and fills the cache.
            </summary>
            <param name="shares">The list of shares from which to fill the cache.</param>
            <param name="options">The current options snapshot.</param>
            <param name="repository">The repository to update.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Shares.ShareScanner.TryCancelScan">
            <summary>
                Cancels the currently running fill operation, if one is running.
            </summary>
            <returns>A value indicating whether a fill operation was cancelled.</returns>
        </member>
        <member name="T:slskd.Shares.ShareService">
            <summary>
                Provides control and interactions with configured shares and shared files.
            </summary>
        </member>
        <member name="M:slskd.Shares.ShareService.#ctor(slskd.Files.FileService,slskd.Shares.IShareRepositoryFactory,Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options},slskd.Shares.IShareScanner)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Shares.ShareService"/> class.
            </summary>
            <param name="fileService"></param>
            <param name="shareRepositoryFactory"></param>
            <param name="optionsMonitor"></param>
            <param name="scanner"></param>
        </member>
        <member name="P:slskd.Shares.ShareService.Hosts">
            <summary>
                Gets the list of share hosts.
            </summary>
        </member>
        <member name="P:slskd.Shares.ShareService.LocalHost">
            <summary>
                Gets the local share host.
            </summary>
        </member>
        <member name="P:slskd.Shares.ShareService.StateMonitor">
            <summary>
                Gets the state monitor for the service.
            </summary>
        </member>
        <member name="M:slskd.Shares.ShareService.AddOrUpdateHost(slskd.Shares.Host)">
            <summary>
                Adds a new, or updates an existing, share host.
            </summary>
            <param name="host">The host to add or update.</param>
        </member>
        <member name="M:slskd.Shares.ShareService.BrowseAsync(slskd.Shares.Share)">
            <summary>
                Returns the entire contents of the share.
            </summary>
            <returns>The entire contents of the share.</returns>
        </member>
        <member name="M:slskd.Shares.ShareService.DumpAsync(System.String)">
            <summary>
                Dumps the local share cache to a file.
            </summary>
            <param name="filename">The destination file.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Shares.ShareService.TryGetHost(System.String,slskd.Shares.Host@)">
            <summary>
                Returns the share host with the specified <paramref name="name"/>.
            </summary>
            <param name="name">The name of the host.</param>
            <param name="host">The host, if found.</param>
            <returns>A value indicating whether the host was found.</returns>
        </member>
        <member name="M:slskd.Shares.ShareService.TryRemoveHost(System.String)">
            <summary>
                Removes the share host with the specified <paramref name="name"/>.
            </summary>
            <param name="name">The name of the host.</param>
            <returns>A value indicating whether the host was removed.</returns>
        </member>
        <member name="M:slskd.Shares.ShareService.ListDirectoryAsync(System.String)">
            <summary>
                Returns the contents of the specified <paramref name="directory"/>.
            </summary>
            <param name="directory">The directory for which the contents are to be listed.</param>
            <returns>The contents of the directory.</returns>
        </member>
        <member name="M:slskd.Shares.ShareService.ResolveFileAsync(System.String)">
            <summary>
                Resolves the local filename of the specified <paramref name="remoteFilename"/>, if the mask is associated with a
                configured share.
            </summary>
            <param name="remoteFilename">The fully qualified filename to resolve.</param>
            <returns>The resolved local filename.</returns>
            <exception cref="T:slskd.NotFoundException">
                Thrown when the specified remote filename can not be associated with a configured share.
            </exception>
        </member>
        <member name="M:slskd.Shares.ShareService.ListScansAsync(System.Int64)">
            <summary>
                Returns the list of all <see cref="T:slskd.Shares.Scan"/>  started at or after the specified <paramref name="startedAtOrAfter"/>
                unix timestamp.
            </summary>
            <param name="startedAtOrAfter">A unix timestamp that serves as the lower bound of the time-based listing.</param>
            <returns>The operation context, including the list of found scans.</returns>
        </member>
        <member name="M:slskd.Shares.ShareService.RequestScan">
            <summary>
                Requests that a share scan is performed.
            </summary>
        </member>
        <member name="M:slskd.Shares.ShareService.SearchAsync(Soulseek.SearchQuery)">
            <summary>
                Searches the cache for the specified <paramref name="query"/> and returns the matching files.
            </summary>
            <param name="query">The query for which to search.</param>
            <returns>The matching files.</returns>
        </member>
        <member name="M:slskd.Shares.ShareService.ScanAsync">
            <summary>
                Scans the configured shares.
            </summary>
            <returns>The operation context.</returns>
            <exception cref="T:slskd.ShareScanInProgressException">Thrown when a scan is already in progress.</exception>
        </member>
        <member name="M:slskd.Shares.ShareService.TryCancelScan">
            <summary>
                Cancels the currently running scan, if one is running.
            </summary>
            <returns>A value indicating whether a scan was cancelled.</returns>
        </member>
        <member name="M:slskd.Shares.ShareService.InitializeAsync(System.Boolean)">
            <summary>
                Initializes the service and shares.
            </summary>
            <param name="forceRescan">A value indicating whether a full re-scan of shares should be performed.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="T:slskd.Shares.ISoulseekFileFactory">
            <summary>
                Creates instances of <see cref="T:Soulseek.File"/>.
            </summary>
        </member>
        <member name="M:slskd.Shares.ISoulseekFileFactory.Create(System.String,System.String)">
            <summary>
                Creates an instance of <see cref="T:Soulseek.File"/> from the given path.
            </summary>
            <param name="filename">The fully qualified path to the file.</param>
            <param name="maskedFilename">The masked filename.</param>
            <returns>The created instance.</returns>
        </member>
        <member name="T:slskd.Shares.SoulseekFileFactory">
            <summary>
                Creates instances of <see cref="T:Soulseek.File"/>.
            </summary>
        </member>
        <member name="M:slskd.Shares.SoulseekFileFactory.#ctor(slskd.Files.FileService)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Shares.SoulseekFileFactory"/> class.
            </summary>
            <param name="fileService"></param>
        </member>
        <member name="M:slskd.Shares.SoulseekFileFactory.Create(System.String,System.String)">
            <summary>
                Creates an instance of <see cref="T:Soulseek.File"/> from the given path.
            </summary>
            <param name="filename">The fully qualified path to the file.</param>
            <param name="maskedFilename">The masked filename.</param>
            <returns>The created instance.</returns>
        </member>
        <member name="T:slskd.Shares.SqliteShareRepository">
            <summary>
                Persistent storage of shared files and metadata.
            </summary>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Shares.SqliteShareRepository"/> class.
            </summary>
            <param name="connectionString"></param>
        </member>
        <member name="P:slskd.Shares.SqliteShareRepository.ConnectionString">
            <summary>
                Gets the connection string for this repository.
            </summary>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.BackupTo(slskd.Shares.IShareRepository)">
            <summary>
                Backs the current database up to the database at the specified <paramref name="repository"/>.
            </summary>
            <param name="repository">The destination repository.</param>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.CountDirectories(System.String)">
            <summary>
                Counts the number of directories in the database.
            </summary>
            <param name="parentDirectory">The optional directory prefix used for counting subdirectories.</param>
            <returns>The number of directories.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.CountFiles(System.String)">
            <summary>
                Counts the number of files in the database.
            </summary>
            <param name="parentDirectory">The optional directory prefix used for counting files in a subdirectory.</param>
            <returns>The number of files.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.Create(System.Boolean)">
            <summary>
                Creates a new database.
            </summary>
            <remarks>
                Creates tables using 'IF NOT EXISTS', so this is idempotent unless 'discardExisting` is specified, in which case
                tables are explicitly dropped prior to creation.
            </remarks>
            <param name="discardExisting">An optional value that determines whether the existing database should be discarded.</param>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.Dispose">
            <summary>
                Disposes this object.
            </summary>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.DumpTo(System.String)">
            <summary>
                Dumps the contents of the database to a file.
            </summary>
            <param name="filename">The destination file.</param>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.EnableKeepalive(System.Boolean)">
            <summary>
                Enable connection keepalive.
            </summary>
            <param name="enable">A value indicating whether the keepalive logic should be executed.</param>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.FindFileInfo(System.String)">
            <summary>
                Finds the filename of the file matching the specified <paramref name="maskedFilename"/>.
            </summary>
            <param name="maskedFilename">The fully qualified remote path of the file.</param>
            <returns>The filename, if found.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.FindLatestScan">
            <summary>
                Finds and returns the most recent scan record.
            </summary>
            <returns>The most recent scan record, or default if no scan was found.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.FlagLatestScanAsSuspect">
            <summary>
                Flags the latest scan as suspect, indicating that the cached contents may have diverged from physical storage.
            </summary>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.InsertDirectory(System.String,System.Int64)">
            <summary>
                Inserts a directory.
            </summary>
            <param name="name">The fully qualified local name of the directory.</param>
            <param name="timestamp">The timestamp to assign to the record.</param>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.InsertFile(System.String,System.String,System.DateTime,Soulseek.File,System.Int64)">
            <summary>
                Inserts a file.
            </summary>
            <param name="maskedFilename">The fully qualified remote path of the file.</param>
            <param name="originalFilename">The fully qualified local path of the file.</param>
            <param name="touchedAt">The timestamp at which the file was last modified, according to the host OS.</param>
            <param name="file">The Soulseek.File instance representing the file.</param>
            <param name="timestamp">The timestamp to assign to the record.</param>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.InsertScan(System.Int64,slskd.Options.SharesOptions)">
            <summary>
                Inserts a scan record at the specified <paramref name="timestamp"/>.
            </summary>
            <param name="timestamp">The timestamp associated with the scan.</param>
            <param name="options">The options snapshot at the start of the scan.</param>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.ListDirectories(System.String)">
            <summary>
                Lists all directories.
            </summary>
            <param name="parentDirectory">The optional directory prefix used for listing subdirectories.</param>
            <returns>The list of directories.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.ListFiles(System.String,System.Boolean)">
            <summary>
                Lists all files.
            </summary>
            <param name="parentDirectory">The optional parent directory.</param>
            <param name="includeFullPath">A value indicating whether the fully qualified path should be returned.</param>
            <returns>The list of files.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.ListScans(System.Int64)">
            <summary>
                Returns the list of all <see cref="T:slskd.Shares.Scan"/> started at or after the specified <paramref name="startedAtOrAfter"/>
                unix timestamp.
            </summary>
            <param name="startedAtOrAfter">A unix timestamp that serves as the lower bound of the time-based listing.</param>
            <returns>The operation context, including the list of found scans.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.PruneDirectories(System.Int64)">
            <summary>
                Deletes directory records with a timestamp prior to the specified <paramref name="olderThanTimestamp"/>.
            </summary>
            <param name="olderThanTimestamp">The timestamp before which to delete directories.</param>
            <returns>The number of records deleted.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.PruneFiles(System.Int64)">
            <summary>
                Deletes file records with a timestamp prior to the specified <paramref name="olderThanTimestamp"/>.
            </summary>
            <param name="olderThanTimestamp">The timestamp before which to delete files.</param>
            <returns>The number of records deleted.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.RebuildFilenameIndex">
            <summary>
                Rebuilds the filename index table using the data in the files table.
            </summary>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.RestoreFrom(slskd.Shares.IShareRepository)">
            <summary>
                Restores the current database from the database at the specified <paramref name="repository"/>.
            </summary>
            <param name="repository">The destination repository.</param>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.Search(Soulseek.SearchQuery)">
            <summary>
                Searches the database for files matching the specified <paramref name="query"/>.
            </summary>
            <param name="query">The search query.</param>
            <returns>The list of matching files.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.TryValidate">
            <summary>
                Attempts to validate the backing database.
            </summary>
            <returns>A value indicating whether the database is valid.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.TryValidate(System.Collections.Generic.IEnumerable{System.String}@)">
            <summary>
                Attempts to validate the backing database.
            </summary>
            <param name="problems">The list of problems, if the database is invalid.</param>
            <returns>A value indicating whether the database is valid.</returns>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.UpdateScan(System.Int64,System.Int64)">
            <summary>
                Updates the scan started at the specified <paramref name="timestamp"/> to set the <paramref name="end"/>.
            </summary>
            <param name="timestamp">The timestamp associated with the scan.</param>
            <param name="end">The timestamp at the conclusion of the scan.</param>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.Vacuum">
            <summary>
                Reclaims unused space.
            </summary>
        </member>
        <member name="M:slskd.Shares.SqliteShareRepository.Dispose(System.Boolean)">
            <summary>
                Disposes this object.
            </summary>
            <param name="disposing"></param>
        </member>
        <member name="T:slskd.Shares.Host">
            <summary>
                A share host.
            </summary>
        </member>
        <member name="M:slskd.Shares.Host.#ctor(System.String,System.Collections.Generic.IEnumerable{slskd.Shares.Share})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Shares.Host"/> class.
            </summary>
            <param name="name">The name of the host.</param>
            <param name="shares">The collection of hosted shares.</param>
        </member>
        <member name="P:slskd.Shares.Host.IsLocalHost">
            <summary>
                Gets a value indicating whether this host is the local host.
            </summary>
        </member>
        <member name="P:slskd.Shares.Host.Name">
            <summary>
                Gets the name of the host.
            </summary>
            <remarks>Corresponds to the configured <see cref="P:slskd.Options.InstanceName"/> of the host, or "local" for the local host.</remarks>
        </member>
        <member name="P:slskd.Shares.Host.Shares">
            <summary>
                Gets the collection of hosted shares.
            </summary>
        </member>
        <member name="T:slskd.Shares.Share">
            <summary>
                A file share.
            </summary>
        </member>
        <member name="M:slskd.Shares.Share.#ctor(System.String,System.String,System.Boolean,System.String,System.String,System.String,System.Nullable{System.Int32},System.Nullable{System.Int32})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Shares.Share"/> class.
            </summary>
            <param name="id"></param>
            <param name="alias"></param>
            <param name="isExcluded"></param>
            <param name="localPath"></param>
            <param name="raw"></param>
            <param name="remotePath"></param>
            <param name="directories"></param>
            <param name="files"></param>
        </member>
        <member name="M:slskd.Shares.Share.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Shares.Share"/> class.
            </summary>
            <param name="share"></param>
        </member>
        <member name="T:slskd.Shares.StorageMode">
            <summary>
                Storage mode.
            </summary>
        </member>
        <member name="F:slskd.Shares.StorageMode.Memory">
            <summary>
                Stored in memory.
            </summary>
        </member>
        <member name="F:slskd.Shares.StorageMode.Disk">
            <summary>
                Stored on disk.
            </summary>
        </member>
        <member name="T:slskd.CommonExtensions">
            <summary>
                Common extensions; things not specific to Soulseek or slskd.
            </summary>
        </member>
        <member name="M:slskd.CommonExtensions.TimeoutAfter``1(System.Threading.Tasks.Task{``0},System.TimeSpan)">
            <summary>
                Times this Task out after the specified TimeSpan.
            </summary>
            <typeparam name="T">The result type.</typeparam>
            <param name="task">The task.</param>
            <param name="timeout">The timeout.</param>
            <returns>The operation context.</returns>
            <exception cref="T:System.TimeoutException">Thrown when the task times out.</exception>
        </member>
        <member name="M:slskd.CommonExtensions.TimeoutAfter(System.Threading.Tasks.Task,System.TimeSpan)">
            <summary>
                Times this Task out after the specified TimeSpan.
            </summary>
            <param name="task">The task.</param>
            <param name="timeout">The timeout.</param>
            <returns>The operation context.</returns>
            <exception cref="T:System.TimeoutException">Thrown when the task times out.</exception>
        </member>
        <member name="M:slskd.CommonExtensions.DiffWith(System.Object,System.Object,System.String)">
            <summary>
                Deeply compares this object with the specified object and returns a list of properties that are different.
            </summary>
            <param name="left">The left side of the comparison.</param>
            <param name="right">The right side of the comparison.</param>
            <param name="parentFqn">The root path for recursive calls.</param>
            <returns>A list of differences between the two objects.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.GuessDirectorySeparator(System.String)">
            <summary>
                Makes a best-guess determination of the directory separator character used by a remote system,
                based on the characters present in the specified <paramref name="remoteFilename"/>.
            </summary>
            <param name="remoteFilename">The fully qualified remote filename to inspect.</param>
            <returns>The guessed directory separator.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.GetDirectoryName(System.String,System.Char)">
            <summary>
                Returns the directory name of the given <paramref name="path"/>, using the specified <paramref name="directorySeparator"/>
                to split and join directories and filename.
            </summary>
            <param name="path">The path for which to return the directory name.</param>
            <param name="directorySeparator">The directory separator character.</param>
            <returns>The specified path, less the last segment.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.DirectoryName(System.String)">
            <summary>
                Returns the directory from the given path, regardless of separator format.
            </summary>
            <param name="path">The path.</param>
            <returns>The directory.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.TryDispose(System.IDisposable)">
            <summary>
                Safely disposes this object without throwing if it is already exposed.
            </summary>
            <param name="obj">The object.</param>
        </member>
        <member name="M:slskd.CommonExtensions.GetPropertiesRecursively(System.Type)">
            <summary>
                Recursively retrieves all properties.
            </summary>
            <param name="type">The type from which to retrieve properties.</param>
            <returns>The list of properties.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.IsValidRegex(System.String)">
            <summary>
                Determines whether the string is a valid regular expression.
            </summary>
            <param name="pattern">The string to validate.</param>
            <returns>A value indicating whether the string is a valid regular expression.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.ReplaceFirst(System.String,System.String,System.String)">
            <summary>
                Replaces the first occurrence of <paramref name="phrase"/> in the string with <paramref name="replacement"/>.
            </summary>
            <param name="str">The string on which to perform the replacement.</param>
            <param name="phrase">The phrase or substring to replace.</param>
            <param name="replacement">The replacement string.</param>
            <returns>The string, with the desired phrase replaced.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.Serialize(System.IdentityModel.Tokens.Jwt.JwtSecurityToken)">
            <summary>
                Serializes the JWT.
            </summary>
            <param name="jwt">The JWT.</param>
            <returns>The serialized string.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.SizeSuffix(System.Double,System.Int32)">
            <summary>
                Formats byte to nearest size (KB, MB, etc.)
            </summary>
            <param name="value">The value to format.</param>
            <param name="decimalPlaces">The number of decimal places to include.</param>
            <returns>The formatted string.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.ToColloquialString(System.Type)">
            <summary>
                Returns a "pretty" string representation of the provided Type; specifically, corrects the naming of generic Types
                and appends the type parameters for the type to the name as it appears in the code editor.
            </summary>
            <param name="type">The type for which the colloquial name should be created.</param>
            <returns>A "pretty" string representation of the provided Type.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.ToJson(System.Object)">
            <summary>
                Serializes this object to json.
            </summary>
            <param name="obj">The object to serialize.</param>
            <returns>A string containing the serialized object.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.ToYaml(System.Object)">
            <summary>
                Serializes this object to yaml.
            </summary>
            <param name="obj">The object to serialize.</param>
            <returns>A string containing the serialized object.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.FromYaml``1(System.String)">
            <summary>
                Deserializes this string from yaml to an object of type <typeparamref name="T"/>.
            </summary>
            <typeparam name="T">The type to which to deserialize the string.</typeparam>
            <param name="str">The string to deserialize.</param>
            <returns>The new object deserialized from the string.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.ToLocalFilename(System.String,System.String)">
            <summary>
                Converts a fully qualified remote filename to a local filename based in the provided
                <paramref name="baseDirectory"/>, swapping directory characters for those specific to the local OS, removing any
                characters that are invalid for the local OS, and making the path relative to the remote store (including the
                filename and the parent folder).
            </summary>
            <param name="remoteFilename">The fully qualified remote filename to convert.</param>
            <param name="baseDirectory">The base directory for the local filename.</param>
            <returns>The converted filename.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.NormalizePathForSoulseek(System.String)">
            <summary>
                Converts the given path to the normalized format (normalizes path separators to backslashes).
            </summary>
            <remarks>
                Various Soulseek clients (including this one) assume paths to use backslashes, regardless of the host system.
            </remarks>
            <param name="path">The path to convert.</param>
            <returns>The converted path.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.LocalizePath(System.String)">
            <summary>
                Converts the given path to the local format (normalizes path separators to Path.DirectorySeparatorChar).
            </summary>
            <param name="path">The path to convert.</param>
            <returns>The converted path.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.GetNormalizedDirectoryName(System.String)">
            <summary>
                <see cref="M:System.IO.Path.GetDirectoryName(System.String)"/>, but for paths normalized to use backslashes.
            </summary>
            <param name="path"></param>
            <returns></returns>
        </member>
        <member name="M:slskd.CommonExtensions.GetNormalizedFileName(System.String)">
            <summary>
                <see cref="M:System.IO.Path.GetFileName(System.String)"/>, but for paths normalized to use backslashes.
            </summary>
            <param name="path"></param>
            <returns></returns>
        </member>
        <member name="M:slskd.CommonExtensions.ToLocalRelativeFilename(System.String)">
            <summary>
                Converts a fully qualified remote filename to a local filename, swapping directory characters for those specific
                to the local OS, removing any characters that are invalid for the local OS, and making the path relative to the
                remote store (including the filename and the parent folder).
            </summary>
            <param name="remoteFilename">The fully qualified remote filename to convert.</param>
            <returns>The converted filename.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.ReplaceInvalidFileNameCharacters(System.String,System.Char)">
            <summary>
                Replaces any occurrence of an invalid filename character with the specified <see paramref="replacement"/>.
            </summary>
            <param name="path">The path to sanitize.</param>
            <param name="replacement">The character with which to replace invalid characters.</param>
            <returns>The sanitized path.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.IsDictionary(System.Object)">
            <summary>
                Determines whether the given object is a <see cref="T:System.Collections.Generic.Dictionary`2"/>.
            </summary>
            <param name="obj">The object to check.</param>
            <returns>A value indicating whether the given object is a dictionary.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.ToEnum``1(System.String)">
            <summary>
                Casts the string to <typeparamref name="T"/>.
            </summary>
            <typeparam name="T">The Enum type to which to cast.</typeparam>
            <param name="str">The string to cast.</param>
            <returns>The cast enum.</returns>
        </member>
        <member name="M:slskd.CommonExtensions.FromJson``1(System.String)">
            <summary>
                Deserializes this string from json to an object of type <typeparamref name="T"/>.
            </summary>
            <typeparam name="T">The type to which to deserialize the string.</typeparam>
            <param name="str">The string to deserialize.</param>
            <returns>The new object deserialized from the string.</returns>
        </member>
        <member name="T:slskd.Compute">
            <summary>
                Computational functions.
            </summary>
        </member>
        <member name="T:slskd.Configuration.CommandLineConfigurationExtensions">
            <summary>
                Extension methods for adding <see cref="T:slskd.Configuration.CommandLineConfigurationProvider"/>.
            </summary>
        </member>
        <member name="M:slskd.Configuration.CommandLineConfigurationExtensions.AddCommandLine(Microsoft.Extensions.Configuration.IConfigurationBuilder,System.Type,System.String[],System.String)">
            <summary>
                Adds a command line argument configuration source to <paramref name="builder"/>.
            </summary>
            <param name="builder">The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/> to which to add.</param>
            <param name="targetType">The type from which to map properties.</param>
            <param name="multiValuedArguments">An array of argument names which can be specified with multiple values.</param>
            <param name="commandLine">The command line string from which to parse arguments.</param>
            <returns>The updated <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/>.</returns>
        </member>
        <member name="M:slskd.Configuration.CommandLineConfigurationExtensions.AddCommandLine(Microsoft.Extensions.Configuration.IConfigurationBuilder,System.Action{slskd.Configuration.CommandLineConfigurationSource})">
            <summary>
                Adds a command line argument configuration source to <paramref name="builder"/>.
            </summary>
            <param name="builder">The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/> to which to add.</param>
            <param name="configureSource">Configures the source.</param>
            <returns>The updated <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/>.</returns>
        </member>
        <member name="T:slskd.Configuration.CommandLineConfigurationProvider">
            <summary>
                A command line argument <see cref="T:Microsoft.Extensions.Configuration.ConfigurationProvider"/>.
            </summary>
        </member>
        <member name="M:slskd.Configuration.CommandLineConfigurationProvider.#ctor(slskd.Configuration.CommandLineConfigurationSource)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Configuration.CommandLineConfigurationProvider"/> class.
            </summary>
            <param name="source">The source settings.</param>
        </member>
        <member name="M:slskd.Configuration.CommandLineConfigurationProvider.Load">
            <summary>
                Parses command line arguments from the specified string and maps them to the corresponding keys.
            </summary>
        </member>
        <member name="T:slskd.Configuration.CommandLineConfigurationSource">
            <summary>
                Represents command line arguments as an <see cref="T:Microsoft.Extensions.Configuration.IConfigurationSource"/>.
            </summary>
        </member>
        <member name="P:slskd.Configuration.CommandLineConfigurationSource.CommandLine">
            <summary>
                Gets or sets the command line string from which to parse arguments.
            </summary>
        </member>
        <member name="P:slskd.Configuration.CommandLineConfigurationSource.TargetType">
            <summary>
                Gets or sets the type from which to map properties.
            </summary>
        </member>
        <member name="P:slskd.Configuration.CommandLineConfigurationSource.MultiValuedArguments">
            <summary>
                Gets or sets an array of argument names which can be specified with multiple values.
            </summary>
        </member>
        <member name="M:slskd.Configuration.CommandLineConfigurationSource.Build(Microsoft.Extensions.Configuration.IConfigurationBuilder)">
            <summary>
                Builds the <see cref="T:slskd.Configuration.CommandLineConfigurationProvider"/> for this source.
            </summary>
            <param name="builder">The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/>.</param>
            <returns>A <see cref="T:slskd.Configuration.CommandLineConfigurationProvider"/>.</returns>
        </member>
        <member name="T:slskd.Configuration.DefaultValueConfigurationExtensions">
            <summary>
                Extension methods for adding <see cref="T:slskd.Configuration.DefaultValueConfigurationProvider"/>.
            </summary>
        </member>
        <member name="M:slskd.Configuration.DefaultValueConfigurationExtensions.AddDefaultValues(Microsoft.Extensions.Configuration.IConfigurationBuilder,System.Type)">
            <summary>
                Adds a default value configuration source to <paramref name="builder"/>.
            </summary>
            <param name="builder">The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/> to which to add.</param>
            <param name="targetType">The type from which to load default values.</param>
            <returns>The updated <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/>.</returns>
        </member>
        <member name="M:slskd.Configuration.DefaultValueConfigurationExtensions.AddDefaultValues(Microsoft.Extensions.Configuration.IConfigurationBuilder,System.Action{slskd.Configuration.DefaultValueConfigurationSource})">
            <summary>
                Adds a default value configuration source to <paramref name="builder"/>.
            </summary>
            <param name="builder">The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/> to which to add.</param>
            <param name="configureSource">Configures the source.</param>
            <returns>The updated <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/>.</returns>
        </member>
        <member name="T:slskd.Configuration.DefaultValueConfigurationProvider">
            <summary>
                A default value <see cref="T:Microsoft.Extensions.Configuration.ConfigurationProvider"/>.
            </summary>
        </member>
        <member name="M:slskd.Configuration.DefaultValueConfigurationProvider.#ctor(slskd.Configuration.DefaultValueConfigurationSource)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Configuration.DefaultValueConfigurationProvider"/> class.
            </summary>
            <param name="source">The source settings.</param>
        </member>
        <member name="M:slskd.Configuration.DefaultValueConfigurationProvider.Load">
            <summary>
                Loads default values from the specified <see cref="P:slskd.Configuration.DefaultValueConfigurationProvider.TargetType"/> and maps them to the corresponding keys.
            </summary>
        </member>
        <member name="T:slskd.Configuration.DefaultValueConfigurationSource">
            <summary>
                Represents default values as an <see cref="T:Microsoft.Extensions.Configuration.IConfigurationSource"/>.
            </summary>
        </member>
        <member name="P:slskd.Configuration.DefaultValueConfigurationSource.TargetType">
            <summary>
                Gets or sets the type from which to map properties.
            </summary>
        </member>
        <member name="M:slskd.Configuration.DefaultValueConfigurationSource.Build(Microsoft.Extensions.Configuration.IConfigurationBuilder)">
            <summary>
                Builds the <see cref="T:slskd.Configuration.DefaultValueConfigurationProvider"/> for this source.
            </summary>
            <param name="builder">The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/>.</param>
            <returns>A <see cref="T:slskd.Configuration.DefaultValueConfigurationProvider"/>.</returns>
        </member>
        <member name="T:slskd.Configuration.EnvironmentVariableConfigurationExtensions">
            <summary>
                Extension methods for adding <see cref="T:slskd.Configuration.EnvironmentVariableConfigurationProvider"/>.
            </summary>
        </member>
        <member name="M:slskd.Configuration.EnvironmentVariableConfigurationExtensions.AddEnvironmentVariables(Microsoft.Extensions.Configuration.IConfigurationBuilder,System.Type,System.String)">
            <summary>
                Adds an environment variable configuration source to <paramref name="builder"/>.
            </summary>
            <param name="builder">The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/> to which to add.</param>
            <param name="targetType">The type from which to map properties.</param>
            <param name="prefix">A prefix to prepend to all variable names.</param>
            <returns>The updated <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/>.</returns>
        </member>
        <member name="M:slskd.Configuration.EnvironmentVariableConfigurationExtensions.AddEnvironmentVariables(Microsoft.Extensions.Configuration.IConfigurationBuilder,System.Action{slskd.Configuration.EnvironmentVariableConfigurationSource})">
            <summary>
                Adds an environment variable configuration source to <paramref name="builder"/>.
            </summary>
            <param name="builder">The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/> to which to add.</param>
            <param name="configureSource">Configures the source.</param>
            <returns>The updated <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/>.</returns>
        </member>
        <member name="T:slskd.Configuration.EnvironmentVariableConfigurationProvider">
            <summary>
                An environment variable <see cref="T:Microsoft.Extensions.Configuration.ConfigurationProvider"/>.
            </summary>
        </member>
        <member name="M:slskd.Configuration.EnvironmentVariableConfigurationProvider.#ctor(slskd.Configuration.EnvironmentVariableConfigurationSource)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Configuration.EnvironmentVariableConfigurationProvider"/> class.
            </summary>
            <param name="source">The source settings.</param>
        </member>
        <member name="M:slskd.Configuration.EnvironmentVariableConfigurationProvider.Load">
            <summary>
                Loads environment variables and maps them to the corresponding keys.
            </summary>
        </member>
        <member name="T:slskd.Configuration.EnvironmentVariableConfigurationSource">
            <summary>
                Represents environment variables as an <see cref="T:Microsoft.Extensions.Configuration.IConfigurationSource"/>.
            </summary>
        </member>
        <member name="P:slskd.Configuration.EnvironmentVariableConfigurationSource.TargetType">
            <summary>
                Gets or sets the type from which to map properties.
            </summary>
        </member>
        <member name="P:slskd.Configuration.EnvironmentVariableConfigurationSource.Prefix">
            <summary>
                Gets or sets a prefix to prepend to all variable names.
            </summary>
        </member>
        <member name="M:slskd.Configuration.EnvironmentVariableConfigurationSource.Build(Microsoft.Extensions.Configuration.IConfigurationBuilder)">
            <summary>
                Builds the <see cref="T:slskd.Configuration.EnvironmentVariableConfigurationProvider"/> for this source.
            </summary>
            <param name="builder">The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/>.</param>
            <returns>A <see cref="T:slskd.Configuration.EnvironmentVariableConfigurationProvider"/>.</returns>
        </member>
        <member name="T:slskd.Configuration.RequiresReconnectAttribute">
            <summary>
                Indicates that the application must disconnect and reconnect to the Soulseek server for changes to take effect.
            </summary>
        </member>
        <member name="T:slskd.Configuration.RequiresRestartAttribute">
            <summary>
                Indicates that the application must be restarted for any changes to take effect.
            </summary>
        </member>
        <member name="T:slskd.Configuration.YamlConfigurationExtensions">
            <summary>
                Extension methods for adding <see cref="T:slskd.Configuration.YamlConfigurationProvider"/>.
            </summary>
        </member>
        <member name="M:slskd.Configuration.YamlConfigurationExtensions.AddYamlFile(Microsoft.Extensions.Configuration.IConfigurationBuilder,System.String,System.Type,System.Boolean,System.Boolean,System.Boolean,Microsoft.Extensions.FileProviders.IFileProvider)">
            <summary>
                Adds a YAML configuration source to <paramref name="builder"/>.
            </summary>
            <param name="builder">The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/> to which to add .</param>
            <param name="path">
                Path relative to the base path stored in <see cref="P:Microsoft.Extensions.Configuration.IConfigurationBuilder.Properties"/> of <paramref name="builder"/>.
            </param>
            <param name="targetType">The type from which to map properties.</param>
            <param name="optional">Whether the file is optional.</param>
            <param name="reloadOnChange">Whether the configuration should be reloaded if the file changes.</param>
            <param name="normalizeKeys">
                A value indicating whether configuration keys should be normalized (_, - removed, changed to lowercase).
            </param>
            <param name="provider">The updated <see cref="T:Microsoft.Extensions.FileProviders.IFileProvider"/> to use to access the file.</param>
            <returns>The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/>.</returns>
        </member>
        <member name="M:slskd.Configuration.YamlConfigurationExtensions.AddYamlFile(Microsoft.Extensions.Configuration.IConfigurationBuilder,System.Action{slskd.Configuration.YamlConfigurationSource})">
            <summary>
                Adds a YAML configuration source to <paramref name="builder"/>.
            </summary>
            <param name="builder">The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/> to which to add.</param>
            <param name="configureSource">Configures the source.</param>
            <returns>The updated <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/>.</returns>
        </member>
        <member name="T:slskd.Configuration.YamlConfigurationProvider">
            <summary>
                A YAML file based <see cref="T:Microsoft.Extensions.Configuration.FileConfigurationProvider"/>.
            </summary>
        </member>
        <member name="M:slskd.Configuration.YamlConfigurationProvider.#ctor(slskd.Configuration.YamlConfigurationSource)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Configuration.YamlConfigurationProvider"/> class.
            </summary>
            <param name="source">The source settings.</param>
        </member>
        <member name="M:slskd.Configuration.YamlConfigurationProvider.Load(System.IO.Stream)">
            <summary>
                Loads the YAML data from a stream.
            </summary>
            <param name="stream">The stream to read.</param>
        </member>
        <member name="T:slskd.Configuration.YamlConfigurationSource">
            <summary>
                Represents a YAML file as an <see cref="T:Microsoft.Extensions.Configuration.IConfigurationSource"/>.
            </summary>
        </member>
        <member name="P:slskd.Configuration.YamlConfigurationSource.TargetType">
            <summary>
                Gets or sets the type from which to map properties.
            </summary>
        </member>
        <member name="P:slskd.Configuration.YamlConfigurationSource.NormalizeKeys">
            <summary>
                Gets or sets a value indicating whether configuration keys should be normalized (_, - removed, changed to lowercase).
            </summary>
        </member>
        <member name="M:slskd.Configuration.YamlConfigurationSource.Build(Microsoft.Extensions.Configuration.IConfigurationBuilder)">
            <summary>
                Builds the <see cref="T:slskd.Configuration.YamlConfigurationProvider"/> for this source.
            </summary>
            <param name="builder">The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationBuilder"/>.</param>
            <returns>A <see cref="T:slskd.Configuration.YamlConfigurationProvider"/>.</returns>
        </member>
        <member name="T:slskd.Cryptography.Aes">
            <summary>
                AES utility methods.
            </summary>
        </member>
        <member name="M:slskd.Cryptography.Aes.Decrypt(System.Byte[],System.Byte[])">
            <summary>
                Decrypts the specified <paramref name="encryptedBytes"/> with the specified <paramref name="key"/>.
            </summary>
            <param name="encryptedBytes">The encrypted data to decrypt.</param>
            <param name="key">The encryption key.</param>
            <returns>The decrypted data.</returns>
        </member>
        <member name="M:slskd.Cryptography.Aes.Encrypt(System.Byte[],System.Byte[])">
            <summary>
                Encrypts the specified <paramref name="plainBytes"/> with the specified <paramref name="key"/>.
            </summary>
            <param name="plainBytes">The plain data to encrypt.</param>
            <param name="key">The encryption key.</param>
            <returns>The encrypted data.</returns>
        </member>
        <member name="M:slskd.Cryptography.Aes.GenerateRandomKey">
            <summary>
                Generates a random key using the default key and block sizes.
            </summary>
            <returns>The generated key.</returns>
        </member>
        <member name="T:slskd.Cryptography.Pbkdf2">
            <summary>
                PBKDF2/RFC 2898 utility methods.
            </summary>
        </member>
        <member name="M:slskd.Cryptography.Pbkdf2.GetKey(System.String)">
            <summary>
                Gets a 256 bit (32 byte) key derived from the specified <paramref name="password"/> using PBKDF2/RFC 2898.
            </summary>
            <param name="password">The password from which to derive the key.</param>
            <returns>The derived key.</returns>
        </member>
        <member name="M:slskd.Cryptography.Pbkdf2.GetKey(System.String,System.String,System.Int32)">
            <summary>
                Gets a variable <paramref name="length"/> key derived from the specified <paramref name="password"/> and <paramref name="salt"/> using PBKDF2/RFC 2898.
            </summary>
            <param name="password">The password from which to derive the key.</param>
            <param name="salt">The value with which to salt the key.</param>
            <param name="length">The desired length of the key, in bytes.</param>
            <returns>The derived key.</returns>
        </member>
        <member name="T:slskd.Cryptography.X509">
            <summary>
                X509 utility methods.
            </summary>
        </member>
        <member name="M:slskd.Cryptography.X509.Generate(System.String,System.String,System.Security.Cryptography.X509Certificates.X509KeyStorageFlags)">
            <summary>
                Generates an X509 certificate for the specified <paramref name="subject"/>.
            </summary>
            <param name="subject">The certificate subject.</param>
            <param name="password">The optional password for the certificate.</param>
            <param name="x509KeyStorageFlags">The optional key storage flags for the certificate.</param>
            <returns>The generated certificate.</returns>
        </member>
        <member name="M:slskd.Cryptography.X509.TryValidate(System.String,System.String,System.String@)">
            <summary>
                Validates an X509 certificate given a PFX <paramref name="fileName"/> and optional <paramref name="password"/>.
            </summary>
            <param name="fileName">The path to the PFX certificate file to validate.</param>
            <param name="password">The optional password for the certificate.</param>
            <param name="result">The error message, if the certificate is invalid.</param>
            <returns>A value indicating whether the certificate is valid.</returns>
        </member>
        <member name="T:slskd.Dumper">
            <summary>
                Dumps the contents of the application's memory to a .dmp file using dotnet-dump.
            </summary>
            <remarks>
                <para>
                    Monitor https://docs.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-dump for tool updates. Currently supported
                    runtime IDs:
                </para>
                <list type="bullet">
                    <listheader>Currently supported runtime IDs:</listheader>
                    <item>https://aka.ms/dotnet-dump/win-x86</item>
                    <item>https://aka.ms/dotnet-dump/win-x64</item>
                    <item>https://aka.ms/dotnet-dump/win-arm</item>
                    <item>https://aka.ms/dotnet-dump/win-arm64</item>
                    <item>https://aka.ms/dotnet-dump/osx-x64</item>
                    <item>https://aka.ms/dotnet-dump/linux-x64</item>
                    <item>https://aka.ms/dotnet-dump/linux-arm</item>
                    <item>https://aka.ms/dotnet-dump/linux-arm64</item>
                    <item>https://aka.ms/dotnet-dump/linux-musl-x64</item>
                    <item>https://aka.ms/dotnet-dump/linux-musl-arm64</item>
                    <item></item>
                </list>
            </remarks>
        </member>
        <member name="T:slskd.ApplicationShutdownException">
            <summary>
                Represents a normal application shutdown.
            </summary>
        </member>
        <member name="M:slskd.ApplicationShutdownException.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ApplicationShutdownException"/> class.
            </summary>
        </member>
        <member name="M:slskd.ApplicationShutdownException.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ApplicationShutdownException"/> class with a specified error message.
            </summary>
            <param name="message">The message that describes the error.</param>
        </member>
        <member name="M:slskd.ApplicationShutdownException.#ctor(System.String,System.Exception)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ApplicationShutdownException"/> class with a specified error message and a
                reference to the inner exception that is the cause of this exception.
            </summary>
            <param name="message">The message that describes the error.</param>
            <param name="innerException">
                The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no
                inner exception is specified.
            </param>
        </member>
        <member name="T:slskd.GitHubException">
            <summary>
                Represents a normal application shutdown.
            </summary>
        </member>
        <member name="M:slskd.GitHubException.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.GitHubException"/> class.
            </summary>
        </member>
        <member name="M:slskd.GitHubException.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.GitHubException"/> class with a specified error message.
            </summary>
            <param name="message">The message that describes the error.</param>
        </member>
        <member name="M:slskd.GitHubException.#ctor(System.String,System.Exception)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.GitHubException"/> class with a specified error message and a
                reference to the inner exception that is the cause of this exception.
            </summary>
            <param name="message">The message that describes the error.</param>
            <param name="innerException">
                The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no
                inner exception is specified.
            </param>
        </member>
        <member name="T:slskd.IntentionalDisconnectException">
            <summary>
                Represents an intentional client disconnect.
            </summary>
        </member>
        <member name="M:slskd.IntentionalDisconnectException.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.IntentionalDisconnectException"/> class.
            </summary>
        </member>
        <member name="M:slskd.IntentionalDisconnectException.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.IntentionalDisconnectException"/> class with a specified error message.
            </summary>
            <param name="message">The message that describes the error.</param>
        </member>
        <member name="M:slskd.IntentionalDisconnectException.#ctor(System.String,System.Exception)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.IntentionalDisconnectException"/> class with a specified error message and a
                reference to the inner exception that is the cause of this exception.
            </summary>
            <param name="message">The message that describes the error.</param>
            <param name="innerException">
                The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no
                inner exception is specified.
            </param>
        </member>
        <member name="T:slskd.NotFoundException">
            <summary>
                Represents errors that originate when a searched resource can't be located.
            </summary>
        </member>
        <member name="M:slskd.NotFoundException.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.NotFoundException"/> class.
            </summary>
        </member>
        <member name="M:slskd.NotFoundException.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.NotFoundException"/> class with a specified error message.
            </summary>
            <param name="message">The message that describes the error.</param>
        </member>
        <member name="M:slskd.NotFoundException.#ctor(System.String,System.Exception)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.NotFoundException"/> class with a specified error message and a
                reference to the inner exception that is the cause of this exception.
            </summary>
            <param name="message">The message that describes the error.</param>
            <param name="innerException">
                The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no
                inner exception is specified.
            </param>
        </member>
        <member name="T:slskd.OutOfRangeException">
            <summary>
                Represents errors that originate when a value falls out of an expected range.
            </summary>
        </member>
        <member name="M:slskd.OutOfRangeException.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.OutOfRangeException"/> class.
            </summary>
        </member>
        <member name="M:slskd.OutOfRangeException.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.OutOfRangeException"/> class with a specified error message.
            </summary>
            <param name="message">The message that describes the error.</param>
        </member>
        <member name="M:slskd.OutOfRangeException.#ctor(System.String,System.Exception)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.OutOfRangeException"/> class with a specified error message and a
                reference to the inner exception that is the cause of this exception.
            </summary>
            <param name="message">The message that describes the error.</param>
            <param name="innerException">
                The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no
                inner exception is specified.
            </param>
        </member>
        <member name="T:slskd.RelayException">
            <summary>
                Represents an error related to the slskd relay feature.
            </summary>
        </member>
        <member name="M:slskd.RelayException.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.RelayException"/> class.
            </summary>
        </member>
        <member name="M:slskd.RelayException.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.RelayException"/> class with a specified error message.
            </summary>
            <param name="message">The message that describes the error.</param>
        </member>
        <member name="M:slskd.RelayException.#ctor(System.String,System.Exception)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.RelayException"/> class with a specified error message and a
                reference to the inner exception that is the cause of this exception.
            </summary>
            <param name="message">The message that describes the error.</param>
            <param name="innerException">
                The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no
                inner exception is specified.
            </param>
        </member>
        <member name="T:slskd.RetryException">
            <summary>
                Represents errors that originate while attempting to execute retry logic.
            </summary>
        </member>
        <member name="M:slskd.RetryException.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.RetryException"/> class.
            </summary>
        </member>
        <member name="M:slskd.RetryException.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.RetryException"/> class with a specified error message.
            </summary>
            <param name="message">The message that describes the error.</param>
        </member>
        <member name="M:slskd.RetryException.#ctor(System.String,System.Exception)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.RetryException"/> class with a specified error message and a
                reference to the inner exception that is the cause of this exception.
            </summary>
            <param name="message">The message that describes the error.</param>
            <param name="innerException">
                The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no
                inner exception is specified.
            </param>
        </member>
        <member name="T:slskd.ShareInitializationException">
            <summary>
                Represents an error that occurs when multiple share scans are attempted concurrently.
            </summary>
        </member>
        <member name="M:slskd.ShareInitializationException.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ShareInitializationException"/> class.
            </summary>
        </member>
        <member name="M:slskd.ShareInitializationException.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ShareInitializationException"/> class with a specified error message.
            </summary>
            <param name="message">The message that describes the error.</param>
        </member>
        <member name="M:slskd.ShareInitializationException.#ctor(System.String,System.Exception)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ShareInitializationException"/> class with a specified error message and a
                reference to the inner exception that is the cause of this exception.
            </summary>
            <param name="message">The message that describes the error.</param>
            <param name="innerException">
                The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no
                inner exception is specified.
            </param>
        </member>
        <member name="T:slskd.ShareScanInProgressException">
            <summary>
                Represents an error that occurs when multiple share scans are attempted concurrently.
            </summary>
        </member>
        <member name="M:slskd.ShareScanInProgressException.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ShareScanInProgressException"/> class.
            </summary>
        </member>
        <member name="M:slskd.ShareScanInProgressException.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ShareScanInProgressException"/> class with a specified error message.
            </summary>
            <param name="message">The message that describes the error.</param>
        </member>
        <member name="M:slskd.ShareScanInProgressException.#ctor(System.String,System.Exception)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ShareScanInProgressException"/> class with a specified error message and a
                reference to the inner exception that is the cause of this exception.
            </summary>
            <param name="message">The message that describes the error.</param>
            <param name="innerException">
                The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no
                inner exception is specified.
            </param>
        </member>
        <member name="T:slskd.ShareValidationException">
            <summary>
                Represents an error that occurs when multiple share scans are attempted concurrently.
            </summary>
        </member>
        <member name="M:slskd.ShareValidationException.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ShareValidationException"/> class.
            </summary>
        </member>
        <member name="M:slskd.ShareValidationException.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ShareValidationException"/> class with a specified error message.
            </summary>
            <param name="message">The message that describes the error.</param>
        </member>
        <member name="M:slskd.ShareValidationException.#ctor(System.String,System.Exception)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ShareValidationException"/> class with a specified error message and a
                reference to the inner exception that is the cause of this exception.
            </summary>
            <param name="message">The message that describes the error.</param>
            <param name="innerException">
                The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no
                inner exception is specified.
            </param>
        </member>
        <member name="T:slskd.SlskdException">
            <summary>
                Represents errors that originate from slskd logic.
            </summary>
        </member>
        <member name="M:slskd.SlskdException.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.SlskdException"/> class.
            </summary>
        </member>
        <member name="M:slskd.SlskdException.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.SlskdException"/> class with a specified error message.
            </summary>
            <param name="message">The message that describes the error.</param>
        </member>
        <member name="M:slskd.SlskdException.#ctor(System.String,System.Exception)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.SlskdException"/> class with a specified error message and a
                reference to the inner exception that is the cause of this exception.
            </summary>
            <param name="message">The message that describes the error.</param>
            <param name="innerException">
                The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no
                inner exception is specified.
            </param>
        </member>
        <member name="T:slskd.UnauthorizedException">
            <summary>
                Represents errors that originate when a restricted resources is accessed without authorization.
            </summary>
        </member>
        <member name="M:slskd.UnauthorizedException.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.UnauthorizedException"/> class.
            </summary>
        </member>
        <member name="M:slskd.UnauthorizedException.#ctor(System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.UnauthorizedException"/> class with a specified error message.
            </summary>
            <param name="message">The message that describes the error.</param>
        </member>
        <member name="M:slskd.UnauthorizedException.#ctor(System.String,System.Exception)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.UnauthorizedException"/> class with a specified error message and a
                reference to the inner exception that is the cause of this exception.
            </summary>
            <param name="message">The message that describes the error.</param>
            <param name="innerException">
                The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no
                inner exception is specified.
            </param>
        </member>
        <member name="T:slskd.ExponentialMovingAverage">
            <summary>
                An exponential moving average.
            </summary>
        </member>
        <member name="M:slskd.ExponentialMovingAverage.#ctor(System.Double)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ExponentialMovingAverage"/> class.
            </summary>
            <param name="smoothingFactor"></param>
        </member>
        <member name="M:slskd.ExponentialMovingAverage.#ctor(System.Double,System.Action{System.Double})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ExponentialMovingAverage"/> class.
            </summary>
            <param name="smoothingFactor"></param>
            <param name="onUpdate"></param>
        </member>
        <member name="P:slskd.ExponentialMovingAverage.Value">
            <summary>
                Gets the current value.
            </summary>
        </member>
        <member name="P:slskd.ExponentialMovingAverage.Initialized">
            <summary>
                Gets a value indicating whether the average has been initialized.
            </summary>
        </member>
        <member name="M:slskd.ExponentialMovingAverage.Update(System.Double)">
            <summary>
                Updates the average with a new value.
            </summary>
            <param name="value"></param>
        </member>
        <member name="T:slskd.IPAddressConverter">
            <summary>
                Serializes IPAddress instances.
            </summary>
        </member>
        <member name="T:slskd.IPEndPointConverter">
            <summary>
                Serializes IPAddress instances.
            </summary>
        </member>
        <member name="T:slskd.ConsoleWriteLineLogger">
            <summary>
                Logs messages to stdout via <see cref="M:System.Console.WriteLine(System.String)"/>.
            </summary>
        </member>
        <member name="M:slskd.ConsoleWriteLineLogger.Write(Serilog.Events.LogEvent)">
            <inheritdoc/>
        </member>
        <member name="T:slskd.IStateMonitor`1">
            <summary>
                Provides observable read access for state objects.
            </summary>
            <typeparam name="T">The type of the tracked state object.</typeparam>
        </member>
        <member name="P:slskd.IStateMonitor`1.CurrentValue">
            <summary>
                Gets the current state.
            </summary>
        </member>
        <member name="M:slskd.IStateMonitor`1.OnChange(System.Action{System.ValueTuple{`0,`0}})">
            <summary>
                Registers a listener to be called whenever the tracked state changes.
            </summary>
            <param name="listener">Registers a listener to be called whenever state changes.</param>
            <returns>An <see cref="T:System.IDisposable"/> which should be disposed to stop listening for changes.</returns>
        </member>
        <member name="T:slskd.IStateMutator`1">
            <summary>
                Provides write access for state objects.
            </summary>
            <typeparam name="T">The type of the tracked state object.</typeparam>
        </member>
        <member name="M:slskd.IStateMutator`1.SetValue(System.Func{`0,`0})">
            <summary>
                Replaces the current state with the value resolved by the <paramref name="setter"/>.
            </summary>
            <param name="setter">Given the current state, resolves a new state value.</param>
            <returns>The updated state.</returns>
        </member>
        <member name="T:slskd.IStateSnapshot`1">
            <summary>
                Provides point-in-time read access for state objects.
            </summary>
            <typeparam name="T">The type of the tracked state object.</typeparam>
        </member>
        <member name="P:slskd.IStateSnapshot`1.Value">
            <summary>
                Gets the snapshotted state.
            </summary>
        </member>
        <member name="T:slskd.IManagedState`1">
            <summary>
                Provides observable management of state objects.
            </summary>
            <typeparam name="T">The type of the tracked state object.</typeparam>
        </member>
        <member name="P:slskd.IManagedState`1.Snapshot">
            <summary>
                Gets a point-in-time snapshot of the current state.
            </summary>
        </member>
        <member name="T:slskd.ManagedStateExtensions">
            <summary>
                ManagedState extension methods.
            </summary>
        </member>
        <member name="M:slskd.ManagedStateExtensions.AddManagedState``1(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Func{``0,``0})">
            <summary>
                <para>
                    Adds managed state of an object of the specified <typeparamref name="T"/> to the specified <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection"/>.
                </para>
                <para>
                    <list type="bullet">
                        <item>A singleton instance of <see cref="T:slskd.IManagedState`1"/> to be used by instances requiring full control over the state</item>
                        <item>A singleton instance of <see cref="T:slskd.IStateMutator`1"/> to be used by instances requiring the ability to mutate the state</item>
                        <item>A singleton instance of <see cref="T:slskd.IStateMonitor`1"/> to be used by instances requiring observable read access to the state</item>
                        <item>A transient instance of <see cref="T:slskd.IStateSnapshot`1"/> to be used by scoped or transient instances requiring the current state</item>
                    </list>
                </para>
            </summary>
            <typeparam name="T">The type of the managed state object.</typeparam>
            <param name="services">The IServiceCollection to which the managed state is to be added.</param>
            <param name="setter">An optional anonymous function used to apply an initial state mutation.</param>
            <returns>The IServiceCollection with managed state added.</returns>
        </member>
        <member name="T:slskd.StateSnapshot`1">
            <summary>
                Provides a point-in-time snapshot of state objects.
            </summary>
            <typeparam name="T">The type of the tracked state object.</typeparam>
        </member>
        <member name="M:slskd.StateSnapshot`1.#ctor(`0)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.StateSnapshot`1"/> class.
            </summary>
            <param name="value">The current value of the state.</param>
        </member>
        <member name="P:slskd.StateSnapshot`1.Value">
            <summary>
                Gets a snapshot of the current application state.
            </summary>
        </member>
        <member name="T:slskd.ManagedState`1">
            <summary>
                Provides observable management of state objects.
            </summary>
            <typeparam name="T">The type of the tracked state object.</typeparam>
        </member>
        <member name="P:slskd.ManagedState`1.CurrentValue">
            <summary>
                Gets the current application state.
            </summary>
        </member>
        <member name="P:slskd.ManagedState`1.Snapshot">
            <summary>
                Gets a point-in-time snapshot of the current state.
            </summary>
        </member>
        <member name="M:slskd.ManagedState`1.OnChange(System.Action{System.ValueTuple{`0,`0}})">
            <summary>
                Registers a listener to be called whenever the tracked state changes.
            </summary>
            <param name="listener">Registers a listener to be called whenever state changes.</param>
            <returns>An <see cref="T:System.IDisposable"/> which should be disposed to stop listening for changes.</returns>
        </member>
        <member name="M:slskd.ManagedState`1.SetValue(System.Func{`0,`0})">
            <summary>
                Replaces the current state with the value resolved by the <paramref name="setter"/>.
            </summary>
            <param name="setter">Given the current state, resolves a new state value.</param>
            <returns>The updated state.</returns>
        </member>
        <member name="T:slskd.DisableFormValueModelBindingAttribute">
            <summary>
                Disables form value model binding for decorated controllers and endpoints. This prevents buffering when processing multipart upload requests.
            </summary>
        </member>
        <member name="T:slskd.HTMLInjectionMiddlewareExtensions">
            <summary>
                Adds the <see cref="T:slskd.HTMLInjectionMiddleware"/>.
            </summary>
        </member>
        <member name="M:slskd.HTMLInjectionMiddlewareExtensions.UseHTMLInjection(Microsoft.AspNetCore.Builder.IApplicationBuilder,System.String,System.Collections.Generic.IEnumerable{System.String})">
            <summary>
                Injects the specified <paramref name="html"/> into html files.
            </summary>
            <param name="builder"></param>
            <param name="html"></param>
            <param name="excludedRoutes"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.HTMLInjectionMiddleware">
            <summary>
                Injects content into html files.
            </summary>
        </member>
        <member name="M:slskd.HTMLInjectionMiddleware.#ctor(Microsoft.AspNetCore.Http.RequestDelegate,System.String,System.Collections.Generic.IEnumerable{System.String})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.HTMLInjectionMiddleware"/> class.
            </summary>
            <param name="next"></param>
            <param name="html"></param>
            <param name="excludedRoutes"></param>
        </member>
        <member name="M:slskd.HTMLInjectionMiddleware.InvokeAsync(Microsoft.AspNetCore.Http.HttpContext)">
            <summary>
                Executes this middleware, returning the contents of the requested HTML file with the specified HTML appended.
            </summary>
            <param name="context"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.HTMLRewriteMiddlewareExtensions">
            <summary>
                Adds the <see cref="T:slskd.HTMLRewriteMiddleware"/>.
            </summary>
        </member>
        <member name="M:slskd.HTMLRewriteMiddlewareExtensions.UseHTMLRewrite(Microsoft.AspNetCore.Builder.IApplicationBuilder,System.String,System.String)">
            <summary>
                Replaces the specified <paramref name="pattern"/> with the specified <paramref name="replacement"/>.
            </summary>
            <param name="builder"></param>
            <param name="pattern"></param>
            <param name="replacement"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.HTMLRewriteMiddleware">
            <summary>
                Replaces parts of HTML files.
            </summary>
        </member>
        <member name="M:slskd.HTMLRewriteMiddleware.#ctor(Microsoft.AspNetCore.Http.RequestDelegate,System.String,System.String)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.HTMLRewriteMiddleware"/> class.
            </summary>
            <param name="next"></param>
            <param name="pattern"></param>
            <param name="replacement"></param>
        </member>
        <member name="M:slskd.HTMLRewriteMiddleware.InvokeAsync(Microsoft.AspNetCore.Http.HttpContext)">
            <summary>
                Executes this middleware, returning the contents of the requested HTML file with the specified replacements made.
            </summary>
            <param name="context"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.RateLimiter">
            <summary>
                Ensures a minimum interval between successive invocations of a delegate.
            </summary>
        </member>
        <member name="M:slskd.RateLimiter.#ctor(System.Int32,System.Boolean)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.RateLimiter"/> class.
            </summary>
            <param name="interval">The minimum interval between invocations.</param>
            <param name="flushOnDispose">A value indicating whether pending action(s) should be executed during disposal.</param>
        </member>
        <member name="M:slskd.RateLimiter.Dispose">
            <summary>
                Releases all resources used by the <see cref="T:System.ComponentModel.Component"/>.
            </summary>
        </member>
        <member name="M:slskd.RateLimiter.Invoke(System.Action)">
            <summary>
                Invokes the specified <paramref name="action"/>, dropping invocations created prior to the elapse of the
                configured interval.
            </summary>
            <param name="action">The delegate to invoke.</param>
        </member>
        <member name="M:slskd.RateLimiter.Dispose(System.Boolean)">
            <summary>
                Releases all resources used by the <see cref="T:System.ComponentModel.Component"/>.
            </summary>
        </member>
        <member name="T:slskd.Redactor">
            <summary>
                Redacts secrets within objects.
            </summary>
        </member>
        <member name="M:slskd.Redactor.Redact(System.Object,System.String)">
            <summary>
                Recursively scans the <paramref name="target"/> for properties marked with <see cref="T:slskd.SecretAttribute"/> and redacts the values by overwriting them.
            </summary>
            <remarks>
                Only works on properties of type <see cref="T:System.String"/>.
            </remarks>
            <param name="target">The object to redact.</param>
            <param name="redactWith">The string with which to replace redacted values.</param>
        </member>
        <member name="T:slskd.SecretAttribute">
            <summary>
                Indicates that a property or field contains a secret, allowing it to be redacted.
            </summary>
        </member>
        <member name="T:slskd.Retry">
            <summary>
                Retry logic.
            </summary>
        </member>
        <member name="M:slskd.Retry.Do(System.Func{System.Threading.Tasks.Task},System.Func{System.Int32,System.Exception,System.Boolean},System.Action{System.Int32,System.Exception},System.Int32,System.Int32,System.Threading.CancellationToken)">
            <summary>
                Executes logic with the specified retry parameters.
            </summary>
            <param name="task">The logic to execute.</param>
            <param name="isRetryable">A function returning a value indicating whether the last Exception is retryable.</param>
            <param name="onFailure">An action to execute on failure.</param>
            <param name="maxAttempts">The maximum number of retry attempts.</param>
            <param name="maxDelayInMilliseconds">The maximum delay in milliseconds.</param>
            <param name="cancellationToken">The token to monitor for cancellation requests.</param>
            <returns>The execution context.</returns>
        </member>
        <member name="M:slskd.Retry.Do``1(System.Func{System.Threading.Tasks.Task{``0}},System.Func{System.Int32,System.Exception,System.Boolean},System.Action{System.Int32,System.Exception},System.Int32,System.Int32,System.Threading.CancellationToken)">
            <summary>
                Executes logic with the specified retry parameters.
            </summary>
            <param name="task">The logic to execute.</param>
            <param name="isRetryable">A function returning a value indicating whether the last Exception is retryable.</param>
            <param name="onFailure">An action to execute on failure.</param>
            <param name="maxAttempts">The maximum number of retry attempts.</param>
            <param name="maxDelayInMilliseconds">The maximum delay in milliseconds.</param>
            <param name="cancellationToken">The token to monitor for cancellation requests.</param>
            <typeparam name="T">The Type of the logic return value.</typeparam>
            <returns>The execution context.</returns>
        </member>
        <member name="T:slskd.ITokenBucket">
            <summary>
                Implements the 'token bucket' or 'leaky bucket' rate limiting algorithm.
            </summary>
        </member>
        <member name="P:slskd.ITokenBucket.Capacity">
            <summary>
                Gets the bucket capacity.
            </summary>
        </member>
        <member name="M:slskd.ITokenBucket.GetAsync(System.Int32,System.Threading.CancellationToken)">
            <summary>
                Asynchronously retrieves the specified token <paramref name="count"/> from the bucket.
            </summary>
            <remarks>
                <para>
                    If the requested <paramref name="count"/> exceeds the bucket <see cref="P:slskd.ITokenBucket.Capacity"/>, the request is lowered to
                    the capacity of the bucket.
                </para>
                <para>If the bucket has tokens available, but fewer than the requested amount, the available tokens are returned.</para>
                <para>
                    If the bucket has no tokens available, execution waits for the bucket to be replenished before servicing the request.
                </para>
            </remarks>
            <param name="count">The number of tokens to retrieve.</param>
            <param name="cancellationToken">The token to monitor for cancellation requests.</param>
            <returns>A Task that completes when tokens have been provided.</returns>
        </member>
        <member name="M:slskd.ITokenBucket.Return(System.Int32)">
            <summary>
                Returns the specified token <paramref name="count"/> to the bucket.
            </summary>
            <remarks>
                <para>This method should only be called if tokens were retrieved from the bucket, but were not used.</para>
                <para>
                    If the specified count exceeds the bucket capacity, the count is lowered to the capacity. Effectively this
                    allows the bucket to 'burst' up to 2x capacity to 'catch up' to the desired rate if tokens were wastefully
                    retrieved.
                </para>
                <para>If the specified count is negative, no change is made to the available count.</para>
            </remarks>
            <param name="count">The number of tokens to return.</param>
        </member>
        <member name="M:slskd.ITokenBucket.SetCapacity(System.Int64)">
            <summary>
                Sets the bucket capacity to the supplied <paramref name="capacity"/>.
            </summary>
            <remarks>Change takes effect on the next reset.</remarks>
            <param name="capacity">The bucket capacity.</param>
        </member>
        <member name="T:slskd.TokenBucket">
            <summary>
                Implements the 'token bucket' or 'leaky bucket' rate limiting algorithm.
            </summary>
        </member>
        <member name="M:slskd.TokenBucket.#ctor(System.Int64,System.Int32)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.TokenBucket"/> class.
            </summary>
            <param name="capacity">The bucket capacity.</param>
            <param name="interval">The interval at which tokens are replenished, in milliseconds.</param>
        </member>
        <member name="P:slskd.TokenBucket.Capacity">
            <summary>
                Gets the bucket capacity.
            </summary>
        </member>
        <member name="M:slskd.TokenBucket.Dispose">
            <summary>
                Disposes this instance.
            </summary>
        </member>
        <member name="M:slskd.TokenBucket.GetAsync(System.Int32,System.Threading.CancellationToken)">
            <summary>
                Asynchronously retrieves the specified token <paramref name="count"/> from the bucket.
            </summary>
            <remarks>
                <para>
                    If the requested <paramref name="count"/> exceeds the bucket <see cref="P:slskd.TokenBucket.Capacity"/>, the request is lowered to
                    the capacity of the bucket.
                </para>
                <para>If the bucket has tokens available, but fewer than the requested amount, the available tokens are returned.</para>
                <para>
                    If the bucket has no tokens available, execution waits for the bucket to be replenished before servicing the request.
                </para>
            </remarks>
            <param name="count">The number of tokens to retrieve.</param>
            <param name="cancellationToken">The token to monitor for cancellation requests.</param>
            <returns>A Task that completes when tokens have been provided.</returns>
        </member>
        <member name="M:slskd.TokenBucket.Return(System.Int32)">
            <summary>
                Returns the specified token <paramref name="count"/> to the bucket.
            </summary>
            <remarks>
                <para>This method should only be called if tokens were retrieved from the bucket, but were not used.</para>
                <para>
                    If the specified count exceeds the bucket capacity, the count is lowered to the capacity. Effectively this
                    allows the bucket to 'burst' up to 2x capacity to 'catch up' to the desired rate if tokens were wastefully
                    retrieved.
                </para>
                <para>If the specified count is negative, no change is made to the available count.</para>
            </remarks>
            <param name="count">The number of tokens to return.</param>
        </member>
        <member name="M:slskd.TokenBucket.SetCapacity(System.Int64)">
            <summary>
                Sets the bucket capacity to the supplied <paramref name="capacity"/>.
            </summary>
            <remarks>Change takes effect on the next reset.</remarks>
            <param name="capacity">The bucket capacity.</param>
        </member>
        <member name="M:slskd.TokenBucket.Dispose(System.Boolean)">
            <summary>
                Disposes this instance.
            </summary>
            <param name="disposing">A value indicating whether disposal is in progress.</param>
        </member>
        <member name="T:slskd.UserEndPointCache">
            <summary>
                Caches user EndPoints.
            </summary>
        </member>
        <member name="M:slskd.UserEndPointCache.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.UserEndPointCache"/> class.
            </summary>
        </member>
        <member name="M:slskd.UserEndPointCache.AddOrUpdate(System.String,System.Net.IPEndPoint)">
            <summary>
                Caches or updates an entry.
            </summary>
            <param name="username">The username for which to cache the endpoint.</param>
            <param name="endPoint">The endpoint to cache.</param>
        </member>
        <member name="M:slskd.UserEndPointCache.TryGet(System.String,System.Net.IPEndPoint@)">
            <summary>
                Gets the cached endpoint for the specified <paramref name="username"/>, if it exists.
            </summary>
            <param name="username">The username for which to retrieve the endpoint.</param>
            <param name="endPoint">The cached endpoint, if it exists.</param>
            <returns>A value indicating whether the endpoint was found in the cache.</returns>
        </member>
        <member name="T:slskd.Validation.CompositeValidationResult">
            <summary>
                The composite result of a recursive validation.
            </summary>
        </member>
        <member name="T:slskd.Validation.DirectoryExistsAttribute">
            <summary>
                Validates that the directory at the specified path exists.
            </summary>
        </member>
        <member name="M:slskd.Validation.DirectoryExistsAttribute.#ctor(System.Boolean,System.Boolean)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Validation.DirectoryExistsAttribute"/> class.
            </summary>
            <param name="relativeToApplicationDirectory">A value indicating that the provided path must be relative (not rooted) to the application directory.</param>
            <param name="ensureWriteable">A value indicating that the provided path, if it exists, should be probed to ensure it is writeable.</param>
        </member>
        <member name="T:slskd.Validation.EnumAttribute">
            <summary>
                Validates that the value is a valid member of the specified <see cref="T:System.Enum"/>.
            </summary>
        </member>
        <member name="T:slskd.Validation.Extensions">
            <summary>
                Extensions.
            </summary>
        </member>
        <member name="M:slskd.Validation.Extensions.TryValidate(slskd.Options,slskd.Validation.CompositeValidationResult@)">
            <summary>
                Validates options.
            </summary>
            <param name="options">The options instance to validate.</param>
            <param name="result">The result of the validation, if invalid.</param>
            <returns>A value indicating whether the instance is valid.</returns>
        </member>
        <member name="T:slskd.Validation.FileExistsAttribute">
            <summary>
                Validates that the file at the specified path exists.
            </summary>
        </member>
        <member name="T:slskd.Validation.IPAddressAttribute">
            <summary>
                Validates that the string is a valid IPv4 or IPv6 IP address.
            </summary>
        </member>
        <member name="T:slskd.Validation.NotNullOrWhiteSpaceAttribute">
            <summary>
                Validates that the value is not null or whitespace.
            </summary>
        </member>
        <member name="T:slskd.Validation.ValidateAttribute">
            <summary>
                Indicates that attributed properties should be recursively validated.
            </summary>
        </member>
        <member name="T:slskd.Validation.ValidationExtensions">
            <summary>
                Extension methods for types involved with validation.
            </summary>
        </member>
        <member name="T:slskd.Validation.X509CertificateAttribute">
            <summary>
                Validates X509 certificate parameters specified through <see cref="T:slskd.Options.WebOptions.HttpsOptions.CertificateOptions"/>.
            </summary>
        </member>
        <member name="T:slskd.IWaiter">
            <summary>
                Enables arbitrary await-able things.
            </summary>
        </member>
        <member name="P:slskd.IWaiter.DefaultTimeout">
            <summary>
                Gets the default timeout duration.
            </summary>
        </member>
        <member name="M:slskd.IWaiter.Cancel(slskd.WaitKey)">
            <summary>
                Cancels the oldest wait matching the specified <paramref name="key"/>.
            </summary>
            <param name="key">The unique WaitKey for the wait.</param>
        </member>
        <member name="M:slskd.IWaiter.CancelAll">
            <summary>
                Cancels all waits.
            </summary>
        </member>
        <member name="M:slskd.IWaiter.Complete``1(slskd.WaitKey,``0)">
            <summary>
                Completes the oldest wait matching the specified <paramref name="key"/> with the specified <paramref name="result"/>.
            </summary>
            <typeparam name="T">The wait result type.</typeparam>
            <param name="key">The unique WaitKey for the wait.</param>
            <param name="result">The wait result.</param>
        </member>
        <member name="M:slskd.IWaiter.Complete(slskd.WaitKey)">
            <summary>
                Completes the oldest wait matching the specified <paramref name="key"/>.
            </summary>
            <param name="key">The unique WaitKey for the wait.</param>
        </member>
        <member name="M:slskd.IWaiter.IsWaitingFor(slskd.WaitKey)">
            <summary>
                Returns a value indicating whether the specified <paramref name="key"/> is being waited upon.
            </summary>
            <param name="key">The unique WaitKey to check.</param>
            <returns>A value indicating whether the specified key is being waited upon.</returns>
        </member>
        <member name="M:slskd.IWaiter.Throw(slskd.WaitKey,System.Exception)">
            <summary>
                Throws the specified <paramref name="exception"/> on the oldest wait matching the specified <paramref name="key"/>.
            </summary>
            <param name="key">The unique WaitKey for the wait.</param>
            <param name="exception">The Exception to throw.</param>
        </member>
        <member name="M:slskd.IWaiter.Timeout(slskd.WaitKey)">
            <summary>
                Causes the oldest wait matching the specified <paramref name="key"/> to time out.
            </summary>
            <param name="key">The unique WaitKey for the wait.</param>
        </member>
        <member name="M:slskd.IWaiter.Wait``1(slskd.WaitKey,System.Nullable{System.Int32},System.Nullable{System.Threading.CancellationToken})">
            <summary>
                Adds a new wait for the specified <paramref name="key"/> and with the specified <paramref name="timeout"/>.
            </summary>
            <typeparam name="T">The wait result type.</typeparam>
            <param name="key">A unique WaitKey for the wait.</param>
            <param name="timeout">The wait timeout.</param>
            <param name="cancellationToken">The cancellation token for the wait.</param>
            <returns>A Task representing the wait.</returns>
        </member>
        <member name="M:slskd.IWaiter.Wait(slskd.WaitKey,System.Nullable{System.Int32},System.Nullable{System.Threading.CancellationToken})">
            <summary>
                Adds a new wait for the specified <paramref name="key"/> and with the specified <paramref name="timeout"/>.
            </summary>
            <param name="key">A unique WaitKey for the wait.</param>
            <param name="timeout">The wait timeout.</param>
            <param name="cancellationToken">The cancellation token for the wait.</param>
            <returns>A Task representing the wait.</returns>
        </member>
        <member name="M:slskd.IWaiter.WaitIndefinitely``1(slskd.WaitKey,System.Nullable{System.Threading.CancellationToken})">
            <summary>
                Adds a new wait for the specified <paramref name="key"/> which does not time out.
            </summary>
            <typeparam name="T">The wait result type.</typeparam>
            <param name="key">A unique WaitKey for the wait.</param>
            <param name="cancellationToken">The cancellation token for the wait.</param>
            <returns>A Task representing the wait.</returns>
        </member>
        <member name="M:slskd.IWaiter.WaitIndefinitely(slskd.WaitKey,System.Nullable{System.Threading.CancellationToken})">
            <summary>
                Adds a new wait for the specified <paramref name="key"/> which does not time out.
            </summary>
            <param name="key">A unique WaitKey for the wait.</param>
            <param name="cancellationToken">The cancellation token for the wait.</param>
            <returns>A Task representing the wait.</returns>
        </member>
        <member name="T:slskd.Waiter">
            <summary>
                Enables arbitrary await-able things.
            </summary>
        </member>
        <member name="M:slskd.Waiter.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Waiter"/> class with the default timeout.
            </summary>
        </member>
        <member name="M:slskd.Waiter.#ctor(System.Int32)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Waiter"/> class with the specified <paramref name="defaultTimeout"/>.
            </summary>
            <param name="defaultTimeout">The default timeout duration for message waits.</param>
        </member>
        <member name="P:slskd.Waiter.DefaultTimeout">
            <summary>
                Gets the default timeout duration, in milliseconds.
            </summary>
        </member>
        <member name="M:slskd.Waiter.Cancel(slskd.WaitKey)">
            <summary>
                Cancels the oldest wait matching the specified <paramref name="key"/>.
            </summary>
            <param name="key">The unique WaitKey for the wait.</param>
        </member>
        <member name="M:slskd.Waiter.CancelAll">
            <summary>
                Cancels all waits.
            </summary>
        </member>
        <member name="M:slskd.Waiter.Complete``1(slskd.WaitKey,``0)">
            <summary>
                Completes the oldest wait matching the specified <paramref name="key"/> with the specified <paramref name="result"/>.
            </summary>
            <typeparam name="T">The wait result type.</typeparam>
            <param name="key">The unique WaitKey for the wait.</param>
            <param name="result">The wait result.</param>
        </member>
        <member name="M:slskd.Waiter.Complete(slskd.WaitKey)">
            <summary>
                Completes the oldest wait matching the specified <paramref name="key"/>.
            </summary>
            <param name="key">The unique WaitKey for the wait.</param>
        </member>
        <member name="M:slskd.Waiter.IsWaitingFor(slskd.WaitKey)">
            <summary>
                Returns a value indicating whether the specified <paramref name="key"/> is being waited upon.
            </summary>
            <param name="key">The unique WaitKey to check.</param>
            <returns>A value indicating whether the specified key is being waited upon.</returns>
        </member>
        <member name="M:slskd.Waiter.Dispose">
            <summary>
                Disposes this instance.
            </summary>
        </member>
        <member name="M:slskd.Waiter.Dispose(System.Boolean)">
            <summary>
                Disposes this instance.
            </summary>
            <param name="disposing">A value indicating whether disposal is in progress.</param>
        </member>
        <member name="M:slskd.Waiter.Throw(slskd.WaitKey,System.Exception)">
            <summary>
                Throws the specified <paramref name="exception"/> on the oldest wait matching the specified <paramref name="key"/>.
            </summary>
            <param name="key">The unique WaitKey for the wait.</param>
            <param name="exception">The Exception to throw.</param>
        </member>
        <member name="M:slskd.Waiter.Timeout(slskd.WaitKey)">
            <summary>
                Causes the oldest wait matching the specified <paramref name="key"/> to time out.
            </summary>
            <param name="key">The unique WaitKey for the wait.</param>
        </member>
        <member name="M:slskd.Waiter.Wait(slskd.WaitKey,System.Nullable{System.Int32},System.Nullable{System.Threading.CancellationToken})">
            <summary>
                Adds a new wait for the specified <paramref name="key"/> and with the specified <paramref name="timeout"/>.
            </summary>
            <param name="key">A unique WaitKey for the wait.</param>
            <param name="timeout">The wait timeout, in milliseconds.</param>
            <param name="cancellationToken">The cancellation token for the wait.</param>
            <returns>A Task representing the wait.</returns>
        </member>
        <member name="M:slskd.Waiter.Wait``1(slskd.WaitKey,System.Nullable{System.Int32},System.Nullable{System.Threading.CancellationToken})">
            <summary>
                Adds a new wait for the specified <paramref name="key"/> and with the specified <paramref name="timeout"/>.
            </summary>
            <typeparam name="T">The wait result type.</typeparam>
            <param name="key">A unique WaitKey for the wait.</param>
            <param name="timeout">The wait timeout, in milliseconds.</param>
            <param name="cancellationToken">The cancellation token for the wait.</param>
            <returns>A Task representing the wait.</returns>
        </member>
        <member name="M:slskd.Waiter.WaitIndefinitely(slskd.WaitKey,System.Nullable{System.Threading.CancellationToken})">
            <summary>
                Adds a new wait for the specified <paramref name="key"/> which does not time out.
            </summary>
            <param name="key">A unique WaitKey for the wait.</param>
            <param name="cancellationToken">The cancellation token for the wait.</param>
            <returns>A Task representing the wait.</returns>
        </member>
        <member name="M:slskd.Waiter.WaitIndefinitely``1(slskd.WaitKey,System.Nullable{System.Threading.CancellationToken})">
            <summary>
                Adds a new wait for the specified <paramref name="key"/> which does not time out.
            </summary>
            <typeparam name="T">The wait result type.</typeparam>
            <param name="key">A unique WaitKey for the wait.</param>
            <param name="cancellationToken">The cancellation token for the wait.</param>
            <returns>A Task representing the wait.</returns>
        </member>
        <member name="T:slskd.Waiter.PendingWait">
            <summary>
                The composite value for the wait dictionary.
            </summary>
        </member>
        <member name="M:slskd.Waiter.PendingWait.#ctor(System.Object,System.Int32,System.Action,System.Action,System.Threading.CancellationToken)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Waiter.PendingWait"/> class.
            </summary>
            <param name="taskCompletionSource">The task completion source for the wait task.</param>
            <param name="timeout">The number of milliseconds after which the wait is to time out.</param>
            <param name="cancelAction">The action to invoke when the task is cancelled.</param>
            <param name="timeoutAction">The action to invoke when the task times out.</param>
            <param name="cancellationToken">The cancellation token for the wait.</param>
        </member>
        <member name="P:slskd.Waiter.PendingWait.TaskCompletionSource">
            <summary>
                Gets the task completion source for the wait task.
            </summary>
        </member>
        <member name="P:slskd.Waiter.PendingWait.Timeout">
            <summary>
                Gets the number of milliseconds after which the wait is to time out.
            </summary>
        </member>
        <member name="M:slskd.Waiter.PendingWait.Dispose">
            <summary>
                Releases the managed and unmanaged resources used by the <see cref="T:slskd.Waiter.PendingWait"/>.
            </summary>
        </member>
        <member name="M:slskd.Waiter.PendingWait.Register">
            <summary>
                Register cancellation and timeout actions.
            </summary>
        </member>
        <member name="M:slskd.Waiter.PendingWait.Dispose(System.Boolean)">
            <summary>
                Releases the managed and unmanaged resources used by the <see cref="T:slskd.Waiter.PendingWait"/>.
            </summary>
            <param name="disposing">A value indicating whether the object is being disposed.</param>
        </member>
        <member name="T:slskd.WaitKey">
            <summary>
                Uniquely identifies a Wait.
            </summary>
        </member>
        <member name="M:slskd.WaitKey.#ctor(System.Object[])">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.WaitKey"/> class.
            </summary>
            <param name="tokenParts">The parts which make up the key.</param>
        </member>
        <member name="P:slskd.WaitKey.Token">
            <summary>
                Gets the wait token.
            </summary>
        </member>
        <member name="P:slskd.WaitKey.TokenParts">
            <summary>
                Gets the parts which make up the key.
            </summary>
        </member>
        <member name="M:slskd.WaitKey.Equals(System.Object)">
            <summary>
                Compares the specified <paramref name="obj"/> to this instance.
            </summary>
            <param name="obj">The object to which to compare.</param>
            <returns>A value indicating whether the specified object is equal to this instance.</returns>
        </member>
        <member name="M:slskd.WaitKey.Equals(slskd.WaitKey)">
            <summary>
                Compares the specified <paramref name="other"/> WaitKey to this instance.
            </summary>
            <param name="other">The WaitKey to which to compare.</param>
            <returns>A value indicating whether the specified WaitKey is equal to this instance.</returns>
        </member>
        <member name="M:slskd.WaitKey.GetHashCode">
            <summary>
                Returns the hash code of this instance.
            </summary>
            <returns>The hash code of this instance.</returns>
        </member>
        <member name="M:slskd.WaitKey.ToString">
            <summary>
                Returns the string representation of the key.
            </summary>
            <returns>The string representation of the key.</returns>
        </member>
        <member name="T:slskd.Core.API.ApplicationController">
            <summary>
                Application.
            </summary>
        </member>
        <member name="M:slskd.Core.API.ApplicationController.State">
            <summary>
                Gets the current state of the application.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Core.API.ApplicationController.Shutdown">
            <summary>
                Stops the application.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Core.API.ApplicationController.Restart">
            <summary>
                Restarts the application.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Core.API.ApplicationController.GetVersion">
            <summary>
                Gets the current application version.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Core.API.ApplicationController.CheckVersion(System.Boolean)">
            <summary>
                Checks for updates.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Core.API.ApplicationController.CollectGarbage">
            <summary>
                Forces garbage collection.
            </summary>
            <returns></returns>
        </member>
        <member name="T:slskd.Core.API.LogsController">
            <summary>
                Logs.
            </summary>
        </member>
        <member name="M:slskd.Core.API.LogsController.Logs">
            <summary>
                Gets the last few application logs.
            </summary>
            <returns></returns>
        </member>
        <member name="T:slskd.Core.API.MetricsController">
            <summary>
                Logs.
            </summary>
        </member>
        <member name="M:slskd.Core.API.MetricsController.Get">
            <summary>
                Gets application metrics.
            </summary>
            <returns></returns>
        </member>
        <member name="T:slskd.Core.API.OptionsController">
            <summary>
                Options.
            </summary>
        </member>
        <member name="M:slskd.Core.API.OptionsController.Current">
            <summary>
                Gets the current application options.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Core.API.OptionsController.Startup">
            <summary>
                Gets the application options provided at startup.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Core.API.OptionsController.Debug">
            <summary>
                Gets the debug view of the current application options.
            </summary>
            <returns></returns>
        </member>
        <member name="T:slskd.Core.API.ServerController">
            <summary>
                Server.
            </summary>
        </member>
        <member name="M:slskd.Core.API.ServerController.Connect">
            <summary>
                Connects the client.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Core.API.ServerController.Disconnect(System.String)">
            <summary>
                Disconnects the client.
            </summary>
            <param name="message"></param>
            <returns></returns>
        </member>
        <member name="M:slskd.Core.API.ServerController.Get">
            <summary>
                Retrieves the current state of the server.
            </summary>
            <returns></returns>
            <response code="200"></response>
        </member>
        <member name="T:slskd.Core.API.SessionController">
            <summary>
                Session.
            </summary>
        </member>
        <member name="M:slskd.Core.API.SessionController.Check">
            <summary>
                Checks whether the provided authentication is valid.
            </summary>
            <remarks>This is a no-op provided so that the application can test for an expired token on load.</remarks>
            <returns></returns>
            <response code="200">The authentication is valid.</response>
            <response code="403">The authentication is is invalid.</response>
        </member>
        <member name="M:slskd.Core.API.SessionController.Enabled">
            <summary>
                Checks whether security is enabled.
            </summary>
            <returns></returns>
            <response code="200">True if security is enabled, false otherwise.</response>
        </member>
        <member name="M:slskd.Core.API.SessionController.Login(slskd.Core.API.LoginRequest)">
            <summary>
                Logs in.
            </summary>
            <param name="login"></param>
            <returns></returns>
            <response code="200">Login was successful.</response>
            <response code="400">Bad request.</response>
            <response code="401">Login failed.</response>
        </member>
        <member name="P:slskd.Core.API.TokenResponse.Expires">
            <summary>
                Gets the time at which the Access Token expires.
            </summary>
        </member>
        <member name="P:slskd.Core.API.TokenResponse.Issued">
            <summary>
                Gets the time at which the Access Token was issued.
            </summary>
        </member>
        <member name="P:slskd.Core.API.TokenResponse.Name">
            <summary>
                Gets the value of the Name claim from the Access Token.
            </summary>
        </member>
        <member name="P:slskd.Core.API.TokenResponse.NotBefore">
            <summary>
                Gets the value of the Not Before claim from the Access Token.
            </summary>
        </member>
        <member name="P:slskd.Core.API.TokenResponse.Token">
            <summary>
                Gets the Access Token string.
            </summary>
        </member>
        <member name="P:slskd.Core.API.TokenResponse.TokenType">
            <summary>
                Gets the Token type.
            </summary>
        </member>
        <member name="T:slskd.Core.API.ApplicationHubExtensions">
            <summary>
                Extension methods for the application SignalR hub.
            </summary>
        </member>
        <member name="M:slskd.Core.API.ApplicationHubExtensions.BroadcastStateAsync(Microsoft.AspNetCore.SignalR.IHubContext{slskd.Core.API.ApplicationHub},slskd.State)">
            <summary>
                Broadcast the present application state.
            </summary>
            <param name="hub">The hub.</param>
            <param name="state">The state to broadcast.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Core.API.ApplicationHubExtensions.BroadcastOptionsAsync(Microsoft.AspNetCore.SignalR.IHubContext{slskd.Core.API.ApplicationHub},slskd.Options)">
            <summary>
                Broadcast the present application options.
            </summary>
            <param name="hub">The hub.</param>
            <param name="options">The options to broadcast.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="T:slskd.Core.API.ApplicationHub">
            <summary>
                The application SignalR hub.
            </summary>
        </member>
        <member name="T:slskd.Core.API.LogHubExtensions">
            <summary>
                Extension methods for the logs SignalR hub.
            </summary>
        </member>
        <member name="M:slskd.Core.API.LogHubExtensions.EmitLogAsync(Microsoft.AspNetCore.SignalR.IHubContext{slskd.Core.API.LogsHub},slskd.LogRecord)">
            <summary>
                Broadcast a log record.
            </summary>
            <param name="hub">The hub.</param>
            <param name="record">The log record to broadcast.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="T:slskd.Core.API.LogsHub">
            <summary>
                The logs SignalR hub.
            </summary>
        </member>
        <member name="T:slskd.BlacklistFormat">
            <summary>
                Blacklist file formats.
            </summary>
        </member>
        <member name="F:slskd.BlacklistFormat.AutoDetect">
            <summary>
                Automatically detect format based on contents.
            </summary>
        </member>
        <member name="F:slskd.BlacklistFormat.CIDR">
            <summary>
                CIDR format. <see href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing"/>.
            </summary>
            <example>
                <code>
                    1.2.4.0/24
                    1.2.8.0/24
                    1.9.96.105/32
                </code>
            </example>
        </member>
        <member name="F:slskd.BlacklistFormat.P2P">
            <summary>
                P2P format. <see href="https://sourceforge.net/p/peerguardian/wiki/dev-blocklist-format-p2p/"/>.
            </summary>
            <example>
                <code>
                    China Internet Information Center (CNNIC):1.2.4.0-1.2.4.255
                    China Internet Information Center (CNNIC):1.2.8.0-1.2.8.255
                    Botnet on Telekom Malaysia:1.9.96.105-1.9.96.105
                </code>
            </example>
        </member>
        <member name="F:slskd.BlacklistFormat.DAT">
            <summary>
                DAT format. <see href="https://sourceforge.net/p/peerguardian/wiki/dev-blocklist-format-dat/"/>.
            </summary>
            <example>
                <code>
                    001.002.004.000 - 001.002.004.255 , 000 , China Internet Information Center (CNNIC)
                    001.002.008.000 - 001.002.008.255 , 000 , China Internet Information Center (CNNIC)
                    001.009.096.105 - 001.009.096.105 , 000 , Botnet on Telekom Malaysia
                </code>
            </example>
        </member>
        <member name="T:slskd.Blacklist">
            <summary>
                A managed blacklist for CIDRs.
            </summary>
        </member>
        <member name="P:slskd.Blacklist.Count">
            <summary>
                Gets the total number of loaded CIDRs.
            </summary>
        </member>
        <member name="M:slskd.Blacklist.DetectFormat(System.String)">
            <summary>
                Examines the contents of the specified <paramref name="filename"/> and attempts to determine the format.
            </summary>
            <param name="filename">The fully qualified path to the file to examine.</param>
            <returns>The detected format.</returns>
            <exception cref="T:System.IO.IOException">Thrown if the specified filename can't be accessed.</exception>
            <exception cref="T:System.FormatException">Thrown if the format can't be determined.</exception>
        </member>
        <member name="M:slskd.Blacklist.Clear">
            <summary>
                Clears the contents of the Blacklist.
            </summary>
        </member>
        <member name="M:slskd.Blacklist.Load(System.String,slskd.BlacklistFormat)">
            <summary>
                Loads the contents of the specified <paramref name="filename"/> into the Blacklist.
            </summary>
            <remarks>
                The existing Blacklist contents are replaced atomically.
            </remarks>
            <param name="filename">The fully qualified path to the file to load.</param>
            <param name="format">The optional blacklist file format.</param>
            <returns>The operation context.</returns>
            <exception cref="T:System.IO.IOException">Thrown if the specified filename can't be accessed.</exception>
            <exception cref="T:System.FormatException">
                Thrown if any of the lines in the file do not match the specified or auto-detected <paramref name="format"/>.
            </exception>
            <exception cref="T:System.FormatException">
                Thrown if the specified <paramref name="format"/> is <see cref="F:slskd.BlacklistFormat.AutoDetect"/> and the format could not be detected.
            </exception>
        </member>
        <member name="M:slskd.Blacklist.Contains(System.Net.IPAddress)">
            <summary>
                Returns a value indicating whether the specified <paramref name="ip"/> is contained within the blacklist.
            </summary>
            <param name="ip">The IP address to check.</param>
            <returns>A value indicating whether the specified IP is contained within the blacklist.</returns>
        </member>
        <member name="T:slskd.Clock">
            <summary>
                The application clock, used for time based events.
            </summary>
        </member>
        <member name="E:slskd.Clock.EveryFiveMinutes">
            <summary>
                Fires every 5 minutes.
            </summary>
        </member>
        <member name="E:slskd.Clock.EveryHour">
            <summary>
                Fires every hour.
            </summary>
        </member>
        <member name="E:slskd.Clock.EveryMinute">
            <summary>
                Fires every minute.
            </summary>
        </member>
        <member name="E:slskd.Clock.EveryThirtyMinutes">
            <summary>
                Fires every 30 minutes.
            </summary>
        </member>
        <member name="M:slskd.Clock.StartAsync">
            <summary>
                Starts the clock.
            </summary>
            <returns>A Task that completes when all startup events have finished processing.</returns>
        </member>
        <member name="M:slskd.Clock.Stop">
            <summary>
                Stops the clock.
            </summary>
        </member>
        <member name="T:slskd.ClockEventArgs">
            <summary>
                EventArgs for the application clock.
            </summary>
        </member>
        <member name="M:slskd.ClockEventArgs.#ctor(System.Boolean)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ClockEventArgs"/> class.
            </summary>
            <param name="firstRun">A value indicating whether this event was raised when the clock was started.</param>
        </member>
        <member name="P:slskd.ClockEventArgs.FirstRun">
            <summary>
                Gets a value indicating whether this event was raised when the click was started.
            </summary>
        </member>
        <member name="T:slskd.IConnectionWatchdog">
            <summary>
                Monitors the connection to the Soulseek server and reconnects with exponential backoff, if necessary.
            </summary>
        </member>
        <member name="P:slskd.IConnectionWatchdog.IsEnabled">
            <summary>
                Gets a value indicating whether the watchdog is monitoring the server connection.
            </summary>
        </member>
        <member name="M:slskd.IConnectionWatchdog.Start">
            <summary>
                Initializes the watchdog and makes the initial connection to the server.
            </summary>
            <remarks>This should be called at application startup.</remarks>
        </member>
        <member name="M:slskd.IConnectionWatchdog.Restart">
            <summary>
                Starts monitoring the server connection following a disconnect.
            </summary>
            <remarks>This should be called when the connection is disconnected.</remarks>
        </member>
        <member name="M:slskd.IConnectionWatchdog.Stop">
            <summary>
                Stops monitoring the server connection.
            </summary>
            <remarks>This should be called when the application is reasonably certain that the connection is connected.</remarks>
        </member>
        <member name="T:slskd.ConnectionWatchdog">
            <summary>
                Monitors the connection to the Soulseek network and reconnects with exponential backoff, if necessary.
            </summary>
        </member>
        <member name="M:slskd.ConnectionWatchdog.#ctor(Soulseek.ISoulseekClient,Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options},slskd.IStateMonitor{slskd.State})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.ConnectionWatchdog"/> class.
            </summary>
            <param name="soulseekClient"></param>
            <param name="optionsMonitor"></param>
            <param name="state"></param>
        </member>
        <member name="P:slskd.ConnectionWatchdog.IsEnabled">
            <summary>
                Gets a value indicating whether the watchdog is monitoring the server connection.
            </summary>
        </member>
        <member name="M:slskd.ConnectionWatchdog.Dispose">
            <summary>
                Disposes this instance.
            </summary>
        </member>
        <member name="M:slskd.ConnectionWatchdog.Start">
            <summary>
                Initializes the watchdog and makes the initial connection to the server.
            </summary>
            <remarks>This should be called at application startup.</remarks>
        </member>
        <member name="M:slskd.ConnectionWatchdog.Restart">
            <summary>
                Starts monitoring the server connection.
            </summary>
            <remarks>This should be called when the connection is disconnected.</remarks>
        </member>
        <member name="M:slskd.ConnectionWatchdog.Stop">
            <summary>
                Stops monitoring the server connection.
            </summary>
            <remarks>This should be called when the application is reasonably certain that the connection is connected.</remarks>
        </member>
        <member name="M:slskd.ConnectionWatchdog.Dispose(System.Boolean)">
            <summary>
                Disposes this instance.
            </summary>
            <param name="disposing"></param>
        </member>
        <member name="T:slskd.IMigration">
            <summary>
                Applies database migrations.
            </summary>
        </member>
        <member name="M:slskd.IMigration.NeedsToBeApplied">
            <summary>
                Determines whether the migration needs to be applied.
            </summary>
            <remarks>
                This method MUST be read-only and should contain no side effects.
            </remarks>
            <returns>A value indicating whether the migration needs to be applied.</returns>
        </member>
        <member name="M:slskd.IMigration.Apply">
            <summary>
               Applies the migration.
            </summary>
        </member>
        <member name="T:slskd.Migrations.Z04012025_TransferStateMigration">
             <summary>
                 Updates the Transfers table to:
            
                 * Add a new StateDescription (TEXT) column
                 * Copy the current (string) contents of the State column to StateDescription
                 * Change the type of the State column to INTEGER
                 * Set the contents of the State column to the numeric representation of the existing State
            
                 This is necessary because Entity Framework doesn't work with [Flags] enums that are stored
                 as strings; it tries to use bitwise operators to apply HasFlags(), and these obviously don't
                 work against strings. Not sure why EF didn't complain about this, but here we are.
             </summary>
        </member>
        <member name="T:slskd.Migrations.Z04012025_TransferStateMigration.Z04012025_TransferStateMigration_TransferStates">
            <summary>
               This is a copy of the TransferStates enum as it was at the time this migration was written. This exists to ensure
               that the migration can be applied to any version of the database, even if the enum changes in the future.
            </summary>
        </member>
        <member name="T:slskd.Migrator">
            <summary>
                Applies database migrations.
            </summary>
        </member>
        <member name="M:slskd.Migrator.#ctor(System.String[])">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Migrator"/> class.
            </summary>
            <param name="databases">A list of known databases.</param>
        </member>
        <member name="P:slskd.Migrator.Migrations">
            <summary>
                A map of all migrations, to be applied in the order they are specified (descending).
            </summary>
        </member>
        <member name="M:slskd.Migrator.Migrate(System.Boolean)">
            <summary>
                Applies database migrations.
            </summary>
            <param name="force">Apply all migrations, regardless of whether there's evidence they have been applied already.</param>
        </member>
        <member name="T:slskd.SchemaInspector">
            <summary>
                Assistive class for inspecting SQLite database schemas.
            </summary>
        </member>
        <member name="M:slskd.SchemaInspector.GetDatabaseSchema(System.String)">
            <summary>
                Retrieves the schema information for the specified SQLite database.
            </summary>
            <param name="connectionString">The connection string for the database.</param>
            <returns>The schema information.</returns>
            <exception cref="T:slskd.SlskdException">Thrown if the database can't be accessed, or something else goes wrong.</exception>
        </member>
        <member name="T:slskd.SchemaInspector.ColumnInfo">
            <summary>
                Represents a SQLite database column.
            </summary>
        </member>
        <member name="M:slskd.SchemaInspector.ColumnInfo.#ctor(System.Int64,System.String,System.String,System.Boolean,System.Object,System.Boolean)">
            <summary>
                Represents a SQLite database column.
            </summary>
        </member>
        <member name="T:slskd.Extensions">
            <summary>
                Core extensions; extensions for types specific to Soulseek or slskd.
            </summary>
        </member>
        <member name="M:slskd.Extensions.Redact(slskd.Options)">
            <summary>
                Redacts this instance of Options, replacing properties marked with <see cref="T:slskd.SecretAttribute"/> with '*****'.
            </summary>
            <remarks>
                Creates a deep clone before redacting.
            </remarks>
            <param name="options">The Options instance to redact.</param>
            <returns>A redacted instance.</returns>
        </member>
        <member name="M:slskd.Extensions.With(Soulseek.ConnectionOptions,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{System.Int32},Soulseek.ProxyOptions,System.Action{System.Net.Sockets.Socket})">
            <summary>
                Creates a copy of this instance with the specified parameters changed.
            </summary>
            <param name="o">The options instance to copy.</param>
            <param name="readBufferSize">The read buffer size for underlying TCP connections.</param>
            <param name="writeBufferSize">The write buffer size for underlying TCP connections.</param>
            <param name="writeQueueSize">The size of the write queue for double buffered writes.</param>
            <param name="connectTimeout">The connection timeout, in milliseconds, for client and peer TCP connections.</param>
            <param name="inactivityTimeout">The inactivity timeout, in milliseconds, for peer TCP connections.</param>
            <param name="proxyOptions">Optional SOCKS 5 proxy configuration options.</param>
            <param name="configureSocketAction">
                The delegate invoked during instantiation to configure the server Socket instance.
            </param>
            <returns>The new instance.</returns>
        </member>
        <member name="M:slskd.Extensions.ToUserStatisticsState(Soulseek.UserStatistics)">
            <summary>
                Creates a new instance of <see cref="T:slskd.UserStatisticsState"/> from this instance of <see cref="T:Soulseek.UserStatistics"/>.
            </summary>
            <param name="stats">The UserStatistics instance from which to copy data.</param>
            <returns>The new instance.</returns>
        </member>
        <member name="M:slskd.Metrics.BuildAsync">
            <summary>
                Builds metrics into a Prometheus-formatted string.
            </summary>
            <returns>A Prometheus-formatted string.</returns>
        </member>
        <member name="P:slskd.Metrics.Search.ResponseLatency">
            <summary>
                Gets a histogram representing the time taken to resolve a response to an incoming search request, in milliseconds.
            </summary>
        </member>
        <member name="P:slskd.Metrics.Search.CurrentResponseLatency">
            <summary>
                Gets an EMA representing the average time taken to resolve a response to an incoming search request, in milliseconds.
            </summary>
        </member>
        <member name="P:slskd.Metrics.Search.RequestsReceived">
            <summary>
                Gets a counter representing the total number of search requests received.
            </summary>
        </member>
        <member name="P:slskd.Metrics.Search.ResponsesSent">
            <summary>
                Gets a counter representing the total number of search responses sent.
            </summary>
        </member>
        <member name="P:slskd.Metrics.Browse.ResponseLatency">
            <summary>
                Gets a histogram representing the time taken to resolve a response to an incoming browse request, in milliseconds.
            </summary>
        </member>
        <member name="P:slskd.Metrics.Browse.CurrentResponseLatency">
            <summary>
                Gets an EMA representing the average time taken to resolve a response to an incoming search request, in milliseconds.
            </summary>
        </member>
        <member name="P:slskd.Metrics.Browse.RequestsReceived">
            <summary>
                Gets a counter representing the total number of browse requests received.
            </summary>
        </member>
        <member name="P:slskd.Metrics.Browse.ResponsesSent">
            <summary>
                Gets a counter representing the total number of browse responses sent.
            </summary>
        </member>
        <member name="P:slskd.Metrics.DistributedNetwork.Children">
            <summary>
                Gets a gauge representing the current number of connected distributed children.
            </summary>
        </member>
        <member name="P:slskd.Metrics.DistributedNetwork.ChildLimit">
            <summary>
                Gets a gauge representing the current distributed child limit.
            </summary>
        </member>
        <member name="P:slskd.Metrics.DistributedNetwork.HasParent">
            <summary>
                Gets a gauge indicating whether a distributed parent connection is established.
            </summary>
        </member>
        <member name="P:slskd.Metrics.DistributedNetwork.BranchLevel">
            <summary>
                Gets a gauge representing the current distributed branch level.
            </summary>
        </member>
        <member name="P:slskd.Metrics.DistributedNetwork.CurrentBroadcastLatency">
            <summary>
                Gets a gauge representing the most recent average time taken to broadcast incoming search requests to connected children.
            </summary>
        </member>
        <member name="P:slskd.Metrics.DistributedNetwork.BroadcastLatency">
            <summary>
                Gets a histogram representing the time taken to resolve a response to an incoming browse request, in milliseconds.
            </summary>
        </member>
        <member name="T:slskd.OptionsAtStartup">
            <summary>
                Disambiguates options derived at startup from options that may update at run time.
            </summary>
            <remarks>
                This class is added directly to dependency injection, but <see cref="T:slskd.Options"/> is not, so consumers must inject <see cref="T:slskd.OptionsAtStartup"/>
                instead of <see cref="T:slskd.Options"/> to make it clear that these options will not change.  Options that may change should be accessed by injecting
                <see cref="T:Microsoft.Extensions.Options.IOptionsMonitor`1"/> or <see cref="T:Microsoft.Extensions.Options.IOptionsSnapshot`1"/>, depending on the lifetime of the component.
            </remarks>
        </member>
        <member name="T:slskd.Options">
            <summary>
                Application options.
            </summary>
            <remarks>
                <para>
                    This class contains all application options, which may be sourced from (in order of precedence):
                    <list type="bullet">
                        <item>
                            <term>Defaults</term>
                            <description>Default values, statically defined in this class.</description>
                        </item>
                        <item>
                            <term>Environment Variables</term>
                            <description>Environment variables set at either the system or user scope.</description>
                        </item>
                        <item>
                            <term>YAML Configuration File</term>
                            <description>A YAML file containing a mapping of this class.</description>
                        </item>
                        <item>
                            <term>Command Line</term>
                            <description>Options provided via the command line when starting the application.</description>
                        </item>
                    </list>
                </para>
                <para>
                    Only the YAML configuration source can change at runtime and consumers of this class must be aware of this, either injecting
                    <see cref="T:Microsoft.Extensions.Options.IOptionsMonitor`1"/> in components with a singleton lifetime, or <see cref="T:Microsoft.Extensions.Options.IOptionsSnapshot`1"/> for transient or scoped lifetimes.
                </para>
                <para>
                    To obtain the Options specified at startup (discarding any updates that may have been applied since), inject <see cref="T:slskd.OptionsAtStartup"/>.
                </para>
                <para>
                    Options specified via the command line can not be overwritten by changes to the YAML file.  This is by design due to the immutable
                    nature of the command line string after the application is started.
                </para>
            </remarks>
        </member>
        <member name="P:slskd.Options.ShowVersion">
            <summary>
                Gets a value indicating whether to display the application version.
            </summary>
        </member>
        <member name="P:slskd.Options.ShowHelp">
            <summary>
                Gets a value indicating whether to display a list of command line arguments.
            </summary>
        </member>
        <member name="P:slskd.Options.ShowEnvironmentVariables">
            <summary>
                Gets a value indicating whether to display a list of configuration environment variables.
            </summary>
        </member>
        <member name="P:slskd.Options.GenerateCertificate">
            <summary>
                Gets a value indicating whether to generate an X509 certificate and password.
            </summary>
        </member>
        <member name="P:slskd.Options.GenerateSecret">
            <summary>
                Gets a value indicating whether to generate a random secret.
            </summary>
        </member>
        <member name="P:slskd.Options.Debug">
            <summary>
                Gets a value indicating whether the application should run in debug mode.
            </summary>
        </member>
        <member name="P:slskd.Options.Headless">
            <summary>
                Gets a value indicating whether the application should run in headless (no web UI) mode.
            </summary>
        </member>
        <member name="P:slskd.Options.RemoteConfiguration">
            <summary>
                Gets a value indicating whether remote configuration of options is allowed.
            </summary>
        </member>
        <member name="P:slskd.Options.RemoteFileManagement">
            <summary>
                Gets a value indicating whether remote file management is allowed.
            </summary>
        </member>
        <member name="P:slskd.Options.InstanceName">
            <summary>
                Gets the unique name for this instance.
            </summary>
        </member>
        <member name="P:slskd.Options.Flags">
            <summary>
                Gets optional flags.
            </summary>
        </member>
        <member name="P:slskd.Options.AppDirectory">
            <summary>
                Gets the path where application data is saved.
            </summary>
        </member>
        <member name="P:slskd.Options.ConfigurationFile">
            <summary>
                Gets the path where application data is saved.
            </summary>
        </member>
        <member name="P:slskd.Options.Relay">
            <summary>
                Gets relay options.
            </summary>
        </member>
        <member name="P:slskd.Options.Permissions">
            <summary>
                Gets permission options.
            </summary>
        </member>
        <member name="P:slskd.Options.Directories">
            <summary>
                Gets directory options.
            </summary>
        </member>
        <member name="P:slskd.Options.Shares">
            <summary>
                Gets share options.
            </summary>
        </member>
        <member name="P:slskd.Options.Global">
            <summary>
                Gets global options.
            </summary>
        </member>
        <member name="P:slskd.Options.Groups">
            <summary>
                Gets user groups.
            </summary>
        </member>
        <member name="P:slskd.Options.Blacklist">
            <summary>
                Gets blacklist options.
            </summary>
        </member>
        <member name="P:slskd.Options.Filters">
            <summary>
                Gets filter options.
            </summary>
        </member>
        <member name="P:slskd.Options.Rooms">
            <summary>
                Gets a list of rooms to automatically join upon connection.
            </summary>
        </member>
        <member name="P:slskd.Options.Web">
            <summary>
                Gets options for the web UI.
            </summary>
        </member>
        <member name="P:slskd.Options.Retention">
            <summary>
                Gets retention options.
            </summary>
        </member>
        <member name="P:slskd.Options.Logger">
            <summary>
                Gets logger options.
            </summary>
        </member>
        <member name="P:slskd.Options.Metrics">
            <summary>
                Gets metrics options.
            </summary>
        </member>
        <member name="P:slskd.Options.Feature">
            <summary>
                Gets feature options.
            </summary>
        </member>
        <member name="P:slskd.Options.Soulseek">
            <summary>
                Gets options for the Soulseek client.
            </summary>
        </member>
        <member name="P:slskd.Options.Integration">
            <summary>
                Gets options for external integrations.
            </summary>
        </member>
        <member name="M:slskd.Options.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
                Handles top-level validation that doesn't fit anywhere else.
            </summary>
            <param name="validationContext"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Options.FlagsOptions">
            <summary>
                Optional flags.
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.NoLogo">
            <summary>
                Gets a value indicating whether the logo should be suppressed on startup.
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.NoStart">
            <summary>
                Gets a value indicating whether the application should quit after initialization.
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.NoConfigWatch">
            <summary>
                Gets a value indicating whether the application should watch the configuration file for changes.
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.NoConnect">
            <summary>
                Gets a value indicating whether the application should connect to the Soulseek network on startup.
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.NoShareScan">
            <summary>
                Gets a value indicating whether the application should scan shared directories on startup.
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.ForceShareScan">
            <summary>
                Gets a value indicating whether shares should be forcibly re-scanned on startup.
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.ForceMigrations">
            <summary>
                Gets a value indicating whether to force database migrations to be applied on startup.
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.NoVersionCheck">
            <summary>
                Gets a value indicating whether the application should check for a newer version on startup.
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.LogSQL">
            <summary>
                Gets a value indicating whether Entity Framework queries should be logged.
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.Experimental">
            <summary>
                Gets a value indicating whether the application should run in experimental mode.
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.Volatile">
            <summary>
                Gets a value indicating whether the application should run in volatile mode.
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.CaseSensitiveRegEx">
            <summary>
                Gets a value indicating whether user-defined regular expressions are case sensitive.
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.LegacyWindowsTcpKeepalive">
            <summary>
                Gets a value indicating whether to use legacy TCP keepalive options, for Windows
                versions prior to Windows 10, version 1709 (and associated Server SKUs).
            </summary>
        </member>
        <member name="P:slskd.Options.FlagsOptions.OptimisticRelayFileInfo">
            <summary>
                Gets a value indicating whether to use the uploaded shares from Relay agents as the source of
                truth for file existence and size, instead of querying the agent prior to enqueueing the file.
            </summary>
        </member>
        <member name="T:slskd.Options.RelayOptions">
            <summary>
                Relay options.
            </summary>
        </member>
        <member name="P:slskd.Options.RelayOptions.Enabled">
            <summary>
                Gets a value indicating whether the relay is enabled.
            </summary>
        </member>
        <member name="P:slskd.Options.RelayOptions.Mode">
            <summary>
                Gets the relay mode.
            </summary>
        </member>
        <member name="P:slskd.Options.RelayOptions.Controller">
            <summary>
                Gets the controller configuration.
            </summary>
        </member>
        <member name="P:slskd.Options.RelayOptions.Agents">
            <summary>
                Gets the agent configuration.
            </summary>
        </member>
        <member name="T:slskd.Options.RelayOptions.RelayControllerConfigurationOptions">
            <summary>
                Relay controller configuration options.
            </summary>
        </member>
        <member name="P:slskd.Options.RelayOptions.RelayControllerConfigurationOptions.Address">
            <summary>
                Gets the controller address.
            </summary>
        </member>
        <member name="P:slskd.Options.RelayOptions.RelayControllerConfigurationOptions.IgnoreCertificateErrors">
            <summary>
                Gets a value indicating whether controller certificate errors should be ignored.
            </summary>
        </member>
        <member name="P:slskd.Options.RelayOptions.RelayControllerConfigurationOptions.ApiKey">
            <summary>
                Gets the controller API key.
            </summary>
        </member>
        <member name="P:slskd.Options.RelayOptions.RelayControllerConfigurationOptions.Secret">
            <summary>
                Gets the controller secret.
            </summary>
        </member>
        <member name="P:slskd.Options.RelayOptions.RelayControllerConfigurationOptions.Downloads">
            <summary>
                Gets a value indicating whether to receive completed downloads from the controller.
            </summary>
        </member>
        <member name="T:slskd.Options.RelayOptions.RelayAgentConfigurationOptions">
            <summary>
                Relay agent configuration options.
            </summary>
        </member>
        <member name="P:slskd.Options.RelayOptions.RelayAgentConfigurationOptions.InstanceName">
            <summary>
                Gets the agent instance name.
            </summary>
        </member>
        <member name="P:slskd.Options.RelayOptions.RelayAgentConfigurationOptions.Secret">
            <summary>
                Gets the agent secret.
            </summary>
        </member>
        <member name="P:slskd.Options.RelayOptions.RelayAgentConfigurationOptions.Cidr">
            <summary>
                Gets the comma separated list of CIDRs that are authorized to connect as this agent.
            </summary>
        </member>
        <member name="M:slskd.Options.RelayOptions.RelayAgentConfigurationOptions.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
                Extended validation.
            </summary>
            <param name="validationContext"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Options.PermissionsOptions">
            <summary>
                Permission options.
            </summary>
        </member>
        <member name="P:slskd.Options.PermissionsOptions.File">
            <summary>
                Gets file permission options.
            </summary>
        </member>
        <member name="T:slskd.Options.PermissionsOptions.FileOptions">
            <summary>
                File permission options.
            </summary>
        </member>
        <member name="P:slskd.Options.PermissionsOptions.FileOptions.Mode">
            <summary>
                Gets the permissions to apply to newly created files.
            </summary>
            <remarks>
                Applicable to non-Windows operating systems, only.
            </remarks>
        </member>
        <member name="M:slskd.Options.PermissionsOptions.FileOptions.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
                Extended validation.
            </summary>
            <param name="validationContext"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Options.DirectoriesOptions">
            <summary>
                Directory options.
            </summary>
        </member>
        <member name="P:slskd.Options.DirectoriesOptions.Incomplete">
            <summary>
                Gets the path where incomplete downloads are saved.
            </summary>
        </member>
        <member name="P:slskd.Options.DirectoriesOptions.Downloads">
            <summary>
                Gets the path where downloaded files are saved.
            </summary>
        </member>
        <member name="T:slskd.Options.SharesOptions">
            <summary>
                Share options.
            </summary>
        </member>
        <member name="P:slskd.Options.SharesOptions.Directories">
            <summary>
                Gets the list of paths to shared files.
            </summary>
        </member>
        <member name="P:slskd.Options.SharesOptions.Filters">
            <summary>
                Gets the list of shared file filters.
            </summary>
        </member>
        <member name="P:slskd.Options.SharesOptions.Cache">
            <summary>
                Share caching options.
            </summary>
        </member>
        <member name="M:slskd.Options.SharesOptions.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
                Extended validation.
            </summary>
            <param name="validationContext"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Options.SharesOptions.ShareCacheOptions">
            <summary>
                Share caching options.
            </summary>
        </member>
        <member name="P:slskd.Options.SharesOptions.ShareCacheOptions.StorageMode">
            <summary>
                Gets the type of storage to use for the share cache.
            </summary>
        </member>
        <member name="P:slskd.Options.SharesOptions.ShareCacheOptions.Workers">
            <summary>
                Gets the number of workers to use while scanning shares.
            </summary>
        </member>
        <member name="P:slskd.Options.SharesOptions.ShareCacheOptions.Retention">
            <summary>
                Gets the time to retain the cache (the interval on which to re-scan automatically), in minutes.
            </summary>
        </member>
        <member name="T:slskd.Options.GlobalOptions">
            <summary>
                Global options.
            </summary>
        </member>
        <member name="P:slskd.Options.GlobalOptions.Upload">
            <summary>
                Gets global upload options.
            </summary>
        </member>
        <member name="P:slskd.Options.GlobalOptions.Limits">
            <summary>
                Gets global limits.
            </summary>
        </member>
        <member name="P:slskd.Options.GlobalOptions.Download">
            <summary>
                Gets global download options.
            </summary>
        </member>
        <member name="T:slskd.Options.GlobalOptions.GlobalUploadOptions">
            <summary>
                Global upload options.
            </summary>
        </member>
        <member name="P:slskd.Options.GlobalOptions.GlobalUploadOptions.Slots">
            <summary>
                Gets the limit for the total number of upload slots.
            </summary>
        </member>
        <member name="P:slskd.Options.GlobalOptions.GlobalUploadOptions.SpeedLimit">
            <summary>
                Gets the total upload speed limit, in kibibytes.
            </summary>
        </member>
        <member name="T:slskd.Options.GlobalOptions.GlobalDownloadOptions">
            <summary>
                Gets global download options.
            </summary>
        </member>
        <member name="P:slskd.Options.GlobalOptions.GlobalDownloadOptions.Slots">
            <summary>
                Gets the limit for the total number of download slots.
            </summary>
        </member>
        <member name="P:slskd.Options.GlobalOptions.GlobalDownloadOptions.SpeedLimit">
            <summary>
                Gets the total download speed limit, in kibibytes.
            </summary>
        </member>
        <member name="T:slskd.Options.LimitsOptions">
            <summary>
                Limit options.
            </summary>
        </member>
        <member name="P:slskd.Options.LimitsOptions.Queued">
            <summary>
                Gets limits for queued transfers.
            </summary>
        </member>
        <member name="P:slskd.Options.LimitsOptions.Daily">
            <summary>
                Gets daily limits for transfers.
            </summary>
        </member>
        <member name="P:slskd.Options.LimitsOptions.Weekly">
            <summary>
                Gets weekly limits for transfers.
            </summary>
        </member>
        <member name="T:slskd.Options.LimitsOptions.Limits">
            <summary>
                Limits.
            </summary>
        </member>
        <member name="P:slskd.Options.LimitsOptions.Limits.Files">
            <summary>
                Gets the limit for number of files.
            </summary>
        </member>
        <member name="P:slskd.Options.LimitsOptions.Limits.Megabytes">
            <summary>
                Gets the limit for number of megabytes.
            </summary>
        </member>
        <member name="P:slskd.Options.LimitsOptions.Limits.Failures">
            <summary>
                Gets the limit for number of failures.
            </summary>
        </member>
        <member name="T:slskd.Options.GroupsOptions">
            <summary>
                User groups.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.Default">
            <summary>
                Gets options for the default user group.
            </summary>
            <remarks>
                These options apply to users that are not privileged, have not been identified as leechers,
                and have not been added as a member of any group.
            </remarks>
        </member>
        <member name="P:slskd.Options.GroupsOptions.Leechers">
            <summary>
                Gets options for the leecher user group.
            </summary>
            <remarks>
                These options apply to users that have been identified as leechers, and have not been added as a member of any group.
            </remarks>
        </member>
        <member name="P:slskd.Options.GroupsOptions.Blacklisted">
            <summary>
                Gets options for the blacklisted user group.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.UserDefined">
            <summary>
                Gets user defined groups and options.
            </summary>
        </member>
        <member name="M:slskd.Options.GroupsOptions.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
                Extended validation.
            </summary>
            <param name="validationContext"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Options.GroupsOptions.GroupOptions">
            <summary>
                Options that are common to all groups.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.GroupOptions.Upload">
            <summary>
                Gets upload options.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.GroupOptions.Limits">
            <summary>
                Gets limit options.
            </summary>
        </member>
        <member name="T:slskd.Options.GroupsOptions.BuiltInOptions">
            <summary>
                Built in user group options.
            </summary>
        </member>
        <member name="T:slskd.Options.GroupsOptions.BlacklistedOptions">
            <summary>
                Built in blacklisted group options.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.BlacklistedOptions.Members">
            <summary>
                Gets the list of group member usernames.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.BlacklistedOptions.Cidrs">
            <summary>
                Gets the list of group CIDRs.
            </summary>
        </member>
        <member name="M:slskd.Options.GroupsOptions.BlacklistedOptions.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
                Extended validation.
            </summary>
            <param name="validationContext"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Options.GroupsOptions.LeecherOptions">
            <summary>
                Built in leecher group options.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.LeecherOptions.Thresholds">
            <summary>
                Gets leecher threshold options.
            </summary>
        </member>
        <member name="T:slskd.Options.GroupsOptions.ThresholdOptions">
            <summary>
                Leecher threshold options.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.ThresholdOptions.Files">
            <summary>
                Gets the minimum number of shared files required to avoid being classified as a leecher.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.ThresholdOptions.Directories">
            <summary>
                Gets the minimum number of shared directories required to avoid being classified as a leecher.
            </summary>
        </member>
        <member name="T:slskd.Options.GroupsOptions.UserDefinedOptions">
            <summary>
                User defined user group options.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.UserDefinedOptions.Members">
            <summary>
                Gets the list of group member usernames.
            </summary>
        </member>
        <member name="T:slskd.Options.GroupsOptions.UploadOptions">
            <summary>
                User group upload options.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.UploadOptions.Priority">
            <summary>
                Gets the priority of the group.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.UploadOptions.Strategy">
            <summary>
                Gets the queue strategy for the group.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.UploadOptions.Slots">
            <summary>
                Gets the limit for the total number of upload slots for the group.
            </summary>
        </member>
        <member name="P:slskd.Options.GroupsOptions.UploadOptions.SpeedLimit">
            <summary>
                Gets the total upload speed limit for the group, in kibibytes.
            </summary>
        </member>
        <member name="T:slskd.Options.FeatureOptions">
            <summary>
                Feature options.
            </summary>
        </member>
        <member name="P:slskd.Options.FeatureOptions.Swagger">
            <summary>
                Gets a value indicating whether swagger documentation and UI should be enabled.
            </summary>
        </member>
        <member name="T:slskd.Options.BlacklistOptions">
            <summary>
                Blacklist options.
            </summary>
        </member>
        <member name="P:slskd.Options.BlacklistOptions.Enabled">
            <summary>
                Gets a value indicating whether blacklist file support should be enabled.
            </summary>
        </member>
        <member name="P:slskd.Options.BlacklistOptions.File">
            <summary>
                Gets the path to the blacklist file.
            </summary>
        </member>
        <member name="M:slskd.Options.BlacklistOptions.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
                Extended validation.
            </summary>
            <param name="validationContext"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Options.FiltersOptions">
            <summary>
                Filter options.
            </summary>
        </member>
        <member name="P:slskd.Options.FiltersOptions.Search">
            <summary>
                Gets search filter options.
            </summary>
        </member>
        <member name="T:slskd.Options.FiltersOptions.SearchOptions">
            <summary>
                Search filter options.
            </summary>
        </member>
        <member name="P:slskd.Options.FiltersOptions.SearchOptions.Request">
            <summary>
                Gets the list of search request filters.
            </summary>
        </member>
        <member name="M:slskd.Options.FiltersOptions.SearchOptions.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
                Extended validation.
            </summary>
            <param name="validationContext"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Options.LoggerOptions">
            <summary>
                Logger options.
            </summary>
        </member>
        <member name="P:slskd.Options.LoggerOptions.Loki">
            <summary>
                Gets the URL to a Grafana Loki instance to which to log.
            </summary>
        </member>
        <member name="P:slskd.Options.LoggerOptions.Disk">
            <summary>
                Gets a value indicating whether to write logs to disk.
            </summary>
        </member>
        <member name="P:slskd.Options.LoggerOptions.NoColor">
            <summary>
                Gets a value indicating whether to suppress colorization of console logs.
            </summary>
        </member>
        <member name="T:slskd.Options.RetentionOptions">
            <summary>
                Retention options.
            </summary>
        </member>
        <member name="P:slskd.Options.RetentionOptions.Search">
            <summary>
                Gets the time to retain searches, in minutes.
            </summary>
        </member>
        <member name="P:slskd.Options.RetentionOptions.Transfers">
            <summary>
                Gets transfer retention options.
            </summary>
        </member>
        <member name="P:slskd.Options.RetentionOptions.Files">
            <summary>
                Gets file retention options.
            </summary>
        </member>
        <member name="P:slskd.Options.RetentionOptions.Logs">
            <summary>
                Gets the time to retain logs, in days.
            </summary>
        </member>
        <member name="T:slskd.Options.RetentionOptions.TransferRetentionOptions">
            <summary>
                Transfer retention options.
            </summary>
        </member>
        <member name="P:slskd.Options.RetentionOptions.TransferRetentionOptions.Upload">
            <summary>
                Gets upload retention options.
            </summary>
        </member>
        <member name="P:slskd.Options.RetentionOptions.TransferRetentionOptions.Download">
            <summary>
                Gets download retention options.
            </summary>
        </member>
        <member name="T:slskd.Options.RetentionOptions.TransferRetentionOptions.TransferTypeRetentionOptions">
            <summary>
                Transfer retention options.
            </summary>
        </member>
        <member name="P:slskd.Options.RetentionOptions.TransferRetentionOptions.TransferTypeRetentionOptions.Succeeded">
            <summary>
                Gets the time to retain successful transfers, in minutes.
            </summary>
        </member>
        <member name="P:slskd.Options.RetentionOptions.TransferRetentionOptions.TransferTypeRetentionOptions.Errored">
            <summary>
                Gets the time to retain errored transfers, in minutes.
            </summary>
        </member>
        <member name="P:slskd.Options.RetentionOptions.TransferRetentionOptions.TransferTypeRetentionOptions.Cancelled">
            <summary>
                Gets the time to retain cancelled transfers, in minutes.
            </summary>
        </member>
        <member name="T:slskd.Options.RetentionOptions.FileRetentionOptions">
            <summary>
                File retention options.
            </summary>
        </member>
        <member name="P:slskd.Options.RetentionOptions.FileRetentionOptions.Complete">
            <summary>
                Gets the time to retain completed files, in minutes.
            </summary>
        </member>
        <member name="P:slskd.Options.RetentionOptions.FileRetentionOptions.Incomplete">
            <summary>
                Gets the time to retain incomplete files, in minutes.
            </summary>
        </member>
        <member name="T:slskd.Options.MetricsOptions">
            <summary>
                Metrics options.
            </summary>
        </member>
        <member name="P:slskd.Options.MetricsOptions.Enabled">
            <summary>
                Gets a value indicating whether the metrics endpoint should be enabled.
            </summary>
        </member>
        <member name="P:slskd.Options.MetricsOptions.Url">
            <summary>
                Gets the url for the metrics endpoint.
            </summary>
        </member>
        <member name="P:slskd.Options.MetricsOptions.Authentication">
            <summary>
                Gets metrics endpoint authentication options.
            </summary>
        </member>
        <member name="T:slskd.Options.MetricsOptions.MetricsAuthenticationOptions">
            <summary>
                Metrics endpoint authentication options.
            </summary>
        </member>
        <member name="P:slskd.Options.MetricsOptions.MetricsAuthenticationOptions.Disabled">
            <summary>
                Gets a value indicating whether authentication should be disabled.
            </summary>
        </member>
        <member name="P:slskd.Options.MetricsOptions.MetricsAuthenticationOptions.Username">
            <summary>
                Gets the username for the metrics endpoint.
            </summary>
        </member>
        <member name="P:slskd.Options.MetricsOptions.MetricsAuthenticationOptions.Password">
            <summary>
                Gets the password for the metrics endpoint.
            </summary>
        </member>
        <member name="T:slskd.Options.SoulseekOptions">
            <summary>
                Soulseek client options.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.Address">
            <summary>
                Gets the address of the Soulseek server.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.Port">
            <summary>
                Gets the port of the Soulseek server.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.Username">
            <summary>
                Gets the username for the Soulseek network.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.Password">
            <summary>
                Gets the password for the Soulseek network.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.Description">
            <summary>
                Gets the description of the Soulseek user.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.Picture">
            <summary>
                Gets the file path for the user's profile picture.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ListenIpAddress">
            <summary>
                Gets the local IP address on which to listen for incoming connections.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ListenPort">
            <summary>
                Gets the port on which to listen for incoming connections.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.DiagnosticLevel">
            <summary>
                Gets the minimum diagnostic level.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.DistributedNetwork">
            <summary>
                Gets options for the distributed network.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.Connection">
            <summary>
                Gets connection options.
            </summary>
        </member>
        <member name="T:slskd.Options.SoulseekOptions.ConnectionOptions">
            <summary>
                Connection options.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.Timeout">
            <summary>
                Gets connection timeout options.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.Buffer">
            <summary>
                Gets connection buffer options.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.Proxy">
            <summary>
                Gets connection proxy options.
            </summary>
        </member>
        <member name="T:slskd.Options.SoulseekOptions.ConnectionOptions.BufferOptions">
            <summary>
                Connection buffer options.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.BufferOptions.Read">
            <summary>
                Gets the connection read buffer size, in bytes.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.BufferOptions.Write">
            <summary>
                Gets the connection write buffer size, in bytes.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.BufferOptions.Transfer">
            <summary>
                Gets the read/write buffer size for transfers, in bytes.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.BufferOptions.WriteQueue">
            <summary>
                Gets the size of the queue for double buffered writes.
            </summary>
        </member>
        <member name="T:slskd.Options.SoulseekOptions.ConnectionOptions.TimeoutOptions">
            <summary>
                Connection timeout options.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.TimeoutOptions.Connect">
            <summary>
                Gets the connection timeout value, in milliseconds.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.TimeoutOptions.Inactivity">
            <summary>
                Gets the connection inactivity timeout, in milliseconds.
            </summary>
        </member>
        <member name="T:slskd.Options.SoulseekOptions.ConnectionOptions.ProxyOptions">
            <summary>
                Connection proxy options.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.ProxyOptions.Enabled">
            <summary>
                Gets a value indicating whether the proxy is enabled.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.ProxyOptions.Address">
            <summary>
                Gets the proxy address.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.ProxyOptions.Port">
            <summary>
                Gets the proxy port.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.ProxyOptions.Username">
            <summary>
                Gets the proxy username, if applicable.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.ConnectionOptions.ProxyOptions.Password">
            <summary>
                Gets the proxy password, if applicable.
            </summary>
        </member>
        <member name="M:slskd.Options.SoulseekOptions.ConnectionOptions.ProxyOptions.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
                Extended validation.
            </summary>
            <param name="validationContext"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Options.SoulseekOptions.DistributedNetworkOptions">
            <summary>
                Distributed network options.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.DistributedNetworkOptions.Disabled">
            <summary>
                Gets a value indicating whether the distributed network should be disabled.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.DistributedNetworkOptions.DisableChildren">
            <summary>
                Gets a value indicating whether to accept distributed child connections.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.DistributedNetworkOptions.ChildLimit">
            <summary>
                Gets the distributed child connection limit.
            </summary>
        </member>
        <member name="P:slskd.Options.SoulseekOptions.DistributedNetworkOptions.Logging">
            <summary>
                Gets a value indicating whether distributed network logging should be enabled.
            </summary>
        </member>
        <member name="T:slskd.Options.WebOptions">
            <summary>
                Web server options.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.Port">
            <summary>
                Gets the HTTP listen port.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.Https">
            <summary>
                Gets HTTPS options.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.UrlBase">
            <summary>
                Gets the base url for web requests.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.ContentPath">
            <summary>
                Gets the path to static web content.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.Logging">
            <summary>
                Gets a value indicating whether HTTP request logging should be enabled.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.Authentication">
            <summary>
                Gets authentication options.
            </summary>
        </member>
        <member name="T:slskd.Options.WebOptions.WebAuthenticationOptions">
            <summary>
                Authentication options.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.WebAuthenticationOptions.Disabled">
            <summary>
                Gets a value indicating whether authentication should be disabled.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.WebAuthenticationOptions.Username">
            <summary>
                Gets the username for the web UI.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.WebAuthenticationOptions.Password">
            <summary>
                Gets the password for the web UI.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.WebAuthenticationOptions.Jwt">
            <summary>
                Gets JWT options.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.WebAuthenticationOptions.ApiKeys">
            <summary>
                Gets API keys.
            </summary>
        </member>
        <member name="T:slskd.Options.WebOptions.WebAuthenticationOptions.JwtOptions">
            <summary>
                JWT options.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.WebAuthenticationOptions.JwtOptions.Key">
            <summary>
                Gets the key with which to sign JWTs.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.WebAuthenticationOptions.JwtOptions.Ttl">
            <summary>
                Gets the TTL for JWTs, in milliseconds.
            </summary>
        </member>
        <member name="T:slskd.Options.WebOptions.WebAuthenticationOptions.ApiKeyOptions">
            <summary>
                API key options.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.WebAuthenticationOptions.ApiKeyOptions.Key">
            <summary>
                Gets the API key value.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.WebAuthenticationOptions.ApiKeyOptions.Role">
            <summary>
                Gets the role for the key.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.WebAuthenticationOptions.ApiKeyOptions.Cidr">
            <summary>
                Gets the comma separated list of CIDRs that are authorized to use the key.
            </summary>
        </member>
        <member name="M:slskd.Options.WebOptions.WebAuthenticationOptions.ApiKeyOptions.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
                Extended validation.
            </summary>
            <param name="validationContext"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Options.WebOptions.HttpsOptions">
            <summary>
                HTTPS options.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.HttpsOptions.Disabled">
            <summary>
                Gets a value indicating whether HTTPS should be disabled.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.HttpsOptions.Port">
            <summary>
                Gets the HTTPS listen port.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.HttpsOptions.Force">
            <summary>
                Gets a value indicating whether HTTP requests should be redirected to HTTPS.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.HttpsOptions.Certificate">
            <summary>
                Gets certificate options.
            </summary>
        </member>
        <member name="T:slskd.Options.WebOptions.HttpsOptions.CertificateOptions">
            <summary>
                Certificate options.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.HttpsOptions.CertificateOptions.Pfx">
            <summary>
                Gets the path to the the X509 certificate .pfx file.
            </summary>
        </member>
        <member name="P:slskd.Options.WebOptions.HttpsOptions.CertificateOptions.Password">
            <summary>
                Gets the password for the X509 certificate.
            </summary>
        </member>
        <member name="T:slskd.Options.IntegrationOptions">
            <summary>
                Options for external integrations.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.Webhooks">
            <summary>
                Gets webhook configuration.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.Scripts">
            <summary>
                Gets script configuration.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.Ftp">
            <summary>
                Gets FTP options.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.Pushbullet">
            <summary>
                Gets Pushbullet options.
            </summary>
        </member>
        <member name="T:slskd.Options.IntegrationOptions.WebhookOptions">
            <summary>
                Webhook configuration.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.WebhookOptions.On">
            <summary>
                Gets the list of Event types that trigger the webhook.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.WebhookOptions.Call">
            <summary>
                Gets details about the webhook call.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.WebhookOptions.Timeout">
            <summary>
                Gets the time to wait before timing out, in milliseconds.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.WebhookOptions.Retry">
            <summary>
                Gets the retry configuration.
            </summary>
        </member>
        <member name="T:slskd.Options.IntegrationOptions.WebhookHttpOptions">
            <summary>
                Webhook HTTP options.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.WebhookHttpOptions.Url">
            <summary>
                Gets the fully qualified URL for the webhook.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.WebhookHttpOptions.Headers">
            <summary>
                Gets the HTTP headers to include with the webhook.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.WebhookHttpOptions.IgnoreCertificateErrors">
            <summary>
                Gets a value indicating whether HTTPS certificate errors should be ignored.
            </summary>
        </member>
        <member name="T:slskd.Options.IntegrationOptions.WebhookHttpHeader">
            <summary>
                Webhook HTTP header configuration.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.WebhookHttpHeader.Name">
            <summary>
                Gets the name of the header.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.WebhookHttpHeader.Value">
            <summary>
                Gets the header's value.
            </summary>
        </member>
        <member name="T:slskd.Options.IntegrationOptions.RetryOptions">
            <summary>
                Retry configuration.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.RetryOptions.Attempts">
            <summary>
                Gets the number of attempts to make before failing.
            </summary>
        </member>
        <member name="T:slskd.Options.IntegrationOptions.ScriptOptions">
            <summary>
                Script configuration.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.ScriptOptions.On">
            <summary>
                Gets the list of Event types that trigger the script.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.ScriptOptions.Run">
            <summary>
                Gets the shell script to invoke.
            </summary>
        </member>
        <member name="T:slskd.Options.IntegrationOptions.ScriptRunOptions">
            <summary>
                Script run options.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.ScriptRunOptions.Command">
            <summary>
                Gets the shell command to run.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.ScriptRunOptions.Executable">
            <summary>
                Gets the executable to start.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.ScriptRunOptions.Args">
            <summary>
                Gets the arguments to pass to the executable.
            </summary>
            <remarks>
                Mutually exclusive with <see cref="P:slskd.Options.IntegrationOptions.ScriptRunOptions.Arglist"/>.
            </remarks>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.ScriptRunOptions.Arglist">
            <summary>
                Gets the list of arguments to pass to the executable.
            </summary>
            <remarks>
                Mutually exclusive with <see cref="P:slskd.Options.IntegrationOptions.ScriptRunOptions.Args"/>.
            </remarks>
        </member>
        <member name="T:slskd.Options.IntegrationOptions.FtpOptions">
            <summary>
                FTP options.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.FtpOptions.Enabled">
            <summary>
                Gets a value indicating whether the FTP integration is enabled.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.FtpOptions.Address">
            <summary>
                Gets the FTP address.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.FtpOptions.Port">
            <summary>
                Gets the FTP port.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.FtpOptions.EncryptionMode">
            <summary>
                Gets the FTP encryption mode.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.FtpOptions.IgnoreCertificateErrors">
            <summary>
                Gets a value indicating whether FTP certificate errors should be ignored.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.FtpOptions.Username">
            <summary>
                Gets the FTP username.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.FtpOptions.Password">
            <summary>
                Gets the FTP password.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.FtpOptions.RemotePath">
            <summary>
                Gets the remote path for uploads.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.FtpOptions.OverwriteExisting">
            <summary>
                Gets a value indicating whether existing files should be overwritten.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.FtpOptions.ConnectionTimeout">
            <summary>
                Gets the connection timeout value, in milliseconds.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.FtpOptions.RetryAttempts">
            <summary>
                Gets the number of times failing uploads will be retried.
            </summary>
        </member>
        <member name="M:slskd.Options.IntegrationOptions.FtpOptions.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
                Extended validation.
            </summary>
            <param name="validationContext"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Options.IntegrationOptions.PushbulletOptions">
            <summary>
                Pushbullet options.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.PushbulletOptions.Enabled">
            <summary>
                Gets a value indicating whether the Pushbullet integration is enabled.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.PushbulletOptions.AccessToken">
            <summary>
                Gets the Pushbullet API access token.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.PushbulletOptions.NotificationPrefix">
            <summary>
                Gets the prefix for Pushbullet notification titles.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.PushbulletOptions.NotifyOnPrivateMessage">
            <summary>
                Gets a value indicating whether a Pushbullet notification should be sent when a private message is received.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.PushbulletOptions.NotifyOnRoomMention">
            <summary>
                Gets a value indicating whether a Pushbullet notification should be sent when the currently logged
                in user's username is mentioned in a room.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.PushbulletOptions.RetryAttempts">
            <summary>
                Gets the number of times failing Pushbullet notifications will be retried.
            </summary>
        </member>
        <member name="P:slskd.Options.IntegrationOptions.PushbulletOptions.CooldownTime">
            <summary>
                Gets the cooldown time for Pushbullet notifications, in milliseconds.
            </summary>
        </member>
        <member name="M:slskd.Options.IntegrationOptions.PushbulletOptions.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
                Extended validation.
            </summary>
            <param name="validationContext"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.State">
            <summary>
                Application service state.
            </summary>
        </member>
        <member name="T:slskd.ShareState">
            <summary>
                Share state.
            </summary>
        </member>
        <member name="P:slskd.SharedFileCacheState.Filling">
            <summary>
                Gets a value indicating whether the cache is being filled.
            </summary>
        </member>
        <member name="P:slskd.SharedFileCacheState.Filled">
            <summary>
                Gets a value indicating whether the cache is filled.
            </summary>
        </member>
        <member name="P:slskd.SharedFileCacheState.Faulted">
            <summary>
                Gets a value indicating whether the cache is faulted.
            </summary>
        </member>
        <member name="P:slskd.SharedFileCacheState.FillProgress">
            <summary>
                Gets the current fill progress.
            </summary>
        </member>
        <member name="P:slskd.SharedFileCacheState.Directories">
            <summary>
                Gets the number of cached directories.
            </summary>
        </member>
        <member name="P:slskd.SharedFileCacheState.Files">
            <summary>
                Gets the number of cached files.
            </summary>
        </member>
        <member name="P:slskd.SharedFileCacheState.ExcludedDirectories">
            <summary>
                Gets the number of directories excluded by filters.
            </summary>
        </member>
        <member name="T:slskd.Events.API.EventsController">
            <summary>
                Events.
            </summary>
        </member>
        <member name="M:slskd.Events.API.EventsController.GetEvents(System.Int32,System.Int32)">
            <summary>
                Retrieves a paginated list of past event records.
            </summary>
            <param name="offset">The offset (number of records) at which to start the requested page.</param>
            <param name="limit">The page size.</param>
            <returns>The list of <see cref="T:slskd.Events.Event"/> records.</returns>
            <response code="400">The offset is less than zero, or if the limit is less than or equal to zero.</response>
            <response code="401">Authentication credentials are omitted.</response>
            <response code="403">Authentication is valid but not sufficient to access this endpoint.</response>
            <response code="500">An unexpected error is encountered.</response>
            <response code="200">The request completed successfully.</response>
        </member>
        <member name="M:slskd.Events.API.EventsController.RaiseEvent(System.String,System.String)">
            <summary>
                Raises a sample event of the specified type.
            </summary>
            <param name="type">The type of event to raise.</param>
            <param name="disambiguator">An optional string used to disambiguate generated events.</param>
            <returns>The randomly generated event that was raised.</returns>
            <response code="400">The specified type is not a valid event type.</response>
            <response code="401">Authentication credentials are omitted.</response>
            <response code="403">Authentication is valid but not sufficient to access this endpoint.</response>
            <response code="500">An unexpected error is encountered.</response>
            <response code="201">The request completed successfully.</response>
        </member>
        <member name="T:slskd.Events.EventBus">
            <summary>
                The event bus supporting interoperability and ancillary functions.
            </summary>
            <remarks>
                <para>
                    This "bus" is meant to mimic an event bus you'd find in a distributed system; fire and forget. If an
                    Exception is encountered while an event is being raised, it will be logged and swallowed.
                </para>
                <para>
                    It is also intended to be used *ONLY* for ancillary and/or third party logic that isn't part of the
                    core application.  The core application should continue to use regular old C# events and method calls
                    to communicate within and among modules.
                </para>
                <para>
                    This design was chosen over built-in C# events to give greater control over how events are dispatched,
                    and bound.
                </para>
            </remarks>
        </member>
        <member name="M:slskd.Events.EventBus.#ctor(slskd.Events.EventService)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Events.EventBus"/> class.
            </summary>
            <param name="eventService"/>
        </member>
        <member name="P:slskd.Events.EventBus.Subscriptions">
            <summary>
                Gets the internal list of event subscriptions.
            </summary>
            <remarks>
                Note that the value is a dictionary to prevent multiple subscriptions from the same subscriber, and to
                support unsubscribing.
            </remarks>
        </member>
        <member name="M:slskd.Events.EventBus.Raise``1(``0)">
            <summary>
                Raises an event.
            </summary>
            <param name="data">The event data.</param>
            <typeparam name="T">The Type of the event.</typeparam>
        </member>
        <member name="M:slskd.Events.EventBus.Subscribe``1(System.String,System.Func{``0,System.Threading.Tasks.Task})">
            <summary>
                Subscribes a <paramref name="subscriber"/>'s <paramref name="callback"/> to an event.
            </summary>
            <param name="subscriber">The unique name of the subscriber.</param>
            <param name="callback">The callback function to execute when an event is raised.</param>
            <typeparam name="T">The Type of the event.</typeparam>
            <exception cref="T:System.ArgumentException">Thrown if the specified <paramref name="subscriber"/> is null or whitespace.</exception>
            <exception cref="T:System.ArgumentNullException">Thrown if the specified <paramref name="callback"/> is null.</exception>
        </member>
        <member name="M:slskd.Events.EventBus.Unsubscribe``1(System.String)">
            <summary>
                Unsubscribes a <paramref name="subscriber"/> from an event.
            </summary>
            <remarks>
                Will not throw if a subscription doesn't exist.
            </remarks>
            <typeparam name="T">The Type of the event.</typeparam>
            <param name="subscriber">The unique name of the subscriber.</param>
        </member>
        <member name="T:slskd.Events.EventService">
            <summary>
                Manages events.
            </summary>
        </member>
        <member name="M:slskd.Events.EventService.#ctor(Microsoft.EntityFrameworkCore.IDbContextFactory{slskd.Events.EventsDbContext})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Events.EventService"/> class.
            </summary>
            <param name="contextFactory"></param>
        </member>
        <member name="M:slskd.Events.EventService.Get(System.Int32,System.Int32)">
            <summary>
                Gets list of events, optionally applying the specified <paramref name="offset"/> and <paramref name="limit"/>.
            </summary>
            <param name="offset">The beginning offset for the page.</param>
            <param name="limit">The page size limit.</param>
            <returns>The retrieved list.</returns>
            <exception cref="T:System.ArgumentOutOfRangeException">Thrown when the specified <paramref name="offset"/> is less than zero.</exception>
            <exception cref="T:System.ArgumentOutOfRangeException">Thrown when the specified <paramref name="limit"/> is zero.</exception>
        </member>
        <member name="M:slskd.Events.EventService.Count">
            <summary>
                Gets the total number of events.
            </summary>
            <returns>The total number of events.</returns>
        </member>
        <member name="M:slskd.Events.EventService.Add(slskd.Events.EventRecord)">
            <summary>
                Adds the specified event <paramref name="eventRecord"/>.
            </summary>
            <remarks>
                To ensure proper construction of the record, use <see cref="M:slskd.Events.EventRecord.From``1(slskd.Events.Event)"/>.
            </remarks>
            <param name="eventRecord">The record to add.</param>
            <exception cref="T:System.ArgumentNullException">Thrown when the specified record is null.</exception>
        </member>
        <member name="M:slskd.Events.EventRecord.From``1(slskd.Events.Event)">
            <summary>
                Converts the specified event <paramref name="e"/> into an instance of <see cref="T:slskd.Events.EventRecord"/>
                for the purpose of database storage.
            </summary>
            <remarks>
                The <see cref="P:slskd.Events.EventRecord.Data"/> property contains the event-specific data serialized as json, applying
                standard formatting such as camel cased property names and null value omission. This is important so that
                the values stored in the database will match the values exposed through other means. Maybe not *that* important,
                but standardizing json is a good practice.
            </remarks>
            <param name="e">The Event to convert.</param>
            <typeparam name="T">The specific type of the Event.</typeparam>
            <returns>The converted EventRecord.</returns>
        </member>
        <member name="T:slskd.Files.API.FilesController">
            <summary>
                Files.
            </summary>
        </member>
        <member name="M:slskd.Files.API.FilesController.GetDownloadContentsAsync(System.Boolean)">
            <summary>
                Lists the contents of the downloads directory.
            </summary>
            <param name="recursive">An optional value indicating whether to recursively list subdirectories and files.</param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="401">Authentication failed.</response>
        </member>
        <member name="M:slskd.Files.API.FilesController.GetDownloadSubdirectoryContentsAsync(System.String,System.Boolean)">
            <summary>
                Lists the contents of the specified subdirectory within the downloads directory.
            </summary>
            <param name="base64SubdirectoryName">The relative, base 64 encoded, name of the subdirectory to list.</param>
            <param name="recursive">An optional value indicating whether to recursively list subdirectories and files.</param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="401">Authentication failed.</response>
            <response code="403">Access to the specified subdirectory was denied.</response>
            <response code="404">The specified subdirectory does not exist.</response>
        </member>
        <member name="M:slskd.Files.API.FilesController.DeleteDownloadSubdirectoryAsync(System.String)">
            <summary>
                Deletes the specified subdirectory within the downloads directory.
            </summary>
            <param name="base64SubdirectoryName">The relative, base 64 encoded, name of the subdirectory to delete.</param>
            <returns></returns>
            <response code="204">The request completed successfully.</response>
            <response code="401">Authentication failed.</response>
            <response code="403">Access to the specified subdirectory was denied.</response>
            <response code="404">The specified subdirectory does not exist.</response>
        </member>
        <member name="M:slskd.Files.API.FilesController.DeleteDownloadFileAsync(System.String)">
            <summary>
                Deletes the specified file within the downloads directory.
            </summary>
            <param name="base64FileName">The relative, base 64 encoded, name of the file to delete.</param>
            <returns></returns>
            <response code="204">The request completed successfully.</response>
            <response code="401">Authentication failed.</response>
            <response code="403">Access to the specified subdirectory was denied.</response>
            <response code="404">The specified subdirectory does not exist.</response>
        </member>
        <member name="M:slskd.Files.API.FilesController.GetIncompleteContentsAsync(System.Boolean)">
            <summary>
                Lists the contents of the downloads directory.
            </summary>
            <param name="recursive">An optional value indicating whether to recursively list subdirectories and files.</param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="401">Authentication failed.</response>
        </member>
        <member name="M:slskd.Files.API.FilesController.GetIncompleteSubdirectoryContentsAsync(System.String,System.Boolean)">
            <summary>
                Lists the contents of the specified subdirectory within the incomplete directory.
            </summary>
            <param name="base64SubdirectoryName">The relative, base 64 encoded, name of the subdirectory to list.</param>
            <param name="recursive">An optional value indicating whether to recursively list subdirectories and files.</param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="401">Authentication failed.</response>
            <response code="403">Access to the specified subdirectory was denied.</response>
            <response code="404">The specified subdirectory does not exist.</response>
        </member>
        <member name="M:slskd.Files.API.FilesController.DeleteIncompleteSubdirectoryAsync(System.String)">
            <summary>
                Deletes the specified subdirectory within the downloads directory.
            </summary>
            <param name="base64SubdirectoryName">The relative, base 64 encoded, name of the subdirectory to delete.</param>
            <returns></returns>
            <response code="204">The request completed successfully.</response>
            <response code="401">Authentication failed.</response>
            <response code="403">Access to the specified subdirectory was denied.</response>
            <response code="404">The specified subdirectory does not exist.</response>
        </member>
        <member name="M:slskd.Files.API.FilesController.DeleteIncompleteFileAsync(System.String)">
            <summary>
                Deletes the specified file within the downloads directory.
            </summary>
            <param name="base64FileName">The relative, base 64 encoded, name of the file to delete.</param>
            <returns></returns>
            <response code="204">The request completed successfully.</response>
            <response code="401">Authentication failed.</response>
            <response code="403">Access to the specified subdirectory was denied.</response>
            <response code="404">The specified subdirectory does not exist.</response>
        </member>
        <member name="T:slskd.Files.FileExtensions">
            <summary>
                Extension methods related to <see cref="N:slskd.Files"/>.
            </summary>
        </member>
        <member name="M:slskd.Files.FileExtensions.ToUnixFileMode(System.String)">
            <summary>
                Converts the specified <paramref name="permissions"/> string into an instance of <see cref="T:System.IO.UnixFileMode"/>.
            </summary>
            <param name="permissions">A 3 or 4 character string consisting of only 0-7, matching a Unix file permission (e.g. one used with 'chmod').</param>
            <returns>The converted UnixFileMode.</returns>
            <exception cref="T:System.ArgumentException">Thrown if the specified <paramref name="permissions"/> string is null or consists of only whitespace.</exception>
            <exception cref="T:System.ArgumentOutOfRangeException">Thrown if the specified <paramref name="permissions"/> are not a 3 or 4 character string consisting of only 0-7.</exception>
        </member>
        <member name="T:slskd.Files.FileService">
            <summary>
                Manages files on disk.
            </summary>
        </member>
        <member name="M:slskd.Files.FileService.#ctor(Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Files.FileService"/> class.
            </summary>
        </member>
        <member name="M:slskd.Files.FileService.ResolveFileInfo(System.String)">
            <summary>
                Resolves an instance of <see cref="T:System.IO.FileInfo"/> for the specified <paramref name="filename"/>, following
                any symlinks that may be present to their final target. A non-null return value is guaranteed.
            </summary>
            <param name="filename">The fully qualified filename for which to resolve the FileInfo instance.</param>
            <returns>The resolved FileInfo instance.</returns>
            <exception cref="T:System.ArgumentException">Thrown if the specified filename is null or contains only whitespace.</exception>
            <exception cref="T:slskd.UnauthorizedException">Thrown if the specified or linked file is restricted.</exception>
            <exception cref="T:System.IO.IOException">Thrown if the specified or linked file can't be resolved for some reason.</exception>
        </member>
        <member name="M:slskd.Files.FileService.DeleteDirectoriesAsync(System.String[])">
            <summary>
                Deletes the specified <paramref name="directories"/>.
            </summary>
            <remarks>
                Returns a dictionary keyed on directory name and containing a result for each specified directory. Exceptions are
                contained in the result, and are not thrown.
            </remarks>
            <param name="directories">The directories to delete.</param>
            <returns>The operation context.</returns>
            <exception cref="T:System.ArgumentException">Thrown if any of the specified directories have a relative path.</exception>
            <exception cref="T:System.ArgumentException">
                Thrown if any of the directories is an exact match for an application-controlled directory.
            </exception>
            <exception cref="T:slskd.NotFoundException">Thrown if a specified directory does not exist.</exception>
            <exception cref="T:slskd.UnauthorizedException">Thrown if a specified directory is restricted.</exception>
        </member>
        <member name="M:slskd.Files.FileService.DeleteFilesAsync(System.String[])">
            <summary>
                Deletes the specified <paramref name="files"/>.
            </summary>
            <remarks>
                Returns a dictionary keyed on directory name and containing a result for each specified directory. Exceptions are
                contained in the result, and are not thrown.
            </remarks>
            <param name="files">The list of files to delete.</param>
            <returns>The operation context.</returns>
            <exception cref="T:System.ArgumentException">Thrown if any of the specified files have a relative path.</exception>
            <exception cref="T:slskd.NotFoundException">Thrown if a specified file does not exist.</exception>
            <exception cref="T:slskd.UnauthorizedException">Thrown if a specified file is restricted.</exception>
        </member>
        <member name="M:slskd.Files.FileService.ListContentsAsync(System.String,System.IO.EnumerationOptions)">
            <summary>
                Lists the contents in the specified <paramref name="directory"/>, optionally applying the specified <paramref name="enumerationOptions"/>.
            </summary>
            <param name="directory">The directory from which to start the listing.</param>
            <param name="enumerationOptions">Optional enumeration options to apply.</param>
            <returns>The list of found contents.</returns>
            <exception cref="T:System.ArgumentException">Thrown if the specified directory has a relative path.</exception>
            <exception cref="T:slskd.NotFoundException">Thrown if the specified directory does not exist.</exception>
            <exception cref="T:slskd.UnauthorizedException">Thrown if the specified root directory is restricted.</exception>
        </member>
        <member name="M:slskd.Files.FileService.CreateFile(System.String,slskd.Files.CreateFileOptions)">
            <summary>
                Creates a new file with the specified fully qualified <paramref name="filename"/> and the optional <paramref name="options"/>,
                returning a <see cref="T:System.IO.Stream"/> with which the contents of the file can be written.
            </summary>
            <remarks>
                Reasonable defaults, including the Unix permissions from app configuration, have been applied. Be sure to review the defaults
                for each new use case and ensure they are appropriate.
            </remarks>
            <param name="filename">The fully qualified filename.</param>
            <param name="options">An optional patch for the underlying <see cref="T:System.IO.FileStreamOptions"/>.</param>
            <returns>A Stream with which the contents of the file can be written.</returns>
            <exception cref="T:System.ArgumentNullException">Thrown if the specified filename is null or contains only whitespace.</exception>
            <exception cref="T:System.IO.IOException">Thrown if the underlying file or Stream can't be created for some reason.</exception>
        </member>
        <member name="M:slskd.Files.FileService.MoveFile(System.String,System.String,System.Boolean,System.Boolean)">
            <summary>
                Moves the specified fully qualified, localized, <paramref name="sourceFilename"/> to the specified fully qualified, localized,
                <paramref name="destinationDirectory"/>.
            </summary>
            <remarks>
                If the destination file already exists and the <paramref name="overwrite"/> option is not set, the destination filename will
                be modified to include the current time to avoid the collision while preserving both files.
            </remarks>
            <param name="sourceFilename">The fully qualified filename of the file to move.</param>
            <param name="destinationDirectory">The fully qualified directory to which to move the source file.</param>
            <param name="overwrite">An optional value indicating whether the destination file should be overwritten if it already exists.</param>
            <param name="deleteSourceDirectoryIfEmptyAfterMove">
                An optional value indicating whether the parent directory of the source file should be deleted if it is empty after the move.
            </param>
            <returns>The fully qualified filename of the resulting file.</returns>
            <exception cref="T:System.ArgumentNullException">Thrown if either of the specified file or directories are null or contain only whitespace.</exception>
            <exception cref="T:System.IO.FileNotFoundException">Thrown if the specified <paramref name="sourceFilename"/> does not exist.</exception>
            <exception cref="T:System.IO.IOException">Thrown if the file can't be moved, or the <paramref name="deleteSourceDirectoryIfEmptyAfterMove"/> option is set and the operation fails.</exception>
        </member>
        <member name="T:slskd.Files.FilesystemDirectory">
            <summary>
                A file directory on the host filesystem.
            </summary>
        </member>
        <member name="P:slskd.Files.FilesystemDirectory.Name">
            <summary>
                The name of the directory.
            </summary>
        </member>
        <member name="P:slskd.Files.FilesystemDirectory.FullName">
            <summary>
                The fully qualified name of the directory.
            </summary>
        </member>
        <member name="P:slskd.Files.FilesystemDirectory.Attributes">
            <summary>
                The directories' attributes.
            </summary>
        </member>
        <member name="P:slskd.Files.FilesystemDirectory.CreatedAt">
            <summary>
                The timestamp at which the directory was created.
            </summary>
        </member>
        <member name="P:slskd.Files.FilesystemDirectory.ModifiedAt">
            <summary>
                The timestamp at which the directory was last modified.
            </summary>
        </member>
        <member name="P:slskd.Files.FilesystemDirectory.Files">
            <summary>
                The files within the directory.
            </summary>
        </member>
        <member name="P:slskd.Files.FilesystemDirectory.Directories">
            <summary>
                The directories within the directory.
            </summary>
        </member>
        <member name="M:slskd.Files.FilesystemDirectory.FromDirectoryInfo(System.IO.DirectoryInfo)">
            <summary>
                Maps a <see cref="T:slskd.Files.FilesystemDirectory"/> from the specified <see cref="T:System.IO.DirectoryInfo"/>.
            </summary>
            <param name="i">The DirectoryInfo instance from which to map.</param>
            <returns>A new instance of FilesystemDirectory.</returns>
        </member>
        <member name="T:slskd.Files.FilesystemFile">
            <summary>
                A file on the host filesystem.
            </summary>
        </member>
        <member name="P:slskd.Files.FilesystemFile.Name">
            <summary>
                The name of the file.
            </summary>
        </member>
        <member name="P:slskd.Files.FilesystemFile.FullName">
            <summary>
                The fully qualified name of the file.
            </summary>
        </member>
        <member name="P:slskd.Files.FilesystemFile.Length">
            <summary>
                The size of the file, in bytes.
            </summary>
        </member>
        <member name="P:slskd.Files.FilesystemFile.Attributes">
            <summary>
                The file's attributes.
            </summary>
        </member>
        <member name="P:slskd.Files.FilesystemFile.CreatedAt">
            <summary>
                The timestamp at which the file was created.
            </summary>
        </member>
        <member name="P:slskd.Files.FilesystemFile.ModifiedAt">
            <summary>
                The timestamp at which the file was last modified.
            </summary>
        </member>
        <member name="M:slskd.Files.FilesystemFile.FromFileInfo(System.IO.FileInfo)">
            <summary>
                Maps a <see cref="T:slskd.Files.FilesystemFile"/> from the specified <see cref="T:System.IO.FileInfo"/>.
            </summary>
            <param name="i">The FileInfo instance from which to map.</param>
            <returns>A new instance of FilesystemFile.</returns>
        </member>
        <member name="T:slskd.Integrations.FTP.FTPClientFactory">
            <summary>
                FTP client factory.
            </summary>
        </member>
        <member name="M:slskd.Integrations.FTP.FTPClientFactory.#ctor(Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Integrations.FTP.FTPClientFactory"/> class.
            </summary>
            <param name="optionsMonitor">The options monitor used to derive application options.</param>
        </member>
        <member name="M:slskd.Integrations.FTP.FTPClientFactory.CreateFtpClient">
            <summary>
                Creates an instance of <see cref="T:FluentFTP.FtpClient"/>.
            </summary>
            <returns>The created instance.</returns>
        </member>
        <member name="T:slskd.Integrations.FTP.FTPService">
            <summary>
                FTP Integration service.
            </summary>
        </member>
        <member name="M:slskd.Integrations.FTP.FTPService.#ctor(slskd.Integrations.FTP.IFTPClientFactory,Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options},Microsoft.Extensions.Logging.ILogger{slskd.Integrations.FTP.FTPService})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Integrations.FTP.FTPService"/> class.
            </summary>
            <param name="ftpClientFactory">The FTP client factory to use.</param>
            <param name="optionsMonitor">The options monitor used to derive application options.</param>
            <param name="log">The logger.</param>
        </member>
        <member name="M:slskd.Integrations.FTP.FTPService.UploadAsync(System.String)">
            <summary>
                Uploads the specified <paramref name="filename"/> to the configured FTP server.
            </summary>
            <param name="filename">The fully qualified name of the file to upload.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="T:slskd.Integrations.FTP.IFTPClientFactory">
            <summary>
                FTP client factory.
            </summary>
        </member>
        <member name="M:slskd.Integrations.FTP.IFTPClientFactory.CreateFtpClient">
            <summary>
                Creates an instance of <see cref="T:FluentFTP.AsyncFtpClient"/>.
            </summary>
            <returns>The created instance.</returns>
        </member>
        <member name="T:slskd.Integrations.FTP.IFTPService">
            <summary>
                FTP Integration service.
            </summary>
        </member>
        <member name="M:slskd.Integrations.FTP.IFTPService.UploadAsync(System.String)">
            <summary>
                Uploads the specified <paramref name="filename"/> to the configured FTP server.
            </summary>
            <param name="filename">The fully qualified name of the file to upload.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="T:slskd.Integrations.Pushbullet.IPushbulletService">
            <summary>
                Pushbullet integration service.
            </summary>
        </member>
        <member name="M:slskd.Integrations.Pushbullet.IPushbulletService.PushAsync(System.String,System.String,System.String)">
            <summary>
                Sends a push notification to Pushbullet.
            </summary>
            <param name="title">The notification title.</param>
            <param name="cacheKey">A unique cache key for the notification.</param>
            <param name="body">The notification body.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="T:slskd.Integrations.Pushbullet.PushbulletService">
            <summary>
                Pushbullet integration service.
            </summary>
        </member>
        <member name="M:slskd.Integrations.Pushbullet.PushbulletService.#ctor(System.Net.Http.IHttpClientFactory,Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options},Microsoft.Extensions.Logging.ILogger{slskd.Integrations.Pushbullet.PushbulletService})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Integrations.Pushbullet.PushbulletService"/> class.
            </summary>
            <param name="httpClientFactory">The HttpClientFactory to use.</param>
            <param name="optionsMonitor">The options monitor used to derive application options.</param>
            <param name="log">The logger.</param>
        </member>
        <member name="M:slskd.Integrations.Pushbullet.PushbulletService.Dispose">
            <summary>
                Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
            </summary>
        </member>
        <member name="M:slskd.Integrations.Pushbullet.PushbulletService.PushAsync(System.String,System.String,System.String)">
            <summary>
                Sends a push notification to Pushbullet.
            </summary>
            <param name="title">The notification title.</param>
            <param name="cacheKey">A unique cache key for the notification.</param>
            <param name="body">The notification body.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="T:slskd.Integrations.Scripts.ScriptService">
            <summary>
                Handles the invocation of shell scripts.
            </summary>
        </member>
        <member name="T:slskd.Messaging.API.ConversationsController">
            <summary>
                Conversations.
            </summary>
        </member>
        <member name="M:slskd.Messaging.API.ConversationsController.#ctor(slskd.IStateMonitor{slskd.State},slskd.Messaging.IMessagingService,Microsoft.Extensions.Options.IOptionsSnapshot{slskd.Options})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Messaging.API.ConversationsController"/> class.
            </summary>
            <param name="applicationStateMonitor"></param>
            <param name="messagingService"></param>
            <param name="optionsSnapshot"></param>
        </member>
        <member name="M:slskd.Messaging.API.ConversationsController.Acknowledge(System.String,System.Int32)">
            <summary>
                Acknowledges the given message id for the given username.
            </summary>
            <param name="username"></param>
            <param name="id"></param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="404">
                A conversation with the specified username, or a message matching the specified id could not be found.
            </response>
        </member>
        <member name="M:slskd.Messaging.API.ConversationsController.AcknowledgeAll(System.String)">
            <summary>
                Acknowledges all messages from the given username.
            </summary>
            <param name="username"></param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="404">A conversation with the specified username could not be found.</response>
        </member>
        <member name="M:slskd.Messaging.API.ConversationsController.Close(System.String)">
            <summary>
                Closes the conversation associated with the given username.
            </summary>
            <returns></returns>
            <response code="204">The request completed successfully.</response>
            <response code="404">A conversation with the specified username could not be found.</response>
        </member>
        <member name="M:slskd.Messaging.API.ConversationsController.GetAll(System.Boolean,System.Boolean)">
            <summary>
                Gets all active conversations.
            </summary>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
        </member>
        <member name="M:slskd.Messaging.API.ConversationsController.GetByUsername(System.String,System.Boolean)">
            <summary>
                Gets the conversation associated with the specified username.
            </summary>
            <param name="username">The username associated with the desired conversation.</param>
            <param name="includeMessages"></param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="404">A matching search was not found.</response>
        </member>
        <member name="M:slskd.Messaging.API.ConversationsController.Send(System.String,System.String)">
            <summary>
                Sends a private message to the specified username.
            </summary>
            <param name="username"></param>
            <param name="message"></param>
            <returns></returns>
            <response code="201">The request completed successfully.</response>
            <response code="400">The specified message is null or empty.</response>
        </member>
        <member name="T:slskd.Messaging.API.PublicChatController">
            <summary>
                Server.
            </summary>
        </member>
        <member name="M:slskd.Messaging.API.PublicChatController.Start">
            <summary>
                Starts public chat.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Messaging.API.PublicChatController.Stop">
            <summary>
                Stops public chat.
            </summary>
            <returns></returns>
        </member>
        <member name="T:slskd.Messaging.API.RoomsController">
            <summary>
                Rooms.
            </summary>
        </member>
        <member name="M:slskd.Messaging.API.RoomsController.GetAll">
            <summary>
                Gets all rooms.
            </summary>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
        </member>
        <member name="M:slskd.Messaging.API.RoomsController.GetByRoomName(System.String)">
            <summary>
                Gets the specified room.
            </summary>
            <param name="roomName"></param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="404">The specified roomName could not be found.</response>
        </member>
        <member name="M:slskd.Messaging.API.RoomsController.SendMessage(System.String,System.String)">
            <summary>
                Sends a message to the specified room.
            </summary>
            <param name="roomName"></param>
            <param name="message"></param>
            <returns></returns>
            <response code="201">The request completed successfully.</response>
            <response code="404">The specified roomName could not be found.</response>
        </member>
        <member name="M:slskd.Messaging.API.RoomsController.SetTicker(System.String,System.String)">
            <summary>
                Sets a ticker for the specified room.
            </summary>
            <param name="roomName"></param>
            <param name="message"></param>
            <returns></returns>
            <response code="201">The request completed successfully.</response>
            <response code="404">The specified roomName could not be found.</response>
        </member>
        <member name="M:slskd.Messaging.API.RoomsController.AddRoomMember(System.String,System.String)">
            <summary>
                Adds a member to a private room.
            </summary>
            <param name="roomName"></param>
            <param name="username"></param>
            <returns></returns>
            <response code="201">The request completed successfully.</response>
            <response code="404">The specified roomName could not be found.</response>
        </member>
        <member name="M:slskd.Messaging.API.RoomsController.GetUsersByRoomName(System.String)">
            <summary>
                Gets the current list of users for the specified room.
            </summary>
            <param name="roomName"></param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="404">The specified roomName could not be found.</response>
        </member>
        <member name="M:slskd.Messaging.API.RoomsController.GetMessagesByRoomName(System.String)">
            <summary>
                Gets the current list of messages for the specified room.
            </summary>
            <param name="roomName"></param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="404">The specified roomName could not be found.</response>
        </member>
        <member name="M:slskd.Messaging.API.RoomsController.GetRooms">
            <summary>
                Gets a list of rooms from the server.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Messaging.API.RoomsController.JoinRoom(System.String)">
            <summary>
                Joins a room.
            </summary>
            <param name="roomName"></param>
            <returns></returns>
            <response code="201">The request completed successfully.</response>
            <response code="304">The room has already been joined.</response>
        </member>
        <member name="M:slskd.Messaging.API.RoomsController.LeaveRoom(System.String)">
            <summary>
                Leaves a room.
            </summary>
            <param name="roomName"></param>
            <returns></returns>
            <response code="204">The request completed successfully.</response>
            <response code="404">The room has not been joined.</response>
        </member>
        <member name="P:slskd.Messaging.API.RoomInfoResponse.Name">
            <summary>
                Gets the room name.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomInfoResponse.UserCount">
            <summary>
                Gets the number of users in the room.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomInfoResponse.IsPrivate">
            <summary>
                Gets a value indicating whether the room is private.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomInfoResponse.IsOwned">
            <summary>
                Gets a value indicating whether the room is owned by the currently logged in user.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomInfoResponse.IsModerated">
            <summary>
                Gets a value indicating whether the room is moderated by the currently logged in user.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomMessageResponse.Timestamp">
            <summary>
                The timestamp of the message.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomMessageResponse.Username">
            <summary>
                The username of the user who sent the message.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomMessageResponse.Message">
            <summary>
                The message.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomMessageResponse.RoomName">
            <summary>
                The room to which the message pertains.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomMessageResponse.Self">
            <summary>
                A value indicating whether this user data belongs to the currently logged in user.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomResponse.Name">
            <summary>
                The room name.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomResponse.IsPrivate">
            <summary>
                A value indicating whether the room is private.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomResponse.OperatorCount">
            <summary>
                The number of operators in the room, if private.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomResponse.Operators">
            <summary>
                The operators in the room, if private.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomResponse.Owner">
            <summary>
                The owner of the room, if private.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomResponse.Users">
            <summary>
                The list of users in the room.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.RoomResponse.Messages">
            <summary>
                The list of messages.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.UserDataResponse.AverageSpeed">
            <summary>
                The average upload speed of the user.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.UserDataResponse.CountryCode">
            <summary>
                The user's country code, if provided.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.UserDataResponse.DirectoryCount">
            <summary>
                The number of directories shared by the user.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.UserDataResponse.FileCount">
            <summary>
                The number of files shared by the user.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.UserDataResponse.Self">
            <summary>
                A value indicating whether this user data belongs to the currently logged in user.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.UserDataResponse.SlotsFree">
            <summary>
                The number of the user's free download slots, if provided.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.UserDataResponse.Status">
            <summary>
                The status of the user (0 = offline, 1 = away, 2 = online).
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.UserDataResponse.UploadCount">
            <summary>
                The number of uploads tracked by the server for the user.
            </summary>
        </member>
        <member name="P:slskd.Messaging.API.UserDataResponse.Username">
            <summary>
                The username of the user.
            </summary>
        </member>
        <member name="T:slskd.Messaging.IConversationService">
            <summary>
                Manages private messages.
            </summary>
        </member>
        <member name="M:slskd.Messaging.IConversationService.AcknowledgeAsync(System.String)">
            <summary>
                Acknowledges all unacknowledged <see cref="T:slskd.Messaging.PrivateMessage"/> records from the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username associated with the conversation.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Messaging.IConversationService.AcknowledgeMessageAsync(System.String,System.Int32)">
            <summary>
                Acknowledges the <see cref="T:slskd.Messaging.PrivateMessage"/> record associated with the specified <paramref name="username"/> and <paramref name="id"/>.
            </summary>
            <param name="username">The username associated with the conversation.</param>
            <param name="id">The ID of the message.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Messaging.IConversationService.CreateAsync(System.String)">
            <summary>
                Creates a new, or activates an existing, conversation with the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username associated with the conversation.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Messaging.IConversationService.FindAsync(System.String,System.Boolean,System.Boolean)">
            <summary>
                Returns the <see cref="T:slskd.Messaging.Conversation"/> record associated with the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username associated with the conversation.</param>
            <param name="includeInactive">A value indicating whether to include conversations marked as inactive.</param>
            <param name="includeMessages">A value indicating whether <see cref="T:slskd.Messaging.PrivateMessage"/> records should be included in the return value.</param>
            <returns>The operation context, including the located conversation, if one was found.</returns>
        </member>
        <member name="M:slskd.Messaging.IConversationService.FindMessageAsync(System.String,System.Int32)">
            <summary>
                Returns the <see cref="T:slskd.Messaging.PrivateMessage"/> record associated with the specified <paramref name="username"/> and <paramref name="id"/>.
            </summary>
            <param name="username">The username associated with the conversation.</param>
            <param name="id">The ID of the message.</param>
            <returns>The operation context, including the located message, if one was found.</returns>
        </member>
        <member name="M:slskd.Messaging.IConversationService.ListAsync(System.Linq.Expressions.Expression{System.Func{slskd.Messaging.Conversation,System.Boolean}})">
            <summary>
                Returns the list of all <see cref="T:slskd.Messaging.Conversation"/> records matching the specified <paramref name="expression"/>.
            </summary>
            <param name="expression">An optional expression used to locate conversations.</param>
            <returns>The operation context, including the list of found conversations.</returns>
        </member>
        <member name="M:slskd.Messaging.IConversationService.ListMessagesAsync(System.Linq.Expressions.Expression{System.Func{slskd.Messaging.PrivateMessage,System.Boolean}})">
            <summary>
                Returns the list of all <see cref="T:slskd.Messaging.PrivateMessage"/> records matching the specified <paramref name="expression"/>.
            </summary>
            <param name="expression">An optional expression used to locate private messages.</param>
            <returns>The operation context, including the list of found private messages.</returns>
        </member>
        <member name="M:slskd.Messaging.IConversationService.HandleMessageAsync(System.String,slskd.Messaging.PrivateMessage)">
            <summary>
                Handles the receipt of an inbound <see cref="T:slskd.Messaging.PrivateMessage"/>.
            </summary>
            <param name="username">The username associated with the message.</param>
            <param name="message">The message.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Messaging.IConversationService.RemoveAsync(System.String)">
            <summary>
                Removes (marks inactive) the conversation with the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username associated with the conversation.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Messaging.IConversationService.SendMessageAsync(System.String,System.String)">
            <summary>
                Sends the specified <paramref name="message"/> to the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username of the recipient.</param>
            <param name="message">The message.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Messaging.ConversationService.AcknowledgeAsync(System.String)">
            <summary>
                Acknowledges all unacknowledged <see cref="T:slskd.Messaging.PrivateMessage"/> records from the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username associated with the conversation.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Messaging.ConversationService.AcknowledgeMessageAsync(System.String,System.Int32)">
            <summary>
                Acknowledges the <see cref="T:slskd.Messaging.PrivateMessage"/> record associated with the specified <paramref name="username"/> and <paramref name="id"/>.
            </summary>
            <param name="username">The username associated with the conversation.</param>
            <param name="id">The ID of the message.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Messaging.ConversationService.CreateAsync(System.String)">
            <summary>
                Creates a new, or activates an existing, conversation with the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username associated with the conversation.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Messaging.ConversationService.FindAsync(System.String,System.Boolean,System.Boolean)">
            <summary>
                Returns the <see cref="T:slskd.Messaging.Conversation"/> record associated with the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username associated with the conversation.</param>
            <param name="includeInactive">A value indicating whether to include conversations marked as inactive.</param>
            <param name="includeMessages">A value indicating whether <see cref="T:slskd.Messaging.PrivateMessage"/> records should be included in the return value.</param>
            <returns>The operation context, including the located conversation, if one was found.</returns>
        </member>
        <member name="M:slskd.Messaging.ConversationService.FindMessageAsync(System.String,System.Int32)">
            <summary>
                Returns the <see cref="T:slskd.Messaging.PrivateMessage"/> record associated with the specified <paramref name="username"/> and <paramref name="id"/>.
            </summary>
            <param name="username">The username associated with the conversation.</param>
            <param name="id">The ID of the message.</param>
            <returns>The operation context, including the located message, if one was found.</returns>
        </member>
        <member name="M:slskd.Messaging.ConversationService.ListAsync(System.Linq.Expressions.Expression{System.Func{slskd.Messaging.Conversation,System.Boolean}})">
            <summary>
                Returns the list of all <see cref="T:slskd.Messaging.Conversation"/> records matching the specified <paramref name="expression"/>.
            </summary>
            <param name="expression">An optional expression used to locate conversations.</param>
            <returns>The operation context, including the list of found conversations.</returns>
        </member>
        <member name="M:slskd.Messaging.ConversationService.ListMessagesAsync(System.Linq.Expressions.Expression{System.Func{slskd.Messaging.PrivateMessage,System.Boolean}})">
            <summary>
                Returns the list of all <see cref="T:slskd.Messaging.PrivateMessage"/> records matching the specified <paramref name="expression"/>.
            </summary>
            <param name="expression">An optional expression used to locate private messages.</param>
            <returns>The operation context, including the list of found private messages.</returns>
        </member>
        <member name="M:slskd.Messaging.ConversationService.HandleMessageAsync(System.String,slskd.Messaging.PrivateMessage)">
            <summary>
                Handles the receipt of an inbound <see cref="T:slskd.Messaging.PrivateMessage"/>.
            </summary>
            <param name="username">The username associated with the message.</param>
            <param name="message">The message.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Messaging.ConversationService.RemoveAsync(System.String)">
            <summary>
                Removes (marks inactive) the conversation with the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username associated with the conversation.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Messaging.ConversationService.SendMessageAsync(System.String,System.String)">
            <summary>
                Sends the specified <paramref name="message"/> to the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username of the recipient.</param>
            <param name="message">The message.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="T:slskd.Messaging.IRoomTracker">
            <summary>
                Tracks rooms.
            </summary>
        </member>
        <member name="P:slskd.Messaging.IRoomTracker.Rooms">
            <summary>
                Gets tracked rooms.
            </summary>
        </member>
        <member name="M:slskd.Messaging.IRoomTracker.AddOrUpdateMessage(System.String,slskd.Messaging.RoomMessage)">
            <summary>
                Adds a room and appends the specified <paramref name="message"/>, or just appends the message if the room exists.
            </summary>
            <param name="roomName"></param>
            <param name="message"></param>
        </member>
        <member name="M:slskd.Messaging.IRoomTracker.TryAdd(System.String,slskd.Messaging.Room)">
            <summary>
                Adds the specified room to the tracker.
            </summary>
            <param name="roomName"></param>
            <param name="room"></param>
        </member>
        <member name="M:slskd.Messaging.IRoomTracker.TryAddUser(System.String,Soulseek.UserData)">
            <summary>
                Adds the specified <paramref name="userData"/> to the specified room.
            </summary>
            <param name="roomName"></param>
            <param name="userData"></param>
        </member>
        <member name="M:slskd.Messaging.IRoomTracker.TryGet(System.String,slskd.Messaging.Room@)">
            <summary>
                Returns the list of messages for the specified <paramref name="roomName"/>, if it is tracked.
            </summary>
            <param name="roomName"></param>
            <param name="room"></param>
            <returns></returns>
        </member>
        <member name="M:slskd.Messaging.IRoomTracker.TryRemove(System.String)">
            <summary>
                Removes a tracked room.
            </summary>
            <param name="roomName"></param>
        </member>
        <member name="M:slskd.Messaging.IRoomTracker.TryRemoveUser(System.String,System.String)">
            <summary>
                Removes the specified <paramref name="username"/> from the specified room.
            </summary>
            <param name="roomName"></param>
            <param name="username"></param>
        </member>
        <member name="T:slskd.Messaging.IMessagingService">
            <summary>
                Manages private and room messages.
            </summary>
        </member>
        <member name="P:slskd.Messaging.IMessagingService.Conversations">
            <summary>
                Gets the <see cref="T:slskd.Messaging.ConversationService"/>.
            </summary>
        </member>
        <member name="T:slskd.Messaging.MessagingService">
            <summary>
                Manages private and room messages.
            </summary>
        </member>
        <member name="M:slskd.Messaging.MessagingService.#ctor(slskd.Messaging.IConversationService)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Messaging.MessagingService"/> class.
            </summary>
            <param name="conversations"></param>
        </member>
        <member name="P:slskd.Messaging.MessagingService.Conversations">
            <summary>
                Gets the <see cref="T:slskd.Messaging.ConversationService"/>.
            </summary>
        </member>
        <member name="T:slskd.Messaging.IRoomService">
            <summary>
                Chat room management and event handling.
            </summary>
        </member>
        <member name="M:slskd.Messaging.IRoomService.JoinAsync(System.String)">
            <summary>
                Joins the specified <paramref name="roomName"/>.
            </summary>
            <param name="roomName">The name of the room to join.</param>
            <returns>The operation context, including information about the room.</returns>
        </member>
        <member name="M:slskd.Messaging.IRoomService.LeaveAsync(System.String)">
            <summary>
                Leaves the specified <paramref name="roomName"/>.
            </summary>
            <param name="roomName">The name of the room to leave.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Messaging.IRoomService.TryJoinAsync(System.String[])">
            <summary>
                Attempts to join the specified <paramref name="roomNames"/>.
            </summary>
            <remarks>
                Failures are logged but not thrown. Use JoinAsync() to trap Exceptions.
            </remarks>
            <param name="roomNames">The list of room names to join.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="T:slskd.Messaging.RoomService">
            <summary>
                Chat room management and event handling.
            </summary>
        </member>
        <member name="M:slskd.Messaging.RoomService.#ctor(Soulseek.ISoulseekClient,Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options},slskd.IStateMutator{slskd.State},slskd.Messaging.IRoomTracker,slskd.Users.IUserService)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Messaging.RoomService"/> class.
            </summary>
            <param name="soulseekClient"></param>
            <param name="optionsMonitor"></param>
            <param name="stateMutator"></param>
            <param name="roomTracker"></param>
            <param name="userService"></param>
        </member>
        <member name="M:slskd.Messaging.RoomService.JoinAsync(System.String)">
            <summary>
                Joins the specified <paramref name="roomName"/>.
            </summary>
            <param name="roomName">The name of the room to join.</param>
            <returns>The operation context, including information about the room.</returns>
        </member>
        <member name="M:slskd.Messaging.RoomService.LeaveAsync(System.String)">
            <summary>
                Leaves the specified <paramref name="roomName"/>.
            </summary>
            <param name="roomName">The name of the room to leave.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Messaging.RoomService.TryJoinAsync(System.String[])">
            <summary>
                Attempts to join the specified <paramref name="roomNames"/>.
            </summary>
            <remarks>
                Failures are logged but not thrown. Use JoinAsync() to trap Exceptions.
            </remarks>
            <param name="roomNames">The list of room names to join.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="T:slskd.Messaging.RoomTracker">
            <summary>
                Tracks rooms.
            </summary>
        </member>
        <member name="M:slskd.Messaging.RoomTracker.#ctor(System.Int32)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Messaging.RoomTracker"/> class.
            </summary>
            <param name="messageLimit"></param>
        </member>
        <member name="P:slskd.Messaging.RoomTracker.Rooms">
            <summary>
                Tracked rooms.
            </summary>
        </member>
        <member name="M:slskd.Messaging.RoomTracker.AddOrUpdateMessage(System.String,slskd.Messaging.RoomMessage)">
            <summary>
                Adds a room and appends the specified <paramref name="message"/>, or just appends the message if the room exists.
            </summary>
            <param name="roomName"></param>
            <param name="message"></param>
        </member>
        <member name="M:slskd.Messaging.RoomTracker.TryAdd(System.String,slskd.Messaging.Room)">
            <summary>
                Adds the specified room to the tracker.
            </summary>
            <param name="roomName"></param>
            <param name="room"></param>
        </member>
        <member name="M:slskd.Messaging.RoomTracker.TryAddUser(System.String,Soulseek.UserData)">
            <summary>
                Adds the specified <paramref name="userData"/> to the specified room.
            </summary>
            <param name="roomName"></param>
            <param name="userData"></param>
        </member>
        <member name="M:slskd.Messaging.RoomTracker.TryGet(System.String,slskd.Messaging.Room@)">
            <summary>
                Removes a tracked room.
            </summary>
            <param name="roomName"></param>
            <param name="room"></param>
            <returns></returns>
        </member>
        <member name="M:slskd.Messaging.RoomTracker.TryRemove(System.String)">
            <summary>
                Returns the list of messages for the specified <paramref name="roomName"/>, if it is tracked.
            </summary>
            <param name="roomName"></param>
        </member>
        <member name="M:slskd.Messaging.RoomTracker.TryRemoveUser(System.String,System.String)">
            <summary>
                Removes the specified <paramref name="username"/> from the specified room.
            </summary>
            <param name="roomName"></param>
            <param name="username"></param>
        </member>
        <member name="T:slskd.Messaging.PrivateMessage">
            <summary>
                A private message.
            </summary>
        </member>
        <member name="P:slskd.Messaging.PrivateMessage.Timestamp">
            <summary>
                The UTC timestamp of the message.
            </summary>
        </member>
        <member name="P:slskd.Messaging.PrivateMessage.Id">
            <summary>
                The unique message id, used to acknowledge receipt.
            </summary>
        </member>
        <member name="P:slskd.Messaging.PrivateMessage.Username">
            <summary>
                The username of the remote user.
            </summary>
        </member>
        <member name="P:slskd.Messaging.PrivateMessage.Direction">
            <summary>
                Gets or sets the message direction.
            </summary>
        </member>
        <member name="P:slskd.Messaging.PrivateMessage.Message">
            <summary>
                The message.
            </summary>
        </member>
        <member name="P:slskd.Messaging.PrivateMessage.IsAcknowledged">
            <summary>
                A value indicating whether the message has been acknowledged.
            </summary>
        </member>
        <member name="P:slskd.Messaging.Room.Name">
            <summary>
                The room name.
            </summary>
        </member>
        <member name="P:slskd.Messaging.Room.IsPrivate">
            <summary>
                A value indicating whether the room is private.
            </summary>
        </member>
        <member name="P:slskd.Messaging.Room.OperatorCount">
            <summary>
                The number of operators in the room, if private.
            </summary>
        </member>
        <member name="P:slskd.Messaging.Room.Operators">
            <summary>
                The operators in the room, if private.
            </summary>
        </member>
        <member name="P:slskd.Messaging.Room.Owner">
            <summary>
                The owner of the room, if private.
            </summary>
        </member>
        <member name="P:slskd.Messaging.Room.Users">
            <summary>
                The list of users in the room.
            </summary>
        </member>
        <member name="P:slskd.Messaging.Room.Messages">
            <summary>
                The list of messages.
            </summary>
        </member>
        <member name="T:slskd.Messaging.RoomMessage">
            <summary>
                A message sent to a room.
            </summary>
        </member>
        <member name="P:slskd.Messaging.RoomMessage.Timestamp">
            <summary>
                The timestamp of the message.
            </summary>
        </member>
        <member name="P:slskd.Messaging.RoomMessage.Username">
            <summary>
                The username of the user who sent the message.
            </summary>
        </member>
        <member name="P:slskd.Messaging.RoomMessage.Message">
            <summary>
                The message.
            </summary>
        </member>
        <member name="P:slskd.Messaging.RoomMessage.RoomName">
            <summary>
                The room to which the message pertains.
            </summary>
        </member>
        <member name="P:slskd.Messaging.RoomMessage.Direction">
            <summary>
                Gets or sets the message direction.
            </summary>
        </member>
        <member name="T:slskd.Program">
            <summary>
                Bootstraps configuration and handles primitive command-line instructions.
            </summary>
        </member>
        <member name="F:slskd.Program.AppName">
            <summary>
                The name of the application.
            </summary>
        </member>
        <member name="F:slskd.Program.LocalHostName">
            <summary>
                The name of the local share host.
            </summary>
        </member>
        <member name="F:slskd.Program.IssuesUrl">
            <summary>
                The url to the issues/support site.
            </summary>
        </member>
        <member name="F:slskd.Program.EnvironmentVariablePrefix">
            <summary>
                The global prefix for environment variables.
            </summary>
        </member>
        <member name="F:slskd.Program.XmlDocumentationFile">
            <summary>
                The default XML documentation filename.
            </summary>
        </member>
        <member name="F:slskd.Program.DefaultAppDirectory">
            <summary>
                The default application data directory.
            </summary>
        </member>
        <member name="F:slskd.Program.InvocationId">
            <summary>
                Gets the unique Id of this application invocation.
            </summary>
        </member>
        <member name="F:slskd.Program.ProcessId">
            <summary>
                Gets the Id of the current application process.
            </summary>
        </member>
        <member name="F:slskd.Program.AssemblyVersion">
            <remarks>
                Inaccurate when running locally.
            </remarks>
        </member>
        <member name="F:slskd.Program.InformationalVersion">
            <remarks>
                Inaccurate when running locally.
            </remarks>
        </member>
        <member name="E:slskd.Program.LogEmitted">
            <summary>
                Occurs when a new log event is emitted.
            </summary>
        </member>
        <member name="P:slskd.Program.SemanticVersion">
            <summary>
                Gets the semantic application version.
            </summary>
        </member>
        <member name="P:slskd.Program.FullVersion">
            <summary>
                Gets the full application version, including both assembly and informational versions.
            </summary>
        </member>
        <member name="P:slskd.Program.IsCanary">
            <summary>
                Gets a value indicating whether the current version is a Canary build.
            </summary>
        </member>
        <member name="P:slskd.Program.IsDevelopment">
            <summary>
                Gets a value indicating whether the current version is a Development build.
            </summary>
        </member>
        <member name="P:slskd.Program.IsRelayAgent">
            <summary>
                Gets a value indicating whether the application is being run in Relay Agent mode.
            </summary>
        </member>
        <member name="P:slskd.Program.Flags">
            <summary>
                Gets the application flags.
            </summary>
        </member>
        <member name="P:slskd.Program.AppDirectory">
            <summary>
                Gets the path where application data is saved.
            </summary>
        </member>
        <member name="P:slskd.Program.ConfigurationFile">
            <summary>
                Gets the fully qualified path to the application configuration file.
            </summary>
        </member>
        <member name="P:slskd.Program.DataDirectory">
            <summary>
                Gets the path where persistent data is saved.
            </summary>
        </member>
        <member name="P:slskd.Program.DataBackupDirectory">
            <summary>
                Gets the path where backups of persistent data saved.
            </summary>
        </member>
        <member name="P:slskd.Program.DefaultConfigurationFile">
            <summary>
                Gets the default fully qualified path to the configuration file.
            </summary>
        </member>
        <member name="P:slskd.Program.DefaultDownloadsDirectory">
            <summary>
                Gets the default downloads directory.
            </summary>
        </member>
        <member name="P:slskd.Program.DefaultIncompleteDirectory">
            <summary>
                Gets the default incomplete download directory.
            </summary>
        </member>
        <member name="P:slskd.Program.LogDirectory">
            <summary>
                Gets the path where application logs are saved.
            </summary>
        </member>
        <member name="P:slskd.Program.ScriptDirectory">
            <summary>
                Gets the path where user-defined scripts are stored.
            </summary>
        </member>
        <member name="P:slskd.Program.LogBuffer">
            <summary>
                Gets a buffer containing the last few log events.
            </summary>
        </member>
        <member name="P:slskd.Program.MasterCancellationTokenSource">
            <summary>
                Gets the master cancellation token source for the program.
            </summary>
            <remarks>
                The token from this source should be used (or linked) to any long-running asynchronous task, so that when the application
                begins to shut down these tasks also shut down in a timely manner. Actions that control the lifecycle of the program
                (POSIX signals, a restart from the API, etc) should cancel this source.
            </remarks>
        </member>
        <member name="M:slskd.Program.Exit(System.Int32)">
            <summary>
                Panic.
            </summary>
            <param name="code">An optional exit code.</param>
        </member>
        <member name="M:slskd.Program.Main(System.String[])">
            <summary>
                Entrypoint.
            </summary>
            <param name="args">Command line arguments.</param>
        </member>
        <member name="T:slskd.Relay.RelayController">
            <summary>
                Relay.
            </summary>
        </member>
        <member name="M:slskd.Relay.RelayController.#ctor(slskd.Relay.IRelayService,Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options},slskd.OptionsAtStartup)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Relay.RelayController"/> class.
            </summary>
            <param name="relayService"></param>
            <param name="optionsMonitor"></param>
            <param name="optionsAtStartup"></param>
        </member>
        <member name="M:slskd.Relay.RelayController.Connect">
            <summary>
                Connects to the configured controller.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Relay.RelayController.Disconnect">
            <summary>
                Disconnects from the connected controller.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Relay.RelayController.DownloadFile(System.String)">
            <summary>
                Downloads a file from the connected controller.
            </summary>
            <param name="token">The unique identifier for the request.</param>
            <returns></returns>
        </member>
        <member name="M:slskd.Relay.RelayController.UploadFile(System.String)">
            <summary>
                Uploads a file to the connected controller.
            </summary>
            <param name="token">The unique identifier for the request.</param>
            <returns></returns>
        </member>
        <member name="M:slskd.Relay.RelayController.UploadShares(System.String)">
            <summary>
                Uploads share information to the connected controller.
            </summary>
            <param name="token">The unique identifier for the request.</param>
            <returns></returns>
        </member>
        <member name="T:slskd.Relay.IRelayHub">
            <summary>
                Methods for the <see cref="T:slskd.Relay.RelayHub"/>.
            </summary>
        </member>
        <member name="M:slskd.Relay.IRelayHub.Challenge(System.String)">
            <summary>
                Sends an authentication challenge token to the newly connected agent.
            </summary>
            <param name="token">The token.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayHub.RequestFileInfo(System.String,System.Guid)">
            <summary>
                Requests information about the specified <paramref name="filename"/> from the agent.
            </summary>
            <param name="filename">The name of the file.</param>
            <param name="id">The unique identifier for the request.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayHub.RequestFileUpload(System.String,System.Int64,System.Guid)">
            <summary>
                Requests the specified <paramref name="filename"/> from the agent.
            </summary>
            <param name="filename">The name of the file.</param>
            <param name="startOffset">The starting offset for the transfer.</param>
            <param name="id">The unique identifier for the request.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayHub.NotifyFileDownloadCompleted(System.String,System.Guid)">
            <summary>
                Notifies the agent that the download of the specified <paramref name="filename"/> is complete and that the file is ready for downloading.
            </summary>
            <param name="filename">The name of the newly downloaded file.</param>
            <param name="id">The unique identifier for the request.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="T:slskd.Relay.RelayHub">
            <summary>
                The relay SignalR hub.
            </summary>
        </member>
        <member name="M:slskd.Relay.RelayHub.#ctor(slskd.Relay.IRelayService,Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options},slskd.OptionsAtStartup)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Relay.RelayHub"/> class.
            </summary>
            <param name="relayService"></param>
            <param name="optionsMonitor"></param>
            <param name="optionsAtStartup"></param>
        </member>
        <member name="M:slskd.Relay.RelayHub.OnConnectedAsync">
            <summary>
                Executed when a new connection is established.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Relay.RelayHub.OnDisconnectedAsync(System.Exception)">
            <summary>
                Executed when a connection is disconnected.
            </summary>
            <param name="exception">The Exception that caused the disconnect.</param>
            <returns></returns>
        </member>
        <member name="M:slskd.Relay.RelayHub.Login(System.String,System.String)">
            <summary>
                Executed by the agent after receipt of an authentication challenge token, shortly after the connection is established.
            </summary>
            <param name="agent">The agent's name.</param>
            <param name="challengeResponse">The response to the challenge token.</param>
            <exception cref="T:System.UnauthorizedAccessException">Thrown when the challenge response is invalid.</exception>
        </member>
        <member name="M:slskd.Relay.RelayHub.BeginShareUpload">
            <summary>
                Executed by the agent to initiate the share upload workflow by generating and retrieving a request token.
            </summary>
            <returns>The generated token.</returns>
            <exception cref="T:System.UnauthorizedAccessException">Thrown when the agent is not fully authenticated.</exception>
        </member>
        <member name="M:slskd.Relay.RelayHub.NotifyFileUploadFailed(System.Guid,System.Exception)">
            <summary>
                Executed by the agent to notify the controller that the agent was unable to upload the file requested by a call to <see cref="M:slskd.Relay.IRelayHub.RequestFileUpload(System.String,System.Int64,System.Guid)"/>.
            </summary>
            <param name="id">The unique identifier of the request.</param>
            <param name="exception">The Exception that caused the failure.</param>
            <exception cref="T:System.UnauthorizedAccessException">Thrown when the agent is not fully authenticated.</exception>
        </member>
        <member name="M:slskd.Relay.RelayHub.ReturnFileInfo(System.Guid,System.Boolean,System.Int64)">
            <summary>
                Executed by the agent to return the response to a call to <see cref="M:slskd.Relay.IRelayHub.RequestFileInfo(System.String,System.Guid)"/>.
            </summary>
            <param name="id">The unique identifier for the request.</param>
            <param name="exists">A value indicating whether the requested file exists on the agent's filesystem.</param>
            <param name="length">The length of the file, or 0 if the file does not exist.</param>
            <exception cref="T:System.UnauthorizedAccessException">Thrown when the agent is not fully authenticated.</exception>
        </member>
        <member name="T:slskd.Relay.IRelayClient">
            <summary>
                Relay client (agent).
            </summary>
        </member>
        <member name="P:slskd.Relay.IRelayClient.StateMonitor">
            <summary>
                Gets the client state.
            </summary>
        </member>
        <member name="M:slskd.Relay.IRelayClient.StartAsync(System.Threading.CancellationToken)">
            <summary>
                Starts the client and connects to the controller.
            </summary>
            <param name="cancellationToken">The token to monitor for cancellation requests.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayClient.StopAsync(System.Threading.CancellationToken)">
            <summary>
                Stops the client and disconnects from the controller.
            </summary>
            <param name="cancellationToken">The token to monitor for cancellation requests.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayClient.SynchronizeAsync(System.Threading.CancellationToken)">
            <summary>
                Synchronizes state with the controller.
            </summary>
            <param name="cancellationToken">The token to monitor for cancellation requests.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="T:slskd.Relay.NullRelayClient">
            <summary>
                A non-operable Relay client.
            </summary>
        </member>
        <member name="P:slskd.Relay.NullRelayClient.StateMonitor">
            <summary>
                Gets the client state.
            </summary>
        </member>
        <member name="M:slskd.Relay.NullRelayClient.Dispose">
            <summary>
                Disposes this instance.
            </summary>
        </member>
        <member name="M:slskd.Relay.NullRelayClient.StartAsync(System.Threading.CancellationToken)">
            <summary>
                Starts the client and connects to the controller.
            </summary>
            <param name="cancellationToken">The token to monitor for cancellation requests.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.NullRelayClient.StopAsync(System.Threading.CancellationToken)">
            <summary>
                Stops the client and disconnects from the controller.
            </summary>
            <param name="cancellationToken">The token to monitor for cancellation requests.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.NullRelayClient.SynchronizeAsync(System.Threading.CancellationToken)">
            <summary>
                Synchronizes state with the controller.
            </summary>
            <param name="cancellationToken">The token to monitor for cancellation requests.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.NullRelayClient.Dispose(System.Boolean)">
            <summary>
                Disposes this instance.
            </summary>
            <param name="disposing">Disposing.</param>
        </member>
        <member name="T:slskd.Relay.RelayClient">
            <summary>
                Relay client (agent).
            </summary>
        </member>
        <member name="M:slskd.Relay.RelayClient.#ctor(slskd.Shares.IShareService,slskd.Files.FileService,Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options},System.Net.Http.IHttpClientFactory)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Relay.RelayClient"/> class.
            </summary>
            <param name="shareService"></param>
            <param name="fileService"></param>
            <param name="optionsMonitor"></param>
            <param name="httpClientFactory"></param>
        </member>
        <member name="P:slskd.Relay.RelayClient.StateMonitor">
            <summary>
                Gets the client state.
            </summary>
        </member>
        <member name="M:slskd.Relay.RelayClient.Dispose">
            <summary>
                Disposes this instance.
            </summary>
        </member>
        <member name="M:slskd.Relay.RelayClient.StartAsync(System.Threading.CancellationToken)">
            <summary>
                Starts the client and connects to the controller.
            </summary>
            <param name="cancellationToken">The token to monitor for cancellation requests.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.RelayClient.StopAsync(System.Threading.CancellationToken)">
            <summary>
                Stops the client and disconnects from the controller.
            </summary>
            <param name="cancellationToken">The token to monitor for cancellation requests.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.RelayClient.SynchronizeAsync(System.Threading.CancellationToken)">
            <summary>
                Synchronizes state with the controller.
            </summary>
            <param name="cancellationToken">The token to monitor for cancellation requests.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.RelayClient.Dispose(System.Boolean)">
            <summary>
                Disposes this instance.
            </summary>
            <param name="disposing">Disposing.</param>
        </member>
        <member name="T:slskd.Relay.IRelayService">
            <summary>
                Handles relay (controller/agent) interactions.
            </summary>
        </member>
        <member name="P:slskd.Relay.IRelayService.Client">
            <summary>
                Gets the relay client (agent).
            </summary>
        </member>
        <member name="P:slskd.Relay.IRelayService.RegisteredAgents">
            <summary>
                Gets the collection of registered Agents.
            </summary>
        </member>
        <member name="P:slskd.Relay.IRelayService.StateMonitor">
            <summary>
                Gets the state monitor for the service.
            </summary>
        </member>
        <member name="M:slskd.Relay.IRelayService.GenerateAuthenticationChallengeToken(System.String)">
            <summary>
                Generates a random authentication challenge token for the specified <paramref name="connectionId"/>.
            </summary>
            <remarks>The token is cached internally, and is only valid while it remains in the cache.</remarks>
            <param name="connectionId">The ID of the agent connection.</param>
            <returns>The generated token.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayService.GenerateShareUploadToken(System.String)">
            <summary>
                Retrieves a new share upload token for the specified <paramref name="agentName"/>.
            </summary>
            <remarks>
                <para>This is the first step in a multi-step workflow. The entire sequence is:</para>
                <list type="number">
                    <item>
                        A remote agent makes a request to the SignalR hub to retrieve a share upload token, which in turn calls
                        <see cref="M:slskd.Relay.IRelayService.GenerateShareUploadToken(System.String)"/>. The token is generated and cached, and is only valid while it is
                        in the cache.
                    </item>
                    <item>
                        The remote agent makes an HTTP POST request containing a multipart upload including a backup of its shared
                        database and a serialized list of locally configured shares, and the controller invokes <see cref="M:slskd.Relay.IRelayService.HandleShareUploadAsync(System.String,System.Guid,System.Collections.Generic.IEnumerable{slskd.Shares.Share},System.String)"/>.
                    </item>
                </list>
            </remarks>
            <param name="agentName">The name of the agent.</param>
            <returns>The generated token.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayService.GetFileInfoAsync(System.String,System.String,System.Int32)">
            <summary>
                Retrieves information about the specified <paramref name="filename"/> from the specified <paramref name="agentName"/>.
            </summary>
            <remarks>
                <para>This is the first step in a multi-step workflow. The entire sequence is:</para>
                <list type="number">
                    <item>
                        Upload service calls and awaits <see cref="M:slskd.Relay.IRelayService.GetFileInfoAsync(System.String,System.String,System.Int32)"/>, which requests the file info from the
                        remote agent, and waits for the response before returning it to the caller.
                    </item>
                    <item>
                        The remote agent sends the response via the SignalR hub, and the hub invokes
                        <see cref="M:slskd.Relay.IRelayService.HandleFileInfoResponse(System.String,System.Guid,System.ValueTuple{System.Boolean,System.Int64})"/>. The response is passed back to <see cref="M:slskd.Relay.IRelayService.GetFileInfoAsync(System.String,System.String,System.Int32)"/> and
                        returned to the caller.
                    </item>
                </list>
            </remarks>
            <param name="agentName">The agent from which to retrieve the file information.</param>
            <param name="filename">The file for which to retrieve information.</param>
            <param name="timeout">An optional timeout value.</param>
            <returns>A value indicating whether the file exists, and the length in bytes.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)">
            <summary>
                Retrieves a stream of the specified <paramref name="filename"/> from the specified <paramref name="agentName"/>.
            </summary>
            <remarks>
                <para>
                    This is the first step in a multi-step workflow that enables proxying of file uploads through agents. The
                    entire sequence is:
                </para>
                <list type="number">
                    <item>
                        Upload service calls and awaits <see cref="M:slskd.Relay.IRelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/>, which requests the file from the remote
                        agent, and waits for the stream to be returned before returning it to the caller.
                    </item>
                    <item>
                        <para>
                            The remote agent makes an HTTP POST request containing a multipart upload including the file, and the
                            API controller invokes and awaits <see cref="M:slskd.Relay.IRelayService.HandleFileStreamResponseAsync(System.String,System.Guid,System.IO.Stream)"/>. The stream is passed from
                            this method back to the awaited <see cref="M:slskd.Relay.IRelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/>, and the Upload service passes the
                            stream to Soulseek.NET, streaming the data from the still-open HTTP request through to the remote
                            Soulseek user.
                        </para>
                        <para>
                            If the remote agent can't find or open the requested file, it invokes
                            <see cref="M:slskd.Relay.IRelayService.NotifyFileStreamException(System.Guid,System.Exception)"/> through the open SignalR connection, and
                            <see cref="M:slskd.Relay.IRelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/> throws with the given exception. If the remote agent fails to respond
                            within the timeout period, <see cref="M:slskd.Relay.IRelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/> throws a <see cref="T:System.TimeoutException"/>.
                        </para>
                    </item>
                    <item>
                        When the Upload is complete (successfully or otherwise), the Upload service invokes
                        <see cref="M:slskd.Relay.IRelayService.TryCloseFileStream(System.String,System.Guid,System.Exception)"/>, passing an optional <see cref="T:System.Exception"/> if the transfer was not
                        successful. This call signals the waiting <see cref="M:slskd.Relay.IRelayService.HandleFileStreamResponseAsync(System.String,System.Guid,System.IO.Stream)"/> to complete, passing
                        control back to the API controller and completing the HTTP POST request from the agent.
                    </item>
                </list>
            </remarks>
            <param name="agentName">The agent from which to retrieve the file.</param>
            <param name="filename">The file to retrieve.</param>
            <param name="startOffset">The starting offset for the transfer.</param>
            <param name="id">A unique ID for the stream.</param>
            <param name="timeout">An optional timeout value.</param>
            <param name="cancellationToken">An optional token to monitor for cancellation requests.</param>
            <returns>The operation context, including a stream containing the requested file.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayService.HandleFileInfoResponse(System.String,System.Guid,System.ValueTuple{System.Boolean,System.Int64})">
            <summary>
                Handles the client response for a <see cref="M:slskd.Relay.IRelayService.GetFileInfoAsync(System.String,System.String,System.Int32)"/> request.
            </summary>
            <param name="agentName">The name of the agent.</param>
            <param name="id">The ID of the request.</param>
            <param name="response">The client response to the request.</param>
        </member>
        <member name="M:slskd.Relay.IRelayService.HandleFileStreamResponseAsync(System.String,System.Guid,System.IO.Stream)">
            <summary>
                Handles the client response for a <see cref="M:slskd.Relay.IRelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/> request, returning when the corresponding file
                upload is complete.
            </summary>
            <param name="agentName">The name of the agent.</param>
            <param name="id">The ID of the request.</param>
            <param name="response">The client response to the request.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayService.HandleShareUploadAsync(System.String,System.Guid,System.Collections.Generic.IEnumerable{slskd.Shares.Share},System.String)">
            <summary>
                Handles incoming share uploads.
            </summary>
            <param name="agentName">The name of the agent.</param>
            <param name="id">The ID obtained by the caller prior to uploading.</param>
            <param name="shares">The list of shares provided.</param>
            <param name="filename">The filename of the temporary file containing the upload.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayService.NotifyFileDownloadCompleteAsync(System.String)">
            <summary>
                Notifies connected agents that a file download has completed.
            </summary>
            <param name="filename">The filename of the completed file, relative to the downloads directory.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayService.NotifyFileStreamException(System.Guid,System.Exception)">
            <summary>
                Notifies the caller of <see cref="M:slskd.Relay.IRelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/> of a failure to obtain a file stream from the requested agent.
            </summary>
            <param name="id">The unique ID for the stream.</param>
            <param name="exception">The remote exception that caused the failure.</param>
        </member>
        <member name="M:slskd.Relay.IRelayService.RegisterAgent(System.String,slskd.Relay.Agent)">
            <summary>
                Registers the specified <paramref name="agent"/> with the specified <paramref name="connectionId"/>.
            </summary>
            <param name="connectionId">The ID of the connection.</param>
            <param name="agent">The agent.</param>
        </member>
        <member name="M:slskd.Relay.IRelayService.TryCloseFileStream(System.String,System.Guid,System.Exception)">
            <summary>
                Safely attempts to close a stream obtained with <see cref="M:slskd.Relay.IRelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/>.
            </summary>
            <param name="agentName">The name of the agent.</param>
            <param name="id">The unique ID for the stream.</param>
            <param name="exception">If the transfer associated with the stream failed, the exception that caused the failure.</param>
        </member>
        <member name="M:slskd.Relay.IRelayService.TryDeregisterAgent(System.String,System.ValueTuple{System.String,slskd.Relay.Agent}@)">
            <summary>
                Attempts to remove the registration for the specified <paramref name="connectionId"/>.
            </summary>
            <param name="connectionId">The connection ID associated with the registration.</param>
            <param name="record">The registration record, if removed.</param>
            <returns>A value indicating whether a registration was removed.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayService.TryGetAgentRegistration(System.String,System.ValueTuple{System.String,slskd.Relay.Agent}@)">
            <summary>
                Attempts to retrieve the registration for the specified <paramref name="connectionId"/>.
            </summary>
            <param name="connectionId">The connection ID associated with the registration.</param>
            <param name="record">The registration record, if found.</param>
            <returns>A value indicating whether the registration exists.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayService.TryValidateAuthenticationCredential(System.String,System.String,System.String)">
            <summary>
                Validates an authentication challenge response.
            </summary>
            <param name="connectionId">The ID of the agent connection.</param>
            <param name="agentName">The agent name.</param>
            <param name="credential">The response credential.</param>
            <returns>A value indicating whether the response is valid.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayService.TryValidateFileDownloadCredential(System.Guid,System.String,System.String,System.String)">
            <summary>
                Attempts to validate the file download response credential associated with the specified <paramref name="token"/>.
            </summary>
            <param name="token">The token.</param>
            <param name="agentName">The name of the responding agent.</param>
            <param name="filename">The name of the file being downloaded.</param>
            <param name="credential">The response credential.</param>
            <returns>A value indicating whether the credential is valid.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayService.TryValidateFileStreamResponseCredential(System.Guid,System.String,System.String,System.String)">
            <summary>
                Attempts to validate the file stream response credential associated with the specified <paramref name="token"/>.
            </summary>
            <param name="token">The token.</param>
            <param name="agentName">The name of the responding agent.</param>
            <param name="filename">The name of the file being uploaded.</param>
            <param name="credential">The response credential.</param>
            <returns>A value indicating whether the credential is valid.</returns>
        </member>
        <member name="M:slskd.Relay.IRelayService.TryValidateShareUploadCredential(System.Guid,System.String,System.String)">
            <summary>
                Attempts to validate the share upload response credential associated with the specified <paramref name="token"/>.
            </summary>
            <param name="token">The token.</param>
            <param name="agentName">The name of the responding agent.</param>
            <param name="credential">The response credential.</param>
            <returns>A value indicating whether the credential is valid.</returns>
        </member>
        <member name="T:slskd.Relay.RelayService">
            <summary>
                Handles relay (controller/agent) interactions.
            </summary>
        </member>
        <member name="M:slskd.Relay.RelayService.#ctor(slskd.IWaiter,slskd.Files.FileService,slskd.Shares.IShareService,slskd.Shares.IShareRepositoryFactory,Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options},Microsoft.AspNetCore.SignalR.IHubContext{slskd.Relay.RelayHub,slskd.Relay.IRelayHub},System.Net.Http.IHttpClientFactory,slskd.Relay.IRelayClient)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Relay.RelayService"/> class.
            </summary>
            <param name="waiter"></param>
            <param name="fileService"></param>
            <param name="shareService"></param>
            <param name="shareRepositoryFactory"></param>
            <param name="optionsMonitor"></param>
            <param name="relayHub"></param>
            <param name="httpClientFactory"></param>
            <param name="relayClient"></param>
        </member>
        <member name="P:slskd.Relay.RelayService.Client">
            <summary>
                Gets the relay client (agent).
            </summary>
        </member>
        <member name="P:slskd.Relay.RelayService.RegisteredAgents">
            <summary>
                Gets the collection of registered Agents.
            </summary>
        </member>
        <member name="P:slskd.Relay.RelayService.StateMonitor">
            <summary>
                Gets the state monitor for the service.
            </summary>
        </member>
        <member name="M:slskd.Relay.RelayService.GenerateAuthenticationChallengeToken(System.String)">
            <summary>
                Generates a random authentication challenge token for the specified <paramref name="connectionId"/>.
            </summary>
            <remarks>The token is cached internally, and is only valid while it remains in the cache.</remarks>
            <param name="connectionId">The ID of the agent connection.</param>
            <returns>The generated token.</returns>
        </member>
        <member name="M:slskd.Relay.RelayService.GenerateShareUploadToken(System.String)">
            <summary>
                Retrieves a new share upload token for the specified <paramref name="agentName"/>.
            </summary>
            <remarks>The token is cached internally, and is only valid while it remains in the cache.</remarks>
            <remarks>
                <para>This is the first step in a multi-step workflow. The entire sequence is:</para>
                <list type="number">
                    <item>
                        A remote agent makes a request to the SignalR hub to retrieve a share upload token, which in turn calls
                        <see cref="M:slskd.Relay.RelayService.GenerateShareUploadToken(System.String)"/>. The token is generated and cached.
                    </item>
                    <item>
                        The remote agent makes an HTTP POST request containing a multipart upload including a backup of its shared
                        database and a serialized list of locally configured shares.
                    </item>
                    <item>
                        The HTTP controller saves the database backup to a temporary file, validates it, and then adds (or
                        updates) a share host for the agent.
                    </item>
                </list>
            </remarks>
            <param name="agentName">The name of the agent.</param>
            <returns>The generated token.</returns>
        </member>
        <member name="M:slskd.Relay.RelayService.GetFileInfoAsync(System.String,System.String,System.Int32)">
            <summary>
                Retrieves information about the specified <paramref name="filename"/> from the specified <paramref name="agentName"/>.
            </summary>
            <remarks>
                <para>This is the first step in a multi-step workflow. The entire sequence is:</para>
                <list type="number">
                    <item>
                        Upload service calls and awaits <see cref="M:slskd.Relay.RelayService.GetFileInfoAsync(System.String,System.String,System.Int32)"/>, which requests the file info from the
                        remote agent, and waits for the response before returning it to the caller.
                    </item>
                    <item>
                        The remote agent sends the response via the SignalR hub, and the hub invokes
                        <see cref="M:slskd.Relay.RelayService.HandleFileInfoResponse(System.String,System.Guid,System.ValueTuple{System.Boolean,System.Int64})"/>. The response is passed back to <see cref="M:slskd.Relay.RelayService.GetFileInfoAsync(System.String,System.String,System.Int32)"/> and
                        returned to the caller.
                    </item>
                </list>
            </remarks>
            <param name="agentName">The agent from which to retrieve the file information.</param>
            <param name="filename">The file for which to retrieve information.</param>
            <param name="timeout">An optional timeout value.</param>
            <returns>A value indicating whether the file exists, and the length in bytes.</returns>
        </member>
        <member name="M:slskd.Relay.RelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)">
            <summary>
                Retrieves a stream of the specified <paramref name="filename"/> from the specified <paramref name="agentName"/>.
            </summary>
            <remarks>
                <para>
                    This is the first step in a multi-step workflow that enables proxying of file uploads through agents. The
                    entire sequence is:
                </para>
                <list type="number">
                    <item>
                        Upload service calls and awaits <see cref="M:slskd.Relay.RelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/>, which requests the file from the remote
                        agent, and waits for the stream to be returned before returning it to the caller.
                    </item>
                    <item>
                        <para>
                            The remote agent makes an HTTP POST request containing a multipart upload including the file, and the
                            API controller invokes and awaits <see cref="M:slskd.Relay.RelayService.HandleFileStreamResponseAsync(System.String,System.Guid,System.IO.Stream)"/>. The stream is passed from
                            this method back to the awaited <see cref="M:slskd.Relay.RelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/>, and the Upload service passes the
                            stream to Soulseek.NET, streaming the data from the still-open HTTP request through to the remote
                            Soulseek user.
                        </para>
                        <para>
                            If the remote agent can't find or open the requested file, it invokes
                            <see cref="M:slskd.Relay.RelayService.NotifyFileStreamException(System.Guid,System.Exception)"/> through the open SignalR connection, and
                            <see cref="M:slskd.Relay.RelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/> throws with the given exception. If the remote agent fails to respond
                            within the timeout period, <see cref="M:slskd.Relay.RelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/> throws a <see cref="T:System.TimeoutException"/>.
                        </para>
                    </item>
                    <item>
                        When the Upload is complete (successfully or otherwise), the Upload service invokes
                        <see cref="M:slskd.Relay.RelayService.TryCloseFileStream(System.String,System.Guid,System.Exception)"/>, passing an optional <see cref="T:System.Exception"/> if the transfer was not
                        successful. This call signals the waiting <see cref="M:slskd.Relay.RelayService.HandleFileStreamResponseAsync(System.String,System.Guid,System.IO.Stream)"/> to complete, passing
                        control back to the API controller and completing the HTTP POST request from the agent.
                    </item>
                </list>
            </remarks>
            <param name="agentName">The agent from which to retrieve the file.</param>
            <param name="filename">The file to retrieve.</param>
            <param name="startOffset">The starting offset for the transfer.</param>
            <param name="id">A unique ID for the stream.</param>
            <param name="timeout">An optional timeout value.</param>
            <param name="cancellationToken">An optional token to monitor for cancellation requests.</param>
            <returns>The operation context, including a stream containing the requested file.</returns>
        </member>
        <member name="M:slskd.Relay.RelayService.HandleFileInfoResponse(System.String,System.Guid,System.ValueTuple{System.Boolean,System.Int64})">
            <summary>
                Handles the client response for a <see cref="M:slskd.Relay.RelayService.GetFileInfoAsync(System.String,System.String,System.Int32)"/> request.
            </summary>
            <param name="agentName">The name of the agent.</param>
            <param name="id">The ID of the request.</param>
            <param name="response">The client response to the request.</param>
        </member>
        <member name="M:slskd.Relay.RelayService.HandleFileStreamResponseAsync(System.String,System.Guid,System.IO.Stream)">
            <summary>
                Handles the client response for a <see cref="M:slskd.Relay.RelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/> request, returning when the corresponding file
                upload is complete.
            </summary>
            <remarks>
                Assumes <see cref="M:slskd.Relay.RelayService.TryValidateFileStreamResponseCredential(System.Guid,System.String,System.String,System.String)"/> has previously been used to ensure the Id and agent match.
            </remarks>
            <param name="agentName">The name of the agent.</param>
            <param name="id">The ID of the request.</param>
            <param name="response">The client response to the request.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.RelayService.HandleShareUploadAsync(System.String,System.Guid,System.Collections.Generic.IEnumerable{slskd.Shares.Share},System.String)">
            <summary>
                Handles incoming share uploads.
            </summary>
            <param name="agentName">The name of the agent.</param>
            <param name="id">The ID obtained by the caller prior to uploading.</param>
            <param name="shares">The list of shares provided.</param>
            <param name="filename">The filename of the temporary file containing the upload.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.RelayService.NotifyFileDownloadCompleteAsync(System.String)">
            <summary>
                Notifies connected agents that a file download has completed.
            </summary>
            <param name="filename">The filename of the completed file, relative to the downloads directory.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Relay.RelayService.NotifyFileStreamException(System.Guid,System.Exception)">
            <summary>
                Notifies the caller of <see cref="M:slskd.Relay.RelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/> of a failure to obtain a file stream from the requested agent.
            </summary>
            <param name="id">The unique ID for the stream.</param>
            <param name="exception">The remote exception that caused the failure.</param>
        </member>
        <member name="M:slskd.Relay.RelayService.RegisterAgent(System.String,slskd.Relay.Agent)">
            <summary>
                Registers the specified <paramref name="agent"/> name with the specified <paramref name="connectionId"/>.
            </summary>
            <param name="connectionId">The ID of the connection.</param>
            <param name="agent">The agent.</param>
        </member>
        <member name="M:slskd.Relay.RelayService.TryCloseFileStream(System.String,System.Guid,System.Exception)">
            <summary>
                Safely attempts to close a stream obtained with <see cref="M:slskd.Relay.RelayService.GetFileStreamAsync(System.String,System.String,System.Int64,System.Guid,System.Int32,System.Threading.CancellationToken)"/>.
            </summary>
            <param name="agentName">The name of the agent.</param>
            <param name="id">The unique ID for the stream.</param>
            <param name="exception">If the transfer associated with the stream failed, the exception that caused the failure.</param>
        </member>
        <member name="M:slskd.Relay.RelayService.TryDeregisterAgent(System.String,System.ValueTuple{System.String,slskd.Relay.Agent}@)">
            <summary>
                Attempts to remove the registration for the specified <paramref name="connectionId"/>.
            </summary>
            <param name="connectionId">The ID of the connection.</param>
            <param name="record">The registration record, if one was removed.</param>
            <returns>A value indicating whether a registration was removed.</returns>
        </member>
        <member name="M:slskd.Relay.RelayService.TryGetAgentRegistration(System.String,System.ValueTuple{System.String,slskd.Relay.Agent}@)">
            <summary>
                Attempts to retrieve the registration for the specified <paramref name="connectionId"/>.
            </summary>
            <param name="connectionId">The ID of the agent connection.</param>
            <param name="record">The registration record, if one exists.</param>
            <returns>A value indicating whether the registration exists.</returns>
        </member>
        <member name="M:slskd.Relay.RelayService.TryValidateAuthenticationCredential(System.String,System.String,System.String)">
            <summary>
                Validates an authentication challenge response.
            </summary>
            <param name="connectionId">The ID of the agent connection.</param>
            <param name="agentName">The agent name.</param>
            <param name="credential">The response credential.</param>
            <returns>A value indicating whether the response is valid.</returns>
        </member>
        <member name="M:slskd.Relay.RelayService.TryValidateFileDownloadCredential(System.Guid,System.String,System.String,System.String)">
            <summary>
                Attempts to validate the file download response credential associated with the specified <paramref name="token"/>.
            </summary>
            <param name="token">The token.</param>
            <param name="agentName">The name of the responding agent.</param>
            <param name="filename">The name of the file being downloaded.</param>
            <param name="credential">The response credential.</param>
            <returns>A value indicating whether the credential is valid.</returns>
        </member>
        <member name="M:slskd.Relay.RelayService.TryValidateFileStreamResponseCredential(System.Guid,System.String,System.String,System.String)">
            <summary>
                Attempts to validate the file stream response credential associated with the specified <paramref name="token"/>.
            </summary>
            <param name="token">The token.</param>
            <param name="agentName">The name of the responding agent.</param>
            <param name="filename">The name of the file being uploaded.</param>
            <param name="credential">The response credential.</param>
            <returns>A value indicating whether the credential is valid.</returns>
        </member>
        <member name="M:slskd.Relay.RelayService.TryValidateShareUploadCredential(System.Guid,System.String,System.String)">
            <summary>
                Attempts to validate the share upload response credential associated with the specified <paramref name="token"/>.
            </summary>
            <param name="token">The token.</param>
            <param name="agentName">The name of the responding agent.</param>
            <param name="credential">The response credential.</param>
            <returns>A value indicating whether the credential is valid.</returns>
        </member>
        <member name="T:slskd.Relay.Agent">
            <summary>
                Tracking information for a Relay agent.
            </summary>
        </member>
        <member name="P:slskd.Relay.Agent.Name">
            <summary>
                The name of the agent.
            </summary>
        </member>
        <member name="P:slskd.Relay.Agent.IPAddress">
            <summary>
                The IP address associated with the active connection.
            </summary>
        </member>
        <member name="T:slskd.Relay.RelayClientState">
            <summary>
                The state of a Relay client.
            </summary>
        </member>
        <member name="F:slskd.Relay.RelayClientState.Disconnected">
            <summary>
                Disconnected.
            </summary>
        </member>
        <member name="F:slskd.Relay.RelayClientState.Connected">
            <summary>
                Connected.
            </summary>
        </member>
        <member name="F:slskd.Relay.RelayClientState.Connecting">
            <summary>
                Connecting.
            </summary>
        </member>
        <member name="F:slskd.Relay.RelayClientState.Reconnecting">
            <summary>
                Reconnecting.
            </summary>
        </member>
        <member name="T:slskd.Relay.RelayMode">
            <summary>
                The mode the Relay is operating under.
            </summary>
        </member>
        <member name="F:slskd.Relay.RelayMode.Controller">
            <summary>
                Controller mode.
            </summary>
        </member>
        <member name="F:slskd.Relay.RelayMode.Agent">
            <summary>
                Agent mode.
            </summary>
        </member>
        <member name="F:slskd.Relay.RelayMode.Debug">
            <summary>
                Debug mode; enables operation as both a controller and agent.
            </summary>
        </member>
        <member name="T:slskd.Search.API.SearchesController">
            <summary>
                Search.
            </summary>
        </member>
        <member name="M:slskd.Search.API.SearchesController.#ctor(slskd.Search.ISearchService,Microsoft.Extensions.Options.IOptionsSnapshot{slskd.Options})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Search.API.SearchesController"/> class.
            </summary>
            <param name="searchService"></param>
            <param name="optionsSnapshot"></param>
        </member>
        <member name="M:slskd.Search.API.SearchesController.Post(slskd.Search.API.SearchRequest)">
            <summary>
                Performs a search for the specified <paramref name="request"/>.
            </summary>
            <param name="request">The search request.</param>
            <returns></returns>
            <response code="200">The search completed successfully.</response>
            <response code="400">The specified <paramref name="request"/> was malformed.</response>
            <response code="500">The search terminated abnormally.</response>
        </member>
        <member name="M:slskd.Search.API.SearchesController.GetById(System.Guid,System.Boolean)">
            <summary>
                Gets the state of the search corresponding to the specified <paramref name="id"/>.
            </summary>
            <param name="id">The unique id of the search.</param>
            <param name="includeResponses">A value indicating whether to include search responses in the response.</param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="404">A matching search was not found.</response>
        </member>
        <member name="M:slskd.Search.API.SearchesController.GetResponsesById(System.Guid)">
            <summary>
                Gets the state of the search corresponding to the specified <paramref name="id"/>.
            </summary>
            <param name="id">The unique id of the search.</param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="404">A matching search was not found.</response>
        </member>
        <member name="M:slskd.Search.API.SearchesController.GetAll">
            <summary>
                Gets the list of active and completed searches.
            </summary>
            <returns></returns>
        </member>
        <member name="M:slskd.Search.API.SearchesController.Cancel(System.Guid)">
            <summary>
                Stops the search corresponding to the specified <paramref name="id"/>.
            </summary>
            <param name="id">The unique id of the search.</param>
            <response code="200">The search was stopped.</response>
            <response code="304">The search was not in progress.</response>
            <returns></returns>
        </member>
        <member name="M:slskd.Search.API.SearchesController.Delete(System.Guid)">
            <summary>
                Deletes the search corresponding to the specified <paramref name="id"/>.
            </summary>
            <param name="id">The unique id of the search.</param>
            <response code="204">The search was deleted.</response>
            <response code="404">A search with the specified id could not be found.</response>
            <returns></returns>
        </member>
        <member name="T:slskd.Search.API.SearchRequest">
            <summary>
                A search request.
            </summary>
        </member>
        <member name="P:slskd.Search.API.SearchRequest.Id">
            <summary>
                Gets or sets the unique search identifier.
            </summary>
        </member>
        <member name="P:slskd.Search.API.SearchRequest.FileLimit">
            <summary>
                Gets or sets the maximum number of file results to accept before the search is considered complete. (Default = 10,000).
            </summary>
        </member>
        <member name="P:slskd.Search.API.SearchRequest.FilterResponses">
            <summary>
                Gets or sets a value indicating whether responses are to be filtered. (Default = true).
            </summary>
        </member>
        <member name="P:slskd.Search.API.SearchRequest.MaximumPeerQueueLength">
            <summary>
                Gets or sets the maximum queue depth a peer may have in order for a response to be processed. (Default = 1000000).
            </summary>
        </member>
        <member name="P:slskd.Search.API.SearchRequest.MinimumPeerUploadSpeed">
            <summary>
                Gets or sets the minimum upload speed a peer must have in order for a response to be processed. (Default = 0).
            </summary>
        </member>
        <member name="P:slskd.Search.API.SearchRequest.MinimumResponseFileCount">
            <summary>
                Gets or sets the minimum number of files a response must contain in order to be processed. (Default = 1).
            </summary>
        </member>
        <member name="P:slskd.Search.API.SearchRequest.ResponseLimit">
            <summary>
                Gets or sets the maximum number of search results to accept before the search is considered complete. (Default = 100).
            </summary>
        </member>
        <member name="P:slskd.Search.API.SearchRequest.SearchText">
            <summary>
                Gets or sets the search text.
            </summary>
        </member>
        <member name="P:slskd.Search.API.SearchRequest.SearchTimeout">
            <summary>
                Gets or sets the search timeout value, in seconds, used to determine when the search is complete. (Default = 15).
            </summary>
            <remarks>The timeout duration is from the time of the last response.</remarks>
        </member>
        <member name="P:slskd.Search.API.SearchRequest.Token">
            <summary>
                Gets or sets the search token.
            </summary>
        </member>
        <member name="M:slskd.Search.API.SearchRequest.ToSearchOptions(System.Func{Soulseek.SearchResponse,System.Boolean},System.Func{Soulseek.File,System.Boolean},System.Action{System.ValueTuple{Soulseek.SearchStates,Soulseek.Search}},System.Action{System.ValueTuple{Soulseek.Search,Soulseek.SearchResponse}})">
            <summary>
                Maps to a new instance of <see cref="T:Soulseek.SearchOptions"/>.
            </summary>
            <param name="responseFilter"></param>
            <param name="fileFilter"></param>
            <param name="stateChanged"></param>
            <param name="responseReceived"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Search.API.SearchHubExtensions">
            <summary>
                Extension methods for the search SignalR hub.
            </summary>
        </member>
        <member name="M:slskd.Search.API.SearchHubExtensions.BroadcastUpdateAsync(Microsoft.AspNetCore.SignalR.IHubContext{slskd.Search.API.SearchHub},slskd.Search.Search)">
            <summary>
                Broadcast an update for a search.
            </summary>
            <remarks>
                Responses are removed prior to sending.
            </remarks>
            <param name="hub">The hub.</param>
            <param name="search">The search to broadcast.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Search.API.SearchHubExtensions.BroadcastResponseAsync(Microsoft.AspNetCore.SignalR.IHubContext{slskd.Search.API.SearchHub},System.Guid,Soulseek.SearchResponse)">
            <summary>
                Broadcast a newly received search response.
            </summary>
            <param name="hub">The hub.</param>
            <param name="searchId">The ID of the search associated with the response.</param>
            <param name="response">The response to broadcast.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Search.API.SearchHubExtensions.BroadcastCreateAsync(Microsoft.AspNetCore.SignalR.IHubContext{slskd.Search.API.SearchHub},slskd.Search.Search)">
            <summary>
                Broadcast the creation of a new search.
            </summary>
            <remarks>
                Responses are removed prior to sending.
            </remarks>
            <param name="hub">The hub.</param>
            <param name="search">The search to broadcast.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Search.API.SearchHubExtensions.BroadcastDeleteAsync(Microsoft.AspNetCore.SignalR.IHubContext{slskd.Search.API.SearchHub},slskd.Search.Search)">
            <summary>
                Broadcast the deletion of a search.
            </summary>
            <remarks>
                Responses are removed prior to sending.
            </remarks>
            <param name="hub">The hub.</param>
            <param name="search">The search to broadcast.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="T:slskd.Search.API.SearchHub">
            <summary>
                The search SignalR hub.
            </summary>
        </member>
        <member name="M:slskd.Search.Extensions.WithActions(Soulseek.SearchOptions,System.Action{System.ValueTuple{Soulseek.SearchStates,Soulseek.Search}},System.Action{System.ValueTuple{Soulseek.Search,Soulseek.SearchResponse}})">
            <summary>
                Returns a copy of the specified <paramref name="options"/> with the specified actions bound, while retaining the existing actions.
            </summary>
            <param name="options"></param>
            <param name="stateChanged"></param>
            <param name="responseReceived"></param>
            <returns></returns>
        </member>
        <member name="M:slskd.Search.Extensions.WithFilters(Soulseek.SearchOptions,System.Func{Soulseek.SearchResponse,System.Boolean},System.Func{Soulseek.File,System.Boolean})">
            <summary>
                Returns a copy of the specified <paramref name="options"/> with the specified filter delegates overridden.
            </summary>
            <param name="options"></param>
            <param name="responseFilter"></param>
            <param name="fileFilter"></param>
            <returns></returns>
        </member>
        <member name="M:slskd.Search.Extensions.WithoutResponses(System.Linq.IQueryable{slskd.Search.Search})">
            <summary>
                Creates a projection over the specified <paramref name="query"/> which omits responses.
            </summary>
            <param name="query"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Search.SearchResponseCache">
            <summary>
                Caches undelivered search responses.
            </summary>
        </member>
        <member name="M:slskd.Search.SearchResponseCache.#ctor">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Search.SearchResponseCache"/> class.
            </summary>
        </member>
        <member name="M:slskd.Search.SearchResponseCache.AddOrUpdate(System.Int32,System.ValueTuple{System.String,System.Int32,System.String,Soulseek.SearchResponse})">
            <summary>
                Caches or updates a response.
            </summary>
            <param name="responseToken">The token for which the response is to be added or updated.</param>
            <param name="response">The response and context to cache.</param>
        </member>
        <member name="M:slskd.Search.SearchResponseCache.TryGet(System.Int32,System.ValueTuple{System.String,System.Int32,System.String,Soulseek.SearchResponse}@)">
            <summary>
                Attempts to fetch a cached response and context for the specified <paramref name="responseToken"/>.
            </summary>
            <param name="responseToken">The token for the cached response.</param>
            <param name="response">The cached response and context, if present.</param>
            <returns>A value indicating whether a response for the specified responseToken is cached.</returns>
        </member>
        <member name="M:slskd.Search.SearchResponseCache.TryRemove(System.Int32,System.ValueTuple{System.String,System.Int32,System.String,Soulseek.SearchResponse}@)">
            <summary>
                Attempts to remove a cached Soulseek.SearchResponse and context for the specified <paramref name="responseToken"/>.
            </summary>
            <param name="responseToken">The token for the cached response.</param>
            <param name="response">The cached response and context, if present.</param>
            <returns>A value indicating whether a response for the specified responseToken was removed.</returns>
        </member>
        <member name="T:slskd.Search.ISearchService">
            <summary>
                Handles the lifecycle and persistence of searches.
            </summary>
        </member>
        <member name="M:slskd.Search.ISearchService.DeleteAsync(slskd.Search.Search)">
            <summary>
                Deletes the specified search.
            </summary>
            <param name="search">The search to delete.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Search.ISearchService.FindAsync(System.Linq.Expressions.Expression{System.Func{slskd.Search.Search,System.Boolean}},System.Boolean)">
            <summary>
                Finds a single search matching the specified <paramref name="expression"/>.
            </summary>
            <param name="expression">The expression to use to match searches.</param>
            <param name="includeResponses">A value indicating whether to include search responses in the result.</param>
            <returns>The found search, or default if not found.</returns>
            <exception cref="T:System.ArgumentException">Thrown when an expression is not supplied.</exception>
        </member>
        <member name="M:slskd.Search.ISearchService.ListAsync(System.Linq.Expressions.Expression{System.Func{slskd.Search.Search,System.Boolean}})">
            <summary>
                Returns a list of all completed and in-progress searches, with responses omitted, matching the optional <paramref name="expression"/>.
            </summary>
            <param name="expression">An optional expression used to match searches.</param>
            <returns>The list of searches matching the specified expression, or all searches if no expression is specified.</returns>
        </member>
        <member name="M:slskd.Search.ISearchService.Update(slskd.Search.Search)">
            <summary>
                Updates the specified <paramref name="search"/>.
            </summary>
            <remark>
                Round-trips the database; use accordingly.
            </remark>
            <param name="search">The search to update.</param>
        </member>
        <member name="M:slskd.Search.ISearchService.StartAsync(System.Guid,Soulseek.SearchQuery,Soulseek.SearchScope,Soulseek.SearchOptions)">
            <summary>
                Performs a search for the specified <paramref name="query"/> and <paramref name="scope"/>.
            </summary>
            <param name="id">A unique identifier for the search.</param>
            <param name="query">The search query.</param>
            <param name="scope">The search scope.</param>
            <param name="options">Search options.</param>
            <returns>The completed search.</returns>
        </member>
        <member name="M:slskd.Search.ISearchService.TryCancel(System.Guid)">
            <summary>
                Cancels the search matching the specified <paramref name="id"/>, if it is in progress.
            </summary>
            <param name="id">The unique identifier for the search.</param>
            <returns>A value indicating whether the search was successfully cancelled.</returns>
        </member>
        <member name="M:slskd.Search.ISearchService.PruneAsync(System.Int32)">
            <summary>
                Removes <see cref="F:Soulseek.SearchStates.Completed"/> searches older than the specified <paramref name="age"/>.
            </summary>
            <param name="age">The age after which records are eligible for pruning, in minutes.</param>
            <returns>The number of pruned records.</returns>
        </member>
        <member name="T:slskd.Search.SearchService">
            <summary>
                Handles the lifecycle and persistence of searches.
            </summary>
        </member>
        <member name="M:slskd.Search.SearchService.#ctor(Microsoft.AspNetCore.SignalR.IHubContext{slskd.Search.API.SearchHub},Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options},Soulseek.ISoulseekClient,Microsoft.EntityFrameworkCore.IDbContextFactory{slskd.Search.SearchDbContext})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Search.SearchService"/> class.
            </summary>
            <param name="searchHub"></param>
            <param name="optionsMonitor"></param>
            <param name="soulseekClient"></param>
            <param name="contextFactory">The database context to use.</param>
        </member>
        <member name="M:slskd.Search.SearchService.DeleteAsync(slskd.Search.Search)">
            <summary>
                Deletes the specified search.
            </summary>
            <param name="search">The search to delete.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Search.SearchService.FindAsync(System.Linq.Expressions.Expression{System.Func{slskd.Search.Search,System.Boolean}},System.Boolean)">
            <summary>
                Finds a single search matching the specified <paramref name="expression"/>.
            </summary>
            <param name="expression">The expression to use to match searches.</param>
            <param name="includeResponses">A value indicating whether to include search responses in the result.</param>
            <returns>The found search, or default if not found.</returns>
            <exception cref="T:System.ArgumentException">Thrown when an expression is not supplied.</exception>
        </member>
        <member name="M:slskd.Search.SearchService.ListAsync(System.Linq.Expressions.Expression{System.Func{slskd.Search.Search,System.Boolean}})">
            <summary>
                Returns a list of all completed and in-progress searches, with responses omitted, matching the optional <paramref name="expression"/>.
            </summary>
            <param name="expression">An optional expression used to match searches.</param>
            <returns>The list of searches matching the specified expression, or all searches if no expression is specified.</returns>
        </member>
        <member name="M:slskd.Search.SearchService.Update(slskd.Search.Search)">
            <summary>
                Updates the specified <paramref name="search"/>.
            </summary>
            <param name="search">The search to update.</param>
        </member>
        <member name="M:slskd.Search.SearchService.StartAsync(System.Guid,Soulseek.SearchQuery,Soulseek.SearchScope,Soulseek.SearchOptions)">
            <summary>
                Performs a search for the specified <paramref name="query"/> and <paramref name="scope"/>.
            </summary>
            <param name="id">A unique identifier for the search.</param>
            <param name="query">The search query.</param>
            <param name="scope">The search scope.</param>
            <param name="options">Search options.</param>
            <returns>The completed search.</returns>
        </member>
        <member name="M:slskd.Search.SearchService.TryCancel(System.Guid)">
            <summary>
                Cancels the search matching the specified <paramref name="id"/>, if it is in progress.
            </summary>
            <param name="id">The unique identifier for the search.</param>
            <returns>A value indicating whether the search was successfully cancelled.</returns>
        </member>
        <member name="M:slskd.Search.SearchService.PruneAsync(System.Int32)">
            <summary>
                Removes <see cref="F:Soulseek.SearchStates.Completed"/> searches older than the specified <paramref name="age"/>.
            </summary>
            <param name="age">The age after which searches are eligible for pruning, in minutes.</param>
            <returns>The number of pruned records.</returns>
        </member>
        <member name="T:slskd.Transfers.API.TransfersController">
            <summary>
                Transfers.
            </summary>
        </member>
        <member name="M:slskd.Transfers.API.TransfersController.#ctor(slskd.Transfers.ITransferService,Microsoft.Extensions.Options.IOptionsSnapshot{slskd.Options})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Transfers.API.TransfersController"/> class.
            </summary>
            <param name="optionsSnapshot"></param>
            <param name="transferService"></param>
        </member>
        <member name="M:slskd.Transfers.API.TransfersController.CancelDownloadAsync(System.String,System.String,System.Boolean)">
            <summary>
                Cancels the specified download.
            </summary>
            <param name="username">The username of the download source.</param>
            <param name="id">The id of the download.</param>
            <param name="remove">A value indicating whether the tracked download should be removed after cancellation.</param>
            <returns></returns>
            <response code="204">The download was cancelled successfully.</response>
            <response code="404">The specified download was not found.</response>
        </member>
        <member name="M:slskd.Transfers.API.TransfersController.ClearCompletedDownloads">
            <summary>
                Removes all completed downloads, regardless of whether they failed or succeeded.
            </summary>
            <returns></returns>
            <response code="204">The downloads were removed successfully.</response>
        </member>
        <member name="M:slskd.Transfers.API.TransfersController.CancelUpload(System.String,System.String,System.Boolean)">
            <summary>
                Cancels the specified upload.
            </summary>
            <param name="username">The username of the upload destination.</param>
            <param name="id">The id of the upload.</param>
            <param name="remove">A value indicating whether the tracked upload should be removed after cancellation.</param>
            <returns></returns>
            <response code="204">The upload was cancelled successfully.</response>
            <response code="404">The specified upload was not found.</response>
        </member>
        <member name="M:slskd.Transfers.API.TransfersController.ClearCompletedUploads">
            <summary>
                Removes all completed uploads, regardless of whether they failed or succeeded.
            </summary>
            <returns></returns>
            <response code="204">The uploads were removed successfully.</response>
        </member>
        <member name="M:slskd.Transfers.API.TransfersController.EnqueueAsync(System.String,System.Collections.Generic.IEnumerable{slskd.Transfers.API.QueueDownloadRequest})">
            <summary>
                Enqueues the specified download.
            </summary>
            <param name="username">The username of the download source.</param>
            <param name="requests">The list of download requests.</param>
            <returns></returns>
            <response code="201">The download was successfully enqueued.</response>
            <response code="403">The download was rejected.</response>
            <response code="500">An unexpected error was encountered.</response>
        </member>
        <member name="M:slskd.Transfers.API.TransfersController.GetDownloadsAsync(System.Boolean)">
            <summary>
                Gets all downloads.
            </summary>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
        </member>
        <member name="M:slskd.Transfers.API.TransfersController.GetDownloadsAsync(System.String)">
            <summary>
                Gets all downloads for the specified username.
            </summary>
            <param name="username"></param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
        </member>
        <member name="M:slskd.Transfers.API.TransfersController.GetPlaceInQueueAsync(System.String,System.String)">
            <summary>
                Gets the download for the specified username matching the specified filename, and requests
                the current place in the remote queue of the specified download.
            </summary>
            <param name="username">The username of the download source.</param>
            <param name="id">The id of the download.</param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
            <response code="404">The specified download was not found.</response>
        </member>
        <member name="M:slskd.Transfers.API.TransfersController.GetUploads(System.Boolean)">
            <summary>
                Gets all uploads.
            </summary>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
        </member>
        <member name="M:slskd.Transfers.API.TransfersController.GetUploads(System.String)">
            <summary>
                Gets all uploads for the specified username.
            </summary>
            <param name="username"></param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
        </member>
        <member name="M:slskd.Transfers.API.TransfersController.GetUploads(System.String,System.String)">
            <summary>
                Gets the upload for the specified username matching the specified filename.
            </summary>
            <param name="username">The username of the upload destination.</param>
            <param name="id">The id of the upload.</param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
        </member>
        <member name="P:slskd.Transfers.API.QueueDownloadRequest.Filename">
            <summary>
                Gets or sets the filename to download.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.QueueDownloadRequest.Size">
            <summary>
                Gets or sets the size of the file.
            </summary>
        </member>
        <member name="T:slskd.Transfers.API.Transfer">
            <summary>
                A single file transfer.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.AverageSpeed">
            <summary>
                Gets the current average transfer speed.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.BytesRemaining">
            <summary>
                Gets the number of remaining bytes to be transferred.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.BytesTransferred">
            <summary>
                Gets the total number of bytes transferred.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.Direction">
            <summary>
                Gets the transfer direction.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.ElapsedTime">
            <summary>
                Gets the current duration of the transfer, if it has been started.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.EndTime">
            <summary>
                Gets the UTC time at which the transfer transitioned into the <see cref="F:Soulseek.TransferStates.Completed"/> state.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.Filename">
            <summary>
                Gets the filename of the file to be transferred.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.Id">
            <summary>
                Gets the transfer id.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.IPEndPoint">
            <summary>
                Gets the ip endpoint of the remote transfer connection, if one has been established.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.PercentComplete">
            <summary>
                Gets the current progress in percent.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.PlaceInQueue">
            <summary>
                Gets the current place in queue, if it has been fetched.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.RemainingTime">
            <summary>
                Gets the projected remaining duration of the transfer.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.RemoteToken">
            <summary>
                Gets the remote unique token for the transfer.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.Size">
            <summary>
                Gets the size of the file to be transferred, in bytes.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.StartOffset">
            <summary>
                Gets the starting offset of the transfer, in bytes.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.StartTime">
            <summary>
                Gets the UTC time at which the transfer transitioned into the <see cref="F:Soulseek.TransferStates.InProgress"/> state.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.State">
            <summary>
                Gets the state of the transfer.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.Token">
            <summary>
                Gets the unique token for the transfer.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.Username">
            <summary>
                Gets the username of the peer to or from which the file is to be transferred.
            </summary>
        </member>
        <member name="P:slskd.Transfers.API.Transfer.Exception">
            <summary>
                Gets the Exception that caused the failure of the transfer, if applicable.
            </summary>
        </member>
        <member name="T:slskd.Transfers.Downloads.IDownloadService">
            <summary>
                Manages downloads.
            </summary>
        </member>
        <member name="M:slskd.Transfers.Downloads.IDownloadService.AddOrSupersede(slskd.Transfers.Transfer)">
            <summary>
                Adds the specified <paramref name="transfer"/>. Supersedes any existing record for the same file and username.
            </summary>
            <remarks>This should generally not be called; use EnqueueAsync() instead.</remarks>
            <param name="transfer"></param>
        </member>
        <member name="M:slskd.Transfers.Downloads.IDownloadService.EnqueueAsync(System.String,System.Collections.Generic.IEnumerable{System.ValueTuple{System.String,System.Int64}})">
            <summary>
                Enqueues the requested list of <paramref name="files"/>.
            </summary>
            <remarks>
                If one file in the specified collection fails, the rest will continue. An <see cref="T:System.AggregateException"/> will be
                thrown after all files are dispositioned if any throws.
            </remarks>
            <param name="username">The username of remote user.</param>
            <param name="files">The list of files to enqueue.</param>
            <returns>The operation context.</returns>
            <exception cref="T:System.ArgumentException">Thrown when the username is null or an empty string.</exception>
            <exception cref="T:System.ArgumentException">Thrown when no files are requested.</exception>
            <exception cref="T:System.AggregateException">Thrown when at least one of the requested files throws.</exception>
        </member>
        <member name="M:slskd.Transfers.Downloads.IDownloadService.Find(System.Linq.Expressions.Expression{System.Func{slskd.Transfers.Transfer,System.Boolean}})">
            <summary>
                Finds a single download matching the specified <paramref name="expression"/>.
            </summary>
            <param name="expression">The expression to use to match downloads.</param>
            <returns>The found transfer, or default if not found.</returns>
        </member>
        <member name="M:slskd.Transfers.Downloads.IDownloadService.GetPlaceInQueueAsync(System.Guid)">
            <summary>
                Retrieves the place in the remote queue for the download matching the specified <paramref name="id"/>.
            </summary>
            <param name="id">The unique identifier for the download.</param>
            <returns>The retrieved place in queue.</returns>
        </member>
        <member name="M:slskd.Transfers.Downloads.IDownloadService.List(System.Linq.Expressions.Expression{System.Func{slskd.Transfers.Transfer,System.Boolean}},System.Boolean)">
            <summary>
                Returns a list of all downloads matching the optional <paramref name="expression"/>.
            </summary>
            <param name="expression">An optional expression used to match downloads.</param>
            <param name="includeRemoved">Optionally include downloads that have been removed previously.</param>
            <returns>The list of downloads matching the specified expression, or all downloads if no expression is specified.</returns>
        </member>
        <member name="M:slskd.Transfers.Downloads.IDownloadService.Prune(System.Int32,Soulseek.TransferStates)">
            <summary>
                Removes <see cref="F:Soulseek.TransferStates.Completed"/> downloads older than the specified <paramref name="age"/>.
            </summary>
            <param name="age">The age after which downloads are eligible for pruning, in hours.</param>
            <param name="stateHasFlag">An optional, additional state by which downloads are filtered for pruning.</param>
            <returns>The number of pruned downloads.</returns>
        </member>
        <member name="M:slskd.Transfers.Downloads.IDownloadService.Remove(System.Guid)">
            <summary>
                Removes the download matching the specified <paramref name="id"/>.
            </summary>
            <remarks>This is a soft delete; the record is retained for historical retrieval.</remarks>
            <param name="id">The unique identifier of the download.</param>
        </member>
        <member name="M:slskd.Transfers.Downloads.IDownloadService.TryCancel(System.Guid)">
            <summary>
                Cancels the download matching the specified <paramref name="id"/>, if it is in progress.
            </summary>
            <param name="id">The unique identifier for the download.</param>
            <returns>A value indicating whether the download was successfully cancelled.</returns>
        </member>
        <member name="M:slskd.Transfers.Downloads.IDownloadService.Update(slskd.Transfers.Transfer)">
            <summary>
                Updates the specified <paramref name="transfer"/>.
            </summary>
            <param name="transfer">The transfer to update.</param>
        </member>
        <member name="T:slskd.Transfers.Downloads.DownloadService">
            <summary>
                Manages downloads.
            </summary>
        </member>
        <member name="M:slskd.Transfers.Downloads.DownloadService.AddOrSupersede(slskd.Transfers.Transfer)">
            <summary>
                Adds the specified <paramref name="transfer"/>. Supersedes any existing record for the same file and username.
            </summary>
            <remarks>This should generally not be called; use EnqueueAsync() instead.</remarks>
            <param name="transfer"></param>
        </member>
        <member name="M:slskd.Transfers.Downloads.DownloadService.EnqueueAsync(System.String,System.Collections.Generic.IEnumerable{System.ValueTuple{System.String,System.Int64}})">
            <summary>
                Enqueues the requested list of <paramref name="files"/>.
            </summary>
            <remarks>
                If one file in the specified collection fails, the rest will continue. An <see cref="T:System.AggregateException"/> will be
                thrown after all files are dispositioned if any throws.
            </remarks>
            <param name="username">The username of the remote user.</param>
            <param name="files">The list of files to enqueue.</param>
            <returns>The operation context.</returns>
            <exception cref="T:System.ArgumentException">Thrown when the username is null or an empty string.</exception>
            <exception cref="T:System.ArgumentException">Thrown when no files are requested.</exception>
            <exception cref="T:System.AggregateException">Thrown when at least one of the requested files throws.</exception>
        </member>
        <member name="M:slskd.Transfers.Downloads.DownloadService.Find(System.Linq.Expressions.Expression{System.Func{slskd.Transfers.Transfer,System.Boolean}})">
            <summary>
                Finds a single download matching the specified <paramref name="expression"/>.
            </summary>
            <param name="expression">The expression to use to match downloads.</param>
            <returns>The found transfer, or default if not found.</returns>
        </member>
        <member name="M:slskd.Transfers.Downloads.DownloadService.GetPlaceInQueueAsync(System.Guid)">
            <summary>
                Retrieves the place in the remote queue for the download matching the specified <paramref name="id"/>.
            </summary>
            <param name="id">The unique identifier for the download.</param>
            <returns>The retrieved place in queue.</returns>
        </member>
        <member name="M:slskd.Transfers.Downloads.DownloadService.List(System.Linq.Expressions.Expression{System.Func{slskd.Transfers.Transfer,System.Boolean}},System.Boolean)">
            <summary>
                Returns a list of all downloads matching the optional <paramref name="expression"/>.
            </summary>
            <param name="expression">An optional expression used to match downloads.</param>
            <param name="includeRemoved">Optionally include downloads that have been removed previously.</param>
            <returns>The list of downloads matching the specified expression, or all downloads if no expression is specified.</returns>
        </member>
        <member name="M:slskd.Transfers.Downloads.DownloadService.Prune(System.Int32,Soulseek.TransferStates)">
            <summary>
                Removes <see cref="F:Soulseek.TransferStates.Completed"/> downloads older than the specified <paramref name="age"/>.
            </summary>
            <param name="age">The age after which downloads are eligible for pruning, in hours.</param>
            <param name="stateHasFlag">An optional, additional state by which downloads are filtered for pruning.</param>
            <returns>The number of pruned downloads.</returns>
        </member>
        <member name="M:slskd.Transfers.Downloads.DownloadService.Remove(System.Guid)">
            <summary>
                Removes the download matching the specified <paramref name="id"/>.
            </summary>
            <remarks>This is a soft delete; the record is retained for historical retrieval.</remarks>
            <param name="id">The unique identifier of the download.</param>
        </member>
        <member name="M:slskd.Transfers.Downloads.DownloadService.TryCancel(System.Guid)">
            <summary>
                Cancels the download matching the specified <paramref name="id"/>, if it is in progress.
            </summary>
            <param name="id">The unique identifier for the download.</param>
            <returns>A value indicating whether the download was successfully cancelled.</returns>
        </member>
        <member name="M:slskd.Transfers.Downloads.DownloadService.Update(slskd.Transfers.Transfer)">
            <summary>
                Synchronously updates the specified <paramref name="transfer"/>.
            </summary>
            <param name="transfer">The transfer to update.</param>
        </member>
        <member name="T:slskd.Transfers.ITransferService">
            <summary>
                Manages transfers.
            </summary>
        </member>
        <member name="P:slskd.Transfers.ITransferService.Uploads">
            <summary>
                Gets the upload service.
            </summary>
        </member>
        <member name="P:slskd.Transfers.ITransferService.Downloads">
            <summary>
                Gets the download service.
            </summary>
        </member>
        <member name="T:slskd.Transfers.TransferService">
            <summary>
                Manages transfers.
            </summary>
        </member>
        <member name="M:slskd.Transfers.TransferService.#ctor(slskd.Transfers.Uploads.IUploadService,slskd.Transfers.Downloads.IDownloadService)">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Transfers.TransferService"/> class.
            </summary>
        </member>
        <member name="P:slskd.Transfers.TransferService.Uploads">
            <summary>
                Gets the upload service.
            </summary>
        </member>
        <member name="P:slskd.Transfers.TransferService.Downloads">
            <summary>
                Gets the download service.
            </summary>
        </member>
        <member name="T:slskd.Transfers.QueueStrategy">
            <summary>
                Queue strategies.
            </summary>
        </member>
        <member name="F:slskd.Transfers.QueueStrategy.RoundRobin">
            <summary>
                Uploads are prioritized based on the time they became ready.
            </summary>
        </member>
        <member name="F:slskd.Transfers.QueueStrategy.FirstInFirstOut">
            <summary>
                Uploads are prioritized based on the time they were enqueued.
            </summary>
        </member>
        <member name="P:slskd.Transfers.Transfer.Filename">
            <summary>
                Gets the remote filename.
            </summary>
        </member>
        <member name="P:slskd.Transfers.Transfer.StateDescription">
            <summary>
                Gets the string representation of the transfer <see cref="P:slskd.Transfers.Transfer.State"/>.
            </summary>
            <remarks>
                This is a hack to get the string into the database. *DO NOT* use this property in code
                and especially **DO NOT** set the value. The getter and setter can't be protected because
                EF Core needs them to be public.
            </remarks>
        </member>
        <member name="P:slskd.Transfers.Transfer.EndedAt">
            <summary>
                The time at which the transfer ended, or null if the transfer has not yet started or is in progress.
            </summary>
            <remarks>
                Guaranteed to be set for transfers in a terminal state.
            </remarks>
        </member>
        <member name="T:slskd.Transfers.IUploadGovernor">
            <summary>
                Governs upload transfer speed.
            </summary>
        </member>
        <member name="M:slskd.Transfers.IUploadGovernor.GetBytesAsync(System.String,System.Int32,System.Threading.CancellationToken)">
            <summary>
                Asynchronously obtains a grant of <paramref name="requestedBytes"/> for the requesting <paramref name="username"/>.
            </summary>
            <remarks>
                This operation completes when any number of bytes can be granted. The amount returned may be smaller than the
                requested amount.
            </remarks>
            <param name="username">The username of the requesting user.</param>
            <param name="requestedBytes">The number of requested bytes.</param>
            <param name="cancellationToken">The token to monitor for cancellation.</param>
            <returns>The operation context, including the number of bytes granted.</returns>
        </member>
        <member name="M:slskd.Transfers.IUploadGovernor.ReturnBytes(System.String,System.Int32,System.Int32,System.Int32)">
            <summary>
                Returns wasted bytes for redistribution.
            </summary>
            <param name="username">The username of the user that generated the waste.</param>
            <param name="attemptedBytes">The number of bytes that were attempted to be transferred.</param>
            <param name="grantedBytes">The number of bytes granted by all governors in the system.</param>
            <param name="actualBytes">The actual number of bytes transferred.</param>
        </member>
        <member name="T:slskd.Transfers.UploadGovernor">
            <summary>
                Governs upload transfer speed.
            </summary>
        </member>
        <member name="M:slskd.Transfers.UploadGovernor.#ctor(slskd.Users.IUserService,Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Transfers.UploadGovernor"/> class.
            </summary>
            <param name="userService">The UserService instance to use.</param>
            <param name="optionsMonitor">The OptionsMonitor instance to use.</param>
        </member>
        <member name="M:slskd.Transfers.UploadGovernor.GetBytesAsync(System.String,System.Int32,System.Threading.CancellationToken)">
            <summary>
                Asynchronously obtains a grant of <paramref name="requestedBytes"/> for the requesting <paramref name="username"/>.
            </summary>
            <remarks>
                This operation completes when any number of bytes can be granted. The amount returned may be smaller than the
                requested amount.
            </remarks>
            <param name="username">The username of the requesting user.</param>
            <param name="requestedBytes">The number of requested bytes.</param>
            <param name="cancellationToken">The token to monitor for cancellation.</param>
            <returns>The operation context, including the number of bytes granted.</returns>
        </member>
        <member name="M:slskd.Transfers.UploadGovernor.ReturnBytes(System.String,System.Int32,System.Int32,System.Int32)">
            <summary>
                Returns wasted bytes for redistribution.
            </summary>
            <param name="username">The username of the user that generated the waste.</param>
            <param name="attemptedBytes">The number of bytes that were attempted to be transferred.</param>
            <param name="grantedBytes">The number of bytes granted by all governors in the system.</param>
            <param name="actualBytes">The actual number of bytes transferred.</param>
        </member>
        <member name="T:slskd.Transfers.IUploadQueue">
            <summary>
                Orchestrates uploads.
            </summary>
        </member>
        <member name="M:slskd.Transfers.IUploadQueue.AwaitStartAsync(System.String,System.String)">
            <summary>
                Awaits the start of an upload.
            </summary>
            <param name="username">The username of the remote user.</param>
            <param name="filename">The filename for which to await the start.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Transfers.IUploadQueue.Complete(System.String,System.String)">
            <summary>
                Signals the completion of an upload.
            </summary>
            <param name="username">The username of the remote user.</param>
            <param name="filename">The completed filename.</param>
        </member>
        <member name="M:slskd.Transfers.IUploadQueue.Enqueue(System.String,System.String)">
            <summary>
                Enqueues an upload.
            </summary>
            <param name="username">The username of the remote user.</param>
            <param name="filename">The filename to enqueue.</param>
        </member>
        <member name="M:slskd.Transfers.IUploadQueue.GetGroupInfo(System.String)">
            <summary>
                Gets information about the specified <paramref name="groupName"/>.
            </summary>
            <param name="groupName">The name of the group.</param>
            <returns>The group information.</returns>
        </member>
        <member name="M:slskd.Transfers.IUploadQueue.EstimatePosition(System.String,System.String)">
            <summary>
                Computes the estimated queue position of the specified <paramref name="filename"/> for the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username associated with the file.</param>
            <param name="filename">The filename of the file for which the position is to be estimated.</param>
            <returns>The estimated queue position of the file.</returns>
            <exception cref="T:slskd.NotFoundException">Thrown if the specified filename is not enqueued.</exception>
        </member>
        <member name="M:slskd.Transfers.IUploadQueue.ForecastPosition(System.String)">
            <summary>
                Computes the estimated queue position of the specified <paramref name="username"/> if they were to enqueue a file,
                or zero if the transfer could start immediately.
            </summary>
            <param name="username">The username for which to estimate.</param>
            <returns>
                The estimated queue position if the user were to enqueue a file, or zero if the transfer could start immediately.
            </returns>
        </member>
        <member name="T:slskd.Transfers.UploadQueue">
            <summary>
                Orchestrates uploads.
            </summary>
        </member>
        <member name="M:slskd.Transfers.UploadQueue.#ctor(slskd.Users.IUserService,Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Transfers.UploadQueue"/> class.
            </summary>
            <param name="userService">The UserService instance to use.</param>
            <param name="optionsMonitor">The OptionsMonitor instance to use.</param>
        </member>
        <member name="M:slskd.Transfers.UploadQueue.AwaitStartAsync(System.String,System.String)">
            <summary>
                Awaits the start of an upload.
            </summary>
            <param name="username">The username of the remote user.</param>
            <param name="filename">The filename for which to await the start.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Transfers.UploadQueue.Complete(System.String,System.String)">
            <summary>
                Signals the completion of an upload.
            </summary>
            <param name="username">The username of the remote user.</param>
            <param name="filename">The completed filename.</param>
        </member>
        <member name="M:slskd.Transfers.UploadQueue.Enqueue(System.String,System.String)">
            <summary>
                Enqueues an upload.
            </summary>
            <param name="username">The username of the remote user.</param>
            <param name="filename">The filename to enqueue.</param>
        </member>
        <member name="M:slskd.Transfers.UploadQueue.GetGroupInfo(System.String)">
            <summary>
                Gets information about the specified <paramref name="groupName"/>.
            </summary>
            <param name="groupName">The name of the group.</param>
            <returns>The group information.</returns>
        </member>
        <member name="M:slskd.Transfers.UploadQueue.EstimatePosition(System.String,System.String)">
            <summary>
                Computes the estimated queue position of the specified <paramref name="filename"/> for the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username associated with the file.</param>
            <param name="filename">The filename of the file for which the position is to be estimated.</param>
            <returns>The estimated queue position of the file.</returns>
            <exception cref="T:slskd.NotFoundException">Thrown if the specified filename is not enqueued.</exception>
        </member>
        <member name="M:slskd.Transfers.UploadQueue.ForecastPosition(System.String)">
            <summary>
                Computes the estimated queue position of the specified <paramref name="username"/> if they were to enqueue a file,
                or zero if the transfer could start immediately.
            </summary>
            <param name="username">The username for which to estimate.</param>
            <returns>
                The estimated queue position if the user were to enqueue a file, or zero if the transfer could start immediately.
            </returns>
        </member>
        <member name="T:slskd.Transfers.Uploads.IUploadService">
            <summary>
                Manages uploads.
            </summary>
        </member>
        <member name="P:slskd.Transfers.Uploads.IUploadService.Governor">
            <summary>
                Gets the upload governor.
            </summary>
        </member>
        <member name="P:slskd.Transfers.Uploads.IUploadService.Queue">
            <summary>
                Gets the upload queue.
            </summary>
        </member>
        <member name="M:slskd.Transfers.Uploads.IUploadService.AddOrSupersede(slskd.Transfers.Transfer)">
            <summary>
                Adds the specified <paramref name="transfer"/>. Supersedes any existing record for the same file and username.
            </summary>
            <remarks>This should generally not be called; use <see cref="M:slskd.Transfers.Uploads.IUploadService.EnqueueAsync(System.String,System.String)"/> instead.</remarks>
            <param name="transfer"></param>
        </member>
        <member name="M:slskd.Transfers.Uploads.IUploadService.EnqueueAsync(System.String,System.String)">
            <summary>
                Enqueues the requested file.
            </summary>
            <param name="username">The username of the requesting user.</param>
            <param name="filename">The local filename of the requested file.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Transfers.Uploads.IUploadService.Find(System.Linq.Expressions.Expression{System.Func{slskd.Transfers.Transfer,System.Boolean}})">
            <summary>
                Finds a single upload matching the specified <paramref name="expression"/>.
            </summary>
            <param name="expression">The expression to use to match uploads.</param>
            <returns>The found transfer, or default if not found.</returns>
        </member>
        <member name="M:slskd.Transfers.Uploads.IUploadService.Summarize(System.Linq.Expressions.Expression{System.Func{slskd.Transfers.Transfer,System.Boolean}})">
            <summary>
                Returns a summary of the uploads matching the specified <paramref name="expression"/>. This can be expensive;
                consider caching.
            </summary>
            <param name="expression">The expression used to select uploads for summarization.</param>
            <returns>
                The generated summary, including the number of files and total size in bytes.
            </returns>
        </member>
        <member name="M:slskd.Transfers.Uploads.IUploadService.List(System.Linq.Expressions.Expression{System.Func{slskd.Transfers.Transfer,System.Boolean}},System.Boolean)">
            <summary>
                Returns a list of all uploads matching the optional <paramref name="expression"/>.
            </summary>
            <param name="expression">An optional expression used to match uploads.</param>
            <param name="includeRemoved">A value indicating whether to include uploads that have been removed previously.</param>
            <returns>The list of uploads matching the specified expression, or all uploads if no expression is specified.</returns>
        </member>
        <member name="M:slskd.Transfers.Uploads.IUploadService.Prune(System.Int32,Soulseek.TransferStates)">
            <summary>
                Removes <see cref="F:Soulseek.TransferStates.Completed"/> uploads older than the specified <paramref name="age"/>.
            </summary>
            <param name="age">The age after which uploads are eligible for pruning, in minutes.</param>
            <param name="stateHasFlag">An optional, additional state by which uploads are filtered for pruning.</param>
            <returns>The number of pruned uploads.</returns>
        </member>
        <member name="M:slskd.Transfers.Uploads.IUploadService.Remove(System.Guid)">
            <summary>
                Removes the upload matching the specified <paramref name="id"/>.
            </summary>
            <remarks>This is a soft delete; the record is retained for historical retrieval.</remarks>
            <param name="id">The unique identifier of the upload.</param>
        </member>
        <member name="M:slskd.Transfers.Uploads.IUploadService.TryCancel(System.Guid)">
            <summary>
                Cancels the upload matching the specified <paramref name="id"/>, if it is in progress.
            </summary>
            <param name="id">The unique identifier for the upload.</param>
            <returns>A value indicating whether the upload was successfully cancelled.</returns>
        </member>
        <member name="M:slskd.Transfers.Uploads.IUploadService.Update(slskd.Transfers.Transfer)">
            <summary>
                Synchronously updates the specified <paramref name="transfer"/>.
            </summary>
            <param name="transfer">The transfer to update.</param>
        </member>
        <member name="T:slskd.Transfers.Uploads.UploadService">
            <summary>
                Manages uploads.
            </summary>
        </member>
        <member name="P:slskd.Transfers.Uploads.UploadService.Governor">
            <summary>
                Gets the upload governor.
            </summary>
        </member>
        <member name="P:slskd.Transfers.Uploads.UploadService.Queue">
            <summary>
                Gets the upload queue.
            </summary>
        </member>
        <member name="M:slskd.Transfers.Uploads.UploadService.AddOrSupersede(slskd.Transfers.Transfer)">
            <summary>
                Adds the specified <paramref name="transfer"/>. Supersedes any existing record for the same file and username.
            </summary>
            <remarks>This should generally not be called; use <see cref="M:slskd.Transfers.Uploads.UploadService.EnqueueAsync(System.String,System.String)"/> instead.</remarks>
            <param name="transfer"></param>
        </member>
        <member name="M:slskd.Transfers.Uploads.UploadService.EnqueueAsync(System.String,System.String)">
            <summary>
                Enqueues the requested file.
            </summary>
            <param name="username">The username of the requesting user.</param>
            <param name="filename">The local filename of the requested file.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Transfers.Uploads.UploadService.Find(System.Linq.Expressions.Expression{System.Func{slskd.Transfers.Transfer,System.Boolean}})">
            <summary>
                Finds a single upload matching the specified <paramref name="expression"/>.
            </summary>
            <param name="expression">The expression to use to match uploads.</param>
            <returns>The found transfer, or default if not found.</returns>
        </member>
        <member name="M:slskd.Transfers.Uploads.UploadService.Summarize(System.Linq.Expressions.Expression{System.Func{slskd.Transfers.Transfer,System.Boolean}})">
            <summary>
                Returns a summary of the uploads matching the specified <paramref name="expression"/>. This can be expensive;
                consider caching.
            </summary>
            <param name="expression">The expression used to select uploads for summarization.</param>
            <returns>
                The generated summary, including the number of files and total size in bytes.
            </returns>
        </member>
        <member name="M:slskd.Transfers.Uploads.UploadService.List(System.Linq.Expressions.Expression{System.Func{slskd.Transfers.Transfer,System.Boolean}},System.Boolean)">
            <summary>
                Returns a list of all uploads matching the optional <paramref name="expression"/>.
            </summary>
            <param name="expression">An optional expression used to match uploads.</param>
            <param name="includeRemoved">A value indicating whether to include uploads that have been removed previously.</param>
            <returns>The list of uploads matching the specified expression, or all uploads if no expression is specified.</returns>
        </member>
        <member name="M:slskd.Transfers.Uploads.UploadService.Prune(System.Int32,Soulseek.TransferStates)">
            <summary>
                Removes <see cref="F:Soulseek.TransferStates.Completed"/> uploads older than the specified <paramref name="age"/>.
            </summary>
            <param name="age">The age after which uploads are eligible for pruning, in minutes.</param>
            <param name="stateHasFlag">An optional, additional state by which uploads are filtered for pruning.</param>
            <returns>The number of pruned uploads.</returns>
        </member>
        <member name="M:slskd.Transfers.Uploads.UploadService.Remove(System.Guid)">
            <summary>
                Removes the upload matching the specified <paramref name="id"/>.
            </summary>
            <remarks>This is a soft delete; the record is retained for historical retrieval.</remarks>
            <param name="id">The unique identifier of the upload.</param>
        </member>
        <member name="M:slskd.Transfers.Uploads.UploadService.TryCancel(System.Guid)">
            <summary>
                Cancels the upload matching the specified <paramref name="id"/>, if it is in progress.
            </summary>
            <param name="id">The unique identifier for the upload.</param>
            <returns>A value indicating whether the upload was successfully cancelled.</returns>
        </member>
        <member name="M:slskd.Transfers.Uploads.UploadService.Update(slskd.Transfers.Transfer)">
            <summary>
                Synchronously updates the specified <paramref name="transfer"/>.
            </summary>
            <param name="transfer">The transfer to update.</param>
        </member>
        <member name="T:slskd.Users.API.UsersController">
            <summary>
                Users.
            </summary>
        </member>
        <member name="M:slskd.Users.API.UsersController.#ctor(Soulseek.ISoulseekClient,slskd.Users.IBrowseTracker,slskd.Users.IUserService,Microsoft.Extensions.Options.IOptionsSnapshot{slskd.Options})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Users.API.UsersController"/> class.
            </summary>
            <param name="soulseekClient"></param>
            <param name="browseTracker"></param>
            <param name="userService"></param>
            <param name="optionsSnapshot"></param>
        </member>
        <member name="M:slskd.Users.API.UsersController.Endpoint(System.String)">
            <summary>
                Retrieves the address of the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username of the user.</param>
            <returns></returns>
            <response code="200">The request completed successfully.</response>
        </member>
        <member name="M:slskd.Users.API.UsersController.Browse(System.String)">
            <summary>
                Retrieves the files shared by the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username of the user.</param>
            <returns></returns>
        </member>
        <member name="M:slskd.Users.API.UsersController.BrowseStatus(System.String)">
            <summary>
                Retrieves the status of the current browse operation for the specified <paramref name="username"/>, if any.
            </summary>
            <param name="username">The username of the user.</param>
            <returns></returns>
        </member>
        <member name="M:slskd.Users.API.UsersController.Directory(System.String,slskd.Users.API.DirectoryContentsRequest)">
            <summary>
                Retrieves the files from the specified directory from the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username of the user.</param>
            <param name="request">The directory contents request.</param>
            <returns></returns>
        </member>
        <member name="M:slskd.Users.API.UsersController.Info(System.String)">
            <summary>
                Retrieves information about the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username of the user.</param>
            <returns></returns>
        </member>
        <member name="M:slskd.Users.API.UsersController.Status(System.String)">
            <summary>
                Retrieves status for the specified <paramref name="username"/>.
            </summary>
            <param name="username">The username of the user.</param>
            <returns></returns>
        </member>
        <member name="P:slskd.Users.API.UserDataResponse.AverageSpeed">
            <summary>
                The average upload speed of the user.
            </summary>
        </member>
        <member name="P:slskd.Users.API.UserDataResponse.CountryCode">
            <summary>
                The user's country code, if provided.
            </summary>
        </member>
        <member name="P:slskd.Users.API.UserDataResponse.DirectoryCount">
            <summary>
                The number of directories shared by the user.
            </summary>
        </member>
        <member name="P:slskd.Users.API.UserDataResponse.FileCount">
            <summary>
                The number of files shared by the user.
            </summary>
        </member>
        <member name="P:slskd.Users.API.UserDataResponse.Self">
            <summary>
                A value indicating whether this user data belongs to the currently logged in user.
            </summary>
        </member>
        <member name="P:slskd.Users.API.UserDataResponse.SlotsFree">
            <summary>
                The number of the user's free download slots, if provided.
            </summary>
        </member>
        <member name="P:slskd.Users.API.UserDataResponse.Status">
            <summary>
                The status of the user (0 = offline, 1 = away, 2 = online).
            </summary>
        </member>
        <member name="P:slskd.Users.API.UserDataResponse.UploadCount">
            <summary>
                The number of uploads tracked by the server for the user.
            </summary>
        </member>
        <member name="P:slskd.Users.API.UserDataResponse.Username">
            <summary>
                The username of the user.
            </summary>
        </member>
        <member name="T:slskd.Users.BrowseTracker">
            <summary>
                Tracks browse operations.
            </summary>
        </member>
        <member name="P:slskd.Users.BrowseTracker.Browses">
            <summary>
                Tracked browse operations.
            </summary>
        </member>
        <member name="M:slskd.Users.BrowseTracker.AddOrUpdate(System.String,Soulseek.BrowseProgressUpdatedEventArgs)">
            <summary>
                Adds or updates a tracked browse operation.
            </summary>
            <param name="username"></param>
            <param name="progress"></param>
        </member>
        <member name="M:slskd.Users.BrowseTracker.TryRemove(System.String)">
            <summary>
                Removes a tracked browse operation for the specified user.
            </summary>
            <param name="username"></param>
        </member>
        <member name="M:slskd.Users.BrowseTracker.TryGet(System.String,Soulseek.BrowseProgressUpdatedEventArgs@)">
            <summary>
                Gets the browse progress for the specified user.
            </summary>
            <param name="username"></param>
            <param name="progress"></param>
            <returns></returns>
        </member>
        <member name="T:slskd.Users.Extensions">
            <summary>
                Users extensions.
            </summary>
        </member>
        <member name="M:slskd.Users.Extensions.ToStatistics(Soulseek.UserStatistics)">
            <summary>
                Converts <see cref="T:Soulseek.UserStatistics"/> to <see cref="T:slskd.Users.Statistics"/>.
            </summary>
            <param name="u">The UserStatistics instance to convert.</param>
            <returns>The converted instance.</returns>
        </member>
        <member name="M:slskd.Users.Extensions.ToStatus(Soulseek.UserStatus)">
            <summary>
                Converts <see cref="T:Soulseek.UserStatus"/> to <see cref="T:slskd.Users.Status"/>.
            </summary>
            <param name="s">The UserStatus instance to convert.</param>
            <returns>The converted instance.</returns>
        </member>
        <member name="M:slskd.Users.Extensions.ToInfo(Soulseek.UserInfo)">
            <summary>
                Converts <see cref="T:Soulseek.UserInfo"/> to <see cref="T:slskd.Users.Info"/>.
            </summary>
            <param name="i">The UserInfo instance to convert.</param>
            <returns>The converted instance.</returns>
        </member>
        <member name="T:slskd.Users.IBrowseTracker">
            <summary>
                Tracks browse operations.
            </summary>
        </member>
        <member name="P:slskd.Users.IBrowseTracker.Browses">
            <summary>
                Tracked browse operations.
            </summary>
        </member>
        <member name="M:slskd.Users.IBrowseTracker.AddOrUpdate(System.String,Soulseek.BrowseProgressUpdatedEventArgs)">
            <summary>
                Adds or updates a tracked browse operation.
            </summary>
            <param name="username"></param>
            <param name="progress"></param>
        </member>
        <member name="M:slskd.Users.IBrowseTracker.TryGet(System.String,Soulseek.BrowseProgressUpdatedEventArgs@)">
            <summary>
                Gets the browse progress for the specified user.
            </summary>
            <param name="username"></param>
            <param name="progress"></param>
            <returns></returns>
        </member>
        <member name="M:slskd.Users.IBrowseTracker.TryRemove(System.String)">
            <summary>
                Removes a tracked browse operation for the specified user.
            </summary>
            <param name="username"></param>
        </member>
        <member name="T:slskd.Users.IUserService">
            <summary>
                Provides information and operations for network peers.
            </summary>
            <remarks>
                <para>
                    This class maintains a UserDictionary that acts as a non-expiring cache of information
                    collected about a user.  This includes their statistics (share counts, speed, etc), their status (privileged, etc)
                    and, if they are a member of a user-defined group, their group.
                </para>
                <para>
                    This class also maintains a WatchedUsernamesDictionary to keep track of which usernames have been
                    "watched" server side and for which we will therefore receive events when their status changes.
                </para>
                <para>
                    If a user's information is in the UserDictionary, it's because we requested it at some point.  If that user
                    is also "watched", we can assume that the data in the dictionary is up to date and will be kept so.
                </para>
                <para>
                    The data in the UserDictionary can continue to grow until -- unlikely -- it contains a record for every
                    user on or that was on the network at any point since the last client connect.  This is a calculated risk, roughly
                    knowing the size of the network, the size of the data being stored, and balanced against the consequences of not having
                    a user's data when it is needed (for queue positioning, speed limits, etc).
                </para>
                <para>
                    The <see cref="M:slskd.Users.IUserService.GetGroup(System.String)"/> method acts on cached data _only_.  This method should be called within hot paths,
                    such as a transfer governor or from the upload queue.  We care more that it is fast than if it is stale.  If no data for the
                    requested user is cached, that user is assumed to be in the default group.
                </para>
                <para>
                    The <see cref="M:slskd.Users.IUserService.GetOrFetchGroupAsync(System.String,System.Boolean)"/> method is similar to <see cref="M:slskd.Users.IUserService.GetGroup(System.String)"/>, except that if
                    the requested user is not cached, it will fetch the user's data and cache it before returning.  This method accepts an optional
                    parameter that can be used to force a "refresh" of the requested user's data, useful for times when we want the latest data,
                    and can afford to wait for it.
                </para>
            </remarks>
        </member>
        <member name="P:slskd.Users.IUserService.Users">
            <summary>
                Gets the list of tracked users.
            </summary>
        </member>
        <member name="P:slskd.Users.IUserService.WatchedUsernames">
            <summary>
                Gets the list of watched usernames.
            </summary>
        </member>
        <member name="M:slskd.Users.IUserService.GetGroup(System.String)">
            <summary>
                Gets the name of the group for the specified <paramref name="username"/>.
            </summary>
            <remarks>The group name is fetched from cached data, and lookups should always be fast.</remarks>
            <param name="username">The username of the peer.</param>
            <returns>The group for the specified username.</returns>
        </member>
        <member name="M:slskd.Users.IUserService.GetInfoAsync(System.String)">
            <summary>
                Retrieves peer <see cref="T:slskd.Users.Info"/>.
            </summary>
            <param name="username">The username of the peer.</param>
            <returns>The retrieved info.</returns>
        </member>
        <member name="M:slskd.Users.IUserService.GetIPEndPointAsync(System.String)">
            <summary>
                Retrieves a peer's IP endpoint, including their IP address and listen port.
            </summary>
            <param name="username">The username of the peer.</param>
            <returns>The retrieved endpoint.</returns>
        </member>
        <member name="M:slskd.Users.IUserService.GetOrFetchGroupAsync(System.String,System.Boolean)">
            <summary>
                Gets the name of the group for the specified <paramref name="username"/>, or, if the user's information isn't
                cached, fetches and caches the user's information from the server, then returns the group.
            </summary>
            <remarks>The fetch of fresh data can be forced by specifying <paramref name="forceFetch"/> = true.</remarks>
            <param name="username">The username of the peer.</param>
            <param name="forceFetch">
                A value determining whether the user's information should be fetched from the server, regardless of local cache.
            </param>
            <returns>The group for the specified username.</returns>
        </member>
        <member name="M:slskd.Users.IUserService.GetStatisticsAsync(System.String)">
            <summary>
                Retrieves the current <see cref="T:slskd.Users.Statistics"/> of a peer, and caches the result.
            </summary>
            <param name="username">The username of the peer.</param>
            <returns>The retrieved statistics.</returns>
        </member>
        <member name="M:slskd.Users.IUserService.GetStatusAsync(System.String)">
            <summary>
                Retrieves the current <see cref="T:slskd.Users.Status"/> of a peer, and caches the result.
            </summary>
            <param name="username">The username of the peer.</param>
            <returns>The retrieved status.</returns>
        </member>
        <member name="M:slskd.Users.IUserService.GrantPrivilegesAsync(System.String,System.Int32)">
            <summary>
                Grants the specified peer the specified number of privilege days.
            </summary>
            <param name="username">The username of the peer.</param>
            <param name="days">The number of days to grant.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Users.IUserService.IsBlacklisted(System.String,System.Net.IPAddress)">
            <summary>
                Gets a value indicating whether the specified <paramref name="username"/> and/or <paramref name="ipAddress"/> are blacklisted.
            </summary>
            <param name="username">The username to check.</param>
            <param name="ipAddress">The IPAddress to check, if available.</param>
            <returns>A value indicating whether the specified user and/or IP are blacklisted.</returns>
        </member>
        <member name="M:slskd.Users.IUserService.IsPrivilegedAsync(System.String)">
            <summary>
                Retrieves a value indicating whether the specified peer is privileged.
            </summary>
            <param name="username">The username of the peer.</param>
            <returns>A value indicating whether the specified peer is privileged.</returns>
        </member>
        <member name="M:slskd.Users.IUserService.IsWatched(System.String)">
            <summary>
                Gets a value indicating whether the specified <paramref name="username"/> is watched.
            </summary>
            <param name="username">The username of the peer.</param>
            <returns>A value indicating whether the username is watched.</returns>
        </member>
        <member name="M:slskd.Users.IUserService.WatchAsync(System.String)">
            <summary>
                Adds the specified username to the server-side user list.
            </summary>
            <param name="username">The username of the peer.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="P:slskd.Users.Statistics.AverageSpeed">
            <summary>
                Gets the average upload speed of the user.
            </summary>
        </member>
        <member name="P:slskd.Users.Statistics.DirectoryCount">
            <summary>
                Gets the number of directories shared by the user.
            </summary>
        </member>
        <member name="P:slskd.Users.Statistics.FileCount">
            <summary>
                Gets the number of files shared by the user.
            </summary>
        </member>
        <member name="P:slskd.Users.Statistics.UploadCount">
            <summary>
                Gets the number of uploads tracked by the server for this user.
            </summary>
        </member>
        <member name="T:slskd.Users.Status">
            <summary>
                User status.
            </summary>
        </member>
        <member name="P:slskd.Users.Status.IsPrivileged">
            <summary>
                Gets a value indicating whether the user is privileged.
            </summary>
        </member>
        <member name="P:slskd.Users.Status.Presence">
            <summary>
                Gets the user's presence.
            </summary>
        </member>
        <member name="P:slskd.Users.User.Username">
            <summary>
                Gets the username of the user.
            </summary>
        </member>
        <member name="P:slskd.Users.User.Group">
            <summary>
                Gets the user's configured group.
            </summary>
        </member>
        <member name="P:slskd.Users.User.Statistics">
            <summary>
                Gets the user's statistics.
            </summary>
        </member>
        <member name="P:slskd.Users.User.Status">
            <summary>
                Gets the user's status.
            </summary>
        </member>
        <member name="T:slskd.Users.UserService">
            <summary>
                Provides information and operations for network peers.
            </summary>
            <remarks>
                <para>
                    This class maintains a <see cref="P:slskd.Users.UserService.UserDictionary"/> that acts as a non-expiring cache of information
                    collected about a user.  This includes their statistics (share counts, speed, etc), their status (privileged, etc)
                    and, if they are a member of a user-defined group, their group.
                </para>
                <para>
                    This class also maintains a <see cref="P:slskd.Users.UserService.WatchedUsernamesDictionary"/> to keep track of which usernames have been
                    "watched" server side and for which we will therefore receive events when their status changes.
                </para>
                <para>
                    If a user's information is in the <see cref="P:slskd.Users.UserService.UserDictionary"/>, it's because we requested it at some point.  If that user
                    is also "watched", we can assume that the data in the dictionary is up to date and will be kept so.
                </para>
                <para>
                    The data in the <see cref="P:slskd.Users.UserService.UserDictionary"/> can continue to grow until -- unlikely -- it contains a record for every
                    user on or that was on the network at any point since the last client connect.  This is a calculated risk, roughly
                    knowing the size of the network, the size of the data being stored, and balanced against the consequences of not having
                    a user's data when it is needed (for queue positioning, speed limits, etc).
                </para>
                <para>
                    The <see cref="M:slskd.Users.UserService.GetGroup(System.String)"/> method acts on cached data _only_.  This method should be called within hot paths,
                    such as a transfer governor or from the upload queue.  We care more that it is fast than if it is stale.  If no data for the
                    requested user is cached, that user is assumed to be in the default group.
                </para>
                <para>
                    The <see cref="M:slskd.Users.UserService.GetOrFetchGroupAsync(System.String,System.Boolean)"/> method is similar to <see cref="M:slskd.Users.UserService.GetGroup(System.String)"/>, except that if
                    the requested user is not cached, it will fetch the user's data and cache it before returning.  This method accepts an optional
                    parameter that can be used to force a "refresh" of the requested user's data, useful for times when we want the latest data,
                    and can afford to wait for it.
                </para>
            </remarks>
        </member>
        <member name="M:slskd.Users.UserService.#ctor(Soulseek.ISoulseekClient,Microsoft.Extensions.Options.IOptionsMonitor{slskd.Options})">
            <summary>
                Initializes a new instance of the <see cref="T:slskd.Users.UserService"/> class.
            </summary>
            <param name="soulseekClient"></param>
            <param name="optionsMonitor"></param>
        </member>
        <member name="P:slskd.Users.UserService.Users">
            <summary>
                Gets the list of tracked users.
            </summary>
        </member>
        <member name="P:slskd.Users.UserService.WatchedUsernames">
            <summary>
                Gets the list of watched usernames.
            </summary>
        </member>
        <member name="P:slskd.Users.UserService.UserDictionary">
            <summary>
                Gets or sets the internal cache of User data.
            </summary>
            <remarks>
                <para>
                    This method retrieves the requested user's information from a dictionary, and is therefore a 'get'. This
                    information is needed to control who can do what, who is subject to what limits, how to control the upload
                    queue, and how to govern speeds. The logic in this method is the 'hottest' in the application and *must*
                    remain very simple and _fast_.
                </para>
                <para>
                    If this method is called for a user who has not previously been cached, it will return the default group,
                    meaning leech, privilege, and user defined group discrimination will not work. For this reason it is critical
                    that user information is retrieved and cached upon first interaction with that user.
                </para>
                <para>
                    Uploads can be cached indefinitely, and for that reason the user data cache must be filled indefinitely;
                    meaning there is no invalidation and that user data will accrue for the lifetime of the application (instance).
                </para>
            </remarks>
        </member>
        <member name="M:slskd.Users.UserService.GetGroup(System.String)">
            <summary>
                Gets the name of the group for the specified <paramref name="username"/>.
            </summary>
            <remarks>The group name is fetched from cached data, and lookups should always be fast.</remarks>
            <param name="username">The username of the peer.</param>
            <returns>The group for the specified username.</returns>
        </member>
        <member name="M:slskd.Users.UserService.GetInfoAsync(System.String)">
            <summary>
                Retrieves peer <see cref="T:slskd.Users.Info"/>.
            </summary>
            <param name="username">The username of the peer.</param>
            <returns>The retrieved info.</returns>
        </member>
        <member name="M:slskd.Users.UserService.GetIPEndPointAsync(System.String)">
            <summary>
                Retrieves a peer's IP endpoint, including their IP address and listen port.
            </summary>
            <param name="username">The username of the peer.</param>
            <returns>The retrieved endpoint.</returns>
        </member>
        <member name="M:slskd.Users.UserService.GetOrFetchGroupAsync(System.String,System.Boolean)">
            <summary>
                Gets the name of the group for the specified <paramref name="username"/>, or, if the user's information isn't
                cached, fetches and caches the user's information from the server, then returns the group.
            </summary>
            <remarks>The fetch of fresh data can be forced by specifying <paramref name="forceFetch"/> = true.</remarks>
            <param name="username">The username of the peer.</param>
            <param name="forceFetch">
                A value determining whether the user's information should be fetched from the server, regardless of local cache.
            </param>
            <returns>The group for the specified username.</returns>
        </member>
        <member name="M:slskd.Users.UserService.GetStatisticsAsync(System.String)">
            <summary>
                Retrieves the current <see cref="T:slskd.Users.Statistics"/> of a peer, and caches the result.
            </summary>
            <param name="username">The username of the peer.</param>
            <returns>The retrieved statistics.</returns>
        </member>
        <member name="M:slskd.Users.UserService.GetStatusAsync(System.String)">
            <summary>
                Retrieves the current <see cref="T:slskd.Users.Status"/> of a peer, and caches the result.
            </summary>
            <param name="username">The username of the peer.</param>
            <returns>The retrieved status.</returns>
        </member>
        <member name="M:slskd.Users.UserService.GrantPrivilegesAsync(System.String,System.Int32)">
            <summary>
                Grants the specified peer the specified number of privilege days.
            </summary>
            <param name="username">The username of the peer.</param>
            <param name="days">The number of days to grant.</param>
            <returns>The operation context.</returns>
        </member>
        <member name="M:slskd.Users.UserService.IsBlacklisted(System.String,System.Net.IPAddress)">
            <summary>
                Gets a value indicating whether the specified <paramref name="username"/> and/or <paramref name="ipAddress"/> are blacklisted.
            </summary>
            <param name="username">The username to check.</param>
            <param name="ipAddress">The IPAddress to check, if available.</param>
            <returns>A value indicating whether the specified user and/or IP are blacklisted.</returns>
        </member>
        <member name="M:slskd.Users.UserService.IsPrivilegedAsync(System.String)">
            <summary>
                Retrieves a value indicating whether the specified peer is privileged.
            </summary>
            <param name="username">The username of the peer.</param>
            <returns>A value indicating whether the specified peer is privileged.</returns>
        </member>
        <member name="M:slskd.Users.UserService.IsWatched(System.String)">
            <summary>
                Gets a value indicating whether the specified <paramref name="username"/> is watched.
            </summary>
            <param name="username">The username of the peer.</param>
            <returns>A value indicating whether the username is watched.</returns>
        </member>
        <member name="M:slskd.Users.UserService.WatchAsync(System.String)">
            <summary>
                Adds the specified username to the server-side user list.
            </summary>
            <remarks>
                <para>Idempotent; if a user is already watched, subsequent calls will only update their status and statistics.</para>
                <para>
                    Any user we want to track in any way needs to be watched so that their statistics and status are updated
                    properly via server side events. This seems extreme and wasteful, but the only alternative is to periodically
                    spam the server for the information instead of letting the server spam the client when things change.
                </para>
            </remarks>
            <param name="username">The username of the peer.</param>
            <returns>The operation context.</returns>
        </member>
    </members>
</doc>
