Display command/action help by parse method annotations
@param string $method
@param string $action
@param array  $aliases
@return int
@throws \ReflectionException
770772
protected function showHelpByMethodAnnotations(string $method, string $action = '', array $aliases = []): int
    {
        $ref  = new \ReflectionClass($this);
        $name = $this->input->getCommand();

        $this->logf(
            Console::VERB_CRAZY,
            'display help info for the method=%s, action=%s, class=%s',
            $method, $action, static::class
        );

        if (!$ref->hasMethod($method)) {
            $this->write("The command [<info>$name</info>] don't exist in the group: " . static::getName());
            return 0;
        }

        // is a console controller command
        if ($action && !$ref->getMethod($method)->isPublic()) {
            $this->write("The command [<info>$name</info>] don't allow access in the class.");
            return 0;
        }

        $doc     = $ref->getMethod($method)->getDocComment();
        $tags    = PhpDoc::getTags($this->parseCommentsVars($doc));
        $isAlone = $ref->isSubclassOf(CommandInterface::class);
        $help    = [];

        if ($aliases) {
            $realName         = $action ?: self::getName();
            $help['Command:'] = \sprintf('%s(alias: <info>%s</info>)', $realName, \implode(',', $aliases));
        }

        foreach (\array_keys(self::$annotationTags) as $tag) {
            if (empty($tags[$tag]) || !\is_string($tags[$tag])) {
                // for alone command
                if ($tag === 'description' && $isAlone) {
                    $help['Description:'] = self::getDescription();
                    continue;
                }

                if ($tag === 'usage') {
                    $help['Usage:'] = $this->commentsVars['fullCommand'] . ' [--options ...] [arguments ...]';
                }

                continue;
            }

            // $msg = trim($tags[$tag]);
            $msg = $tags[$tag];
            $tag = \ucfirst($tag);

            // for alone command
            if (!$msg && $tag === 'description' && $isAlone) {
                $msg = self::getDescription();
            } else {
                $msg = \preg_replace('#(\n)#', '$1 ', $msg);
            }

            $help[$tag . ':'] = $msg;
        }

        if (isset($help['Description:'])) {
            $description = $help['Description:'] ?: 'No description message for the command';
            $this->write(\ucfirst($description) . \PHP_EOL);
            unset($help['Description:']);
        }

        $help['Group Options:']  = null;
        $help['Global Options:'] = FormatUtil::alignOptions(Application::getGlobalOptions());

        $this->beforeRenderCommandHelp($help);

        $this->output->mList($help, [
            'sepChar'     => '  ',
            'lastNewline' => 0,
        ]);

        return 0;
    }
1262305
public String getAction(final Method method) {
        final Annotation[] annotations = method.getAnnotations();
        return this.getAction(annotations, method);
    }
656230
public function renderCall($method, array $arguments = [], $semicolon = false, $newLine = false)
    {
        return $this->renderCode(
            $method.$this->renderArguments($arguments),
            $semicolon,
            $newLine
        );
    }
120627
private function callCountBy(string $method, array $arguments)
    {
        $whereByWithUpper = lcfirst(substr($method, 7, mb_strlen($method)));
        $whereBy = Str::convertCamelCaseToSnakeCase($whereByWithUpper);

        $column = (isset($arguments[1])) ? $arguments[1] : '*';

        return $this->where($whereBy, '=', $arguments[0])->count($column);
    }
936285
protected function executeCliAction(Config\Action $action) : void
    {
        // since the cli has no straight way to communicate back to php
        // cli hooks have to handle sync stuff by them self
        // so no 'beforeAction' or 'afterAction' is called here
        $runner = new Action\Cli();
        $runner->execute($this->io, $action, $this->arguments);
    }
1232886
private function addCallback(string $method, $state) : void
    {
        $state = $this->makeCallable($state);
        $this->actions[$method] = $state;
    }
988833
private function _action($params)
    {
        // Shift and get the method
        $method = array_shift($params);

        // Behavior
        if ($this->behaviors[$method]) {
            $this->behaviors[$method]();
        }

        if (!isset($this->routes[$method])) {
            $this->_defaultAction();
        }

        // Get corresponding method name
        $method = $this->routes[$method];

        if (!method_exists($this, $method)) {
            $this->_defaultAction();
        }

        return call_user_func_array([$this, $method], $params);
    }
925202
private static function executeAction($actionContext) {
        $controller = $actionContext->getController();
        $actionName = $actionContext->getActionName();
        $action = new \ReflectionMethod($controller, $actionName);

        if (!$action->isPublic()) {
            throw new \Exception('Action methods must have a public modifier. The action call "' . $actionName . '" is denied.');
        }

        return $action->invokeArgs($controller, $actionContext->getArguments());
    }
1356157
private function getOperation(Action $action, EnvironmentInterface $environment)
    {
        /** @var Contao2BackendViewDefinitionInterface $definition */
        $definition = $environment->getDataDefinition()->getDefinition(Contao2BackendViewDefinitionInterface::NAME);
        $name       = $action->getName();
        $commands   = $definition->getModelCommands();

        if (!$commands->hasCommandNamed($name)) {
            return null;
        }

        return $commands->getCommandNamed($name);
    }
579774
public function getMethodByAction($action)
    {
        foreach ($this->methods as $method => $actions) {
            if (in_array($action, $actions)) {
                return $method;
            }
        }

        return 'get';
    }
229113
protected function afterRunInBreadCrumbSupport($action, $view, $method) {
        /**@var Annotation $ann */
        $ann = $method->anns;
        if ($view instanceof View) {
            $breadCrumbs = [];
            $crumb       = $ann->getString('crumb');
            if ($crumb && preg_match('#^([a-z][a-z_\d]*)-(\d+)(\s+.*)?$#i', trim($crumb), $ms)) {
                $sname       = '_wula_bdCbs_' . $ms[1];
                $breadCrumbs = sess_get($sname, []);
                $level       = intval($ms[2]);
                $data        = $view->getData();
                $title       = isset($data['crumbTitle']) && $data['crumbTitle'] ? $data['crumbTitle'] : false;
                if (!$title && isset($ms[3])) {
                    $title = trim($ms[3]);
                }
                if ($title) {
                    $breadCrumbs[ $level ] = [$title, Router::getFullURI()];
                    ksort($breadCrumbs);
                    $breadCrumbs        = array_slice($breadCrumbs, 0, $level + 1, true);
                    $_SESSION[ $sname ] = $breadCrumbs;
                }
            }

            if ($crumb && $breadCrumbs) {
                $view->assign('breadCrumbs', $breadCrumbs);
            }
        }
        unset($ann);

        return $view;
    }
1024739
public static function getAroundActions($clazz, $action) {
        $actions = null;
        if (isset(static::$aroundActions[ $clazz ]) && static::$aroundActions[ $clazz ]) {
            $actions = static::buildActions(static::$aroundActions[ $clazz ], $action);
        }
        if ($actions && count($actions) > 0) {
            return $actions[ 0 ];
        }
        return null;
    }
1078031
protected function runActionMethod($action, $vars = array()) {
		return call_user_func_array(
		    array($this, $action),
            $this->getActionArguments($action, $vars)
        );
	}
416390
private function getControllerActionAnnotations($controller, $action)
    {
        if ($controller instanceof \Closure) {
            return $this->annotation->readFunction($controller);
        }

        return $this->annotation->readMethod($controller, $action . 'Action');
    }
420057
public String getAction(final Class<?> clazz, final Method method) {
        final Annotation[] annotations = clazz.getAnnotations();
        return this.getAction(annotations, method);
    }
426891
public static function getMethodFromAction(string $action): string
    {
        $method = str_replace(['.', '-', '_'], ' ', $action);
        $method = ucwords($method);
        $method = str_replace(' ', '', $method);
        $method = lcfirst($method);
        $method .= 'Action';
        return $method;
    }
164929
protected function parseAction($action)
	{
		// If the action is already a Closure instance, we will just set that instance
		// as the "uses" property, because there is nothing else we need to do when
		// it is available. Otherwise we will need to find it in the action list.
		if (is_callable($action))
		{
			return array('uses' => $action);
		}

		// If no "uses" property has been set, we will dig through the array to find a
		// Closure instance within this list. We will set the first Closure we come
		// across into the "uses" property that will get fired off by this route.
		elseif ( ! isset($action['uses']))
		{
			$action['uses'] = $this->findCallable($action);
		}

		return $action;
	}