private static function enumerateWildcards(
        Header $header,
        $directive,
        $sources
    ) {
        Types::assert(['string' => [$directive, $sources]], [2, 3]);

        if (preg_match_all(self::CSP_SOURCE_WILDCARD_RE, $sources, $matches))
        {
            if ( ! in_array($directive, self::$cspSensitiveDirectives))
            {
                # if we're not looking at one of the above, we'll
                # be a little less strict with data:
                if (($key = array_search('data:', $matches[0])) !== false)
                {
                    unset($matches[0][$key]);
                }
            }

            if ( ! empty($matches[0]))
            {
                $friendlyHeader = $header->getFriendlyName();

                return new Error(
                    $friendlyHeader . ' ' . (count($matches[0]) > 1 ?
                        'contains the following wildcards '
                        : 'contains a wildcard ')
                    . '<b>' . implode(', ', $matches[0]) . '</b> as a
                        source value in <b>' . $directive . '</b>; this can
                        allow anyone to insert elements covered by
                        the <b>' . $directive . '</b> directive into the
                        page.',

                    E_USER_WARNING
                );
            }
        }

        return null;
    }