public static bool TryNormalizeYoutubeUrl(string url, out string normalizedUrl)
        {
            // If you fix something in here, please be sure to fix in 
            // YouTubeService.TryNormalize as well.

            normalizedUrl = null;

            var builder = new StringBuilder(url);

            url = builder.Replace("youtu.be/", "youtube.com/watch?v=")
                .Replace("youtube.com/embed/", "youtube.com/watch?v=")
                .Replace("/v/", "/watch?v=")
                .Replace("/watch#", "/watch?")
                .ToString();

            string value;

            var query = new Query(url);

            if (!query.TryGetValue("v", out value))
                return false;

            normalizedUrl = "https://youtube.com/watch?v=" + value;
            return true;
        }
        private async Task<string> DecryptAsync(string uri)
        {
            var query = new Query(uri);

            string signature;
            if (!query.TryGetValue("signature", out signature))
                return uri;

            string js = 
				await sourceFactory(jsPlayer)
                .ConfigureAwait(false);

            query["signature"] = DecryptedSignature(signature, js);
            return query.ToString();
        }
        private async Task<string> DecryptAsync(string uri, Func<DelegatingClient> makeClient)
        {
            var query = new Query(uri);

            string signature;
            if (!query.TryGetValue("signature", out signature))
                return uri;

            string js =
                await makeClient()
                .GetStringAsync(jsPlayer)
                .ConfigureAwait(false);

            query["signature"] = DecryptedSignature(signature, js);
            return query.ToString();
        }