public function login($nick, $realname, $usermode = 0, $username = null,
        $password = null
    ) {
        $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: logging in',
            __FILE__, __LINE__
        );

        $this->_nick = str_replace(' ', '', $nick);
        $this->_realname = $realname;

        if ($username !== null) {
            $this->_username = str_replace(' ', '', $username);
        } else {
            $this->_username = str_replace(' ', '', exec('whoami'));
        }

        if ($password !== null) {
            $this->_password = $password;
            $this->send('PASS '.$this->_password, SMARTIRC_CRITICAL);
        }

        if (!is_numeric($usermode)) {
            $ipos = strpos($usermode, 'i');
            $wpos = strpos($usermode, 'w');
            $val = 0;
            if ($ipos) $val += 8;
            if ($wpos) $val += 4;

            if ($val == 0) {
                $this->log(SMARTIRC_DEBUG_NOTICE, 'DEBUG_NOTICE: login() usermode ('
                    .$usermode.') is not valid, using 0 instead',
                    __FILE__, __LINE__
                );
            }
            $usermode = $val;
        }

        $this->send('NICK '.$this->_nick, SMARTIRC_CRITICAL);
        $this->send('USER '.$this->_username.' '.$usermode.' '.SMARTIRC_UNUSED
            .' :'.$this->_realname, SMARTIRC_CRITICAL
        );

        if (count($this->_performs)) {
            // if we have extra commands to send, do it now
            foreach ($this->_performs as $command) {
                $this->send($command, SMARTIRC_HIGH);
            }
            // if we sent "ns auth" commands, we may need to resend our nick
            $this->send('NICK '.$this->_nick, SMARTIRC_HIGH);
        }

        return $this;
    }