public virtual ProxySocket GetPreparedSocket(IPAddress address, int port)
        {
            //Creates the Socket for sending data over TCP.
            ProxySocket proxySocket = new ProxySocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            // incorporate the connection settings like proxy's
            // Note: ProxyType is in MSNPSharp namespace, ProxyTypes in ProxySocket namespace.

            if (ConnectivitySettings.ProxyType == ProxyType.None)
            {
                proxySocket.ProxyType = ProxyTypes.None;
            }
            else
            {
                // set the proxy type
                switch (ConnectivitySettings.ProxyType)
                {
                    case ProxyType.Socks4:
                        proxySocket.ProxyType = ProxyTypes.Socks4;
                        break;

                    case ProxyType.Socks5:
                        proxySocket.ProxyType = ProxyTypes.Socks5;
                        break;

                    case ProxyType.Http:
                        proxySocket.ProxyType = ProxyTypes.Http;
                        break;
                }

                proxySocket.ProxyUser = ConnectivitySettings.ProxyUsername;
                proxySocket.ProxyPass = ConnectivitySettings.ProxyPassword;

                // resolve the proxy host
                if (proxyEndPoint == null)
                {
                    bool worked = false;
                    int retries = 0;
                    Exception exp = null;

                    //we retry a few times, because dns resolve failure is quite common
                    do
                    {
                        try
                        {
                            System.Net.IPAddress ipAddress = Network.DnsResolve(ConnectivitySettings.ProxyHost);

                            // assign to the connection object so other sockets can make use of it quickly
                            proxyEndPoint = new IPEndPoint(ipAddress, ConnectivitySettings.ProxyPort);

                            worked = true;
                        }
                        catch (Exception e)
                        {
                            retries++;
                            exp = e;
                        }
                    } while (!worked && retries < 3);

                    if (!worked)
                        throw new ConnectivityException("DNS Resolve for the proxy server failed: " + ConnectivitySettings.ProxyHost + " failed.", exp);
                }

                proxySocket.ProxyEndPoint = proxyEndPoint;
            }

            //Send operations will timeout of confirmation is not received within 3000 milliseconds.
            proxySocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 3000);

            //Socket will linger for 2 seconds after close is called.
            LingerOption lingerOption = new LingerOption(true, 2);
            proxySocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lingerOption);

            try
            {
                proxySocket.Bind(new IPEndPoint(address, port));
            }
            catch (SocketException ex)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "An error occured while trying to bind to a local address, error code: " + ex.ErrorCode + ".");
            }

            return proxySocket;
        }