public function call($hookName, $arg = '')
    {
        $hookName = $this->sanitize($hookName);
        if (!$hookName) {
            return false;
        }
        if (! isset($this->actions[$hookName])) {
            $this->actions[$hookName] = 1;
        } else {
            $this->actions[$hookName]++;
        }

        // Do 'all' actions first
        if (isset($this->filters['all'])) {
            $this->current[] = $hookName;
            $all_args = func_get_args();
            $this->callAll($all_args);
        }

        if (!isset($this->filters[$hookName])) {
            if (isset($this->filters['all'])) {
                array_pop($this->current);
            }
            return null;
        }

        if (!isset($this->filters['all'])) {
            $this->current[] = $hookName;
        }

        $args = array();
        if (is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0])) {
            // array(&$this)
            $args[] =& $arg[0];
        } else {
            $args[] = $arg;
        }

        for ($a = 2, $num = func_num_args(); $a < $num; $a++) {
            $args[] = func_get_arg($a);
        }
        // Sort
        if (!isset($this->merged[$hookName])) {
            ksort($this->filters[$hookName]);
            $this->merged[$hookName] = true;
        }
        reset($this->filters[$hookName]);
        do {
            foreach ((array) current($this->filters[$hookName]) as $the_) {
                if (!is_null($the_['function'])) {
                    call_user_func_array(
                        $the_['function'],
                        array_slice($args, 0, (int) $the_['accepted_args'])
                    );
                }
            }
        } while (next($this->filters[$hookName]) !== false);
        array_pop($this->current);

        return true;
    }