/// <summary>
        /// Asynchronously connects using the specified information.
        /// </summary>
        /// <param name="nickname">The desired nickname.</param>
        /// <param name="realName">The desired real name.</param>
        /// <param name="mode">The desired mode. Most modes must be set after connecting.</param>
        /// <param name="password">Optional. The password, if any.</param>
        /// <returns>True if the connection attempt was successful; false otherwise.</returns>
        public async Task <bool> ConnectAsync(string nickname, string realName, IrcUserLoginModes mode, string password = "")
        {
            Validate.IsNotDisposed(this._disposed);
            Validate.HasText(nickname, "nickname");
            Validate.HasText(realName, "realName");
            Validate.IsEnumValue(mode, "mode");
            Validate.IsNotNull(password, "password");
            IrcValidate.IsNotConnected(this.IsConnected);

            if (await this.Client.ConnectAsync())
            {
                this.IsConnected = true;

                if (password.HasText())
                {
                    this.SendPassword(password);
                }
                this.SendUserNames(nickname, realName, mode);
                this.ChangeNickname(nickname);
                this.CurrentUser.Nickname = nickname;
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Authenticates using a nickname and a real name, as well as the desired mode.
        /// This is a mandatory part of the authentication process.
        /// </summary>
        private void SendUserNames(string userName, string realName, IrcUserLoginModes mode)
        {
            this.CurrentUser.UserName = userName;
            this.CurrentUser.RealName = realName;

            // USER <user name> <mode> * :<real name>
            this.Send("USER", userName, ((int)mode).ToString(), "*", ":", realName);
        }