--- evolution-2.8.2.1/e-util/e-pilot-util.c	2004-08-02 20:34:56.000000000 +0200
+++ edit/e-util/e-pilot-util.c	2007-01-16 09:38:15.000000000 +0100
@@ -25,6 +25,10 @@
 #include <time.h>
 #include <libxml/parser.h>
 #include <pi-util.h>
+#include <string.h>
+
+#include <libedataserver/e-categories.h>
+#include <pi-appinfo.h>
 
 #include "e-pilot-util.h"
 
@@ -105,3 +109,140 @@
 		e_source_set_property (source, "pilot-sync", "true");
 	e_source_list_sync (source_list, NULL);
 }
+
+/*
+ * Adds a category to the category app info structure (name and ID),
+ * sets category->renamed[i] to true if possible to rename.
+ * 
+ * This will be packed and written to the app info block during post_sync.
+ */
+int
+e_pilot_add_category_if_possible(char *cat_to_add, struct CategoryAppInfo *category)
+{
+	int i, j;
+	int retval = 0; /* 0 is the Unfiled category */
+	//LOG(g_message("e_pilot_add_category_if_possible\n"));
+	
+	for(i=0; i<PILOT_MAX_CATEGORIES; i++){
+		/* if strlen is 0, then the category is empty
+		   the PalmOS doesn't let 0-length strings for
+		   categories */
+		if(strlen(category->name[i]) == 0){
+			int cat_to_add_len;
+			
+			cat_to_add_len = strlen(cat_to_add);
+			retval = i;
+			
+			/* only 15 characters for category, 16th is
+			 * '\0' can't do direct mem transfer due to
+			 * declaration type
+			 */
+			for(j=0; j<cat_to_add_len; j++){
+				category->name[i][j] = cat_to_add[j];
+			}
+
+			for(j=cat_to_add_len; j<16; j++)
+				category->name[i][j] = '\0';
+			
+			//category->ID[i] = lastDesktopUniqueID;
+			//lastDesktopUniqueID++;
+			category->renamed[i] = TRUE;
+			
+			break;
+		}
+	}
+	
+	if(retval == 0){
+		//LOG(g_warning( _("*** not adding category - category list already full ***") ));
+	}
+	
+	return retval;
+}
+
+/*
+ *conversion from an evolution category to a palm category
+ */
+void e_pilot_local_category_to_remote(int * pilotCategory, ECalComponent *comp, struct CategoryAppInfo *category)
+{
+	GSList *c_list = NULL;
+	char * category_string;
+	int i;
+	e_cal_component_get_categories_list (comp, &c_list);
+	if (c_list) {
+		//list != 0, so at least 1 category is assigned
+		category_string = (char *) c_list->data;
+		if (c_list->next != 0) {
+			//LOG (g_message ("Note: item has more categories in evolution, first chosen"));
+		}
+		i=1;
+		while (1) {
+			if (strcmp(category_string,category->name[i]) == 0) {
+				*pilotCategory = i;
+				break;
+			}
+			i++;
+			if (i == PILOT_MAX_CATEGORIES) {
+				/*category not available on palm, try to create it*/
+				*pilotCategory = e_pilot_add_category_if_possible(category_string,category);
+				break;
+			}
+		}
+		e_cal_component_free_categories_list(c_list);
+		c_list = NULL;
+	} else {
+		*pilotCategory = 0;
+	}
+	/*end category*/
+}
+
+/*
+ *conversion from a palm category to an evolution category
+ */
+void e_pilot_remote_category_to_local(int pilotCategory, ECalComponent *comp, struct CategoryAppInfo *category)
+{
+	GSList *new_category = NULL;
+	GSList *c_list = NULL;
+	char *category_string;
+
+	/*Category*/
+	if (pilotCategory != 0) {
+		/*pda has category assigned*/
+		//LOG(g_message("Category: %s\n",categoryInfo.name[remote->category]));
+		new_category = g_slist_append(new_category, category->name[pilotCategory]); /*put the pda category on the first place*/
+		/* TODO The calendar editor page and search bar are not updated until a restart of the evolution client */
+		if(e_categories_exist(category->name[pilotCategory]) == FALSE){
+			/* add if it doesn't exist */
+			//LOG(g_message("Category created on pc\n"));
+			e_categories_add(category->name[pilotCategory], NULL, NULL, TRUE);
+		}
+	}
+		
+	/*Add the remaining categories already assigned on the pc*/
+	e_cal_component_get_categories_list (comp, &c_list);
+	if (c_list != 0) {
+		/*there were already categories assigned on the pc*/
+		category_string = (char *) c_list->data;
+		/*Only the first category on the pc is synced with palm, so we only replace this one with the one from the PDA
+		Note that this is NOT foolproof, but it will handle most situations*/
+		
+		/*now add the rest of the categories from the pc (if there are) */
+		c_list = c_list->next;
+		while (c_list != 0) {
+			category_string = (char *) c_list->data;
+			if (strcmp(category_string, category->name[pilotCategory]) != 0) {
+				/*different category from pda, so add it*/
+				new_category = g_slist_append(new_category, category_string);
+			}
+		c_list = c_list->next;
+		}
+	}
+	e_cal_component_free_categories_list(c_list);
+	/*store the data on pc*/
+	if (new_category == 0) {
+		e_cal_component_set_categories (comp, " "); /*note: this space is needed to make shure evolution clears the category*/
+	} 
+	else {
+		e_cal_component_set_categories_list (comp, new_category);
+	}
+	/*end category*/
+}
--- evolution-2.8.2.1/e-util/e-pilot-util.h	2004-08-02 20:34:56.000000000 +0200
+++ edit/e-util/e-pilot-util.h	2007-01-16 09:38:27.000000000 +0100
@@ -22,15 +22,24 @@
 
 #include <libedataserver/e-source-list.h>
 #include <libedataserver/e-source.h>
+#include <libedataserver/e-categories.h>
+#include <libecal/e-cal.h>
+#include <pi-appinfo.h>
 
 #ifndef E_PILOT_UTIL_H
 #define E_PILOT_UTIL_H
 
+#define PILOT_MAX_CATEGORIES 16
+
 char *e_pilot_utf8_to_pchar (const char *string);
 char *e_pilot_utf8_from_pchar (const char *string);
 
 ESource *e_pilot_get_sync_source (ESourceList *source_list);
 void e_pilot_set_sync_source (ESourceList *source_list, ESource *source);
 
+int e_pilot_add_category_if_possible(char *cat_to_add, struct CategoryAppInfo *category);
+void e_pilot_local_category_to_remote(int * pilotCategory, ECalComponent *comp, struct CategoryAppInfo *category);
+void e_pilot_remote_category_to_local(int   pilotCategory, ECalComponent *comp, struct CategoryAppInfo *category);
+
 
 #endif /* E_PILOT_UTIL_H */
--- patch/calendar/conduits/calendar/calendar-conduit.c	2007-01-13 12:40:19.000000000 +0100
+++ edit/calendar/conduits/calendar/calendar-conduit.c	2007-01-16 09:57:21.000000000 +0100
@@ -940,6 +940,9 @@
 		pi_buffer_free (record);
 #endif
 	}
+	
+	/*Category support*/
+	e_pilot_local_category_to_remote(&(local->local.category), comp, &(ctxt->ai.category));
 
 	/* STOP: don't replace these with g_strdup, since free_Appointment
 	   uses free to deallocate */
@@ -1185,7 +1188,8 @@
 			 GnomePilotRecord *remote,
 			 ECalComponent *in_comp,
 			 ECal *client,
-			 icaltimezone *timezone)
+			 icaltimezone *timezone,
+			 struct CategoryAppInfo *category)
 {
 	ECalComponent *comp;
 	struct Appointment appt;
@@ -1231,6 +1235,9 @@
 	summary.value = txt = e_pilot_utf8_from_pchar (appt.description);
 	e_cal_component_set_summary (comp, &summary);
 	free (txt);
+	
+	/*Category support*/
+	e_pilot_remote_category_to_local(remote->category, comp, category);
 
 	/* The iCal description field */
 	if (!appt.note) {
@@ -1623,6 +1630,7 @@
 	pi_buffer_free(buffer);
 #endif
 	unpack_AppointmentAppInfo (&(ctxt->ai), buf, len);
+	//unpack_CategoryAppInfo (&(ctxt->ai.category), buf, len);
 	g_free (buf);
 
 	check_for_slow_setting (conduit, ctxt);
@@ -1640,8 +1648,28 @@
 {
 	GList *changed;
 	gchar *filename, *change_id;
+	unsigned char *buf;
+	int dlpRetVal, len;
 	
 	LOG (g_message ( "post_sync: Calendar Conduit v.%s", CONDUIT_VERSION ));
+	
+	/* Write AppBlock to PDA - updates categories */
+	buf = (unsigned char*)g_malloc (0xffff);
+	
+	len = pack_AppointmentAppInfo (&(ctxt->ai), buf, 0xffff);
+	
+	dlpRetVal = dlp_WriteAppBlock (dbi->pilot_socket, dbi->db_handle, 
+			      (unsigned char *)buf, len);
+	
+	g_free (buf);
+			      
+	if (dlpRetVal < 0) {
+		WARN (_("Could not write pilot's Calendar application block"));
+		WARN ("dlp_WriteAppBlock(...) = %d", dlpRetVal);
+		gnome_pilot_conduit_error (conduit,
+					   _("Could not write pilot's Calendar application block"));
+		return -1;
+	}
 
 	g_free (ctxt->cfg->last_uri);
 	ctxt->cfg->last_uri = g_strdup (e_cal_get_uri (ctxt->client));
@@ -1839,7 +1867,7 @@
 
 	LOG (g_message ( "add_record: adding %s to desktop\n", print_remote (remote) ));
 
-	comp = comp_from_remote_record (conduit, remote, ctxt->default_comp, ctxt->client, ctxt->timezone);
+	comp = comp_from_remote_record (conduit, remote, ctxt->default_comp, ctxt->client, ctxt->timezone, &(ctxt->ai.category));
 
 	/* Give it a new UID otherwise it will be the uid of the default comp */
 	uid = e_cal_component_gen_uid ();
@@ -1871,7 +1899,7 @@
 	LOG (g_message ("replace_record: replace %s with %s\n",
 			print_local (local), print_remote (remote)));
 
-	new_comp = comp_from_remote_record (conduit, remote, local->comp, ctxt->client, ctxt->timezone);
+	new_comp = comp_from_remote_record (conduit, remote, local->comp, ctxt->client, ctxt->timezone, &(ctxt->ai.category));
 	g_object_unref (local->comp);
 	local->comp = new_comp;
 
--- patch/calendar/conduits/memo/memo-conduit.c	2007-01-13 12:40:19.000000000 +0100
+++ edit/calendar/conduits/memo/memo-conduit.c	2007-01-16 10:13:37.000000000 +0100
@@ -506,70 +506,6 @@
 }
 
 /*
- * Adds a category to the category app info structure (name and ID),
- * sets category->renamed[i] to true if possible to rename.
- * 
- * This will be packed and written to the app info block during post_sync.
- */
- 
-static int
-add_category_if_possible(char *cat_to_add, struct CategoryAppInfo *category)
-{
-	int i, j;
-	int retval = 0; /* 0 is the Unfiled category */
-	LOG(fprintf(stderr, "add_category_if_possible: called\n"));
-	
-	for(i=0; i<16; i++){
-		/* if strlen is 0, then the category is empty
-		   the PalmOS doesn't let 0-length strings for
-		   categories */
-		LOG(fprintf(stderr, "add_category_if_possible: calling strlen, i==%d\n", i));
-		if(strlen(category->name[i]) == 0){
-			int cat_to_add_len;
-			LOG(fprintf(stderr, "add_category_if_possible: strlen == 0\n"));
-			
-			cat_to_add_len = strlen(cat_to_add);
-			LOG(fprintf(stderr, "add_category_if_possible: cat_to_add_len: %d\n",
-					cat_to_add_len));
-			retval = i;
-			
-			/* only 15 characters for category, 16th is
-			 * '\0' can't do direct mem transfer due to
-			 * declaration type
-			 */
-			LOG(fprintf(stderr, "add_category_if_possible: copying first 15 of category\n"));
-			for(j=0; j<cat_to_add_len; j++){
-				category->name[i][j] = cat_to_add[j];
-			}
-			LOG(fprintf(stderr,
-				"add_category_if_possible: setting from %d to i==15 to \\0\n",
-				cat_to_add_len));
-
-			for(j=cat_to_add_len; j<16; j++)
-				category->name[i][j] = '\0';
-			
-			LOG(fprintf(stderr, "add_category_if_possible: setting ID[%d] to %d\n",
-				category->ID[i], lastDesktopUniqueID));
-			category->ID[i] = lastDesktopUniqueID;
-			lastDesktopUniqueID++;
-			
-			LOG(fprintf(stderr, "add_category_if_possible: setting renamed[%d] to TRUE\n", i));
-			category->renamed[i] = TRUE;
-			
-			LOG(g_message("*** adding category '%s', ID %d ***",
-				category->name[i], category->ID[i]));
-			break;
-		}
-	}
-	
-	if(retval == 0){
-		LOG(g_message("*** not adding category - category list already full ***"));
-	}
-	
-	return retval;
-}
-
-/*
  * converts a ECalComponent object to a EMemoLocalRecord
  */
 static void
@@ -640,51 +576,8 @@
 		LOG(fprintf(stderr, "local_record_from_comp: done calling dlp_ReadRecordById\n"));
 	}
 	
-	/*
-	 * Grab category from existing category list in ctxt->ai.category
-	 */
-	if(local->local.category == 0){
-		GSList *categ_list_head, *categ_list_cur;
-		int cat = -1;
-		int i;
-		
-		LOG(fprintf(stderr, "local_record_from_comp: trying to set category"));
-		LOG(fprintf(stderr, "local_record_from_comp: calling e_cal_component_get_categories_list\n"));
-		
-		e_cal_component_get_categories_list(comp, &categ_list_head);
-		LOG(fprintf(stderr, "local_record_from_comp: got list, setting categ_list_cur to head\n"));
-		
-		categ_list_cur = categ_list_head;
-		while (categ_list_cur && cat == -1)
-		{	
-			LOG(fprintf(stderr, "local_record_from_comp: iterating, data == %s",
-				(char *)categ_list_cur->data));
-			for(i=0; i<16; i++){
-				LOG(fprintf(stderr, "local_record_from_comp: i == %d\n", i));
-				if(strcmp((char *)categ_list_cur->data,
-					  ctxt->ai.category.name[i]) == 0){
-					cat = i;
-					LOG(fprintf(stderr, "local_record_from_comp: found category, name: %s\n",
-							ctxt->ai.category.name[i]));
-					break;
-				}
-			}
-			
-			LOG(fprintf(stderr, "local_record_from_comp: calling g_slist_next\n"));
-			categ_list_cur = g_slist_next(categ_list_cur);
-		}
-		
-		if(cat != -1){
-			LOG(fprintf(stderr, "local_record_from_comp: setting category\n"));
-			local->local.category = cat;
-		}
-		else if(categ_list_head != NULL){
-			local->local.category =
-				add_category_if_possible(
-					(char *)(categ_list_head->data),
-					&(ctxt->ai.category));
-		}
-	}
+	/*Category support*/
+	e_pilot_local_category_to_remote(&(local->local.category), comp, &(ctxt->ai.category));
 
 	/* STOP: don't replace these with g_strdup, since free_Memo
 	   uses free to deallocate */
@@ -799,6 +692,9 @@
 
 	e_cal_component_set_last_modified (comp, &now);
 	
+	/*Category support*/
+	e_pilot_remote_category_to_local(remote->category, comp, &(ai->category));
+	
 	/* The iCal description field */
 	if (!memo.text) {
 		e_cal_component_set_comment_list (comp, NULL);
@@ -853,19 +749,6 @@
 		e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_PRIVATE);
 	else
 		e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_PUBLIC);
-	
-	
-	/* set the category properly */
-	category = ai->category.name[remote->category];
-	
-	/* TODO The Memos editor page and search bar are not updated until
-	  a restart of the evolution client */
-	if(e_categories_exist(category) == FALSE){
-		/* add if it doesn't exist */
-		e_categories_add(category, NULL, NULL, TRUE);
-	}
-	
-	e_cal_component_set_categories(comp, category);
 
 	e_cal_component_commit_sequence (comp);
 	
--- patch/calendar/conduits/todo/todo-conduit.c	2007-01-13 12:40:19.000000000 +0100
+++ edit/calendar/conduits/todo/todo-conduit.c	2007-01-16 13:49:09.000000000 +0100
@@ -648,55 +648,6 @@
 }
 
 /*
- * Adds a category to the category app info structure (name and ID),
- * sets category->renamed[i] to true if possible to rename.
- * 
- * This will be packed and written to the app info block during post_sync.
- */
- 
-static int
-add_category_if_possible(char *cat_to_add, struct CategoryAppInfo *category)
-{
-	int i, j;
-	int retval = 0; // 0 is the Unfiled category
-	
-	for(i=0; i<16; i++){
-		// if strlen is 0, then the category is empty
-		// the PalmOS doesn't let 0-length strings for
-		// categories
-		if(strlen(category->name[i]) == 0){
-			int cat_to_add_len = strlen(cat_to_add);
-			retval = i;
-			
-			/* only 15 characters for category, 16th is
-			 * '\0' can't do direct mem transfer due to
-			 * declaration type
-			 */
-			for(j=0; j<cat_to_add_len; j++)
-				category->name[i][j] = cat_to_add[j];
-
-			for(j=cat_to_add_len; j<16; j++)
-				category->name[i][j] = '\0';
-			
-			category->ID[i] = lastDesktopUniqueID;
-			lastDesktopUniqueID++;
-			
-			category->renamed[i] = TRUE;
-			
-			LOG(g_message("*** adding category '%s', ID %d ***",
-				category->name[i], category->ID[i]));
-			break;
-		}
-	}
-	
-	if(retval == 0){
-		LOG(g_message("*** not adding category - category list already full ***"));
-	}
-	
-	return retval;
-}
-
-/*
  * converts a ECalComponent object to a EToDoLocalRecord
  */
 static void
@@ -757,42 +708,8 @@
 #endif
 	}
 	
-	/*
-	 * Grab category from existing category list in ctxt->ai.category
-	 */
-	if(local->local.category == 0){
-		GSList *categ_list_head, *categ_list_cur;
-		int cat = -1;
-		int i;
-		
-		e_cal_component_get_categories_list(comp, &categ_list_head);
-		
-		categ_list_cur = categ_list_head;
-		while (categ_list_cur && cat == -1)
-		{	
-			for(i=0; i<16; i++){
-				if(strcmp((char *)categ_list_cur->data,
-					  ctxt->ai.category.name[i]) == 0){
-					cat = i;
-					break;
-				}
-			}
-			
-			categ_list_cur = g_slist_next(categ_list_cur);
-		}
-		
-		if(cat != -1){
-			local->local.category = cat;
-		}
-		else{
-			if(categ_list_head != NULL){
-				local->local.category =
-					add_category_if_possible(
-						(char *)(categ_list_head->data),
-						&(ctxt->ai.category));
-			}
-		}
-	}
+	/*Category support*/
+	e_pilot_local_category_to_remote(&(local->local.category), comp, &(ctxt->ai.category));
 
 	/* STOP: don't replace these with g_strdup, since free_ToDo
 	   uses free to deallocate */
@@ -951,6 +868,9 @@
 	e_cal_component_set_summary (comp, &summary);
 	free (txt);
 	
+	/*Category support*/
+	e_pilot_remote_category_to_local(remote->category, comp, &(ai->category));
+	
 	/* The iCal description field */
 	if (!todo.note) {
 		e_cal_component_set_comment_list (comp, NULL);
@@ -1022,20 +942,6 @@
 		e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_PRIVATE);
 	else
 		e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_PUBLIC);
-	
-	
-	// set the category properly
-	category = ai->category.name[remote->category];
-	
-	
-	// TODO The Tasks editor page and search bar are not updated until
-	// a restart of the evolution client
-	if(e_categories_exist(category) == FALSE){
-		// add if it doesn't exist
-		e_categories_add(category, NULL, NULL, TRUE);
-	}
-	
-	e_cal_component_set_categories(comp, category);
 
 	e_cal_component_commit_sequence (comp);
 	
