/// <summary>
        ///     Open a WebSocket connection using the <see cref="K8sChannelProtocol.V1"/> sub-protocol.
        /// </summary>
        /// <param name="client">
        ///     The Kubernetes API client.
        /// </param>
        /// <param name="targetUri">
        ///     The target URI.
        /// </param>
        /// <param name="cancellationToken">
        ///     An optional cancellation token that can be used to cancel the request.
        /// </param>
        /// <returns>
        ///     The configured <see cref="WebSocket"/>.
        /// </returns>
        public static Task <WebSocket> ConnectWebSocket(this KubeApiClient client, string targetUri, CancellationToken cancellationToken = default)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }

            if (String.IsNullOrWhiteSpace(targetUri))
            {
                throw new ArgumentException("Argument cannot be null, empty, or entirely composed of whitespace: 'targetUri'.", nameof(targetUri));
            }

            return(client.ConnectWebSocket(new Uri(client.ApiEndPoint, targetUri), cancellationToken));
        }
        /// <summary>
        ///     Open a WebSocket connection using the <see cref="K8sChannelProtocol.V1"/> sub-protocol.
        /// </summary>
        /// <param name="client">
        ///     The Kubernetes API client.
        /// </param>
        /// <param name="targetUri">
        ///     The template used to generate the target URI.
        /// </param>
        /// <param name="templateParameters">
        ///     A <see cref="Dictionary{TKey, TValue}"/> containing the template parameters.
        /// </param>
        /// <param name="cancellationToken">
        ///     An optional cancellation token that can be used to cancel the request.
        /// </param>
        /// <returns>
        ///     The configured <see cref="WebSocket"/>.
        /// </returns>
        public static Task <WebSocket> ConnectWebSocket(this KubeApiClient client, UriTemplate targetUri, Dictionary <string, string> templateParameters, CancellationToken cancellationToken = default)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }

            if (targetUri == null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }

            if (templateParameters == null)
            {
                throw new ArgumentNullException(nameof(templateParameters));
            }

            return(client.ConnectWebSocket(
                       targetUri.Populate(client.ApiEndPoint, templateParameters),
                       cancellationToken
                       ));
        }
        /// <summary>
        ///     Open a WebSocket connection using the <see cref="K8sChannelProtocol.V1"/> sub-protocol.
        /// </summary>
        /// <typeparam name="TParameters">
        ///     The type to use use as template parameters.
        /// </typeparam>
        /// <param name="client">
        ///     The Kubernetes API client.
        /// </param>
        /// <param name="targetUri">
        ///     The target URI or URI template.
        /// </param>
        /// <param name="uriTemplateParameters">
        ///     The <typeparamref name="TParameters"/> whose properties will be used as template parameters.
        /// </param>
        /// <param name="cancellationToken">
        ///     An optional cancellation token that can be used to cancel the request.
        /// </param>
        /// <returns>
        ///     The configured <see cref="WebSocket"/>.
        /// </returns>
        public static Task <WebSocket> ConnectWebSocket <TParameters>(this KubeApiClient client, string targetUri, TParameters uriTemplateParameters, CancellationToken cancellationToken = default)
            where TParameters : class
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }

            if (uriTemplateParameters == null)
            {
                throw new ArgumentNullException(nameof(uriTemplateParameters));
            }

            var parameters = new Dictionary <string, string>();

            // yesyesyes, reflection might be "slow", but it's still blazingly fast compared to making a request over the network.
            foreach (PropertyInfo property in typeof(TParameters).GetTypeInfo().DeclaredProperties)
            {
                // Ignore write-only properties.
                if (!property.CanRead)
                {
                    continue;
                }

                // Public instance properties only.
                if (!property.GetMethod.IsPublic || property.GetMethod.IsStatic)
                {
                    continue;
                }

                parameters.Add(property.Name,
                               property.GetValue(uriTemplateParameters)?.ToString()
                               );
            }

            return(client.ConnectWebSocket(new UriTemplate(targetUri), parameters, cancellationToken));
        }