public static async Task <ShoutcastStream> ConnectAsync(Uri serverUrl,
                                                                ShoutcastStreamFactoryConnectionSettings settings)
        {
            //http://www.smackfu.com/stuff/programming/shoutcast.html

            ShoutcastStream shoutStream = null;

            ShoutcastStreamFactoryInternalConnectResult result = await ConnectInternalAsync(serverUrl, settings);

            SocketWrapper socketWrapper = SocketWrapperFactory.CreateSocketWrapper(result);

            shoutStream = new ShoutcastStream(serverUrl, settings, socketWrapper);

            string httpLine = result.httpResponse.Substring(0, result.httpResponse.IndexOf('\n')).Trim();

            if (string.IsNullOrWhiteSpace(httpLine))
            {
                throw new InvalidOperationException("httpLine is null or whitespace");
            }

            var action = ParseHttpCodeAndResponse(httpLine, result.httpResponse, shoutStream);

            //todo handle when we get a text/html page.


            if (action != null)
            {
                switch (action.ActionType)
                {
                case ConnectionActionType.Success:
                    var headers = ParseResponse(result.httpResponse, shoutStream);
                    await shoutStream.HandleHeadersAsync(headers);

                    return(shoutStream);

                case ConnectionActionType.Fail:
                    throw action.ActionException;

                case ConnectionActionType.Redirect:
                {
                    //clean up.
                    shoutStream.Dispose();

                    return(await ConnectAsync(action.ActionUrl, settings));
                }

                default:
                    socketWrapper.Dispose();
                    throw new Exception("We weren't able to connect for some reason.");
                }
            }
            else
            {
                socketWrapper.Dispose();
                throw new Exception("We weren't able to connect for some reason.");
            }
        }
        private async Task ReconnectSocketsAsync()
        {
            cancelTokenSource.Token.ThrowIfCancellationRequested();

            var result = await ShoutcastStreamFactory.ConnectInternalAsync(serverUrl,
                                                                           serverSettings);

            this.socket = SocketWrapperFactory.CreateSocketWrapper(result);

            cancelTokenSource = new CancellationTokenSource();

            streamProcessor = new ShoutcastStreamProcessor(this, socket);
        }