protected function getCommands()
    {
        // construct command classes path depending on grp_cmd flag
        $cmdPath = rtrim(__DIR__ . "/" . $this->data['cmd_path'], '/') . '/';
        $cmdPath .= ($this->data['grp_cmd']) ? "*/*.php" : "*.php";

        // construct commad path regex depending on grp_cmd flag
        $cmdPattern = ($this->data['grp_cmd'])
            ? '/^.*\/([^\/]+)\/([^\/]+)\.php$/'
            : '/^.*\/([^\/]+)\.php$/';

        // find all command files and commands
        $commands = [];
        foreach (glob($cmdPath) as $file) {
           // match only php files, extract group dir name
            if (!preg_match($cmdPattern, $file, $matches)) {
                continue;
            }

            // construct a class name from our namespace, optional
            // command group subdir and actual class file name
            $className = __NAMESPACE__ . "\\" . str_replace("/", "\\", $this->data['cmd_path']) . $matches[1];
            $className .= ($this->data['grp_cmd']) ? "\\" . $matches[2] : "";

            // skip if class doesn't exist
            if (!class_exists($className)) {
                continue;
            }

            // add to our commands list
            $commands []= $className;
        }

        if (!empty($this->data['config']['extra_commands']) && is_array($this->data['config']['extra_commands'])) {
            $commands = array_merge($commands, $this->data['config']['extra_commands']);
        }

        return $commands;
    }