public static function off($class, $name, $handler = null)
    {
        $class = ltrim($class, '\\');
        if (empty(self::$_events[$name][$class]) && empty(self::$_eventWildcards[$name][$class])) {
            return false;
        }
        if ($handler === null) {
            unset(self::$_events[$name][$class]);
            unset(self::$_eventWildcards[$name][$class]);
            return true;
        }

        // plain event names
        if (isset(self::$_events[$name][$class])) {
            $removed = false;
            foreach (self::$_events[$name][$class] as $i => $event) {
                if ($event[0] === $handler) {
                    unset(self::$_events[$name][$class][$i]);
                    $removed = true;
                }
            }
            if ($removed) {
                self::$_events[$name][$class] = array_values(self::$_events[$name][$class]);
                return $removed;
            }
        }

        // wildcard event names
        $removed = false;
        if (isset(self::$_eventWildcards[$name][$class])) {
            foreach (self::$_eventWildcards[$name][$class] as $i => $event) {
                if ($event[0] === $handler) {
                    unset(self::$_eventWildcards[$name][$class][$i]);
                    $removed = true;
                }
            }
            if ($removed) {
                self::$_eventWildcards[$name][$class] = array_values(self::$_eventWildcards[$name][$class]);
                // remove empty wildcards to save future redundant regex checks :
                if (empty(self::$_eventWildcards[$name][$class])) {
                    unset(self::$_eventWildcards[$name][$class]);
                    if (empty(self::$_eventWildcards[$name])) {
                        unset(self::$_eventWildcards[$name]);
                    }
                }
            }
        }

        return $removed;
    }