public function postEvent($eventName, $params, $pending = false, $plugins = null)
    {
        if ($pending) {
            $this->pendingEvents[] = array($eventName, $params);
        }

        $manager = $this->pluginManager;

        if (empty($plugins)) {
            $plugins = $manager->getPluginsLoadedAndActivated();
        }

        $callbacks = array();

        // collect all callbacks to execute
        foreach ($plugins as $pluginName) {
            if (!is_string($pluginName)) {
                $pluginName = $pluginName->getPluginName();
            }

            if (!isset($this->pluginHooks[$pluginName])) {
                $plugin = $manager->getLoadedPlugin($pluginName);
                $this->pluginHooks[$pluginName] = $plugin->getListHooksRegistered();
            }

            $hooks = $this->pluginHooks[$pluginName];

            if (isset($hooks[$eventName])) {
                list($pluginFunction, $callbackGroup) = $this->getCallbackFunctionAndGroupNumber($hooks[$eventName]);

                if (is_string($pluginFunction)) {
                    $plugin = $manager->getLoadedPlugin($pluginName);
                    $callbacks[$callbackGroup][] = array($plugin, $pluginFunction) ;
                } else {
                    $callbacks[$callbackGroup][] = $pluginFunction;
                }
            }
        }

        if (isset($this->extraObservers[$eventName])) {
            foreach ($this->extraObservers[$eventName] as $callbackInfo) {
                list($callback, $callbackGroup) = $this->getCallbackFunctionAndGroupNumber($callbackInfo);

                $callbacks[$callbackGroup][] = $callback;
            }
        }

        // sort callbacks by their importance
        ksort($callbacks);

        // execute callbacks in order
        foreach ($callbacks as $callbackGroup) {
            foreach ($callbackGroup as $callback) {
                call_user_func_array($callback, $params);
            }
        }
    }