Index: camel/ChangeLog
===================================================================
--- camel/ChangeLog	(revision 9931)
+++ camel/ChangeLog	(working copy)
@@ -1,3 +1,13 @@
+2009-01-14  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #204891
+
+	* camel-session.h: (camel_session_forward_to):
+	* camel-session.c: (camel_session_init), (session_forward_to),
+	(camel_session_forward_to):
+	* camel-filter-driver.c: (do_forward_to):
+	Be able to forward messages in a filter, passing it to a session.
+
 2009-01-13  Srinivasa Ragavan  <sragavan@novell.com>
 
 	* camel/camel-db.c: Speed up total-count info, by counting indexed
Index: camel/camel-session.c
===================================================================
--- camel/camel-session.c	(revision 9931)
+++ camel/camel-session.c	(working copy)
@@ -48,6 +48,8 @@
 #include "camel-string-utils.h"
 #include "camel-transport.h"
 #include "camel-url.h"
+#include "camel-folder.h"
+#include "camel-mime-message.h"
 
 #define d(x)
 
@@ -66,6 +68,7 @@ static void session_thread_msg_free(Came
 static int session_thread_queue(CamelSession *session, CamelSessionThreadMsg *msg, int flags);
 static void session_thread_wait(CamelSession *session, int id);
 static void session_thread_status(CamelSession *session, CamelSessionThreadMsg *msg, const char *text, int pc);
+static void session_forward_to (CamelSession *session, CamelFolder *folder, CamelMimeMessage *message, const char *address, CamelException *ex);
 
 static void
 camel_session_init (CamelSession *session)
@@ -120,6 +123,8 @@ camel_session_class_init (CamelSessionCl
 	camel_session_class->thread_wait = session_thread_wait;
 	camel_session_class->thread_status = session_thread_status;
 
+	camel_session_class->forward_to = session_forward_to;
+
 	camel_object_class_add_event((CamelObjectClass *)camel_session_class, "online", NULL);
 }
 
@@ -809,3 +814,27 @@ camel_session_get_junk_headers (CamelSes
 
 	return session->priv->junk_headers;
 }
+
+static void
+session_forward_to (CamelSession *session, CamelFolder *folder, CamelMimeMessage *message, const char *address, CamelException *ex)
+{
+	if (ex)
+		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Camel session doesn't support forwarding of a message."));
+}
+
+/**
+ * camel_session_forward_to:
+ * Forwards message to some address(es) in a given type. The meaning of the forward_type defines session itself.
+ * @session #CameSession. 
+ * @folder #CamelFolder where is @message located.
+ * @message Message to forward.
+ * @address Where forward to.
+ * @ex Exception.
+ **/
+void
+camel_session_forward_to (CamelSession *session, CamelFolder *folder, CamelMimeMessage *message, const char *address, CamelException *ex)
+{
+	g_return_if_fail (CAMEL_IS_SESSION (session));
+	
+	CS_CLASS (session)->forward_to (session, folder, message, address, ex);
+}
Index: camel/camel-session.h
===================================================================
--- camel/camel-session.h	(revision 9931)
+++ camel/camel-session.h	(working copy)
@@ -118,6 +118,11 @@ typedef struct {
 					      int pc);
 	gboolean        (*lookup_addressbook)(CamelSession *session,
 					      const char *name);
+	void		(*forward_to)        (CamelSession *session,
+					      struct _CamelFolder *folder,
+					      struct _CamelMimeMessage *message,
+					      const char *address,
+					      CamelException *ex);
 } CamelSessionClass;
 
 
@@ -224,6 +229,12 @@ void               camel_session_set_jun
 gboolean           camel_session_lookup_addressbook (CamelSession *session,
 						     const char *name);
 
+void		   camel_session_forward_to         (CamelSession *session,
+						     struct _CamelFolder *folder,
+					             struct _CamelMimeMessage *message,
+						     const char *address,
+						     CamelException *ex);
+
 G_END_DECLS
 
 #endif /* CAMEL_SESSION_H */
Index: camel/camel-filter-driver.c
===================================================================
--- camel/camel-filter-driver.c	(revision 9931)
+++ camel/camel-filter-driver.c	(working copy)
@@ -101,7 +101,6 @@ struct _CamelFilterDriverPrivate {
 	/* run-time data */
 	GHashTable *folders;       /* folders that message has been copied to */
 	int closed;		   /* close count */
-	GHashTable *forwards;      /* addresses that have been forwarded the message */
 	GHashTable *only_once;     /* actions to run only-once */
 	
 	gboolean terminated;       /* message processing was terminated */
@@ -137,7 +136,7 @@ static CamelFolder *open_folder (CamelFi
 static int close_folders (CamelFilterDriver *d);
 
 static ESExpResult *do_delete (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *);
-static ESExpResult *mark_forward (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *);
+static ESExpResult *do_forward_to (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *);
 static ESExpResult *do_copy (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *);
 static ESExpResult *do_move (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *);
 static ESExpResult *do_stop (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *);
@@ -161,7 +160,7 @@ static struct {
 				   doesn't execute everything, 0 otherwise */
 } symbols[] = {
 	{ "delete",            (ESExpFunc *) do_delete,    0 },
-	{ "forward-to",        (ESExpFunc *) mark_forward, 0 },
+	{ "forward-to",        (ESExpFunc *) do_forward_to, 0 },
 	{ "copy-to",           (ESExpFunc *) do_copy,      0 },
 	{ "move-to",           (ESExpFunc *) do_move,      0 },
 	{ "stop",              (ESExpFunc *) do_stop,      0 },
@@ -447,14 +446,25 @@ do_delete (struct _ESExp *f, int argc, s
 }
 
 static ESExpResult *
-mark_forward (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *driver)
+do_forward_to (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *driver)
 {
-	/*struct _CamelFilterDriverPrivate *p = _PRIVATE (driver);*/
-	
+	struct _CamelFilterDriverPrivate *p = _PRIVATE (driver);
+
 	d(fprintf (stderr, "marking message for forwarding\n"));
-	/* FIXME: do stuff here */
-	camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Forward");
-	
+
+	/* requires one parameter, string with a destination address */
+	if (argc < 1 || argv[0]->type != ESEXP_RES_STRING)
+		return NULL;
+
+	/* make sure we have the message... */
+	if (p->message == NULL) {
+		if (!(p->message = camel_folder_get_message (p->source, p->uid, p->ex)))
+			return NULL;
+	}
+
+	camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Forward message to '%s'", argv[0]->value.string);
+	camel_session_forward_to (p->session, p->source, p->message, argv[0]->value.string, p->ex);
+
 	return NULL;
 }
 
