public function getParams()
    {
        if ($this->cachedParams) {
            return $this->cachedParams;
        }

        $CMDS = [];
        $KEYS = [];
        $ARGV = [];
        $KEYNUM = 0;
        $ARGNUM = 0;

        foreach ($this->stack as $part) {
            list($cmd, $keys, $argv) = $part;

            if (!empty($keys)) {
                $cmd = preg_replace_callback('~KEYS\[(\d+)\]~', function ($m) use (&$KEYS, &$KEYNUM, $keys) {
                    $key = $keys[$m[1] - 1];
                    if (!isset($KEYS[$key])) {
                        $KEYS[$key] = ++$KEYNUM;
                    }
                    return 'KEYS[' . $KEYS[$key] . ']';
                }, $cmd);
            }

            if (!empty($argv)) {
                $cmd = preg_replace_callback('~ARGV\[(\d+)\]~', function ($m) use (&$ARGV, &$ARGNUM, $argv) {
                    $arg = $argv[$m[1] - 1];
                    if (!isset($ARGV[$arg])) {
                        $ARGV[$arg] = ++$ARGNUM;
                    }
                    return 'ARGV[' . $ARGV[$arg] . ']';
                }, $cmd);
            }

            $CMDS[] = $cmd;
        }

        return $this->cachedParams = array_merge(
            [implode(';', $CMDS), count($KEYS)],
            array_keys($KEYS),
            array_keys($ARGV)
        );
    }