/// <summary>
        /// Tries to get the host instance for a WebSocket service with
        /// the specified <paramref name="path"/>.
        /// </summary>
        /// <remarks>
        /// <paramref name="path"/> is converted to a URL-decoded string and
        /// / is trimmed from the end of the converted string if any.
        /// </remarks>
        /// <returns>
        /// <c>true</c> if the service is successfully found;
        /// otherwise, <c>false</c>.
        /// </returns>
        /// <param name="path">
        /// A <see cref="string"/> that represents an absolute path to
        /// the service to find.
        /// </param>
        /// <param name="host">
        ///   <para>
        ///   When this method returns, a <see cref="WebSocketServiceHostBase"/>
        ///   instance or <see langword="null"/> if not found.
        ///   </para>
        ///   <para>
        ///   That host instance provides the function to access
        ///   the information in the service.
        ///   </para>
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="path"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///   <para>
        ///   <paramref name="path"/> is empty.
        ///   </para>
        ///   <para>
        ///   -or-
        ///   </para>
        ///   <para>
        ///   <paramref name="path"/> is not an absolute path.
        ///   </para>
        ///   <para>
        ///   -or-
        ///   </para>
        ///   <para>
        ///   <paramref name="path"/> includes either or both
        ///   query and fragment components.
        ///   </para>
        /// </exception>
        public bool TryGetServiceHost(string path, out WebSocketServiceHostBase host)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            if (path.Length == 0)
            {
                throw new ArgumentException("An empty string.", "path");
            }

            if (path[0] != '/')
            {
                throw new ArgumentException("Not an absolute path.", "path");
            }

            if (path.IndexOfAny(new[] { '?', '#' }) > -1)
            {
                var msg = "It includes either or both query and fragment components.";
                throw new ArgumentException(msg, "path");
            }

            return(InternalTryGetServiceHost(path, out host));
        }
        internal bool InternalTryGetServiceHost(
            string path, out WebSocketServiceHostBase host
            )
        {
            path = HttpUtility.UrlDecode(path).TrimSlashFromEnd();

            lock (_sync)
                return(_hosts.TryGetValue(path, out host));
        }