void ConnectThread(object _maxRetryCount)
        {
            int maxRetryCount = _maxRetryCount as int? ?? 0;
            int waitTime      = 500;

            netClient = new TcpClient();
            for (int i = 0; i <= maxRetryCount; ++i, waitTime *= 2)
            {
                try
                {
                    netClient = new TcpClient();
                    var asyncResult = netClient.BeginConnect(hostname, port, null, null);

                    try
                    {
                        // Stop what we're doing if the connection is cancelled from the main thread
                        if (EventWaitHandle.WaitAny(new WaitHandle[] { connectDone, asyncResult.AsyncWaitHandle }) == 0)
                        {
                            netClient.Close();
                            netClient = null;

                            return;
                        }

                        netClient.EndConnect(asyncResult);
                    }
                    finally
                    {
                        asyncResult.AsyncWaitHandle.Close();
                    }

                    break;
                }
                catch (SocketException ex)
                {
                    if (i == maxRetryCount)
                    {
                        NotifyConnectionResult(false, ex.Message);
                        return;
                    }
                    else
                    {
                        Thread.Sleep(waitTime);
                    }
                }
            }

            // If the main thread cancels the connection, this will be set to true
            bool itsOver = false;

            client.Connect(netClient.GetStream());
            client.LogIn(username, password, (sender, e) =>
            {
                if (itsOver)
                {
                    return;
                }

                NotifyConnectionResult(e.Success, e.ResultMessage);

                connectDone.Set();
            });

            connectDone.WaitOne();
            itsOver = true;
        }