public static function executeStoredProc(
        $db,
        $proc,
        $params,
        $wrapper = 'SwatDBDefaultRecordsetWrapper',
        $types = null
    ) {
        if (!is_array($params)) {
            $params = array($params);
        }

        $mdb2_types = $types === null ? true : $types;

        $db->loadModule('Function');
        $rs = $db->function->executeStoredProc(
            $proc,
            $params,
            $mdb2_types,
            true,
            false
        );

        if (MDB2::isError($rs)) {
            throw new SwatDBException($rs);
        }

        // Wrap results. Do it here instead of in MDB2 so we can wrap using
        // an existing object instance.
        if (is_string($wrapper)) {
            $rs = new $wrapper($rs);
        } elseif ($wrapper instanceof SwatDBRecordsetWrapper) {
            $wrapper->initializeFromResultSet($rs);
            $rs = $wrapper;
        }

        return $rs;
    }