public function getInfo($token, $info, $args = array())
    {
        if ($token instanceof \Erebot\Module\IrcTracker\Token) {
            $methods = array(
                self::INFO_ISON     => 'isOn',
                self::INFO_MASK     => 'getMask',
                self::INFO_NICK     => 'getNick',
                self::INFO_IDENT    => 'getIdent',
                self::INFO_HOST     => 'getHost',
            );
            if (!isset($methods[$info])) {
                throw new \Erebot\InvalidValueException('No such information');
            }
            array_unshift($args, $token, $methods[$info]);
            return call_user_func($args);
        }

        $fmt = $this->getFormatter(null);
        if (is_string($token)) {
            $collator   = $this->connection->getCollator();
            $token      = $collator->normalizeNick(
                self::extractNick($token)
            );
            $token = array_search($token, $this->nicks);
            if ($token === false) {
                throw new \Erebot\NotFoundException(
                    $fmt->_('No such user')
                );
            }
        }

        if (!isset($this->ial[$token])) {
            throw new \Erebot\NotFoundException($fmt->_('No such token'));
        }

        $info = strtolower($info);
        if ($info == 'mask') {
            if ($this->ial[$token]['ident'] === null) {
                return $this->ial[$token]['nick'].'!*@*';
            }
            return  $this->ial[$token]['nick'].'!'.
                    $this->ial[$token]['ident'].'@'.
                    $this->ial[$token]['host'];
        }

        if (!array_key_exists($info, $this->ial[$token])) {
            throw new \Erebot\InvalidValueException(
                $fmt->_('No such information')
            );
        }
        return $this->ial[$token][$info];
    }