public static function fulltext_search_filter($value, $attributes, $mode = 1)
    {
        if (empty($attributes)) {
            $attributes = array('cn');
        }

        $groups = array();
        $value = str_replace('*', '', $value);
        $words = $mode == 0 ? rcube_utils::tokenize_string($value, 1) : array($value);

        // set wildcards
        $wp = $ws = '';
        if ($mode != 1) {
            $ws = '*';
            $wp = !$mode ? '*' : '';
        }

        // search each word in all listed attributes
        foreach ($words as $word) {
            $parts = array();
            foreach ($attributes as $attr) {
                $parts[] = "($attr=$wp" . self::quote_string($word) . "$ws)";
            }
            $groups[] = '(|' . join('', $parts) . ')';
        }

        return count($groups) > 1 ? '(&' . join('', $groups) . ')' : join('', $groups);
    }