public function execute(...$commandNames)
    {
        $logger = $this->logger;
        $app = $this->getApplication();
        $progname = basename($app->getProgramName());

        // if there is no subcommand to render help, show all available commands.
        $count = count($commandNames);

        if ($count) {
            $cmd = $app;
            for ($i = 0; $cmd && $i < $count; ++$i) {
                $cmd = $cmd->getCommand($commandNames[$i]);
            }

            if (!$cmd) {
                throw new \Exception('Command entry ' . implode(' ', $commandNames) . ' not found');
            }

            if ($brief = $cmd->brief()) {
                $logger->writeln('NAME', 'yellow');
                $logger->writeln("\t<strong_white>" . $cmd->name() . '</strong_white> - ' . $brief);
                $logger->newline();
            }

            if ($aliases = $cmd->aliases()) {
                $logger->writeln('ALIASES', 'yellow');
                $logger->writeln("\t<strong_white>" . implode(', ', $aliases) . '</strong_white>');
                $logger->newline();
            }

            $this->printUsage($cmd);

            $logger->writeln('SYNOPSIS', 'yellow');
            $prototypes = $cmd->getAllCommandPrototype();
            foreach ($prototypes as $prototype) {
                $logger->writeln("\t" . ' ' . $prototype);
            }
            $logger->newline();

            $this->printOptions($cmd);
            $this->printCommand($cmd);
            $this->printHelp($cmd);
        } else {
            // print application
            $cmd = $this->parent;
            $logger->writeln(ucfirst($cmd->brief()), 'strong_white');
            $logger->newline();

            $this->printUsage($cmd);

            $logger->writeln('SYNOPSIS', 'yellow');
            $logger->write("\t" . $progname);
            if (!empty($cmd->getOptionCollection()->options)) {
                $logger->write(' [options]');
            }

            if ($cmd->hasCommands()) {
                $logger->write(' <command>');
            } else {
                foreach ($cmd->getArguments() as $argument) {
                    $logger->write(' <' . $argument->name() . '>');
                }
            }

            $logger->newline();
            $logger->newline();

            $this->printOptions($cmd);
            $this->printCommand($cmd);
            $this->printHelp($cmd);
        }
    }