private void Stop(ConnectionStates state)
        {
            if (timer != null)
            {
                timer.Dispose();
                timer = null;
            }

            if (reconnectTimer != null)
            {
                reconnectTimer.Dispose();
                reconnectTimer = null;
            }

            if (ircServer != null)
            {
                ircServer.Dispose();
                ircServer = null;
            }

            IsRunning = false;

            if (ConnectionState != null)
            {
                ConnectionState.BeginInvoke(this, new ConnectionStateEventArgs(state), null, null);
            }
        }
        private bool ProcessServerMessage(string line, int spacePos)
        {
            // Get the number out of the message
            // :wormnet1.team17.com 322 Test #Help 10 :05 A place to get help, or help others
            int number;
            int spacePos2 = line.IndexOf(' ', spacePos + 1);

            if (spacePos2 == -1 || !int.TryParse(line.Substring(spacePos + 1, spacePos2 - spacePos - 1), out number))
            {
                return(false);
            }

            // Find the space after our nickname in the message
            spacePos = line.IndexOf(' ', spacePos2 + 1);
            if (spacePos == -1)
            {
                return(false);
            }
            spacePos++; // we will start all the regex match from this position

            // Process the message
            switch (number)
            {
            // Connection success
            case 4:
                spacePos2 = line.IndexOf(' ', spacePos);
                if (spacePos2 != -1)
                {
                    this.serverIrcAddress = ':' + line.Substring(spacePos, spacePos2 - spacePos).ToLower();

                    //if (!this.IsWormNet)
                    //    Send("authserv auth " + this.User.Name + " " + Properties.Settings.Default.WormsPassword);

                    if (ConnectionState != null)
                    {
                        ConnectionState.BeginInvoke(this, new ConnectionStateEventArgs(ConnectionStates.Connected), null, null);
                    }
                }
                break;

            // This nickname is already in use!
            case 433:
                if (serverIrcAddress == string.Empty)
                {
                    return(true);
                }
                else
                {
                    // nickname is in use when we tried to change with /NICK command
                    GlobalManager.UITasks.Enqueue(new NickNameInUseTask(this));
                }
                break;

            // A channel (answer for the LIST command)
            case 322:
                // :wormnet1.team17.com 322 Test #Help 10 :05 A place to get help, or help others
                Match chMatch = channelRegex.Match(line, spacePos);
                if (chMatch.Success)
                {
                    string channelName = chMatch.Groups[1].Value;
                    string description = chMatch.Groups[3].Value;

                    if (!channelListHelper.ContainsKey(channelName))
                    {
                        channelListHelper.Add(channelName, description);
                    }
                }
                break;

            // LIST END
            case 323:
                GlobalManager.UITasks.Enqueue(new ChannelListUITask(this, channelListHelper));
                break;

            // A client (answer for WHO command)
            case 352:
                // :wormnet1.team17.com 352 Test #AnythingGoes ~UserName no.address.for.you wormnet1.team17.com Herbsman H :0 68 7 LT The Wheat Snooper 2.8
                Match clMatch = clientRegex.Match(line, spacePos);
                if (clMatch.Success)
                {
                    string   channelHash = clMatch.Groups[1].Value.ToLower();
                    string   clan        = clMatch.Groups[2].Value.ToLower() == "username" ? string.Empty : clMatch.Groups[2].Value;
                    string   clientName  = clMatch.Groups[3].Value;
                    string[] realName    = clMatch.Groups[4].Value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);  // 68 7 LT The Wheat Snooper

                    CountryClass country            = CountriesClass.DefaultCountry;
                    int          rank               = 0;
                    bool         clientGreatSnooper = false;
                    string       clientApp          = clMatch.Groups[4].Value;

                    if (realName.Length >= 3)
                    {
                        if (int.TryParse(realName[1], out rank))
                        {
                            if (rank > 13)
                            {
                                rank = 13;
                            }
                            if (rank < 0)
                            {
                                rank = 0;
                            }
                        }

                        int countrycode;
                        if (int.TryParse(realName[0], out countrycode) && countrycode >= 0 && countrycode <= 52)
                        {
                            if (countrycode == 49 && realName[2].Length == 2)     // use cc as countricode
                            {
                                if (realName[2] == "UK")
                                {
                                    realName[2] = "GB";
                                }
                                else if (realName[2] == "EL")
                                {
                                    realName[2] = "GR";
                                }
                                country = CountriesClass.GetCountryByCC(realName[2]);
                            }
                            else
                            {
                                country = CountriesClass.GetCountryByID(countrycode);
                            }
                        }
                        else if (realName[2].Length == 2)     // use cc if countrycode is bigger than 52
                        {
                            if (realName[2] == "UK")
                            {
                                realName[2] = "GB";
                            }
                            else if (realName[2] == "EL")
                            {
                                realName[2] = "GR";
                            }
                            country = CountriesClass.GetCountryByCC(realName[2]);
                        }

                        clientGreatSnooper = realName.Length >= 6 && realName[3] == "Great" && realName[4] == "Snooper" && gsVersionRegex.IsMatch(realName[5]);
                        StringBuilder sb = new StringBuilder();
                        for (int i = 3; i < realName.Length; i++)
                        {
                            sb.Append(realName[i]);
                            if (i + 1 < realName.Length)
                            {
                                sb.Append(" ");
                            }
                        }
                        clientApp = sb.ToString();
                    }

                    GlobalManager.UITasks.Enqueue(new ClientUITask(this, channelHash, clientName, country, clan, rank, clientGreatSnooper, clientApp));
                }
                break;

            // The user is offline message
            case 401:
                // :wormnet1.team17.com 401 Test sToOMiToO :No such nick/channel
                spacePos2 = line.IndexOf(' ', spacePos);
                if (spacePos2 != -1)
                {
                    string clientName = line.Substring(spacePos, spacePos2 - spacePos);
                    GlobalManager.UITasks.Enqueue(new OfflineUITask(this, clientName));
                }
                break;
            }

            return(false);
        }