static gboolean
check_header_in_message_info (CamelMessageInfo *info,
                              gint argc,
                              struct _CamelSExpResult **argv,
                              camel_search_match_t how,
                              gboolean *matched)
{
	struct _KnownHeaders {
		const gchar *header_name;
		guint info_key;
	} known_headers[] = {
		{ "Subject", CAMEL_MESSAGE_INFO_SUBJECT },
		{ "From", CAMEL_MESSAGE_INFO_FROM },
		{ "To", CAMEL_MESSAGE_INFO_TO },
		{ "Cc", CAMEL_MESSAGE_INFO_CC }
	};
	camel_search_t type = CAMEL_SEARCH_TYPE_ENCODED;
	const gchar *name, *value;
	gboolean found = FALSE;
	gint ii;

	g_return_val_if_fail (argc > 1, FALSE);
	g_return_val_if_fail (argv != NULL, FALSE);
	g_return_val_if_fail (matched != NULL, FALSE);

	if (!info)
		return FALSE;

	name = argv[0]->value.string;
	g_return_val_if_fail (name != NULL, FALSE);

	value = NULL;

	for (ii = 0; ii < G_N_ELEMENTS (known_headers); ii++) {
		found = g_ascii_strcasecmp (name, known_headers[ii].header_name) == 0;
		if (found) {
			value = camel_message_info_ptr (info, known_headers[ii].info_key);
			if (known_headers[ii].info_key == CAMEL_MESSAGE_INFO_FROM ||
			    known_headers[ii].info_key == CAMEL_MESSAGE_INFO_TO ||
			    known_headers[ii].info_key == CAMEL_MESSAGE_INFO_CC)
				type = CAMEL_SEARCH_TYPE_ADDRESS_ENCODED;
			break;
		}
	}

	if (!found || !value)
		return FALSE;

	for (ii = 1; ii < argc && !*matched; ii++) {
		if (argv[ii]->type == CAMEL_SEXP_RES_STRING)
			*matched = camel_search_header_match (value, argv[ii]->value.string, how, type, NULL);
	}

	return TRUE;
}
/* check for the clues */
static gboolean
check_for_attachment_clues (GByteArray *msg_text)
{
	GSettings *settings;
	gchar **clue_list;
	gboolean found = FALSE;

	settings = e_util_ref_settings ("org.gnome.evolution.plugin.attachment-reminder");

	/* Get the list from GSettings */
	clue_list = g_settings_get_strv (settings, CONF_KEY_ATTACH_REMINDER_CLUES);

	g_object_unref (settings);

	if (clue_list && clue_list[0]) {
		gint ii, jj, to;

		g_byte_array_append (msg_text, (const guint8 *) "\0", 1);

		censor_quoted_lines (msg_text);

		for (ii = 0; clue_list[ii] && !found; ii++) {
			GString *word;
			const gchar *clue = clue_list[ii];

			if (!*clue)
				continue;

			word = g_string_new ("\"");

			to = word->len;
			g_string_append (word, clue);

			for (jj = word->len - 1; jj >= to; jj--) {
				if (word->str[jj] == '\\' || word->str[jj] == '\"')
					g_string_insert_c (word, jj, '\\');
			}

			g_string_append_c (word, '\"');

			found = camel_search_header_match ((const gchar *) msg_text->data, word->str, CAMEL_SEARCH_MATCH_WORD, CAMEL_SEARCH_TYPE_ASIS, NULL);

			g_string_free (word, TRUE);
		}
	}

	if (clue_list) {
		g_strfreev (clue_list);
	}

	return found;
}
static CamelSExpResult *
check_header (struct _CamelSExp *f,
              gint argc,
              struct _CamelSExpResult **argv,
              FilterMessageSearch *fms,
              camel_search_match_t how)
{
	gboolean matched = FALSE;
	CamelSExpResult *r;
	gint i;

	if (argc > 1 && argv[0]->type == CAMEL_SEXP_RES_STRING) {
		gchar *name = argv[0]->value.string;

		/* shortcut: a match for "" against any header always matches */
		for (i = 1; i < argc && !matched; i++)
			matched = argv[i]->type == CAMEL_SEXP_RES_STRING && argv[i]->value.string[0] == 0;

		if (g_ascii_strcasecmp (name, "x-camel-mlist") == 0) {
			const gchar *list = camel_message_info_mlist (fms->info);

			if (list) {
				for (i = 1; i < argc && !matched; i++) {
					if (argv[i]->type == CAMEL_SEXP_RES_STRING)
						matched = camel_search_header_match (list, argv[i]->value.string, how, CAMEL_SEARCH_TYPE_MLIST, NULL);
				}
			}
		} else if (fms->message || !check_header_in_message_info (fms->info, argc, argv, how, &matched)) {
			CamelMimeMessage *message;
			CamelMimePart *mime_part;
			struct _camel_header_raw *header;
			const gchar *charset = NULL;
			camel_search_t type = CAMEL_SEARCH_TYPE_ENCODED;
			CamelContentType *ct;

			message = camel_filter_search_get_message (fms, f);
			mime_part = CAMEL_MIME_PART (message);

			/* FIXME: what about Resent-To, Resent-Cc and Resent-From? */
			if (g_ascii_strcasecmp ("to", name) == 0 || g_ascii_strcasecmp ("cc", name) == 0 || g_ascii_strcasecmp ("from", name) == 0)
				type = CAMEL_SEARCH_TYPE_ADDRESS_ENCODED;
			else if (message) {
				ct = camel_mime_part_get_content_type (mime_part);
				if (ct) {
					charset = camel_content_type_param (ct, "charset");
					charset = camel_iconv_charset_name (charset);
				}
			}

			for (header = mime_part->headers; header && !matched; header = header->next) {
				/* empty name means any header */
				if (!name || !*name || !g_ascii_strcasecmp (header->name, name)) {
					for (i = 1; i < argc && !matched; i++) {
						if (argv[i]->type == CAMEL_SEXP_RES_STRING)
							matched = camel_search_header_match (header->value, argv[i]->value.string, how, type, charset);
					}
				}
			}
		}
	}

	r = camel_sexp_result_new (f, CAMEL_SEXP_RES_BOOL);
	r->value.boolean = matched;

	return r;
}