public function generateHook($type, $programPath, $programName = null, $multiple = false)
    {
        if (!isset(self::$hooks[$type])) {
            throw new \RuntimeException(sprintf(
                "Cannot generate hook for unknown shell type '%s'. Available hooks are: %s",
                $type,
                implode(', ', self::getShellTypes())
            ));
        }

        // Use the program path if an alias/name is not given
        $programName = $programName ?: $programPath;

        if ($multiple) {
            $completionCommand = '$1 _completion';
        } else {
            $completionCommand = $programPath . ' _completion';
        }

        // Pass shell type during completion so output can be encoded if the shell requires it
        $completionCommand .= " --shell-type $type";

        return str_replace(
            array(
                '%%function_name%%',
                '%%program_name%%',
                '%%program_path%%',
                '%%completion_command%%',
            ),
            array(
                $this->generateFunctionName($programPath, $programName),
                $programName,
                $programPath,
                $completionCommand
            ),
            $this->stripComments(self::$hooks[$type])
        );
    }