Fix FSF address (Tobias Mueller, #470445)
[platform/upstream/evolution-data-server.git] / servers / groupwise / e-gw-connection.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* 
3  * Authors : 
4  *  JP Rosevear <jpr@ximian.com>
5  *  Rodrigo Moya <rodrigo@ximian.com>
6  *
7  * Copyright 2003, Novell, Inc.
8  *
9  * This program is free software; you can redistribute it and/or 
10  * modify it under the terms of version 2 of the GNU Lesser General Public 
11  * License as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21  * USA
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 #include <string.h>
28 #include <ctype.h>
29 #include <glib/gi18n-lib.h>
30 #include <libsoup/soup-session-sync.h>
31 #include <libsoup/soup-soap-message.h>
32 #include <libsoup/soup-misc.h>
33 #include "e-gw-connection.h"
34 #include "e-gw-message.h"
35 #include "e-gw-filter.h"
36 #include "build-timestamp.h"
37
38 /* For soup sync session timeout */
39 #define GW_SOUP_SESSION_TIMEOUT 30
40
41 static GObjectClass *parent_class = NULL;
42 static GHashTable *loaded_connections_permissions = NULL;
43
44 struct _EGwConnectionPrivate {
45         SoupSession *soup_session;
46
47         char *uri;
48         char *username;
49         char *password;
50         char *session_id;
51         char *user_name;
52         char *user_email;
53         char *user_uuid;
54         char *version;
55         char *server_time ;
56         GHashTable *categories_by_name;
57         GHashTable *categories_by_id;
58         GList *book_list;
59         EGwSendOptions *opts;
60         GMutex *reauth_mutex;
61 };
62
63 static EGwConnectionStatus 
64 reauthenticate (EGwConnection *cnc) 
65 {
66         EGwConnectionPrivate  *priv;
67         SoupSoapMessage *msg;
68         SoupSoapResponse *response;
69         SoupSoapParameter *param;
70         EGwConnectionStatus status = -1;
71         char *session = NULL;
72         
73         priv = cnc->priv;
74         if (!priv)
75                 return E_GW_CONNECTION_STATUS_INVALID_CONNECTION;
76
77         g_mutex_lock (priv->reauth_mutex);
78         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getCategoryListRequest");
79         e_gw_message_write_footer (msg);
80
81         /* just to make sure we still have invlaid session 
82            when multiple e_gw_connection apis see inavlid connection error 
83            at the sma time this prevents this function sending login requests multiple times */
84         response = e_gw_connection_send_message (cnc, msg); 
85         if (!response) {
86                 g_object_unref (msg);
87                 g_mutex_unlock (priv->reauth_mutex);
88                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
89         }
90         status = e_gw_connection_parse_response_status (response);
91         g_object_unref (response);
92
93         if (status == E_GW_CONNECTION_STATUS_OK) {
94                 g_mutex_unlock (priv->reauth_mutex);
95                 return status;
96         }
97         /* build the SOAP message */
98         msg = e_gw_message_new_with_header (priv->uri, NULL, "loginRequest");
99         soup_soap_message_start_element (msg, "auth", "types", NULL);
100         soup_soap_message_add_attribute (msg, "type", "types:PlainText", "xsi",
101                                          "http://www.w3.org/2001/XMLSchema-instance");
102         e_gw_message_write_string_parameter (msg, "username", "types", priv->username);
103         e_gw_message_write_string_parameter (msg, "password", "types", priv->password);
104         soup_soap_message_end_element (msg);
105         e_gw_message_write_footer (msg);
106
107         /* send message to server */
108         response = e_gw_connection_send_message (cnc, msg);
109         if (response) 
110                 status = e_gw_connection_parse_response_status (response);
111
112         if (status == E_GW_CONNECTION_STATUS_OK) {
113                 param = soup_soap_response_get_first_parameter_by_name (response, "session");
114                 if (param) 
115                         session = soup_soap_parameter_get_string_value (param);
116                         
117         }
118                 
119         if (session) {
120                 g_free (priv->session_id);
121                 priv->session_id = session;
122         } 
123         g_object_unref (msg);
124         if (response)
125                 g_object_unref (response);
126         g_mutex_unlock (priv->reauth_mutex);
127         return status;
128         
129 }
130
131 EGwConnectionStatus
132 e_gw_connection_parse_response_status (SoupSoapResponse *response)
133 {
134         SoupSoapParameter *param, *subparam;
135
136         param = soup_soap_response_get_first_parameter_by_name (response, "status");
137         if (!param)
138                 return E_GW_CONNECTION_STATUS_UNKNOWN;
139
140         subparam = soup_soap_parameter_get_first_child_by_name (param, "code");
141         if (!subparam)
142                 return E_GW_CONNECTION_STATUS_UNKNOWN;
143
144         switch (soup_soap_parameter_get_int_value (subparam)) {
145         case 0 : return E_GW_CONNECTION_STATUS_OK;
146         case 59905 : return E_GW_CONNECTION_STATUS_BAD_PARAMETER;
147         case 53505 : return E_GW_CONNECTION_STATUS_UNKNOWN_USER;
148         case 59914: return E_GW_CONNECTION_STATUS_ITEM_ALREADY_ACCEPTED;
149         case 59910: return E_GW_CONNECTION_STATUS_INVALID_CONNECTION;
150         case 59923: return E_GW_CONNECTION_STATUS_REDIRECT;
151         case 53530: return E_GW_CONNECTION_STATUS_OTHER;
152         /* FIXME: 58652 should be changed with an enum.*/
153         case 58652: return 58652;
154         case 59922: return 59922; /*Very big attachment, get in chunks*/
155                 /* FIXME: map all error codes */
156         }
157
158         return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
159 }
160
161 const char *
162 e_gw_connection_get_error_message (EGwConnectionStatus status)
163 {
164         switch (status) {
165         case E_GW_CONNECTION_STATUS_OK :
166                 break;
167         case E_GW_CONNECTION_STATUS_INVALID_CONNECTION :
168                 return _("Invalid connection");
169         case E_GW_CONNECTION_STATUS_INVALID_OBJECT :
170                 return _("Invalid object");
171         case E_GW_CONNECTION_STATUS_INVALID_RESPONSE :
172                 return _("Invalid response from server");
173         case E_GW_CONNECTION_STATUS_NO_RESPONSE:
174                 return _("No response from the server");
175         case E_GW_CONNECTION_STATUS_OBJECT_NOT_FOUND :
176                 return _("Object not found");
177         case E_GW_CONNECTION_STATUS_UNKNOWN_USER :
178                 return _("Unknown User");
179         case E_GW_CONNECTION_STATUS_BAD_PARAMETER :
180                 return _("Bad parameter");
181         case E_GW_CONNECTION_STATUS_OTHER :
182         case E_GW_CONNECTION_STATUS_UNKNOWN :
183         default :
184                 return _("Unknown error");
185         }
186
187         return NULL;
188 }
189
190 static EGwConnectionStatus
191 logout (EGwConnection *cnc)
192 {
193         SoupSoapMessage *msg;
194         SoupSoapResponse *response;
195         EGwConnectionStatus status;
196
197         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
198
199         /* build the SOAP message */
200         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "logoutRequest");
201         e_gw_message_write_string_parameter (msg, "session", "types", cnc->priv->session_id);
202         e_gw_message_write_footer (msg);
203
204         /* send message to server */
205         response = e_gw_connection_send_message (cnc, msg);
206         if (!response) {
207                 g_object_unref (msg);
208                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
209         }
210
211         status = e_gw_connection_parse_response_status (response);
212
213         /* free memory */
214         g_object_unref (response);
215         g_object_unref (msg);
216
217         return status;
218 }
219
220 static void
221 e_gw_connection_dispose (GObject *object)
222 {
223         EGwConnection *cnc = (EGwConnection *) object;
224         EGwConnectionPrivate *priv;
225         char *hash_key;
226         
227         g_return_if_fail (E_IS_GW_CONNECTION (cnc));
228         
229         priv = cnc->priv;
230         printf ("gw connection dispose \n");
231         
232         /* removed the connection from the hash table */
233         if (loaded_connections_permissions != NULL) {
234                 hash_key = g_strdup_printf ("%s:%s@%s",
235                                             priv->username ? priv->username : "",
236                                             priv->password ? priv->password : "",
237                                             priv->uri ? priv->uri : "");
238                 g_hash_table_remove (loaded_connections_permissions, hash_key);
239                 if (g_hash_table_size (loaded_connections_permissions) == 0) {
240                         g_hash_table_destroy (loaded_connections_permissions);
241                         loaded_connections_permissions = NULL;
242                 }
243                 g_free (hash_key);
244         }
245         
246         if (priv) {
247                 if (priv->session_id) {
248                         logout (cnc);
249                         priv->session_id = NULL;
250                 }
251
252                 if (priv->soup_session) {
253                         g_object_unref (priv->soup_session);
254                         priv->soup_session = NULL;
255                 }
256
257                 if (priv->uri) {
258                         g_free (priv->uri);
259                         priv->uri = NULL;
260                 }
261
262                 if (priv->username) {
263                         g_free (priv->username);
264                         priv->username = NULL;
265                 }
266
267                 if (priv->password) {
268                         g_free (priv->password);
269                         priv->password = NULL;
270                 }
271
272                 if (priv->user_name) {
273                         g_free (priv->user_name);
274                         priv->user_name = NULL;
275                 }
276
277                 if (priv->user_email) {
278                         g_free (priv->user_email);
279                         priv->user_email = NULL;
280                 }
281
282                 if (priv->user_uuid) {
283                         g_free (priv->user_uuid);
284                         priv->user_uuid = NULL;
285                 }
286         
287                 if (priv->reauth_mutex) {
288                         g_mutex_free (priv->reauth_mutex);
289                         priv->reauth_mutex = NULL;
290                 }
291         
292                 if (priv->categories_by_id) {
293                         g_hash_table_destroy (priv->categories_by_id);
294                         priv->categories_by_id = NULL;
295                 }       
296                 
297                 if (priv->categories_by_name) {
298                         g_hash_table_destroy (priv->categories_by_name);
299                         priv->categories_by_name = NULL;
300                 }
301         
302                 if (priv->book_list) {
303                         g_list_foreach (priv->book_list, (GFunc) g_object_unref, NULL);
304                         g_list_free (priv->book_list);
305                         priv->book_list = NULL;
306                 }
307                 
308                 if (priv->opts) {
309                         g_object_unref (priv->opts);
310                         priv->opts = NULL;
311                 }
312                 
313                 if (priv->version) {
314                         g_free (priv->version) ;
315                         priv->opts = NULL ;
316                 }
317
318                 if (priv->server_time) {
319                         g_free (priv->server_time) ;
320                         priv->server_time = NULL ;
321                 }
322         }
323
324         if (parent_class->dispose)
325                 (* parent_class->dispose) (object);
326
327
328 static void
329 e_gw_connection_finalize (GObject *object)
330 {
331         EGwConnection *cnc = (EGwConnection *) object;
332         EGwConnectionPrivate *priv;
333
334         g_return_if_fail (E_IS_GW_CONNECTION (cnc));
335
336         priv = cnc->priv;
337         printf ("gw connection finalize\n");
338         /* clean up */
339         g_free (priv);
340         cnc->priv = NULL;
341
342         if (parent_class->finalize)
343                 (* parent_class->finalize) (object);
344 }
345
346 static void
347 e_gw_connection_class_init (EGwConnectionClass *klass)
348 {
349         GObjectClass *object_class = G_OBJECT_CLASS (klass);
350
351         parent_class = g_type_class_peek_parent (klass);
352
353         object_class->dispose = e_gw_connection_dispose;
354         object_class->finalize = e_gw_connection_finalize;
355 }
356
357 static void
358 e_gw_connection_init (EGwConnection *cnc, EGwConnectionClass *klass)
359 {
360         EGwConnectionPrivate *priv;
361         guint timeout = GW_SOUP_SESSION_TIMEOUT;
362
363         /* allocate internal structure */
364         priv = g_new0 (EGwConnectionPrivate, 1);
365         cnc->priv = priv;
366
367         /* Set a default timeout value of 30 seconds.
368            FIXME: Make timeout configurable 
369         */
370         if (g_getenv ("SOUP_SESSION_TIMEOUT"))
371                 timeout = atoi (g_getenv ("SOUP_SESSION_TIMEOUT"));
372         
373         /* create the SoupSession for this connection */
374         priv->soup_session = soup_session_sync_new_with_options (SOUP_SESSION_TIMEOUT, timeout, NULL);
375         priv->reauth_mutex = g_mutex_new ();
376         priv->categories_by_id = NULL;
377         priv->categories_by_name = NULL;
378         priv->book_list = NULL;
379         priv->opts = NULL;
380 }
381
382 GType
383 e_gw_connection_get_type (void)
384 {
385         static GType type = 0;
386
387         if (!type) {
388                 static GTypeInfo info = {
389                         sizeof (EGwConnectionClass),
390                         (GBaseInitFunc) NULL,
391                         (GBaseFinalizeFunc) NULL,
392                         (GClassInitFunc) e_gw_connection_class_init,
393                         NULL, NULL,
394                         sizeof (EGwConnection),
395                         0,
396                         (GInstanceInitFunc) e_gw_connection_init
397                 };
398                 type = g_type_register_static (G_TYPE_OBJECT, "EGwConnection", &info, 0);
399         }
400
401         return type;
402 }
403
404 static SoupSoapMessage*
405 form_login_request (const char*uri, const char* username, const char* password)
406 {
407         SoupSoapMessage *msg;
408         /* build the SOAP message */
409         msg = e_gw_message_new_with_header (uri, NULL, "loginRequest");
410         e_gw_message_write_string_parameter (msg, "application", "types", build_timestamp);
411         soup_soap_message_start_element (msg, "auth", "types", NULL);
412         soup_soap_message_add_attribute (msg, "type", "types:PlainText", "xsi",
413                                          "http://www.w3.org/2001/XMLSchema-instance");
414         e_gw_message_write_string_parameter (msg, "username", "types", username);
415         if (password && *password)
416                 e_gw_message_write_string_parameter (msg, "password", "types", password);
417         soup_soap_message_end_element (msg);
418         e_gw_message_write_footer (msg);
419         return msg;
420 }
421
422 EGwConnection *
423 e_gw_connection_new (const char *uri, const char *username, const char *password)
424 {
425         EGwConnection *cnc;
426         SoupSoapMessage *msg;
427         SoupSoapResponse *response;
428         SoupSoapParameter *param;
429         EGwConnectionStatus status;
430         char *hash_key;
431         char *redirected_uri = NULL;
432         
433         static GStaticMutex connecting = G_STATIC_MUTEX_INIT;   
434         
435         g_static_mutex_lock (&connecting);
436
437         /* search the connection in our hash table */
438         if (loaded_connections_permissions != NULL) {
439                 hash_key = g_strdup_printf ("%s:%s@%s",
440                                             username ? username : "",
441                                             password ? password : "",
442                                             uri);
443                 cnc = g_hash_table_lookup (loaded_connections_permissions, hash_key);
444                 g_free (hash_key);
445
446                 if (E_IS_GW_CONNECTION (cnc)) {
447                         g_object_ref (cnc);
448                         g_static_mutex_unlock (&connecting);
449                         return cnc;
450                 }
451         }
452
453         
454         /* not found, so create a new connection */
455         cnc = g_object_new (E_TYPE_GW_CONNECTION, NULL);
456
457         msg = form_login_request (uri, username, password);
458         
459         /* send message to server */
460         response = e_gw_connection_send_message (cnc, msg);
461
462         if (!response) {
463                 g_object_unref (cnc);
464                 g_static_mutex_unlock (&connecting);
465                 g_object_unref (msg);
466                 return NULL;
467         }
468
469         status = e_gw_connection_parse_response_status (response);
470         if (status == E_GW_CONNECTION_STATUS_REDIRECT) {
471                 char *host, *port;
472                 char **tokens;
473                 SoupSoapParameter *subparam;
474
475                 param = soup_soap_response_get_first_parameter_by_name (response, "redirectToHost");
476                 subparam = soup_soap_parameter_get_first_child_by_name (param, "ipAddress");
477                 host = soup_soap_parameter_get_string_value (subparam);
478                 subparam = soup_soap_parameter_get_first_child_by_name (param, "port");
479                 port = soup_soap_parameter_get_string_value (subparam);
480                 if (host && port) {
481                         tokens = g_strsplit (uri, "://", 2);
482                         redirected_uri = g_strconcat (tokens[0], "://", host, ":", port, "/soap", NULL);
483                         g_object_unref (msg);
484                         g_object_unref (response);
485                         msg = form_login_request (redirected_uri, username, password);
486                         uri = redirected_uri;
487                         response = e_gw_connection_send_message (cnc, msg);
488                         status = e_gw_connection_parse_response_status (response);
489                         g_strfreev (tokens);
490                         g_free (host);
491                         g_free (port);
492                 }
493                        
494         }
495         param = soup_soap_response_get_first_parameter_by_name (response, "session");
496         if (!param) {
497                 g_object_unref (response);
498                 g_object_unref (msg);
499                 g_object_unref (cnc);
500                 g_static_mutex_unlock (&connecting);
501                 return NULL;
502         }
503         
504         cnc->priv->uri = g_strdup (uri);
505         cnc->priv->username = g_strdup (username);
506         cnc->priv->password = g_strdup (password);
507         cnc->priv->session_id = soup_soap_parameter_get_string_value (param);
508
509         /* retrieve user information */
510         param = soup_soap_response_get_first_parameter_by_name (response, "userinfo");
511         
512         if (param) {
513                 SoupSoapParameter *subparam;
514                 char *param_value;
515
516                 subparam = soup_soap_parameter_get_first_child_by_name (param, "email");
517                 if (subparam) {
518                         param_value = soup_soap_parameter_get_string_value (subparam);
519                         cnc->priv->user_email  = param_value;
520                 }
521
522                 subparam = soup_soap_parameter_get_first_child_by_name (param, "name");
523                 if (subparam) {
524                         param_value = soup_soap_parameter_get_string_value (subparam);
525                         cnc->priv->user_name = param_value;
526                 }
527
528                 subparam = soup_soap_parameter_get_first_child_by_name (param, "uuid");
529                 if (subparam) {
530                         param_value = soup_soap_parameter_get_string_value (subparam);
531                         cnc->priv->user_uuid = param_value;
532                 }
533         }
534
535         param = soup_soap_response_get_first_parameter_by_name (response, "gwVersion");
536         if (param) {
537                 char *param_value;
538                 param_value = soup_soap_parameter_get_string_value (param);
539                 cnc->priv->version = param_value;
540         } else
541                 cnc->priv->version = NULL;      
542
543         param = soup_soap_response_get_first_parameter_by_name (response, "serverUTCTime");
544         if (param) 
545                 cnc->priv->server_time = soup_soap_parameter_get_string_value (param);
546
547         /* add the connection to the loaded_connections_permissions hash table */
548         hash_key = g_strdup_printf ("%s:%s@%s",
549                                     cnc->priv->username ? cnc->priv->username : "",
550                                     cnc->priv->password ? cnc->priv->password : "",
551                                     cnc->priv->uri);
552         if (loaded_connections_permissions == NULL)
553                 loaded_connections_permissions = g_hash_table_new_full (g_str_hash, g_str_equal,
554                                 g_free, NULL);
555         g_hash_table_insert (loaded_connections_permissions, hash_key, cnc);
556
557         /* free memory */
558         g_object_unref (response);
559         g_object_unref (msg);
560         g_static_mutex_unlock (&connecting);
561         g_free (redirected_uri);
562         return cnc;
563 }
564
565 SoupSoapResponse *
566 e_gw_connection_send_message (EGwConnection *cnc, SoupSoapMessage *msg)
567 {
568         SoupSoapResponse *response;
569
570         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), NULL);
571         g_return_val_if_fail (SOUP_IS_SOAP_MESSAGE (msg), NULL);
572
573         soup_session_send_message (cnc->priv->soup_session, SOUP_MESSAGE (msg));
574
575         /* process response */
576         response = soup_soap_message_parse_response (msg);
577
578         return response;
579 }
580
581 EGwConnectionStatus
582 e_gw_connection_logout (EGwConnection *cnc)
583 {
584         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
585
586         g_object_unref (cnc);
587
588         return E_GW_CONNECTION_STATUS_OK;
589 }
590
591 EGwConnectionStatus
592 e_gw_connection_get_container_list (EGwConnection *cnc, const char *top, GList **container_list)
593 {
594         SoupSoapMessage *msg;
595         SoupSoapResponse *response;
596         EGwConnectionStatus status;
597         SoupSoapParameter *param;
598
599         /* when user cancels password dialog, then the cnc is NULL */
600         if (!cnc)
601                 return E_GW_CONNECTION_STATUS_UNKNOWN;
602         
603         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
604         g_return_val_if_fail (container_list != NULL, E_GW_CONNECTION_STATUS_UNKNOWN);
605
606         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getFolderListRequest");
607         if (!msg) {
608                 g_warning (G_STRLOC ": Could not build SOAP message");
609                 return E_GW_CONNECTION_STATUS_UNKNOWN;
610         }
611
612         e_gw_message_write_string_parameter (msg, "parent", NULL, top);
613         e_gw_message_write_string_parameter (msg, "recurse", NULL, "true");
614         e_gw_message_write_footer (msg);
615
616         /* send message to server */
617         response = e_gw_connection_send_message (cnc, msg);
618         if (!response) {
619                 g_object_unref (msg);
620                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
621         }
622
623         status = e_gw_connection_parse_response_status (response);
624         g_object_unref (msg);
625
626         if (status != E_GW_CONNECTION_STATUS_OK) {
627                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
628                         reauthenticate (cnc);
629                 g_object_unref (response);
630                 return status;
631         }
632
633         /* if status is OK - parse result. return the list */   
634         param = soup_soap_response_get_first_parameter_by_name (response, "folders");   
635         if (param) {
636                 SoupSoapParameter *subparam;
637                 for (subparam = soup_soap_parameter_get_first_child_by_name (param, "folder");
638                      subparam != NULL;
639                      subparam = soup_soap_parameter_get_next_child_by_name (subparam, "folder")) {
640                         EGwContainer *container;
641
642                         container = e_gw_container_new_from_soap_parameter (subparam);
643                         if (container) 
644                                 *container_list = g_list_append (*container_list, container);
645                 }
646         }
647
648         g_object_unref (response);
649
650         return status;
651 }
652
653 void
654 e_gw_connection_free_container_list (GList *container_list)
655 {
656         g_return_if_fail (container_list != NULL);
657
658         g_list_foreach (container_list, (GFunc) g_object_unref, NULL);
659         g_list_free (container_list);
660 }
661
662 char *
663 e_gw_connection_get_container_id (EGwConnection *cnc, const char *name)
664 {
665         EGwConnectionStatus status;
666         GList *container_list = NULL, *l;
667         char *container_id = NULL;
668
669         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), NULL);
670         g_return_val_if_fail (name != NULL, NULL);
671
672         status = e_gw_connection_get_container_list (cnc, "folders", &container_list);
673         if (status != E_GW_CONNECTION_STATUS_OK) {
674                 e_gw_connection_free_container_list (container_list);
675                 return NULL;
676         }
677
678         /* search the container in the list */
679         for (l = container_list; l != NULL; l = l->next) {
680                 EGwContainer *container = E_GW_CONTAINER (l->data);
681
682                 if (strcmp (e_gw_container_get_name (container), name) == 0) {
683                         container_id = g_strdup (e_gw_container_get_id (container));
684                         break;
685                 }
686         }
687
688         e_gw_connection_free_container_list (container_list);
689
690         return container_id;
691 }
692
693 EGwConnectionStatus 
694 e_gw_connection_get_items_delta_info (EGwConnection *cnc, const char *container, gdouble *first_sequence, 
695                                         gdouble *last_sequence, gdouble *last_po_rebuild_time )
696 {
697         SoupSoapMessage *msg;
698         SoupSoapResponse *response;
699         EGwConnectionStatus status;
700         SoupSoapParameter *param, *subparam;
701         char *tmp = NULL;
702         
703         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
704         
705         /* build the SOAP message */
706         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getDeltaInfoRequest");
707         if (!msg) {
708                 g_warning (G_STRLOC ": Could not build SOAP message");
709                 return E_GW_CONNECTION_STATUS_UNKNOWN;
710         }
711
712         e_gw_message_write_string_parameter (msg, "container", NULL, container);
713
714         e_gw_message_write_footer (msg);
715
716         /* send message to server */
717         response = e_gw_connection_send_message (cnc, msg);
718         if (!response) {
719                 g_object_unref (msg);
720                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
721         }
722
723         status = e_gw_connection_parse_response_status (response);
724         if (status != E_GW_CONNECTION_STATUS_OK) {
725                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
726                         reauthenticate (cnc);
727                 g_object_unref (response);
728                 g_object_unref (msg);
729                 return status;
730         }
731
732         param = soup_soap_response_get_first_parameter_by_name (response, "deltaInfo");
733         if (!param) {
734                 g_object_unref (response);
735                 g_object_unref (msg);
736                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
737         }
738         
739         /* parse these parameters */
740
741         subparam = soup_soap_parameter_get_first_child_by_name (param, "firstSequence");
742
743         if (subparam) {
744                 tmp = soup_soap_parameter_get_string_value(subparam);
745                 *first_sequence = strtod (tmp, NULL);
746                 g_free (tmp);
747         } else
748                 *first_sequence = -1;
749
750         subparam = soup_soap_parameter_get_first_child_by_name (param, "lastSequence");
751
752         if (subparam) {
753                 tmp = soup_soap_parameter_get_string_value(subparam);
754                 *last_sequence = strtod (tmp, NULL);
755                 g_free (tmp);
756         }
757         else
758                 *last_sequence = -1;
759                 
760         subparam = soup_soap_parameter_get_first_child_by_name (param, "lastTimePORebuild");
761
762         if (subparam) {
763                 tmp = soup_soap_parameter_get_string_value(subparam);
764                 *last_po_rebuild_time = strtod (tmp, NULL);
765                 g_free (tmp);
766         } else
767                 *last_po_rebuild_time = -1;
768
769         g_object_unref (response);
770         g_object_unref (msg);
771
772         return status;
773 }
774
775 EGwConnectionStatus
776 e_gw_connection_get_items_delta (EGwConnection *cnc, const char *container, const char *view, const char *count, const char * start_sequence, GList **add_list, GList **delete_list)
777 {
778         SoupSoapMessage *msg;
779         SoupSoapResponse *response;
780         EGwConnectionStatus status;
781         SoupSoapParameter *param, *subparam, *subsubparam;
782         
783         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
784         
785         /* build the SOAP message */
786         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getDeltasRequest");
787         if (!msg) {
788                 g_warning (G_STRLOC ": Could not build SOAP message");
789                 return E_GW_CONNECTION_STATUS_UNKNOWN;
790         }
791
792         e_gw_message_write_string_parameter (msg, "container", NULL, container);
793         if (view)
794                 e_gw_message_write_string_parameter (msg, "view", NULL, view);
795         
796         soup_soap_message_start_element (msg, "deltaInfo", NULL, NULL);
797         e_gw_message_write_string_parameter (msg, "firstSequence", NULL, start_sequence);
798         e_gw_message_write_string_parameter (msg, "count", NULL, count);
799         soup_soap_message_end_element(msg);
800         
801         /* send message to server */
802
803         e_gw_message_write_footer (msg);
804         response = e_gw_connection_send_message (cnc, msg);
805         if (!response) {
806                 g_object_unref (msg);
807                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
808         }
809
810         status = e_gw_connection_parse_response_status (response);
811         if (status != E_GW_CONNECTION_STATUS_OK) {
812                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
813                         reauthenticate (cnc);
814                 g_object_unref (response);
815                 g_object_unref (msg);
816                 return status;
817         }
818
819         /* if status is OK - parse result. return the list */   
820         param = soup_soap_response_get_first_parameter_by_name (response, "items");
821         if (!param) {
822                 g_object_unref (response);
823                 g_object_unref (msg);
824                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
825         }
826         
827         /* parse these parameters */
828         for (subparam = soup_soap_parameter_get_first_child_by_name (param, "item");
829              subparam != NULL;
830              subparam = soup_soap_parameter_get_next_child_by_name (subparam, "item")) {
831                 EGwItem *item;
832
833         
834                 item = e_gw_item_new_from_soap_parameter (cnc->priv->user_email, container, subparam);
835                 
836                 subsubparam =  soup_soap_parameter_get_first_child_by_name(subparam, "sync");
837                 if (subsubparam) {
838                         char *value;
839
840                         value = soup_soap_parameter_get_string_value (subsubparam);
841                         if (!strcmp (value, "add") || !strcmp (value, "update")) {
842                                 *add_list = g_list_append (*add_list, item);
843                         } else if (!strcmp (value, "delete")) {
844                                 *delete_list = g_list_append (*delete_list, item);
845                         } 
846                         g_free (value);
847                 }
848         }
849                
850         /* free memory */
851         g_object_unref (response);
852         g_object_unref (msg);
853
854         return E_GW_CONNECTION_STATUS_OK;
855
856 }
857
858
859 EGwConnectionStatus
860 e_gw_connection_get_items (EGwConnection *cnc, const char *container, const char *view, EGwFilter *filter, GList **list)
861 {
862         SoupSoapMessage *msg;
863         SoupSoapResponse *response;
864         EGwConnectionStatus status;
865         SoupSoapParameter *param, *subparam;
866         
867         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
868         
869         /* build the SOAP message */
870         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getItemsRequest");
871         if (!msg) {
872                 g_warning (G_STRLOC ": Could not build SOAP message");
873                 return E_GW_CONNECTION_STATUS_UNKNOWN;
874         }
875
876         e_gw_message_write_string_parameter (msg, "container", NULL, container);
877         if (view)
878                 e_gw_message_write_string_parameter (msg, "view", NULL, view);
879        
880         if (filter) 
881                 e_gw_filter_append_to_soap_message (filter, msg);
882         e_gw_message_write_footer (msg);
883
884         /* send message to server */
885         response = e_gw_connection_send_message (cnc, msg);
886         if (!response) {
887                 g_object_unref (msg);
888                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
889         }
890
891         status = e_gw_connection_parse_response_status (response);
892         if (status != E_GW_CONNECTION_STATUS_OK) {
893                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
894                         reauthenticate (cnc);
895                 g_object_unref (response);
896                 g_object_unref (msg);
897                 return status;
898         }
899
900         /* if status is OK - parse result. return the list */   
901         param = soup_soap_response_get_first_parameter_by_name (response, "items");
902         if (!param) {
903                 g_object_unref (response);
904                 g_object_unref (msg);
905                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
906         }
907         
908         /* parse these parameters into ecalcomponents*/
909         for (subparam = soup_soap_parameter_get_first_child_by_name (param, "item");
910              subparam != NULL;
911              subparam = soup_soap_parameter_get_next_child_by_name (subparam, "item")) {
912                 EGwItem *item;
913
914                 item = e_gw_item_new_from_soap_parameter (cnc->priv->user_email, container, subparam);
915                 if (item)
916                         *list = g_list_append (*list, item);
917         }
918                
919         /* free memory */
920         g_object_unref (response);
921         g_object_unref (msg);
922
923         return E_GW_CONNECTION_STATUS_OK;
924 }
925
926 EGwConnectionStatus
927 e_gw_connection_get_items_from_ids (EGwConnection *cnc, const char *container, const char *view, GPtrArray *item_ids, GList **list)
928 {
929         SoupSoapMessage *msg;
930         SoupSoapResponse *response;
931         EGwConnectionStatus status;
932         SoupSoapParameter *param, *subparam;
933         int i;
934         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
935         
936         /* build the SOAP message */
937         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getItemsRequest");
938         if (!msg) {
939                 g_warning (G_STRLOC ": Could not build SOAP message");
940                 return E_GW_CONNECTION_STATUS_UNKNOWN;
941         }
942
943         e_gw_message_write_string_parameter (msg, "container", NULL, container);
944         if (view)
945                 e_gw_message_write_string_parameter (msg, "view", NULL, view);
946         soup_soap_message_start_element (msg, "items", NULL, NULL);
947         for (i = 0; i < item_ids->len; i ++) {
948                 char *id = g_ptr_array_index (item_ids, i);
949                 e_gw_message_write_string_parameter (msg, "item", NULL, id);
950         }
951         soup_soap_message_end_element (msg);
952
953         e_gw_message_write_footer (msg);
954
955         /* send message to server */
956         response = e_gw_connection_send_message (cnc, msg);
957         if (!response) {
958                 g_object_unref (msg);
959                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
960         }
961
962         status = e_gw_connection_parse_response_status (response);
963         if (status != E_GW_CONNECTION_STATUS_OK) {
964                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
965                         reauthenticate (cnc);
966                 g_object_unref (response);
967                 g_object_unref (msg);
968                 return status;
969         }
970
971         /* if status is OK - parse result. return the list */   
972         param = soup_soap_response_get_first_parameter_by_name (response, "items");
973         if (!param) {
974                 g_object_unref (response);
975                 g_object_unref (msg);
976                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
977         }
978         
979         /* parse these parameters into ecalcomponents*/
980         for (subparam = soup_soap_parameter_get_first_child_by_name (param, "item");
981              subparam != NULL;
982              subparam = soup_soap_parameter_get_next_child_by_name (subparam, "item")) {
983                 EGwItem *item;
984
985                 item = e_gw_item_new_from_soap_parameter (cnc->priv->user_email, container, subparam);
986                 if (item)
987                         *list = g_list_append (*list, item);
988         }
989                
990         /* free memory */
991         g_object_unref (response);
992         g_object_unref (msg);
993
994         return E_GW_CONNECTION_STATUS_OK;
995 }
996
997 EGwConnectionStatus
998 e_gw_connection_get_deltas ( EGwConnection *cnc, GSList **adds, GSList **deletes, GSList **updates)
999 {
1000         SoupSoapMessage *msg; 
1001         SoupSoapResponse *response; 
1002         EGwConnectionStatus status; 
1003         SoupSoapParameter *param, *subparam; 
1004         
1005         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT); 
1006
1007         /* build the SOAP message */ 
1008          msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getDeltaRequest"); 
1009          if (!msg) { 
1010                  g_warning (G_STRLOC ": Could not build SOAP message"); 
1011                  // g_object_unref (cnc); 
1012                  return E_GW_CONNECTION_STATUS_UNKNOWN; 
1013          } 
1014         
1015          /*FIXME  make this generic */
1016          soup_soap_message_start_element (msg, "CalendarItem", NULL, NULL); 
1017          soup_soap_message_end_element (msg); 
1018          e_gw_message_write_footer (msg); 
1019
1020          /* send message to server */ 
1021          response = e_gw_connection_send_message (cnc, msg); 
1022          if (!response) { 
1023                  g_object_unref (msg); 
1024                  // g_object_unref (cnc); 
1025                  return E_GW_CONNECTION_STATUS_NO_RESPONSE; 
1026          } 
1027
1028          status = e_gw_connection_parse_response_status (response); 
1029          if (status != E_GW_CONNECTION_STATUS_OK) { 
1030                 g_object_unref (response); 
1031                 g_object_unref (msg); 
1032                 //      g_object_unref (cnc); 
1033                 return status; 
1034         } 
1035
1036         /* if status is OK - parse result. return the list */    
1037         param = soup_soap_response_get_first_parameter_by_name (response, "changed"); 
1038          if (!param) { 
1039                  g_object_unref (response); 
1040                  g_object_unref (msg); 
1041                  // g_object_unref (cnc); 
1042                  return E_GW_CONNECTION_STATUS_INVALID_RESPONSE; 
1043          } 
1044         
1045          if (!g_ascii_strcasecmp ( soup_soap_parameter_get_string_value (param), "0")) { 
1046                  g_message ("No deltas"); 
1047                  // g_object_unref (cnc); 
1048                  return E_GW_CONNECTION_STATUS_OK; 
1049          }                 
1050
1051          param = soup_soap_response_get_first_parameter_by_name (response, "deltas"); 
1052          if (!param) { 
1053                  g_object_unref (response); 
1054                  g_object_unref (msg); 
1055                  // g_object_unref (cnc); 
1056 //                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE; 
1057                 /* getting around the server behavior that deltas can be null
1058                  * though changes is true */
1059                  return E_GW_CONNECTION_STATUS_OK;
1060          } 
1061         
1062          /* process all deletes first*/ 
1063          param = soup_soap_parameter_get_first_child_by_name (param, "delete"); 
1064          if (param) { 
1065                  for (subparam = soup_soap_parameter_get_first_child_by_name (param, "item"); 
1066                          subparam != NULL; 
1067                          subparam = soup_soap_parameter_get_next_child_by_name (subparam, "item")) {  
1068                                  /*process each item */  
1069                                  char *uid; 
1070                                  SoupSoapParameter *param_id; 
1071
1072                                  param_id = soup_soap_parameter_get_first_child_by_name (subparam, "id"); 
1073                                  if (!param_id) { 
1074                                          g_object_unref (response); 
1075                                          g_object_unref (msg); 
1076                                          // g_object_unref (cnc); 
1077                                  } 
1078                                  uid = (char *)soup_soap_parameter_get_string_value (param_id); 
1079                                  /*if (!e_cal_backend_cache_remove_component (cache, uid, NULL)) 
1080                                          g_message ("Could not remove %s", uid); */
1081                                  *deletes = g_slist_append (*deletes, uid);
1082                  } 
1083          } 
1084         
1085          /* process adds*/ 
1086          param = soup_soap_parameter_get_first_child_by_name (param, "add"); 
1087          if (param) { 
1088                  for (subparam = soup_soap_parameter_get_first_child_by_name (param, "item"); 
1089                          subparam != NULL; 
1090                          subparam = soup_soap_parameter_get_next_child_by_name (subparam, "item")) {  
1091                                 /*process each item */  
1092                                 EGwItem *item;
1093                                 /*FIXME  pass the container id */
1094                                 item = e_gw_item_new_from_soap_parameter (cnc->priv->user_email, "Calendar", subparam);
1095                                 if (!item) { 
1096                                          g_object_unref (response); 
1097                                          g_object_unref (msg); 
1098                                          // g_object_unref (cnc); 
1099                                         return E_GW_CONNECTION_STATUS_INVALID_RESPONSE; 
1100                                  } 
1101                                  /*if (!e_cal_backend_cache_put_component (cache, comp)) 
1102                                          g_message ("Could not add the component"); */
1103                                  *adds = g_slist_append (*adds, item);
1104                  } 
1105          } 
1106         
1107          /* process updates*/ 
1108          param = soup_soap_parameter_get_first_child_by_name (param, "update"); 
1109          if (param) { 
1110                  for (subparam = soup_soap_parameter_get_first_child_by_name(param, "item"); 
1111                      subparam != NULL; 
1112                      subparam = soup_soap_parameter_get_next_child (subparam)) {  
1113                          EGwItem *item;
1114                          /*process each item */
1115                          /*item = get_item_from_updates (subparam);*/
1116                          item = e_gw_item_new_from_soap_parameter (cnc->priv->user_email, "Calendar", subparam);
1117                          if (item)
1118                                  *updates = g_slist_append (*updates, item);
1119                  } 
1120          }
1121          
1122          /* free memory */ 
1123          g_object_unref (response); 
1124          g_object_unref (msg); 
1125
1126         return E_GW_CONNECTION_STATUS_OK;        
1127 }
1128
1129 EGwConnectionStatus
1130 e_gw_connection_send_item (EGwConnection *cnc, EGwItem *item, GSList **id_list)
1131 {
1132         SoupSoapMessage *msg;
1133         SoupSoapResponse *response;
1134         EGwConnectionStatus status = E_GW_CONNECTION_STATUS_UNKNOWN;
1135
1136         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
1137         g_return_val_if_fail (E_IS_GW_ITEM (item), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
1138
1139         if (id_list)
1140                 *id_list = NULL;
1141
1142         /* compose SOAP message */
1143         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "sendItemRequest");
1144         if (!msg) {
1145                 g_warning (G_STRLOC ": Could not build SOAP message");
1146                 return E_GW_CONNECTION_STATUS_UNKNOWN;
1147         }
1148
1149         if (!e_gw_item_append_to_soap_message (item, msg)) {
1150                 g_warning (G_STRLOC ": Could not append item to SOAP message");
1151                 g_object_unref (msg);
1152                 return E_GW_CONNECTION_STATUS_INVALID_OBJECT;
1153         }
1154
1155         e_gw_message_write_footer (msg);
1156
1157         /* send message to server */
1158         response = e_gw_connection_send_message (cnc, msg);
1159         if (!response) {
1160                 g_object_unref (msg);
1161                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
1162         }
1163
1164         status = e_gw_connection_parse_response_status (response);
1165         if (status == E_GW_CONNECTION_STATUS_OK && id_list != NULL) {
1166                 SoupSoapParameter *param;
1167
1168                 /* get the generated ID from the SOAP response */
1169                 // for loop here to populate the list_ids.
1170                 for (param = soup_soap_response_get_first_parameter_by_name (response, "id");
1171                         param; param = soup_soap_response_get_next_parameter_by_name (response, param, "id")) {
1172                         
1173                         *id_list = g_slist_append (*id_list, soup_soap_parameter_get_string_value (param));
1174                 }
1175         }
1176         else if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1177                 reauthenticate (cnc);
1178         g_object_unref (msg);
1179         g_object_unref (response);
1180
1181         return status;
1182 }
1183
1184 EGwConnectionStatus
1185 e_gw_connection_create_item (EGwConnection *cnc, EGwItem *item, char** id)
1186 {
1187         SoupSoapMessage *msg;
1188         SoupSoapResponse *response;
1189         SoupSoapParameter *param;
1190         EGwConnectionStatus status = E_GW_CONNECTION_STATUS_UNKNOWN;
1191         
1192         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
1193         g_return_val_if_fail (E_IS_GW_ITEM (item), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
1194
1195         /* compose SOAP message */
1196         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "createItemRequest");
1197         if (!msg) {
1198                 g_warning (G_STRLOC ": Could not build SOAP message");
1199                 return E_GW_CONNECTION_STATUS_UNKNOWN;
1200         }
1201
1202         if (!e_gw_item_append_to_soap_message (item, msg)) {
1203                 g_warning (G_STRLOC ": Could not append item to SOAP message");
1204                 g_object_unref (msg);
1205                 return E_GW_CONNECTION_STATUS_INVALID_OBJECT;
1206         }
1207
1208         e_gw_message_write_footer (msg);
1209
1210         /* send message to server */
1211         response = e_gw_connection_send_message (cnc, msg);
1212         if (!response) {
1213                 g_object_unref (msg);
1214                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
1215         }
1216
1217         status = e_gw_connection_parse_response_status (response);
1218         if (status == E_GW_CONNECTION_STATUS_OK) {
1219                 param = soup_soap_response_get_first_parameter_by_name (response, "id");
1220                 if (param != NULL) 
1221                         *id = g_strdup (soup_soap_parameter_get_string_value (param));
1222         } else if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1223                 reauthenticate (cnc);
1224         
1225         g_object_unref (msg);
1226         g_object_unref (response);
1227
1228         return status;
1229 }
1230
1231 EGwConnectionStatus 
1232 e_gw_connection_modify_item (EGwConnection *cnc, const char *id , EGwItem *item)
1233 {
1234         SoupSoapMessage *msg;
1235         SoupSoapResponse *response;
1236         EGwConnectionStatus status;
1237         
1238         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
1239
1240         /* build the SOAP message */
1241         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "modifyItemRequest");
1242         if (!msg) {
1243                 g_warning (G_STRLOC ": Could not build SOAP message");
1244                 return E_GW_CONNECTION_STATUS_UNKNOWN;
1245         }
1246
1247         e_gw_message_write_string_parameter (msg, "id", NULL, id);
1248
1249         if (!e_gw_item_append_changes_to_soap_message (item, msg)) {
1250                 g_warning (G_STRLOC ": Could not append item to SOAP message");
1251                 g_object_unref (msg);
1252                 return E_GW_CONNECTION_STATUS_INVALID_OBJECT;
1253         }
1254
1255         e_gw_message_write_footer (msg);
1256
1257         /* send message to server */
1258         response = e_gw_connection_send_message (cnc, msg);
1259         if (!response) {
1260                 g_object_unref (msg);
1261                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
1262         }
1263
1264         status = e_gw_connection_parse_response_status (response);
1265         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1266                 reauthenticate (cnc);
1267         g_object_unref (msg);
1268         g_object_unref (response);
1269
1270         return status;
1271                 
1272 }
1273
1274 EGwConnectionStatus 
1275 e_gw_connection_get_item (EGwConnection *cnc, const char *container, const char *id, const char *view, EGwItem **item)
1276 {
1277
1278         SoupSoapMessage *msg;
1279         SoupSoapResponse *response;
1280         EGwConnectionStatus status;
1281         SoupSoapParameter *param;
1282
1283         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
1284
1285         /* build the SOAP message */
1286         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getItemRequest");
1287         if (!msg) {
1288                 g_warning (G_STRLOC ": Could not build SOAP message");
1289                 return E_GW_CONNECTION_STATUS_UNKNOWN;
1290         }
1291       
1292
1293         e_gw_message_write_string_parameter (msg, "id", NULL, id);
1294
1295         if (view)
1296                 e_gw_message_write_string_parameter (msg, "view", NULL, view) ;
1297         e_gw_message_write_footer (msg);
1298
1299         /* send message to server */
1300         response = e_gw_connection_send_message (cnc, msg);
1301         if (!response) {
1302                 g_object_unref (msg);
1303                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
1304         }
1305
1306         status = e_gw_connection_parse_response_status (response);
1307         if (status != E_GW_CONNECTION_STATUS_OK) {
1308                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1309                         reauthenticate (cnc);
1310                 g_object_unref (response);
1311                 g_object_unref (msg);
1312                 return status;
1313         }
1314
1315         /* if status is OK - parse result. return the list */   
1316         param = soup_soap_response_get_first_parameter_by_name (response, "item");
1317         if (!param) {
1318                 g_object_unref (response);
1319                 g_object_unref (msg);
1320                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
1321         }
1322         
1323         *item = e_gw_item_new_from_soap_parameter (cnc->priv->user_email, container, param);
1324         
1325                
1326         /* free memory */
1327         g_object_unref (response);
1328         g_object_unref (msg);
1329
1330         return E_GW_CONNECTION_STATUS_OK;
1331 }
1332
1333
1334
1335
1336
1337 EGwConnectionStatus
1338 e_gw_connection_remove_item (EGwConnection *cnc, const char *container, const char *id)
1339 {
1340         SoupSoapMessage *msg;
1341         SoupSoapResponse *response;
1342         EGwConnectionStatus status;
1343
1344         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
1345         g_return_val_if_fail (id != NULL, E_GW_CONNECTION_STATUS_INVALID_OBJECT);
1346
1347         /* build the SOAP message */
1348         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "removeItemRequest");
1349
1350         if (container && *container)
1351                 e_gw_message_write_string_parameter (msg, "container", NULL, container);
1352         e_gw_message_write_string_parameter (msg, "id", NULL, id);
1353         e_gw_message_write_footer (msg);
1354
1355         /* send message to server */
1356         response = e_gw_connection_send_message (cnc, msg);
1357         if (!response) {
1358                 g_object_unref (msg);
1359                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
1360         }
1361
1362         status = e_gw_connection_parse_response_status (response);
1363         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1364                 reauthenticate (cnc);
1365         /* free memory */
1366         g_object_unref (response);
1367         g_object_unref (msg);
1368
1369         return status;
1370 }
1371
1372 EGwConnectionStatus
1373 e_gw_connection_remove_items (EGwConnection *cnc, const char *container, GList *item_ids)
1374 {
1375         SoupSoapMessage *msg;
1376         SoupSoapResponse *response;
1377         EGwConnectionStatus status;
1378
1379         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
1380
1381         /* build the SOAP message */
1382         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "removeItemsRequest");
1383         if (container && *container)
1384                 e_gw_message_write_string_parameter (msg, "container", NULL, container);
1385
1386         soup_soap_message_start_element (msg, "items", NULL, NULL);
1387         for (; item_ids != NULL; item_ids = g_list_next (item_ids))
1388                 e_gw_message_write_string_parameter (msg, "item", NULL, item_ids->data);
1389         soup_soap_message_end_element (msg);
1390         e_gw_message_write_footer (msg);
1391
1392         /* send message to server */
1393         response = e_gw_connection_send_message (cnc, msg);
1394         if (!response) {
1395                 g_object_unref (msg);
1396                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
1397         }
1398
1399         status = e_gw_connection_parse_response_status (response);
1400         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1401                 reauthenticate (cnc);
1402         /* free memory */
1403         g_object_unref (response);
1404         g_object_unref (msg);
1405
1406         return status;
1407 }
1408
1409 EGwConnectionStatus
1410 e_gw_connection_accept_request (EGwConnection *cnc, const char *id, const char *accept_level, const char *accept_comment, const char *recurrence_key)
1411 {
1412         SoupSoapMessage *msg;
1413         int status;
1414         SoupSoapResponse *response;
1415
1416         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "acceptRequest");
1417         soup_soap_message_start_element (msg, "items", NULL, NULL);
1418         e_gw_message_write_string_parameter (msg, "item", NULL, id);
1419         soup_soap_message_end_element (msg);
1420         e_gw_message_write_string_parameter (msg, "acceptLevel", NULL, accept_level);
1421         
1422         if (recurrence_key)
1423                 e_gw_message_write_string_parameter (msg, "recurrenceAllInstances", NULL, recurrence_key);
1424
1425         if (accept_comment)
1426                 e_gw_message_write_string_parameter (msg, "comment", NULL, accept_comment);
1427
1428         e_gw_message_write_footer (msg);
1429
1430         response = e_gw_connection_send_message (cnc, msg);
1431         if (!response) {
1432                 g_object_unref (msg);
1433                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
1434         }
1435
1436         status = e_gw_connection_parse_response_status (response);
1437         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1438                 reauthenticate (cnc);
1439         g_object_unref (response);
1440         g_object_unref (msg);
1441         return status;
1442 }
1443
1444 EGwConnectionStatus
1445 e_gw_connection_decline_request (EGwConnection *cnc, const char *id, const char *decline_comment, const char *recurrence_key)
1446 {
1447         SoupSoapMessage *msg;
1448         int status;
1449         SoupSoapResponse *response;
1450
1451         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "declineRequest");
1452         soup_soap_message_start_element (msg, "items", NULL, NULL);
1453         e_gw_message_write_string_parameter (msg, "item", NULL, id);
1454         soup_soap_message_end_element (msg);
1455         
1456         if (decline_comment)
1457                 e_gw_message_write_string_parameter (msg, "comment", NULL, decline_comment);
1458
1459         if (recurrence_key)
1460                 e_gw_message_write_string_parameter (msg, "recurrenceAllInstances", NULL, recurrence_key);
1461
1462         e_gw_message_write_footer (msg);
1463
1464         response = e_gw_connection_send_message (cnc, msg);
1465         if (!response) {
1466                 g_object_unref (msg);
1467                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
1468         }
1469
1470         status = e_gw_connection_parse_response_status (response);
1471         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1472                 reauthenticate (cnc);
1473         g_object_unref (response);
1474         g_object_unref (msg);
1475         return status;
1476 }
1477
1478 EGwConnectionStatus
1479 e_gw_connection_retract_request (EGwConnection *cnc, const char *id, const char *comment, gboolean retract_all, gboolean resend)
1480 {
1481         SoupSoapMessage *msg;
1482         int status;
1483         SoupSoapResponse *response;
1484
1485         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "retractRequest");
1486         soup_soap_message_start_element (msg, "items", NULL, NULL);
1487         e_gw_message_write_string_parameter (msg, "item", NULL, id);
1488         soup_soap_message_end_element (msg);
1489         /* comment, FALSE, FALSE to be filled in later. */
1490         e_gw_message_write_footer (msg);
1491
1492         response = e_gw_connection_send_message (cnc, msg);
1493         if (!response) {
1494                 g_object_unref (msg);
1495                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
1496         }
1497
1498         status = e_gw_connection_parse_response_status (response);
1499         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1500                 reauthenticate (cnc);
1501         g_object_unref (response);
1502         g_object_unref (msg);
1503         return status;
1504 }
1505
1506 EGwConnectionStatus
1507 e_gw_connection_complete_request (EGwConnection *cnc, const char *id)
1508 {
1509         SoupSoapMessage *msg;
1510         int status;
1511         SoupSoapResponse *response;
1512
1513         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "completeRequest");
1514         soup_soap_message_start_element (msg, "items", NULL, NULL);
1515         e_gw_message_write_string_parameter (msg, "item", NULL, id);
1516         soup_soap_message_end_element (msg);
1517         e_gw_message_write_footer (msg);
1518
1519         response = e_gw_connection_send_message (cnc, msg);
1520         if (!response) {
1521                 g_object_unref (msg);
1522                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
1523         }
1524
1525         status = e_gw_connection_parse_response_status (response);
1526         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1527                 reauthenticate (cnc);
1528         g_object_unref (response);
1529         g_object_unref (msg);
1530         return status;
1531 }
1532
1533 EGwConnectionStatus 
1534 e_gw_connection_delegate_request (EGwConnection *cnc, EGwItem *item, const char *id, const char *comments_org, const char *comments_del, const char *recur_key)
1535 {
1536         SoupSoapMessage *msg;
1537         int status;
1538         SoupSoapResponse *response;
1539
1540         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "delegateRequest");
1541         
1542         if (id)
1543                 e_gw_message_write_string_parameter (msg, "id", NULL, id);
1544
1545         e_gw_item_add_distribution_to_soap_message (item, msg);
1546         if (comments_org)
1547                 e_gw_message_write_string_parameter (msg, "commentToOrganizer", NULL, comments_org);
1548         if (comments_del)
1549                 e_gw_message_write_string_parameter (msg, "commentToDelegatee", NULL, comments_del);
1550         if (recur_key)
1551                 e_gw_message_write_string_parameter (msg, "recurrenceAllInstances", NULL, recur_key);
1552         
1553         e_gw_message_write_footer (msg);
1554
1555         response = e_gw_connection_send_message (cnc, msg);
1556         if (!response) {
1557                 g_object_unref (msg);
1558                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
1559         }
1560
1561         status = e_gw_connection_parse_response_status (response);
1562         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1563                 reauthenticate (cnc);
1564         
1565         g_object_unref (response);
1566         g_object_unref (msg);
1567         
1568         return status;
1569 }
1570
1571 const char *
1572 e_gw_connection_get_version (EGwConnection *cnc)
1573 {
1574         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), NULL);
1575
1576         return (const char *) cnc->priv->version;
1577 }
1578
1579 const char *
1580 e_gw_connection_get_uri (EGwConnection *cnc)
1581 {
1582         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), NULL);
1583
1584         return (const char *) cnc->priv->uri;
1585 }
1586
1587 const char *
1588 e_gw_connection_get_session_id (EGwConnection *cnc)
1589 {
1590         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), NULL);
1591
1592         return (const char *) cnc->priv->session_id;
1593 }
1594
1595 const char *
1596 e_gw_connection_get_user_name (EGwConnection *cnc)
1597 {
1598         g_return_val_if_fail (cnc != NULL, NULL);
1599         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), NULL);
1600
1601         return (const char *) cnc->priv->user_name;
1602 }
1603
1604 const char* 
1605 e_gw_connection_get_user_email (EGwConnection *cnc)
1606 {
1607         g_return_val_if_fail (cnc != NULL, NULL);
1608         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), NULL);
1609   
1610         return (const char*) cnc->priv->user_email;
1611         
1612 }
1613
1614 const char *
1615 e_gw_connection_get_user_uuid (EGwConnection *cnc)
1616 {
1617         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), NULL);
1618
1619         return (const char *) cnc->priv->user_uuid;
1620 }
1621
1622 const char * 
1623 e_gw_connection_get_server_time (EGwConnection *cnc)
1624 {
1625         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), NULL) ;
1626
1627         return (const char *) cnc->priv->server_time ;
1628 }
1629
1630 static time_t
1631 timet_from_string (const char *str)
1632 {
1633         struct tm date;
1634         int len, i;
1635                                                               
1636         g_return_val_if_fail (str != NULL, -1);
1637
1638         /* yyyymmdd[Thhmmss[Z]] */
1639         len = strlen (str);
1640
1641         if (!(len == 8 || len == 15 || len == 16))
1642                 return -1;
1643
1644         for (i = 0; i < len; i++)
1645                 if (!((i != 8 && i != 15 && isdigit (str[i]))
1646                       || (i == 8 && str[i] == 'T')
1647                       || (i == 15 && str[i] == 'Z')))
1648                         return -1;
1649
1650 #define digit_at(x,y) (x[y] - '0')
1651
1652         date.tm_year = digit_at (str, 0) * 1000
1653                 + digit_at (str, 1) * 100
1654                 + digit_at (str, 2) * 10
1655                 + digit_at (str, 3) -1900;
1656         date.tm_mon = digit_at (str, 4) * 10 + digit_at (str, 5) -1;
1657         date.tm_mday = digit_at (str, 6) * 10 + digit_at (str, 7);
1658         if (len > 8) {
1659                 date.tm_hour = digit_at (str, 9) * 10 + digit_at (str, 10);
1660                 date.tm_min  = digit_at (str, 11) * 10 + digit_at (str, 12);
1661                 date.tm_sec  = digit_at (str, 13) * 10 + digit_at (str, 14);
1662         } else
1663                 date.tm_hour = date.tm_min = date.tm_sec = 0; 
1664
1665         return mktime (&date);
1666 }
1667
1668 char *
1669 e_gw_connection_format_date_string (const char *dtstring)
1670 {
1671         char *str2;
1672         int i, j, len = strlen (dtstring);
1673         
1674         str2 = g_malloc0 (len);
1675         if (len <= 0)
1676                 return str2;
1677
1678         for (i = 0,j = 0; i < len; i++) {
1679                 if ((dtstring[i] != '-') && (dtstring[i] != ':')) {
1680                         str2[j] = dtstring[i];
1681                         j++;
1682                 }
1683         }
1684
1685         str2[j] = '\0';
1686         return str2;
1687 }
1688
1689 time_t
1690 e_gw_connection_get_date_from_string (const char *dtstring)
1691 {
1692         char *str2;
1693         int i, j, len = strlen (dtstring);
1694         time_t t;
1695         
1696         str2 = g_malloc0 (len+1);
1697         for (i = 0,j = 0; i < len; i++) {
1698                 if ((dtstring[i] != '-') && (dtstring[i] != ':')) {
1699                         str2[j] = dtstring[i];
1700                         j++;
1701                 }
1702         }
1703
1704         str2[j] = '\0';
1705         t = timet_from_string (str2);
1706         g_free (str2);
1707
1708         return t;
1709 }
1710
1711 EGwConnectionStatus 
1712 e_gw_connection_create_book (EGwConnection *cnc, char *book_name, char**id)
1713 {
1714         SoupSoapMessage *msg;
1715         int status;
1716         SoupSoapResponse *response;
1717         SoupSoapParameter *param;
1718         char *value;
1719
1720         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "createItemRequest");
1721         soup_soap_message_start_element (msg, "item", NULL, NULL);
1722         soup_soap_message_add_attribute (msg, "type", "AddressBook", "xsi", NULL);
1723         e_gw_message_write_string_parameter (msg, "name", NULL, book_name);
1724         soup_soap_message_end_element (msg);
1725         e_gw_message_write_footer (msg);
1726
1727         response = e_gw_connection_send_message (cnc, msg);
1728         if (!response) {
1729                 g_object_unref (msg);
1730                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
1731         }
1732
1733         status = e_gw_connection_parse_response_status (response);
1734         if (status != E_GW_CONNECTION_STATUS_OK) {
1735                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1736                         reauthenticate (cnc);
1737                 g_object_unref (response);
1738                 g_object_unref (msg);
1739                 return status;
1740         }
1741         value = NULL;
1742         param = soup_soap_response_get_first_parameter_by_name (response, "id");
1743         if (param)
1744                 value = soup_soap_parameter_get_string_value (param);
1745         if (value)
1746                 *id = value;
1747
1748         status = E_GW_CONNECTION_STATUS_OK;     
1749         return status;  
1750
1751
1752 EGwConnectionStatus
1753 e_gw_connection_get_address_book_list (EGwConnection *cnc, GList **container_list)
1754 {
1755         SoupSoapMessage *msg;
1756         SoupSoapResponse *response;
1757         EGwConnectionStatus status;
1758         EGwConnectionPrivate *priv;
1759         SoupSoapParameter *param;
1760         SoupSoapParameter *type_param;
1761         char *value;
1762         static GStaticMutex connecting = G_STATIC_MUTEX_INIT;
1763
1764         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
1765         g_return_val_if_fail (container_list != NULL, E_GW_CONNECTION_STATUS_UNKNOWN);
1766
1767         priv = cnc->priv;
1768         g_static_mutex_lock (&connecting);
1769
1770         if (priv->book_list) {
1771                 *container_list = priv->book_list;
1772                 g_static_mutex_unlock (&connecting);
1773                 return E_GW_CONNECTION_STATUS_OK;
1774         }
1775
1776         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getAddressBookListRequest");
1777         if (!msg) {
1778                 g_warning (G_STRLOC ": Could not build SOAP message");
1779                 g_static_mutex_unlock (&connecting);
1780                 return E_GW_CONNECTION_STATUS_UNKNOWN;
1781         }
1782
1783         e_gw_message_write_footer (msg);
1784
1785         /* send message to server */
1786         response = e_gw_connection_send_message (cnc, msg);
1787         if (!response) {
1788                 g_object_unref (msg);
1789                 g_static_mutex_unlock (&connecting);
1790                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
1791         }
1792
1793         status = e_gw_connection_parse_response_status (response);
1794         g_object_unref (msg);
1795
1796         if (status != E_GW_CONNECTION_STATUS_OK) {
1797                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1798                         reauthenticate (cnc);
1799                 g_object_unref (response);
1800                 g_static_mutex_unlock (&connecting);
1801                 return status;
1802         }
1803         
1804         /* if status is OK - parse result. return the list */   
1805         param = soup_soap_response_get_first_parameter_by_name (response, "books");     
1806         if (!param) {
1807                 g_object_unref (response);
1808                 g_static_mutex_unlock (&connecting);
1809                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
1810         } else {
1811                 SoupSoapParameter *subparam;
1812                 for (subparam = soup_soap_parameter_get_first_child_by_name (param, "book");
1813                      subparam != NULL;
1814                      subparam = soup_soap_parameter_get_next_child_by_name (subparam, "book")) {
1815                         EGwContainer *container;
1816                                        
1817                         container = e_gw_container_new_from_soap_parameter (subparam);
1818                         if (container) {
1819                                 priv->book_list = g_list_append (priv->book_list, container);
1820                                 type_param = soup_soap_parameter_get_first_child_by_name (subparam, "isPersonal");
1821                                 value = NULL;
1822                                 if (type_param)
1823                                         value = soup_soap_parameter_get_string_value (type_param);
1824                                 if (value && g_str_equal(value , "1"))
1825                                         e_gw_container_set_is_writable (container, TRUE);
1826                                 else 
1827                                         e_gw_container_set_is_writable (container, FALSE);
1828                                 g_free (value);
1829                                 value = NULL;
1830                                 type_param = soup_soap_parameter_get_first_child_by_name (subparam, "isFrequentContacts");
1831                                 if (type_param)
1832                                         value = soup_soap_parameter_get_string_value (type_param);
1833                                 if (value && g_str_equal(value , "1"))
1834                                         e_gw_container_set_is_frequent_contacts (container, TRUE);
1835                                                                         
1836                                 g_free (value);
1837                                         
1838                         }
1839                                      
1840                 }
1841         }
1842
1843         g_object_unref (response);
1844         *container_list = priv->book_list;
1845         g_static_mutex_unlock (&connecting);
1846
1847         return status;
1848 }
1849
1850
1851 EGwConnectionStatus 
1852 e_gw_connection_get_address_book_id ( EGwConnection *cnc, char *book_name, char**id , gboolean *is_writable)
1853 {
1854         EGwConnectionStatus status;
1855         GList *container_list = NULL, *l;
1856
1857         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
1858         g_return_val_if_fail (book_name != NULL, E_GW_CONNECTION_STATUS_INVALID_OBJECT);
1859
1860         status = e_gw_connection_get_address_book_list (cnc, &container_list);
1861         if (status != E_GW_CONNECTION_STATUS_OK) {
1862                 return status;
1863         }
1864
1865         /* search the container in the list */
1866         for (l = container_list; l != NULL; l = l->next) {
1867                 EGwContainer *container = E_GW_CONTAINER (l->data);
1868                 if (strcmp (e_gw_container_get_name (container), book_name) == 0) {
1869                         
1870                         *id = g_strdup (e_gw_container_get_id (container));
1871                         *is_writable = e_gw_container_get_is_writable (container);
1872                         break;
1873                 }
1874         }
1875
1876         return status;
1877
1878 }
1879
1880 EGwConnectionStatus
1881 e_gw_connection_modify_settings (EGwConnection *cnc, EGwSendOptions *opts)
1882 {
1883         SoupSoapMessage *msg;
1884         SoupSoapResponse *response;
1885         EGwConnectionStatus status;
1886         EGwConnectionPrivate *priv;
1887
1888         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
1889         g_return_val_if_fail (opts != NULL, E_GW_CONNECTION_STATUS_INVALID_OBJECT);
1890
1891         priv = cnc->priv;
1892
1893         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "modifySettingsRequest");
1894         if (!msg) {
1895                 g_warning (G_STRLOC ": Could not build SOAP message");
1896                 return E_GW_CONNECTION_STATUS_UNKNOWN;
1897         }
1898         
1899         if (!e_gw_sendoptions_form_message_to_modify (msg, opts, priv->opts)) {
1900                 g_warning (G_STRLOC ": Could not append changes to SOAP message");
1901                 g_object_unref (msg);
1902                 return E_GW_CONNECTION_STATUS_INVALID_OBJECT;
1903         }
1904
1905         e_gw_message_write_footer (msg);
1906         
1907         /* send message to server */
1908         response = e_gw_connection_send_message (cnc, msg);
1909         if (!response) {
1910                 g_object_unref (msg);
1911                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
1912         }
1913
1914         status = e_gw_connection_parse_response_status (response);
1915         if (status != E_GW_CONNECTION_STATUS_OK) {
1916                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1917                         reauthenticate (cnc);
1918                 g_object_unref (response);
1919                 g_object_unref (msg);
1920                 return status;
1921         } else {
1922                 g_object_unref (priv->opts);
1923                 priv->opts = NULL;
1924                 priv->opts = opts;
1925         }
1926
1927         g_object_unref (response);
1928         g_object_unref (msg);
1929
1930         return status;
1931 }
1932
1933 EGwConnectionStatus
1934 e_gw_connection_get_settings (EGwConnection *cnc, EGwSendOptions **opts)
1935 {
1936         SoupSoapMessage *msg;
1937         SoupSoapResponse *response;
1938         EGwConnectionStatus status;
1939         SoupSoapParameter *param;
1940         EGwConnectionPrivate *priv;
1941         static GStaticMutex connecting = G_STATIC_MUTEX_INIT;   
1942
1943
1944         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
1945
1946         priv = cnc->priv;
1947
1948         g_static_mutex_lock (&connecting);
1949
1950         if (priv->opts) {
1951                 g_object_ref (priv->opts);
1952                 *opts = priv->opts;
1953                 g_static_mutex_unlock (&connecting);
1954                 
1955                 return E_GW_CONNECTION_STATUS_OK;
1956         }
1957
1958         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getSettingsRequest");
1959         if (!msg) {
1960                 g_warning (G_STRLOC ": Could not build SOAP message");
1961                 g_static_mutex_unlock (&connecting);
1962                 return E_GW_CONNECTION_STATUS_UNKNOWN;
1963         }
1964         e_gw_message_write_footer (msg);
1965
1966         /* send message to server */
1967         response = e_gw_connection_send_message (cnc, msg);
1968         if (!response) {
1969                 g_object_unref (msg);
1970                 g_static_mutex_unlock (&connecting);
1971                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
1972         }
1973
1974         status = e_gw_connection_parse_response_status (response);
1975         if (status != E_GW_CONNECTION_STATUS_OK) {
1976                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
1977                         reauthenticate (cnc);
1978                 g_object_unref (response);
1979                 g_object_unref (msg);
1980                 g_static_mutex_unlock (&connecting);
1981                 return status;
1982         }
1983         
1984         param = soup_soap_response_get_first_parameter_by_name (response, "settings");
1985         if (!param) {
1986                 g_object_unref (response);
1987                 g_object_unref (msg);
1988                 g_static_mutex_unlock (&connecting);
1989                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
1990         } else 
1991                 priv->opts = e_gw_sendoptions_new_from_soap_parameter (param);
1992
1993         g_object_ref (priv->opts);
1994         *opts = priv->opts;
1995         g_object_unref (response);
1996         g_object_unref (msg);
1997         g_static_mutex_unlock (&connecting);
1998         
1999         return E_GW_CONNECTION_STATUS_OK;
2000 }
2001
2002 EGwConnectionStatus 
2003 e_gw_connection_get_categories (EGwConnection *cnc, GHashTable **categories_by_id, GHashTable **categories_by_name)
2004 {
2005         SoupSoapMessage *msg;
2006         SoupSoapResponse *response;
2007         EGwConnectionStatus status;
2008         EGwConnectionPrivate *priv;
2009         SoupSoapParameter *param, *subparam, *second_level_child;
2010         char *id, *name;
2011         static GStaticMutex connecting = G_STATIC_MUTEX_INIT;
2012
2013         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
2014
2015         priv = cnc->priv;
2016         g_static_mutex_lock (&connecting);
2017
2018         if (priv->categories_by_id && priv->categories_by_name) {
2019                 *categories_by_id = priv->categories_by_id;
2020                 *categories_by_name = priv->categories_by_name;
2021                 g_static_mutex_unlock (&connecting);
2022                 return E_GW_CONNECTION_STATUS_OK;
2023         }
2024
2025         /* build the SOAP message */
2026         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getCategoryListRequest");
2027         if (!msg) {
2028                 g_warning (G_STRLOC ": Could not build SOAP message");
2029                 g_static_mutex_unlock (&connecting);
2030                 return E_GW_CONNECTION_STATUS_UNKNOWN;
2031         }
2032         e_gw_message_write_footer (msg);
2033
2034         /* send message to server */
2035         response = e_gw_connection_send_message (cnc, msg);
2036         if (!response) {
2037                 g_object_unref (msg);
2038                 g_static_mutex_unlock (&connecting);
2039                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2040         }
2041
2042         status = e_gw_connection_parse_response_status (response);
2043         if (status != E_GW_CONNECTION_STATUS_OK) {
2044                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2045                         reauthenticate (cnc);
2046                 g_object_unref (response);
2047                 g_object_unref (msg);
2048                 g_static_mutex_unlock (&connecting);
2049                 return status;
2050         }
2051
2052         /* if status is OK - parse result. return the list */   
2053         param = soup_soap_response_get_first_parameter_by_name (response, "categories");
2054         if (!param) {
2055                 g_object_unref (response);
2056                 g_object_unref (msg);
2057                 g_static_mutex_unlock (&connecting);
2058                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
2059         }
2060         
2061         priv->categories_by_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
2062         priv->categories_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
2063
2064         for (subparam = soup_soap_parameter_get_first_child_by_name (param, "category");
2065              subparam != NULL;
2066              subparam = soup_soap_parameter_get_next_child_by_name (subparam, "category")) {
2067                 id = name = NULL;
2068                 second_level_child = soup_soap_parameter_get_first_child_by_name (subparam, "id");
2069                 if (second_level_child)
2070                         id = soup_soap_parameter_get_string_value (second_level_child);
2071                 second_level_child = soup_soap_parameter_get_first_child_by_name (subparam, "name");
2072                 if (second_level_child)
2073                         name = soup_soap_parameter_get_string_value (second_level_child);
2074                 if (id && name) {
2075                         char **components = g_strsplit (id, "@", -1);
2076                         g_free (id);
2077                         id = components[0];
2078                         if (categories_by_id) 
2079                                 g_hash_table_insert (priv->categories_by_id, g_strdup (id), g_strdup (name));
2080                         if (categories_by_name) 
2081                                 g_hash_table_insert (priv->categories_by_name, g_strdup (name), g_strdup (id));
2082                         g_strfreev (components);
2083                         g_free (name);
2084                 }
2085                 
2086         }
2087                
2088         /* free memory */
2089         g_object_unref (response);
2090         g_object_unref (msg);
2091         *categories_by_id = priv->categories_by_id;
2092         *categories_by_name = priv->categories_by_name;
2093         g_static_mutex_unlock (&connecting);
2094
2095         return E_GW_CONNECTION_STATUS_OK;
2096 }
2097
2098 EGwConnectionStatus 
2099 e_gw_connection_add_members (EGwConnection *cnc, const char *group_id, GList *member_ids)
2100 {
2101         SoupSoapMessage *msg;
2102         SoupSoapResponse *response;
2103         EGwConnectionStatus status;
2104         
2105         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
2106         g_return_val_if_fail (member_ids != NULL, E_GW_CONNECTION_STATUS_UNKNOWN);
2107         g_return_val_if_fail (group_id != NULL, E_GW_CONNECTION_STATUS_UNKNOWN);
2108         
2109          msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "addMembersRequest");
2110         if (!msg) {
2111                 g_warning (G_STRLOC ": Could not build SOAP message");
2112                 return E_GW_CONNECTION_STATUS_UNKNOWN;
2113         }
2114         e_gw_message_write_string_parameter (msg, "container", NULL, group_id);
2115         soup_soap_message_start_element (msg, "members", NULL, NULL);
2116
2117         for (; member_ids != NULL; member_ids = g_list_next (member_ids)) {
2118                 soup_soap_message_start_element (msg, "member", NULL, NULL);
2119                 e_gw_message_write_string_parameter (msg, "id", NULL, member_ids->data);
2120                 soup_soap_message_end_element(msg);
2121         }
2122         
2123         soup_soap_message_end_element(msg);
2124         e_gw_message_write_footer (msg);
2125         response = e_gw_connection_send_message (cnc, msg);
2126         if (!response) {
2127                 g_object_unref (msg);
2128                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2129         }
2130
2131         status = e_gw_connection_parse_response_status (response);
2132         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2133                 reauthenticate (cnc);
2134         g_object_unref (response);
2135         g_object_unref (msg);
2136         return status;
2137         
2138
2139 }
2140
2141 EGwConnectionStatus 
2142 e_gw_connection_remove_members (EGwConnection *cnc, const char *group_id, GList *member_ids)
2143 {
2144         
2145         SoupSoapMessage *msg;
2146         SoupSoapResponse *response;
2147         EGwConnectionStatus status;
2148         
2149         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
2150         g_return_val_if_fail (member_ids != NULL, E_GW_CONNECTION_STATUS_UNKNOWN);
2151         g_return_val_if_fail (group_id != NULL, E_GW_CONNECTION_STATUS_UNKNOWN);
2152         
2153         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "removeMembersRequest");
2154         if (!msg) {
2155                 g_warning (G_STRLOC ": Could not build SOAP message");
2156                 return E_GW_CONNECTION_STATUS_UNKNOWN;
2157         }
2158         e_gw_message_write_string_parameter (msg, "container", NULL, group_id);
2159         soup_soap_message_start_element (msg, "members", NULL, NULL);
2160
2161         for (; member_ids != NULL; member_ids = g_list_next (member_ids)) {
2162                 soup_soap_message_start_element (msg, "member", NULL, NULL);
2163                 e_gw_message_write_string_parameter (msg, "id", NULL, member_ids->data);
2164                 soup_soap_message_end_element(msg);
2165         }
2166
2167         soup_soap_message_end_element(msg);
2168         e_gw_message_write_footer (msg);
2169         response = e_gw_connection_send_message (cnc, msg);
2170         if (!response) {
2171                 g_object_unref (msg);
2172                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2173         }
2174
2175         status = e_gw_connection_parse_response_status (response);
2176         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2177                 reauthenticate (cnc);
2178         g_object_unref (response);
2179         g_object_unref (msg);
2180         return status;
2181
2182
2183
2184 }
2185
2186
2187 EGwConnectionStatus
2188 e_gw_connection_create_cursor (EGwConnection *cnc, const char *container, const char *view, EGwFilter *filter, int *cursor)
2189 {
2190         SoupSoapMessage *msg;
2191         SoupSoapResponse *response;
2192         EGwConnectionStatus status;
2193         SoupSoapParameter *param;
2194         char *value;
2195
2196         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
2197         g_return_val_if_fail ((container != NULL), E_GW_CONNECTION_STATUS_UNKNOWN);
2198
2199         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "createCursorRequest");
2200         e_gw_message_write_string_parameter (msg, "container", NULL, container);
2201         if (view)
2202                 e_gw_message_write_string_parameter (msg, "view", NULL, view);
2203         if (E_IS_GW_FILTER(filter))
2204                 e_gw_filter_append_to_soap_message (filter, msg);
2205         
2206         e_gw_message_write_footer (msg);
2207
2208         response = e_gw_connection_send_message (cnc, msg);
2209         if (!response) {
2210                 g_object_unref (msg);
2211                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2212         }
2213         
2214         status = e_gw_connection_parse_response_status (response);
2215         if (status != E_GW_CONNECTION_STATUS_OK) {
2216                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2217                         reauthenticate (cnc);
2218                 g_object_unref (response);
2219                 g_object_unref (msg);
2220                 return status;
2221         }
2222         param = soup_soap_response_get_first_parameter_by_name (response, "cursor");
2223         if (!param) {
2224                 g_object_unref (response);
2225                 g_object_unref (msg);
2226                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
2227         }
2228         value = soup_soap_parameter_get_string_value(param);
2229         
2230         if (!value) {
2231                  g_object_unref (response);
2232                 g_object_unref (msg);
2233                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
2234         }
2235
2236         *cursor =(int) g_ascii_strtod (value, NULL);
2237         
2238         g_free (value);
2239         g_object_unref (response);
2240         g_object_unref (msg);
2241         return E_GW_CONNECTION_STATUS_OK;
2242 }
2243
2244 EGwConnectionStatus
2245 e_gw_connection_destroy_cursor (EGwConnection *cnc, const char *container,  int cursor)
2246 {
2247         SoupSoapMessage *msg;
2248         SoupSoapResponse *response;
2249         EGwConnectionStatus status;
2250         
2251         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
2252         g_return_val_if_fail ((container != NULL), E_GW_CONNECTION_STATUS_UNKNOWN);
2253         
2254         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "destroyCursorRequest");
2255         e_gw_message_write_string_parameter (msg, "container", NULL, container);
2256
2257         e_gw_message_write_int_parameter (msg, "cursor", NULL, cursor);
2258         e_gw_message_write_footer (msg);
2259
2260         response = e_gw_connection_send_message (cnc, msg);
2261         if (!response) {
2262                 g_object_unref (msg);
2263                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2264         }
2265         
2266         status = e_gw_connection_parse_response_status (response);
2267         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2268                 reauthenticate (cnc);
2269         g_object_unref (response);
2270         g_object_unref (msg);
2271         return status;
2272      
2273 }
2274
2275
2276
2277 EGwConnectionStatus
2278 e_gw_connection_position_cursor (EGwConnection *cnc, const char *container, int cursor, const char *seek, int offset)
2279 {
2280         SoupSoapMessage *msg;
2281         SoupSoapResponse *response;
2282         EGwConnectionStatus status;
2283
2284         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
2285         g_return_val_if_fail ((container != NULL), E_GW_CONNECTION_STATUS_UNKNOWN);
2286
2287         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "positionCursorRequest");
2288         e_gw_message_write_int_parameter (msg, "cursor", NULL, cursor);
2289         e_gw_message_write_string_parameter (msg, "container", NULL, container);
2290         e_gw_message_write_string_parameter (msg, "seek", NULL, seek);
2291         e_gw_message_write_int_parameter (msg, "offset", NULL, offset);
2292         
2293         e_gw_message_write_footer (msg);
2294
2295         response = e_gw_connection_send_message (cnc, msg);
2296         if (!response) {
2297                 g_object_unref (msg);
2298                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2299         }
2300         
2301         status = e_gw_connection_parse_response_status (response);
2302         g_object_unref (response);
2303         g_object_unref (msg);
2304         return status;
2305 }
2306
2307 EGwConnectionStatus
2308 e_gw_connection_read_cursor (EGwConnection *cnc, const char *container, int cursor, gboolean forward, int count, const char *cursor_seek, GList **item_list)
2309 {
2310         SoupSoapMessage *msg;
2311         SoupSoapResponse *response;
2312         EGwConnectionStatus status;
2313         SoupSoapParameter *param, *subparam;
2314         
2315         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
2316         g_return_val_if_fail ((container != NULL), E_GW_CONNECTION_STATUS_UNKNOWN);
2317         
2318         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "readCursorRequest");
2319         e_gw_message_write_int_parameter (msg, "cursor", NULL, cursor);
2320         /* there is problem in read curosr if you set this, uncomment after the problem 
2321            is fixed in server */
2322         e_gw_message_write_string_parameter (msg, "position", NULL, cursor_seek);
2323         e_gw_message_write_string_parameter (msg, "forward", NULL, forward ? "true": "false");
2324         e_gw_message_write_string_parameter (msg, "container", NULL, container);
2325         e_gw_message_write_int_parameter (msg, "count", NULL, count);
2326         
2327         e_gw_message_write_footer (msg);
2328
2329         response = e_gw_connection_send_message (cnc, msg);
2330         if (!response) {
2331                 g_object_unref (msg);
2332                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2333         }
2334         
2335         status = e_gw_connection_parse_response_status (response);
2336         if (status != E_GW_CONNECTION_STATUS_OK) {
2337                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2338                         reauthenticate (cnc);
2339                 g_object_unref (response);
2340                 g_object_unref (msg);
2341                 return status;
2342         }
2343
2344         /* if status is OK - parse result. return the list */   
2345         param = soup_soap_response_get_first_parameter_by_name (response, "items");
2346         if (!param) {
2347                 g_object_unref (response);
2348                 g_object_unref (msg);
2349                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
2350         }
2351
2352         for (subparam = soup_soap_parameter_get_first_child_by_name (param, "item");
2353              subparam != NULL;
2354              subparam = soup_soap_parameter_get_next_child_by_name (subparam, "item")) {
2355                 EGwItem *item;
2356
2357                 item = e_gw_item_new_from_soap_parameter (cnc->priv->user_email, container, subparam);
2358                 if (item)
2359                         *item_list = g_list_append (*item_list, item);
2360         }
2361                
2362         /* free memory */
2363         g_object_unref (response);
2364         g_object_unref (msg);
2365         return E_GW_CONNECTION_STATUS_OK;
2366 }
2367
2368 EGwConnectionStatus e_gw_connection_get_quick_messages (EGwConnection *cnc, const char *container, const char *view, char **start_date, const char *message_list, const char *item_types, const char *item_sources, int count, GSList **item_list)
2369 {
2370         SoupSoapMessage *msg;
2371         SoupSoapResponse *response;
2372         EGwConnectionStatus status;
2373         SoupSoapParameter *param, *subparam;
2374         
2375         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
2376         g_return_val_if_fail (message_list != NULL, E_GW_CONNECTION_STATUS_UNKNOWN);
2377
2378         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getQuickMessagesRequest");
2379         e_gw_message_write_string_parameter (msg, "list", NULL, message_list);
2380         if (start_date && *start_date)
2381                 e_gw_message_write_string_parameter (msg, "startDate", NULL, *start_date);
2382         if (container)
2383                 e_gw_message_write_string_parameter (msg, "container", NULL, container);
2384         if (item_types) 
2385                 e_gw_message_write_string_parameter (msg, "types", NULL, item_types);
2386         if (item_sources)
2387                 e_gw_message_write_string_parameter (msg, "source", NULL, item_sources);
2388         if (view)
2389                 e_gw_message_write_string_parameter (msg, "view", NULL, view);
2390         if (count > 0)
2391                 e_gw_message_write_int_parameter (msg, "count", NULL, count);
2392         
2393         e_gw_message_write_footer (msg);
2394
2395         response = e_gw_connection_send_message (cnc, msg);
2396         if (!response) {
2397                 g_object_unref (msg);
2398                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2399         }
2400         
2401         status = e_gw_connection_parse_response_status (response);
2402         if (status != E_GW_CONNECTION_STATUS_OK) {
2403                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2404                         reauthenticate (cnc);
2405                 g_object_unref (response);
2406                 g_object_unref (msg);
2407                 return status;
2408         }
2409
2410         /* if status is OK - parse result. return the list */   
2411         *item_list = NULL;
2412         param = soup_soap_response_get_first_parameter_by_name (response, "items");
2413         if (!param) {
2414                 g_object_unref (response);
2415                 g_object_unref (msg);
2416                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
2417         }
2418         if (start_date && *start_date && (((!strcmp (message_list, "New")) || (!strcmp (message_list, "Modified"))))) {
2419                 subparam = soup_soap_response_get_first_parameter_by_name (response, "startDate");
2420                 if (subparam) {
2421                         char *date;
2422
2423                         date = soup_soap_parameter_get_string_value (subparam);
2424                         if (date)
2425                                 g_free (*start_date), *start_date = NULL, *start_date = date;
2426                         else 
2427                                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
2428                 } else 
2429                         return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
2430         }
2431         
2432         if (!strcmp (message_list, "All")) { 
2433                 gboolean view_is_id = FALSE;
2434
2435                 if (!strcmp (view, "id")) 
2436                         view_is_id = TRUE;
2437                 /* We are  interested only in getting the ids */
2438                 for (subparam = soup_soap_parameter_get_first_child_by_name (param, "item");
2439                      subparam != NULL;
2440                      subparam = soup_soap_parameter_get_next_child_by_name (subparam, "item")) {
2441                         SoupSoapParameter *param_id;
2442                         char *id;
2443                         
2444                         if (view_is_id) {
2445                                 param_id = soup_soap_parameter_get_first_child_by_name (subparam, "id");
2446                                 if (!param_id) {
2447                                         g_object_unref (response);
2448                                         g_object_unref (msg);
2449                                         return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
2450                                 }
2451                         } else {
2452                                 param_id = soup_soap_parameter_get_first_child_by_name (subparam, "iCalId");
2453                                 if (!param_id) {
2454                                         g_object_unref (response);
2455                                         g_object_unref (msg);
2456                                         return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
2457                                 }
2458                         }
2459                      
2460                         id = g_strdup (soup_soap_parameter_get_string_value (param_id));
2461                         if (id)
2462                                 *item_list = g_slist_append (*item_list, id);
2463                 }
2464                 
2465                 g_object_unref (response);
2466                 g_object_unref (msg);
2467                 return E_GW_CONNECTION_STATUS_OK;
2468
2469         }
2470
2471         for (subparam = soup_soap_parameter_get_first_child_by_name (param, "item");
2472              subparam != NULL;
2473              subparam = soup_soap_parameter_get_next_child_by_name (subparam, "item")) {
2474                 EGwItem *item;
2475
2476                 item = e_gw_item_new_from_soap_parameter (cnc->priv->user_email, container, subparam);
2477                 if (item)
2478                         *item_list = g_slist_append (*item_list, item);
2479         }
2480                
2481         /* free memory */
2482         g_object_unref (response);
2483         g_object_unref (msg);
2484         return E_GW_CONNECTION_STATUS_OK;
2485         
2486
2487 }
2488
2489
2490 EGwConnectionStatus 
2491 e_gw_connection_create_folder(EGwConnection *cnc, const char *parent_name,const char *folder_name, char **container_id)
2492 {
2493         SoupSoapMessage *msg;
2494         SoupSoapResponse *response;
2495         SoupSoapParameter *param ;
2496         EGwConnectionStatus status = E_GW_CONNECTION_STATUS_UNKNOWN;
2497
2498         msg = e_gw_message_new_with_header (e_gw_connection_get_uri (cnc), e_gw_connection_get_session_id(cnc), "createItemRequest");
2499
2500         soup_soap_message_start_element (msg, "item", NULL, NULL);
2501         soup_soap_message_add_attribute (msg, "type", "Folder", "xsi", NULL);
2502
2503         e_gw_message_write_string_parameter (msg, "name", NULL, folder_name);
2504         e_gw_message_write_string_parameter (msg, "parent", NULL,parent_name );
2505
2506         soup_soap_message_end_element (msg);
2507
2508         e_gw_message_write_footer (msg);
2509
2510         response =  e_gw_connection_send_message (cnc, msg);
2511         if (!response) {
2512                 g_object_unref (msg);
2513                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2514         }
2515         status = e_gw_connection_parse_response_status (response);
2516         if (status != E_GW_CONNECTION_STATUS_OK) {
2517                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2518                         reauthenticate (cnc);
2519                 g_object_unref (response);
2520                 g_object_unref (msg);
2521                 return status;
2522         } else {
2523                 param = soup_soap_response_get_first_parameter_by_name (response, "id") ;
2524                 *container_id = soup_soap_parameter_get_string_value(param) ;
2525                 printf ("CONTAINER ID %s \n", *container_id) ;
2526         }
2527
2528         return status ;
2529
2530 }
2531
2532 /*
2533  * 
2534  */
2535 EGwConnectionStatus
2536 e_gw_connection_get_attachment (EGwConnection *cnc, const char *id, int offset, int length, const char **attachment, int *attach_length)
2537 {
2538
2539         SoupSoapMessage *msg;
2540         SoupSoapResponse *response;
2541         EGwConnectionStatus status;
2542         SoupSoapParameter *param ;
2543         char *buffer = NULL, *buf_length = NULL ;
2544
2545         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
2546
2547         /* build the SOAP message */
2548         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getAttachmentRequest");
2549         if (!msg) {
2550                 g_warning (G_STRLOC ": Could not build SOAP message");
2551                 return E_GW_CONNECTION_STATUS_UNKNOWN;
2552         }
2553       
2554
2555         e_gw_message_write_string_parameter (msg, "id", NULL, id);
2556         e_gw_message_write_int_parameter (msg, "offset", NULL, offset);
2557         e_gw_message_write_int_parameter (msg, "length", NULL, length);
2558
2559         e_gw_message_write_footer (msg);
2560
2561         /* send message to server */
2562         response = e_gw_connection_send_message (cnc, msg);
2563         if (!response) {
2564                 g_object_unref (msg);
2565                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2566         }
2567
2568         status = e_gw_connection_parse_response_status (response);
2569         if (status != E_GW_CONNECTION_STATUS_OK) {
2570                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2571                         reauthenticate (cnc);
2572                 g_object_unref (response);
2573                 g_object_unref (msg);
2574                 return status;
2575         }
2576
2577         
2578         param = soup_soap_response_get_first_parameter_by_name (response, "part") ;
2579         if (param) {
2580                 buf_length =  soup_soap_parameter_get_property (param, "length") ;
2581                 buffer = soup_soap_parameter_get_string_value (param) ;
2582         }
2583         
2584         if (buffer && buf_length) {
2585                 int len = atoi (buf_length) ;
2586                 *attachment = soup_base64_decode (buffer,&len) ;
2587                 *attach_length = len ;
2588         }
2589
2590         /* free memory */
2591         g_free (buffer) ;
2592         g_free (buf_length) ;
2593         g_object_unref (response);
2594         g_object_unref (msg);
2595
2596         return E_GW_CONNECTION_STATUS_OK;
2597 }
2598
2599 /*
2600  * 
2601  */
2602 EGwConnectionStatus
2603 e_gw_connection_get_attachment_base64 (EGwConnection *cnc, const char *id, int offset, int length, const char **attachment, int *attach_length, int *offset_r)
2604 {
2605
2606         SoupSoapMessage *msg;
2607         SoupSoapResponse *response;
2608         EGwConnectionStatus status;
2609         SoupSoapParameter *param ;
2610         char *buffer = NULL, *buf_length = NULL, *o_return = NULL;
2611
2612         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
2613
2614         /* build the SOAP message */
2615         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getAttachmentRequest");
2616         if (!msg) {
2617                 g_warning (G_STRLOC ": Could not build SOAP message");
2618                 return E_GW_CONNECTION_STATUS_UNKNOWN;
2619         }
2620       
2621
2622         e_gw_message_write_string_parameter (msg, "id", NULL, id);
2623         e_gw_message_write_int_parameter (msg, "offset", NULL, offset);
2624         e_gw_message_write_int_parameter (msg, "length", NULL, length);
2625
2626         e_gw_message_write_footer (msg);
2627
2628         /* send message to server */
2629         response = e_gw_connection_send_message (cnc, msg);
2630         if (!response) {
2631                 g_object_unref (msg);
2632                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2633         }
2634
2635         status = e_gw_connection_parse_response_status (response);
2636         if (status != E_GW_CONNECTION_STATUS_OK) {
2637                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2638                         reauthenticate (cnc);
2639                 g_object_unref (response);
2640                 g_object_unref (msg);
2641                 return status;
2642         }
2643
2644         
2645         param = soup_soap_response_get_first_parameter_by_name (response, "part") ;
2646         if (param) {
2647                 buf_length =  soup_soap_parameter_get_property (param, "length") ;
2648                 o_return =  soup_soap_parameter_get_property (param, "offset") ;
2649                 buffer = soup_soap_parameter_get_string_value (param) ;
2650         }
2651         
2652         if (buffer && buf_length) {
2653                 int len = atoi (buf_length) ;
2654                 *attachment = g_strdup (buffer);
2655                 *attach_length = len;
2656                 *offset_r = atoi (o_return);
2657         }
2658
2659         /* free memory */
2660         g_free (buffer) ;
2661         g_free (buf_length) ;
2662         g_free (o_return);
2663         g_object_unref (response);
2664         g_object_unref (msg);
2665
2666         return E_GW_CONNECTION_STATUS_OK;
2667 }
2668
2669 EGwConnectionStatus
2670 e_gw_connection_add_item (EGwConnection *cnc, const char *container, const char *id)
2671 {
2672         SoupSoapMessage *msg;
2673         SoupSoapResponse *response;
2674         EGwConnectionStatus status;
2675
2676         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
2677         g_return_val_if_fail (id != NULL, E_GW_CONNECTION_STATUS_INVALID_OBJECT);
2678
2679         /* build the SOAP message */
2680         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "addItemRequest");
2681
2682         if (container && *container)
2683                 e_gw_message_write_string_parameter (msg, "container", NULL, container);
2684         e_gw_message_write_string_parameter (msg, "id", NULL, id);
2685         e_gw_message_write_footer (msg);
2686
2687         /* send message to server */
2688         response = e_gw_connection_send_message (cnc, msg);
2689         if (!response) {
2690                 g_object_unref (msg);
2691                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2692         }
2693
2694         status = e_gw_connection_parse_response_status (response);
2695         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2696                 reauthenticate (cnc);
2697         /* free memory */
2698         g_object_unref (response);
2699         g_object_unref (msg);
2700
2701         return status;
2702 }
2703
2704 EGwConnectionStatus
2705 e_gw_connection_add_items (EGwConnection *cnc, const char *container, GList *item_ids)
2706 {
2707         SoupSoapMessage *msg;
2708         SoupSoapResponse *response;
2709         EGwConnectionStatus status;
2710
2711         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
2712         g_return_val_if_fail (item_ids != NULL, E_GW_CONNECTION_STATUS_INVALID_OBJECT);
2713
2714         /* build the SOAP message */
2715         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "addItemsRequest");
2716
2717         if (container && *container)
2718                 e_gw_message_write_string_parameter (msg, "container", NULL, container);
2719         
2720         soup_soap_message_start_element (msg, "items", NULL, NULL);
2721         for (; item_ids != NULL; item_ids = g_list_next (item_ids))
2722                 e_gw_message_write_string_parameter (msg, "item", NULL, item_ids->data);
2723         soup_soap_message_end_element (msg);
2724
2725         e_gw_message_write_footer (msg);
2726
2727         /* send message to server */
2728         response = e_gw_connection_send_message (cnc, msg);
2729         if (!response) {
2730                 g_object_unref (msg);
2731                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2732         }
2733
2734         status = e_gw_connection_parse_response_status (response);
2735         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2736                 reauthenticate (cnc);
2737         /* free memory */
2738         g_object_unref (response);
2739         g_object_unref (msg);
2740
2741         return status;
2742 }
2743
2744 EGwConnectionStatus 
2745 e_gw_connection_rename_folder (EGwConnection *cnc, const char *id ,const char *new_name)
2746 {
2747         SoupSoapMessage *msg;
2748         SoupSoapResponse *response;
2749         EGwConnectionStatus status;
2750         
2751         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
2752
2753         /* build the SOAP message */
2754         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "modifyItemRequest");
2755         if (!msg) {
2756                 g_warning (G_STRLOC ": Could not build SOAP message");
2757                 return E_GW_CONNECTION_STATUS_UNKNOWN;
2758         }
2759
2760         e_gw_message_write_string_parameter (msg, "id", NULL, id);
2761
2762         soup_soap_message_start_element (msg, "updates", NULL, NULL);
2763         soup_soap_message_start_element (msg, "update", NULL, NULL);
2764         e_gw_message_write_string_parameter (msg, "name", NULL, new_name);
2765         soup_soap_message_end_element (msg) ;
2766         soup_soap_message_end_element (msg) ;
2767         
2768         e_gw_message_write_footer (msg);
2769
2770         /* send message to server */
2771         response = e_gw_connection_send_message (cnc, msg);
2772         if (!response) {
2773                 g_object_unref (msg);
2774                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2775         }
2776
2777         status = e_gw_connection_parse_response_status (response);
2778         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2779                 reauthenticate (cnc);
2780         g_object_unref (msg);
2781         g_object_unref (response);
2782
2783         return status;
2784                 
2785 }
2786
2787 EGwConnectionStatus 
2788 e_gw_connection_share_folder(EGwConnection *cnc, gchar *id, GList *new_list, const char *sub, const char *mesg ,int flag) 
2789 {
2790         SoupSoapMessage *msg;
2791         SoupSoapResponse *response;
2792         EGwConnectionStatus status = E_GW_CONNECTION_STATUS_UNKNOWN;
2793
2794         msg = e_gw_message_new_with_header (e_gw_connection_get_uri (cnc), e_gw_connection_get_session_id (cnc), "modifyItemRequest");
2795         e_gw_container_form_message (msg, id, new_list, sub, mesg, flag);
2796         e_gw_message_write_footer (msg);
2797         response =  e_gw_connection_send_message (cnc, msg);
2798         
2799         if (!response) {
2800                 g_object_unref (msg);
2801                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
2802         }
2803
2804         status = e_gw_connection_parse_response_status (response);
2805         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2806                 reauthenticate (cnc);
2807         /* free memory */
2808         g_object_unref (response);
2809         g_object_unref (msg);
2810
2811         return status;
2812 }
2813
2814 EGwConnectionStatus
2815 e_gw_connection_move_item (EGwConnection *cnc, const char *id, const char *dest_container_id, const char *from_container_id)
2816
2817 {
2818         SoupSoapMessage *msg;
2819         SoupSoapResponse *response;
2820         EGwConnectionStatus status;
2821
2822         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
2823         g_return_val_if_fail (id != NULL, E_GW_CONNECTION_STATUS_INVALID_OBJECT);
2824         g_return_val_if_fail (dest_container_id != NULL, E_GW_CONNECTION_STATUS_INVALID_OBJECT);
2825
2826         
2827         /* build the SOAP message */
2828         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "moveItemRequest");
2829         e_gw_message_write_string_parameter (msg, "id", NULL, id);
2830         e_gw_message_write_string_parameter (msg, "container", NULL,dest_container_id);
2831         if (from_container_id)
2832                 e_gw_message_write_string_parameter (msg, "from", NULL,from_container_id);      
2833         e_gw_message_write_footer (msg);
2834
2835         /* send message to server */
2836         response = e_gw_connection_send_message (cnc, msg);
2837         if (!response) {
2838                 g_object_unref (msg);
2839                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2840         }
2841
2842         status = e_gw_connection_parse_response_status (response);
2843         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2844                 reauthenticate (cnc);
2845         /* free memory */
2846         g_object_unref (response);
2847         g_object_unref (msg);
2848         return status;
2849
2850
2851 }
2852
2853 EGwConnectionStatus
2854 e_gw_connection_accept_shared_folder (EGwConnection *cnc, gchar *name, gchar *container_id, gchar *item_id, gchar *desc)
2855 {
2856
2857         SoupSoapMessage *msg;
2858         SoupSoapResponse *response;
2859         EGwConnectionStatus status = E_GW_CONNECTION_STATUS_UNKNOWN;
2860
2861         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
2862         g_return_val_if_fail (container_id != NULL, E_GW_CONNECTION_STATUS_INVALID_OBJECT);
2863         g_return_val_if_fail (item_id != NULL, E_GW_CONNECTION_STATUS_INVALID_OBJECT);
2864         g_return_val_if_fail (name != NULL, E_GW_CONNECTION_STATUS_INVALID_OBJECT);
2865
2866         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "acceptShareRequest");
2867         e_gw_message_write_string_parameter (msg, "id", NULL, item_id);
2868         e_gw_message_write_string_parameter (msg, "name", NULL, name);
2869         e_gw_message_write_string_parameter (msg, "container", NULL, container_id);
2870         e_gw_message_write_string_parameter (msg, "description", NULL, desc);
2871         e_gw_message_write_footer (msg);
2872         response =  e_gw_connection_send_message (cnc, msg);
2873         if (!response) {
2874                 g_object_unref (msg);
2875                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2876         }
2877         status = e_gw_connection_parse_response_status (response);
2878         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2879                 reauthenticate (cnc);
2880         /* free memory */
2881         g_object_unref (response);
2882         g_object_unref (msg);
2883
2884         return status;
2885
2886 }
2887
2888 EGwConnectionStatus 
2889 e_gw_connection_purge_deleted_items (EGwConnection *cnc)
2890 {
2891
2892         SoupSoapMessage *msg;
2893         SoupSoapResponse *response;
2894         EGwConnectionStatus status = E_GW_CONNECTION_STATUS_UNKNOWN;
2895         
2896         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "purgeDeletedItemsRequest");
2897         e_gw_message_write_footer (msg);
2898         response =  e_gw_connection_send_message (cnc, msg);
2899         if (!response) {
2900                 g_object_unref (msg);
2901                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2902         }
2903         status = e_gw_connection_parse_response_status (response);
2904         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2905                 reauthenticate (cnc);
2906         /* free memory */
2907         g_object_unref (response);
2908         g_object_unref (msg);
2909
2910         return status;
2911
2912 }
2913
2914 EGwConnectionStatus 
2915 e_gw_connection_purge_selected_items (EGwConnection *cnc, GList *item_ids)
2916 {
2917
2918         SoupSoapMessage *msg;
2919         SoupSoapResponse *response;
2920         EGwConnectionStatus status = E_GW_CONNECTION_STATUS_UNKNOWN;
2921         
2922         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "purgeRequest");
2923         /* Now write the elements that need to be deleted */
2924         soup_soap_message_start_element (msg, "items", NULL, NULL);
2925         for (; item_ids != NULL; item_ids = g_list_next (item_ids))
2926                 e_gw_message_write_string_parameter (msg, "item", NULL, item_ids->data);
2927         soup_soap_message_end_element (msg);
2928         /*End message*/
2929         e_gw_message_write_footer (msg);
2930         /* Send to server */
2931         response =  e_gw_connection_send_message (cnc, msg);
2932         if (!response) {
2933                 g_object_unref (msg);
2934                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2935         }
2936         status = e_gw_connection_parse_response_status (response);
2937         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2938                 reauthenticate (cnc);
2939         /* free memory */
2940         g_object_unref (response);
2941         g_object_unref (msg);
2942
2943         return status;
2944
2945 }
2946
2947 EGwConnectionStatus
2948 e_gw_connection_mark_read(EGwConnection *cnc, GList *item_ids)
2949 {
2950         SoupSoapMessage *msg;
2951         SoupSoapResponse *response;
2952         EGwConnectionStatus status;
2953
2954         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
2955
2956         /* build the SOAP message */
2957         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "markReadRequest");
2958
2959         soup_soap_message_start_element (msg, "items", NULL, NULL);
2960         for (; item_ids != NULL; item_ids = g_list_next (item_ids))
2961                 e_gw_message_write_string_parameter (msg, "item", NULL, item_ids->data);
2962         soup_soap_message_end_element (msg);
2963         e_gw_message_write_footer (msg);
2964
2965         /* send message to server */
2966         response = e_gw_connection_send_message (cnc, msg);
2967         if (!response) {
2968                 g_object_unref (msg);
2969                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
2970         }
2971
2972         status = e_gw_connection_parse_response_status (response);
2973         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
2974                 reauthenticate (cnc);
2975         /* free memory */
2976         g_object_unref (response);
2977         g_object_unref (msg);
2978
2979         return status;
2980 }
2981
2982 EGwConnectionStatus
2983 e_gw_connection_mark_unread(EGwConnection *cnc, GList *item_ids)
2984 {
2985         SoupSoapMessage *msg;
2986         SoupSoapResponse *response;
2987         EGwConnectionStatus status;
2988
2989         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
2990
2991         /* build the SOAP message */
2992         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "markUnReadRequest");
2993
2994         soup_soap_message_start_element (msg, "items", NULL, NULL);
2995         for (; item_ids != NULL; item_ids = g_list_next (item_ids))
2996                 e_gw_message_write_string_parameter (msg, "item", NULL, item_ids->data);
2997         soup_soap_message_end_element (msg);
2998         e_gw_message_write_footer (msg);
2999
3000         /* send message to server */
3001         response = e_gw_connection_send_message (cnc, msg);
3002         if (!response) {
3003                 g_object_unref (msg);
3004                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
3005         }
3006
3007         status = e_gw_connection_parse_response_status (response);
3008         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
3009                 reauthenticate (cnc);
3010         /* free memory */
3011         g_object_unref (response);
3012         g_object_unref (msg);
3013
3014         return status;
3015 }
3016
3017 EGwConnectionStatus
3018 e_gw_connection_reply_item (EGwConnection *cnc, const char *id, const char *view, EGwItem **item)
3019 {
3020         SoupSoapMessage *msg;
3021         SoupSoapResponse *response;
3022         EGwConnectionStatus status;
3023         SoupSoapParameter *param;
3024         
3025         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
3026         
3027         /* build the SOAP message */
3028         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "replyRequest");
3029         if (!msg) {
3030                 g_warning (G_STRLOC ": Could not build SOAP message");
3031                 return E_GW_CONNECTION_STATUS_UNKNOWN;
3032         }
3033         
3034         e_gw_message_write_string_parameter (msg, "id", NULL, id);
3035
3036         if (view)
3037                 e_gw_message_write_string_parameter (msg, "view", NULL, view) ;
3038         e_gw_message_write_footer (msg);
3039         
3040         /* send message to server */
3041         response = e_gw_connection_send_message (cnc, msg);
3042         if (!response) {
3043                 g_object_unref (msg);
3044                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
3045         }
3046         
3047         status = e_gw_connection_parse_response_status (response);
3048         if (status != E_GW_CONNECTION_STATUS_OK) {
3049                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
3050                         reauthenticate (cnc);
3051                 g_object_unref (response);
3052                 g_object_unref (msg);
3053                 return status;
3054         }
3055
3056         /* if status is OK - parse result. return the list */   
3057         param = soup_soap_response_get_first_parameter_by_name (response, "item");
3058         if (!param) {
3059                 g_object_unref (response);
3060                 g_object_unref (msg);
3061                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
3062         }
3063         
3064         *item = e_gw_item_new_from_soap_parameter (cnc->priv->user_email, "", param);
3065         
3066                
3067         /* free memory */
3068         g_object_unref (response);
3069         g_object_unref (msg);
3070
3071         return E_GW_CONNECTION_STATUS_OK;
3072 }
3073
3074 EGwConnectionStatus
3075 e_gw_connection_forward_item (EGwConnection *cnc, const char *id, const char *view, gboolean embed, EGwItem **item)
3076 {
3077         SoupSoapMessage *msg;
3078         SoupSoapResponse *response;
3079         EGwConnectionStatus status;
3080         SoupSoapParameter *param;
3081
3082         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
3083         
3084         /* build the SOAP message */
3085         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "forwardRequest");
3086         if (!msg) {
3087                 g_warning (G_STRLOC ": Could not build SOAP message");
3088                 return E_GW_CONNECTION_STATUS_UNKNOWN;
3089         }
3090         
3091         e_gw_message_write_string_parameter (msg, "id", NULL, id);
3092
3093         if (view)
3094                 e_gw_message_write_string_parameter (msg, "view", NULL, view) ;
3095
3096         if (embed) 
3097                 e_gw_message_write_int_parameter (msg, "embed", NULL,1);
3098         
3099         e_gw_message_write_footer (msg);
3100         /* send message to server */
3101         response = e_gw_connection_send_message (cnc, msg);
3102         if (!response) {
3103                 g_object_unref (msg);
3104                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
3105         }
3106
3107         status = e_gw_connection_parse_response_status (response);
3108         if (status != E_GW_CONNECTION_STATUS_OK) {
3109                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
3110                         reauthenticate (cnc);
3111                 g_object_unref (response);
3112                 g_object_unref (msg);
3113                 return status;
3114         }
3115
3116         /* if status is OK - parse result. return the list */   
3117         param = soup_soap_response_get_first_parameter_by_name (response, "item");
3118         if (!param) {
3119                 g_object_unref (response);
3120                 g_object_unref (msg);
3121                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
3122         }
3123         
3124         *item = e_gw_item_new_from_soap_parameter (cnc->priv->user_email, "", param);
3125         
3126                
3127         /* free memory */
3128         g_object_unref (response);
3129         g_object_unref (msg);
3130
3131         return E_GW_CONNECTION_STATUS_OK;
3132 }
3133
3134 /* e_gw_connection_create_junk_entry :creates a junk entry in the list
3135  * @cnc
3136  * @value : to be added in the list 
3137  * @match_type : "email"/"domain" default: email
3138  * @list_type : "junk"/"trust"/"block" default: junk
3139  * */
3140
3141 EGwConnectionStatus
3142 e_gw_connection_create_junk_entry (EGwConnection *cnc, const char *value, const char *match_type, const char *list_type) 
3143 {
3144         SoupSoapMessage *msg;
3145         SoupSoapResponse *response;
3146         EGwConnectionStatus status;
3147         
3148         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
3149         g_return_val_if_fail (value != NULL, E_GW_CONNECTION_STATUS_INVALID_OBJECT);
3150         
3151         /* build the SOAP message */
3152         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "createJunkEntryRequest");
3153         if (!msg) {
3154                 g_warning (G_STRLOC ": Could not build SOAP message");
3155                 return E_GW_CONNECTION_STATUS_UNKNOWN;
3156         }
3157         soup_soap_message_start_element (msg, "entry", NULL, NULL);
3158         e_gw_message_write_string_parameter (msg, "match", NULL, value);
3159         e_gw_message_write_string_parameter (msg, "matchType", NULL, match_type);
3160         e_gw_message_write_string_parameter (msg, "listType", NULL, list_type);
3161         soup_soap_message_end_element (msg);
3162         e_gw_message_write_footer (msg);
3163         response =  e_gw_connection_send_message (cnc, msg);
3164         
3165         if (!response) {
3166                 g_object_unref (msg);
3167                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
3168         }
3169
3170         status = e_gw_connection_parse_response_status (response);
3171         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
3172                 reauthenticate (cnc);
3173         /* free memory */
3174         g_object_unref (response);
3175         g_object_unref (msg);
3176
3177         return status;
3178 }
3179
3180 /*TODO: move to different file*/
3181 static void
3182 parse_junk_settings (SoupSoapParameter *param, int *use_junk, int *use_block, int *use_pab, int *persistence)
3183 {
3184         SoupSoapParameter *subparam, *field_param, *val_param;
3185         
3186         if (param == NULL)
3187                 return ;
3188         else    {
3189                 /* parse these parameters into junk settings*/
3190                 for (subparam = soup_soap_parameter_get_first_child_by_name (param, "setting");
3191                                 subparam != NULL;
3192                                 subparam = soup_soap_parameter_get_next_child_by_name (subparam, "setting")) {
3193                         char *field = NULL;
3194                         int val = 0;
3195
3196                         field_param = soup_soap_parameter_get_first_child_by_name (subparam, "field");
3197                         val_param = soup_soap_parameter_get_first_child_by_name (subparam, "value");
3198
3199                         if (field_param) {
3200                                 field = soup_soap_parameter_get_string_value (field_param);
3201                                 if (!field)
3202                                         continue;
3203                         } else
3204                                 continue;
3205
3206                         if (!g_ascii_strcasecmp (field, "useJunkList")) {
3207                                 if (val_param)
3208                                         val = soup_soap_parameter_get_int_value (val_param);
3209                                 *use_junk = val;
3210                                 g_free (field);
3211                         } else  if (!g_ascii_strcasecmp (field, "useBlockList")) {
3212                                 if (val_param)
3213                                         val = soup_soap_parameter_get_int_value (val_param);
3214                                 *use_block = val;
3215                                 g_free (field);
3216                         } else if (!g_ascii_strcasecmp (field, "usePAB")) {
3217                                 if (val_param)
3218                                         val = soup_soap_parameter_get_int_value (val_param);
3219                                 *use_pab = val;
3220                                 g_free (field);
3221                         } else if (!g_ascii_strcasecmp (field, "persistence")) { 
3222                                 if (val_param)
3223                                         val = soup_soap_parameter_get_int_value (val_param);
3224                                 *persistence = val;
3225                                 g_free (field);
3226                         }
3227                 }
3228         }
3229 }
3230
3231 /*
3232  * e_gw_connection_get_junk_settings: gets the junk settings
3233  * use_junk : returned value, whether junk list is being used
3234  * use_block: use block list
3235  * use_pab: returned value, whether personal addresbook is used
3236  * persistence: 
3237  * */
3238 EGwConnectionStatus
3239 e_gw_connection_get_junk_settings (EGwConnection *cnc, int *use_junk, int *use_block, int *use_pab, int *persistence)
3240 {
3241         SoupSoapMessage *msg;
3242         SoupSoapResponse *response;
3243         SoupSoapParameter *param;
3244         EGwConnectionStatus status;
3245         
3246         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
3247         
3248         /* build the SOAP message */
3249         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getJunkMailSettingsRequest");
3250
3251         if (!msg) {
3252                 g_warning (G_STRLOC ": Could not build SOAP message");
3253                 return E_GW_CONNECTION_STATUS_UNKNOWN;
3254         }
3255         e_gw_message_write_footer (msg);
3256         response =  e_gw_connection_send_message (cnc, msg);
3257         
3258         if (!response) {
3259                 g_object_unref (msg);
3260                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
3261         }
3262
3263         status = e_gw_connection_parse_response_status (response);
3264         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
3265                 reauthenticate (cnc);
3266
3267         /* if status is OK - parse result. return the list */
3268         if (status == E_GW_CONNECTION_STATUS_OK) {
3269                 param = soup_soap_response_get_first_parameter_by_name (response, "settings");
3270                 parse_junk_settings (param, use_junk, use_block, use_pab, persistence);
3271         }
3272         /* free memory */
3273         g_object_unref (response);
3274         g_object_unref (msg);
3275
3276         return status;
3277
3278 }
3279
3280 static void 
3281 msg_add_settings (SoupSoapMessage *msg, char *field, int value)
3282 {
3283         soup_soap_message_start_element (msg, "setting", NULL, NULL);
3284         e_gw_message_write_string_parameter (msg, "field", NULL, field);
3285         e_gw_message_write_int_parameter (msg, "value", NULL, value);
3286         soup_soap_message_end_element (msg);
3287 }
3288
3289 /* e_gw_connection_modify_junk_settings: creates/removes junk mail settings
3290  * @cnc
3291  * @use_junk 0 : disable spam learning from junk list 1: enable
3292  * @use_block: same for block list
3293  * use_pab 1: put messages except from personal add book in junk, 0 disable
3294  * @persistence :delete after
3295  * */
3296  
3297 EGwConnectionStatus
3298 e_gw_connection_modify_junk_settings (EGwConnection *cnc, int use_junk, int use_pab, int use_block, int persistence)
3299 {
3300         SoupSoapMessage *msg;
3301         SoupSoapResponse *response;
3302         EGwConnectionStatus status;
3303
3304         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
3305
3306         /* build the SOAP message */
3307         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "modifyJunkMailSettingsRequest");
3308         if (!msg) {
3309                 g_warning (G_STRLOC ": Could not build SOAP message");
3310                 return E_GW_CONNECTION_STATUS_UNKNOWN;
3311         }
3312
3313         soup_soap_message_start_element (msg, "settings", NULL, NULL);
3314
3315         msg_add_settings (msg, "useJunkList", use_junk);
3316         msg_add_settings (msg, "usePAB", use_pab);
3317         msg_add_settings (msg, "useBlockList", use_block);
3318         msg_add_settings (msg, "persistence", persistence);
3319
3320         soup_soap_message_end_element (msg);
3321         e_gw_message_write_footer (msg);
3322         response =  e_gw_connection_send_message (cnc, msg);
3323
3324         if (!response) {
3325                 g_object_unref (msg);
3326                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
3327         }
3328
3329         status = e_gw_connection_parse_response_status (response);
3330         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
3331                 reauthenticate (cnc);
3332         
3333         /* free memory */
3334         g_object_unref (response);
3335         g_object_unref (msg);
3336
3337         return status;
3338
3339 }
3340
3341 /*TODO:Move this code to some other file and make this function public*/
3342 static EGwJunkEntry *
3343 e_gw_junkentry_new_from_soap_parameter (SoupSoapParameter *param)
3344 {
3345         EGwJunkEntry *junk_entry;
3346         SoupSoapParameter *subparam;
3347
3348         g_return_val_if_fail (param != NULL, NULL);
3349
3350         junk_entry = g_new0(EGwJunkEntry, 1);
3351
3352         subparam = soup_soap_parameter_get_first_child_by_name (param, "id");
3353         if (!subparam) {
3354                 g_warning (G_STRLOC ": found junk entry with no name");
3355                 return NULL;
3356         }
3357         junk_entry->id = soup_soap_parameter_get_string_value (subparam);
3358
3359         subparam = soup_soap_parameter_get_first_child_by_name (param, "match");
3360         if (!subparam) {
3361                 g_warning (G_STRLOC ": found junk entry with no Match");
3362                 return NULL;
3363         }
3364         junk_entry->match = soup_soap_parameter_get_string_value (subparam);
3365
3366         subparam = soup_soap_parameter_get_first_child_by_name (param, "matchType");
3367         if (!subparam) {
3368                 g_warning (G_STRLOC ": found junk entry with no MatchType");
3369                 return NULL;
3370         }
3371         junk_entry->matchType = soup_soap_parameter_get_string_value (subparam);
3372
3373         subparam = soup_soap_parameter_get_first_child_by_name (param, "lastUsed");
3374         if (subparam) 
3375                 junk_entry->lastUsed = soup_soap_parameter_get_string_value (subparam);
3376
3377         subparam = soup_soap_parameter_get_first_child_by_name (param, "version");
3378         if (subparam) 
3379                 junk_entry->version = soup_soap_parameter_get_int_value (subparam);
3380
3381         subparam = soup_soap_parameter_get_first_child_by_name (param, "modified");
3382         if (subparam) 
3383                 junk_entry->modified = soup_soap_parameter_get_string_value (subparam);
3384
3385         return junk_entry;
3386
3387 }
3388
3389 /*TODO:Move this code to some other file and make this function public*/
3390 static void
3391 get_junk_list_from_soap_response (SoupSoapResponse *response, GList **entries)
3392 {
3393         SoupSoapParameter *param, *subparam;
3394
3395         param = soup_soap_response_get_first_parameter_by_name (response, "junk");
3396         if (param) {
3397                 /* parse these parameters into junk entries*/
3398                 for (subparam = soup_soap_parameter_get_first_child_by_name (param, "entry");
3399                                 subparam != NULL;
3400                                 subparam = soup_soap_parameter_get_next_child_by_name (subparam, "entry")) {
3401                         EGwJunkEntry *junk_entry;
3402
3403                         junk_entry = e_gw_junkentry_new_from_soap_parameter (subparam);
3404                         if (junk_entry)
3405                                 *entries = g_list_append (*entries, junk_entry);
3406                 }
3407         }       
3408         param = soup_soap_response_get_first_parameter_by_name (response, "block");
3409         if (param) {
3410                 for (subparam = soup_soap_parameter_get_first_child_by_name (param, "entry");
3411                                 subparam != NULL;
3412                                 subparam = soup_soap_parameter_get_next_child_by_name (subparam, "entry")) {
3413                         EGwJunkEntry *junk_entry;
3414                         junk_entry = e_gw_junkentry_new_from_soap_parameter (subparam);
3415                         if (junk_entry)
3416                                 *entries = g_list_append (*entries, junk_entry);
3417                 }
3418         }
3419         param = soup_soap_response_get_first_parameter_by_name (response, "trust");
3420         if (param) {
3421                 for (subparam = soup_soap_parameter_get_first_child_by_name (param, "entry");
3422                                 subparam != NULL;
3423                                 subparam = soup_soap_parameter_get_next_child_by_name (subparam, "entry")) {
3424                         EGwJunkEntry *junk_entry;
3425                         junk_entry = e_gw_junkentry_new_from_soap_parameter (subparam);
3426                         if (junk_entry)
3427                                 *entries = g_list_append (*entries, junk_entry);
3428                 }
3429         }
3430  }
3431
3432 /* Caller must free the entries*** TODO: have a function in the generic file to free these*/
3433 EGwConnectionStatus
3434 e_gw_connection_get_junk_entries (EGwConnection *cnc, GList **entries)
3435 {
3436         SoupSoapMessage *msg;
3437         SoupSoapResponse *response;
3438         EGwConnectionStatus status;
3439         
3440         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
3441         
3442         /* build the SOAP message */
3443         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getJunkEntriesRequest");
3444
3445         if (!msg) {
3446                 g_warning (G_STRLOC ": Could not build SOAP message");
3447                 return E_GW_CONNECTION_STATUS_UNKNOWN;
3448         }
3449         e_gw_message_write_footer (msg);
3450         response =  e_gw_connection_send_message (cnc, msg);
3451         
3452         if (!response) {
3453                 g_object_unref (msg);
3454                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
3455         }
3456
3457         status = e_gw_connection_parse_response_status (response);
3458         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
3459                 reauthenticate (cnc);
3460
3461         /* if status is OK - parse result. return the list */
3462         if (status == E_GW_CONNECTION_STATUS_OK)
3463                 get_junk_list_from_soap_response (response, entries);
3464         
3465         /* free memory */
3466         g_object_unref (response);
3467         g_object_unref (msg);
3468
3469         return status;
3470 }
3471
3472 EGwConnectionStatus
3473 e_gw_connection_remove_junk_entry (EGwConnection *cnc, const char *id)
3474 {
3475         SoupSoapMessage *msg;
3476         SoupSoapResponse *response;
3477         EGwConnectionStatus status;
3478
3479         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
3480         g_return_val_if_fail (id != NULL, E_GW_CONNECTION_STATUS_INVALID_OBJECT);
3481
3482         /* build the SOAP message */
3483         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "removeJunkEntryRequest");
3484
3485         e_gw_message_write_string_parameter (msg, "id", NULL, id);
3486         e_gw_message_write_footer (msg);
3487
3488         /* send message to server */
3489         response = e_gw_connection_send_message (cnc, msg);
3490         if (!response) {
3491                 g_object_unref (msg);
3492                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
3493         }
3494
3495         status = e_gw_connection_parse_response_status (response);
3496         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
3497                 reauthenticate (cnc);
3498         
3499         /* free memory */
3500         g_object_unref (response);
3501         g_object_unref (msg);
3502
3503         return status;
3504
3505 }
3506
3507 EGwConnectionStatus
3508 e_gw_connection_read_cal_ids (EGwConnection *cnc, const char *container, int cursor, gboolean forward, int count, const char *cursor_seek, GList **list)
3509 {
3510         SoupSoapMessage *msg;
3511         SoupSoapResponse *response;
3512         EGwConnectionStatus status;
3513         SoupSoapParameter *param, *subparam;
3514         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
3515         g_return_val_if_fail ((container != NULL), E_GW_CONNECTION_STATUS_UNKNOWN);
3516
3517         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "readCursorRequest");
3518         e_gw_message_write_int_parameter (msg, "cursor", NULL, cursor);
3519         *list = NULL;
3520         /* there is problem in read curosr if you set this, uncomment after the problem 
3521            is fixed in server */
3522         e_gw_message_write_string_parameter (msg, "position", NULL, cursor_seek);
3523         e_gw_message_write_string_parameter (msg, "forward", NULL, forward ? "true": "false");
3524         e_gw_message_write_string_parameter (msg, "container", NULL, container);
3525         e_gw_message_write_int_parameter (msg, "count", NULL, count);
3526
3527         e_gw_message_write_footer (msg);
3528
3529         /* send message to server */
3530         response = e_gw_connection_send_message (cnc, msg);
3531         if (!response) {
3532                 g_object_unref (msg);
3533                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
3534         }
3535
3536         status = e_gw_connection_parse_response_status (response);
3537         if (status != E_GW_CONNECTION_STATUS_OK) {
3538                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
3539                         reauthenticate (cnc);
3540                 g_object_unref (response);
3541                 g_object_unref (msg);
3542                 return status;
3543         }
3544
3545         /* if status is OK - parse result. return the list */   
3546         param = soup_soap_response_get_first_parameter_by_name (response, "items");
3547         if (!param) {
3548                 g_object_unref (response);
3549                 g_object_unref (msg);
3550                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
3551         }
3552
3553         /* parse these parameters into ecalcomponents*/
3554         for (subparam = soup_soap_parameter_get_first_child_by_name (param, "item");
3555                         subparam != NULL;
3556                         subparam = soup_soap_parameter_get_next_child_by_name (subparam, "item")) {
3557                 SoupSoapParameter *param_id;
3558                 EGwItemCalId *calid = g_new0 (EGwItemCalId, 1);
3559                 EGwItemType type;
3560                 char *id = NULL, *item_type = NULL;
3561                 
3562                 item_type = soup_soap_parameter_get_property (subparam, "type");
3563                 
3564                 if (g_str_equal (item_type, "Appointment"))
3565                                 type  = E_GW_ITEM_TYPE_APPOINTMENT;
3566                 else if  (g_str_equal (item_type, "Task"))
3567                         type = E_GW_ITEM_TYPE_TASK;
3568                 else {
3569                         type = E_GW_ITEM_TYPE_NOTE;
3570                 }
3571                 g_free (item_type);
3572                 
3573                 param_id = soup_soap_parameter_get_first_child_by_name (subparam, "id");
3574                 if (param_id) {
3575                         id = soup_soap_parameter_get_string_value (param_id);
3576                         if (!id) {
3577                                 e_gw_item_free_cal_id (calid);
3578                                 g_object_unref (response);
3579                                 g_object_unref (msg);
3580                                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
3581                         }
3582
3583                         calid->item_id = id;
3584                 } else {
3585                         e_gw_item_free_cal_id (calid);
3586                         g_object_unref (response);
3587                         g_object_unref (msg);
3588                         return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
3589                 }
3590                 
3591                 id = NULL;
3592                 
3593                 param_id = soup_soap_parameter_get_first_child_by_name (subparam, "recurrenceKey");
3594                 if (param_id) {
3595                         id = soup_soap_parameter_get_string_value (param_id);
3596                 }
3597                 
3598                 if (id && !g_str_equal (id, "0")) {
3599                         guint allday = 0;
3600
3601                         calid->recur_key = id;
3602                 
3603                         if (type == E_GW_ITEM_TYPE_APPOINTMENT) {
3604                                 param_id = soup_soap_parameter_get_first_child_by_name (subparam, "allDayEvent");
3605                                 if (param_id) {
3606                                         allday = soup_soap_parameter_get_int_value (param_id);
3607                                 }
3608
3609                         }
3610
3611                         if (allday) 
3612                                 param_id = soup_soap_parameter_get_first_child_by_name (subparam, "startDay");
3613                         else
3614                                 param_id = soup_soap_parameter_get_first_child_by_name (subparam, "startDate");
3615
3616                         if (param_id) {
3617                                 char *formatted_date;
3618                                 id = soup_soap_parameter_get_string_value (param_id);
3619                                 formatted_date = e_gw_connection_format_date_string (id);
3620                                  /* store the date in calid for recurring events */
3621                                 calid->ical_id = formatted_date; 
3622                                 g_free (id);
3623                         }
3624
3625                 } else {
3626                         g_free (id);
3627                         id = NULL;
3628
3629                         param_id = soup_soap_parameter_get_first_child_by_name (subparam, "iCalId");
3630                         if (!param_id) {
3631                                 if (*list) {
3632                                         g_list_foreach (*list, (GFunc) e_gw_item_free_cal_id, NULL);
3633                                         g_list_free (*list);
3634                                         *list = NULL;
3635                                 }
3636
3637                                 e_gw_item_free_cal_id (calid);
3638                                 g_object_unref (response);
3639                                 g_object_unref (msg);
3640                                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
3641                         }
3642
3643                         id = soup_soap_parameter_get_string_value (param_id);
3644                         calid->ical_id = id;
3645                 }
3646
3647                 *list = g_list_append (*list, calid);
3648         }
3649
3650         /* free memory */
3651         g_object_unref (response);
3652         g_object_unref (msg);
3653         return E_GW_CONNECTION_STATUS_OK;
3654 }
3655
3656 EGwConnectionStatus
3657 e_gw_connection_get_all_mail_uids (EGwConnection *cnc, const char *container, int cursor, gboolean forward, int count, const char *cursor_seek, GList **list)
3658 {
3659         SoupSoapMessage *msg;
3660         SoupSoapResponse *response;
3661         EGwConnectionStatus status;
3662         SoupSoapParameter *param, *subparam;
3663         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
3664         g_return_val_if_fail ((container != NULL), E_GW_CONNECTION_STATUS_UNKNOWN);
3665
3666         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "readCursorRequest");
3667         e_gw_message_write_int_parameter (msg, "cursor", NULL, cursor);
3668         *list = NULL;
3669         /* there is problem in read curosr if you set this, uncomment after the problem 
3670            is fixed in server */
3671         e_gw_message_write_string_parameter (msg, "position", NULL, cursor_seek);
3672         e_gw_message_write_string_parameter (msg, "forward", NULL, forward ? "true": "false");
3673         e_gw_message_write_string_parameter (msg, "container", NULL, container);
3674         e_gw_message_write_int_parameter (msg, "count", NULL, count);
3675
3676         e_gw_message_write_footer (msg);
3677
3678         /* send message to server */
3679         response = e_gw_connection_send_message (cnc, msg);
3680         if (!response) {
3681                 g_object_unref (msg);
3682                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
3683         }
3684
3685         status = e_gw_connection_parse_response_status (response);
3686         if (status != E_GW_CONNECTION_STATUS_OK) {
3687                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
3688                         reauthenticate (cnc);
3689                 g_object_unref (response);
3690                 g_object_unref (msg);
3691                 return status;
3692         }
3693
3694         /* if status is OK - parse result. return the list */   
3695         param = soup_soap_response_get_first_parameter_by_name (response, "items");
3696         if (!param) {
3697                 g_object_unref (response);
3698                 g_object_unref (msg);
3699                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
3700         }
3701
3702         /* parse these parameters into ecalcomponents*/
3703         for (subparam = soup_soap_parameter_get_first_child_by_name (param, "item");
3704                         subparam != NULL;
3705                         subparam = soup_soap_parameter_get_next_child_by_name (subparam, "item")) {
3706                 SoupSoapParameter *param_id;
3707                 char *id = NULL;
3708                 
3709                 param_id = soup_soap_parameter_get_first_child_by_name (subparam, "id");
3710                 if (!param_id) {
3711                         if (*list) {
3712                                 g_list_foreach (*list, (GFunc) g_free, NULL);
3713                                 g_list_free (*list);
3714                                 *list = NULL;
3715                         }
3716                         g_object_unref (response);
3717                         g_object_unref (msg);
3718                         return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
3719                 }
3720                 
3721                 id = soup_soap_parameter_get_string_value (param_id);
3722                 if (id)
3723                         *list = g_list_prepend (*list, id);
3724                 else {
3725                         if (*list) {
3726                                 g_list_foreach (*list, (GFunc) g_free, NULL);
3727                                 g_list_free (*list);
3728                                 *list = NULL;
3729                         }
3730                         g_object_unref (response);
3731                         g_object_unref (msg);
3732                         return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
3733                 }
3734         }
3735         /* free memory */
3736         g_object_unref (response);
3737         g_object_unref (msg);
3738         return E_GW_CONNECTION_STATUS_OK;
3739 }
3740
3741 EGwConnectionStatus
3742 e_gw_connection_get_proxy_access_list (EGwConnection *cnc, GList **proxy_list)
3743 {
3744         SoupSoapMessage *msg = NULL;
3745         SoupSoapResponse *response = NULL;
3746         EGwConnectionStatus status;
3747         SoupSoapParameter *param;
3748
3749         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
3750
3751         /* build the SOAP message */
3752         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getProxyAccessListRequest");
3753
3754         e_gw_message_write_footer (msg);
3755
3756         /* send message to server */
3757         response = e_gw_connection_send_message (cnc, msg);
3758         if (!response) {
3759                 g_object_unref (msg);
3760                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
3761         }
3762
3763         status = e_gw_connection_parse_response_status (response);
3764         if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
3765                 reauthenticate (cnc);
3766
3767         param = soup_soap_response_get_first_parameter_by_name (response, "accessRights");      
3768         if (!param) {
3769                 g_object_unref (response);
3770                 return status;
3771         } else  {
3772                 e_gw_proxy_construct_proxy_access_list (param, proxy_list);
3773         }
3774         /* free memory */
3775         if (response)
3776                 g_object_unref (response);
3777         if (msg)
3778                 g_object_unref (msg);
3779         return status;
3780 }
3781
3782 EGwConnectionStatus 
3783 e_gw_connection_add_proxy (EGwConnection *cnc, proxyHandler *new_proxy)
3784 {
3785         SoupSoapMessage *msg = NULL;
3786         SoupSoapResponse *response = NULL;
3787         EGwConnectionStatus status;
3788         
3789         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
3790         msg = e_gw_message_new_with_header (e_gw_connection_get_uri (cnc), e_gw_connection_get_session_id (cnc), "createProxyAccessRequest");
3791
3792         e_gw_proxy_form_proxy_add_msg (msg, new_proxy);
3793                         
3794         e_gw_message_write_footer (msg);
3795         response = e_gw_connection_send_message (cnc, msg);
3796         if (!response) {
3797                 g_object_unref (msg);
3798                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
3799         }
3800         status = e_gw_connection_parse_response_status (response);
3801
3802         if (response)
3803         g_object_unref (response);
3804
3805         if (msg)
3806         g_object_unref (msg);
3807         return status;
3808 }
3809
3810 EGwConnectionStatus
3811 e_gw_connection_remove_proxy (EGwConnection *cnc, proxyHandler *removeProxy)
3812 {
3813         SoupSoapMessage *msg;
3814         SoupSoapResponse *response;
3815         EGwConnectionStatus status;
3816
3817         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
3818
3819         msg = e_gw_message_new_with_header (e_gw_connection_get_uri(cnc), e_gw_connection_get_session_id(cnc), "removeProxyAccessRequest");
3820
3821         e_gw_proxy_form_proxy_remove_msg (msg, removeProxy);
3822         
3823         e_gw_message_write_footer (msg);
3824
3825         response = e_gw_connection_send_message (cnc, msg);
3826         if (!response) {
3827                 g_object_unref (msg);
3828                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
3829         }
3830         status = e_gw_connection_parse_response_status (response);
3831         g_object_unref (response);
3832         g_object_unref (msg);
3833         return E_GW_CONNECTION_STATUS_OK;
3834
3835 }
3836
3837 EGwConnectionStatus 
3838 e_gw_connection_modify_proxy (EGwConnection *cnc, proxyHandler *new_proxy)
3839 {
3840         SoupSoapMessage *msg = NULL;
3841         SoupSoapResponse *response = NULL;
3842         EGwConnectionStatus status;
3843         
3844         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_UNKNOWN);
3845         msg = e_gw_message_new_with_header (e_gw_connection_get_uri (cnc), e_gw_connection_get_session_id (cnc), "modifyProxyAccessRequest");
3846         e_gw_message_write_string_parameter (msg, "id", NULL, new_proxy->uniqueid);
3847         
3848         e_gw_proxy_form_modify_proxy_msg (msg, new_proxy);
3849         
3850         e_gw_message_write_footer (msg);
3851         response = e_gw_connection_send_message (cnc, msg);
3852         
3853         if (!response) {
3854                 g_object_unref (msg);
3855                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
3856         }
3857         status = e_gw_connection_parse_response_status (response);
3858
3859         if (response)
3860         g_object_unref (response);
3861
3862         if (msg)
3863         g_object_unref (msg);
3864         return status;
3865 }
3866
3867 EGwConnectionStatus
3868 e_gw_connection_get_proxy_list (EGwConnection *cnc, GList **proxy_info)
3869 {
3870         SoupSoapMessage *msg;
3871         SoupSoapResponse *response;
3872         EGwConnectionStatus status;
3873         SoupSoapParameter *param;
3874
3875         g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_OBJECT);
3876         /* build the SOAP message */
3877         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "getProxyListRequest");
3878         if (!msg) {
3879                 g_warning (G_STRLOC ": Could not build SOAP message");
3880                 return E_GW_CONNECTION_STATUS_UNKNOWN;
3881         }
3882         
3883         e_gw_message_write_footer (msg);
3884         
3885         /* send message to server */
3886         response = e_gw_connection_send_message (cnc, msg);
3887         if (!response) {
3888                 g_object_unref (msg);
3889                 return E_GW_CONNECTION_STATUS_NO_RESPONSE;
3890         }
3891         status = e_gw_connection_parse_response_status (response);
3892         if (status != E_GW_CONNECTION_STATUS_OK) {
3893                 if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
3894                         reauthenticate (cnc);
3895                 g_object_unref (response);
3896                 g_object_unref (msg);
3897                 return status;
3898         }
3899         /* if status is OK - parse result. return the list */   
3900         param = soup_soap_response_get_first_parameter_by_name (response, "proxies");
3901         e_gw_proxy_construct_proxy_list (param, proxy_info);                    
3902         if (!param) {
3903                 g_object_unref (response);
3904                 g_object_unref (msg);
3905                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
3906         }
3907         
3908         g_object_unref (response);
3909         g_object_unref (msg);
3910
3911         return E_GW_CONNECTION_STATUS_OK;
3912 }
3913
3914 static SoupSoapMessage*
3915 form_proxy_login_request (EGwConnection *cnc, const char* username, const char* password, const char *proxy)
3916 {
3917         SoupSoapMessage *msg;
3918         /* build the SOAP message */
3919         msg = e_gw_message_new_with_header (cnc->priv->uri, cnc->priv->session_id, "loginRequest");
3920         soup_soap_message_start_element (msg, "auth", "types", NULL);
3921         soup_soap_message_add_attribute (msg, "type", "types:Proxy", "xsi",
3922                                          "http://www.w3.org/2001/XMLSchema-instance");
3923         e_gw_message_write_string_parameter (msg, "username", "types", username);
3924         e_gw_message_write_string_parameter (msg, "password", "types", password);
3925         e_gw_message_write_string_parameter (msg, "proxy", "types", proxy);
3926         soup_soap_message_end_element (msg);
3927         e_gw_message_write_footer (msg);
3928         return msg;
3929 }
3930
3931 EGwConnection *
3932 e_gw_connection_get_proxy_connection (EGwConnection *parent_cnc, char *username, const char *password, const char *proxy, int  *permissions)
3933 {
3934         EGwConnection *cnc;
3935         SoupSoapMessage *msg;
3936         SoupSoapResponse *response;
3937         EGwConnectionStatus status;
3938         SoupSoapParameter *param;
3939         SoupSoapParameter *subparam;
3940         char *hash_key;
3941         char *name = NULL;
3942         int i;
3943         char *permissions_key = NULL;
3944
3945         static GStaticMutex connecting = G_STATIC_MUTEX_INIT;   
3946
3947         g_static_mutex_lock (&connecting);
3948
3949         for (i=0; proxy[i]!='\0' && proxy[i]!='@'; i++);
3950         if (proxy[i]=='@')
3951                 name = g_strndup(proxy, i);
3952         else 
3953                 name = g_strdup (proxy);
3954         /* search the connection in our hash table */
3955         if (loaded_connections_permissions != NULL) {
3956                 hash_key = g_strdup_printf ( "%s:%s@%s",
3957                                 name,
3958                                 "",
3959                                 parent_cnc->priv->uri);
3960                 cnc = g_hash_table_lookup (loaded_connections_permissions, hash_key);
3961                 permissions_key = g_strdup_printf ("%s:permissions", hash_key);
3962
3963                 if (E_IS_GW_CONNECTION (cnc)) {
3964                         *permissions = GPOINTER_TO_INT (g_hash_table_lookup (loaded_connections_permissions, permissions_key));
3965                         g_free (permissions_key);
3966                         g_free (name);
3967                         g_free (hash_key);
3968                         g_object_ref (cnc);
3969                         g_static_mutex_unlock (&connecting);
3970                         return cnc;
3971                 }
3972                 g_free (permissions_key);
3973         }
3974
3975         /* not found, so create a new connection */
3976         cnc = g_object_new (E_TYPE_GW_CONNECTION, NULL);
3977
3978         msg = form_proxy_login_request (parent_cnc, username, password, proxy);
3979
3980         /* send message to server */
3981         response = e_gw_connection_send_message (parent_cnc, msg);
3982
3983         if (!response) {
3984                 g_object_unref (cnc);
3985                 g_static_mutex_unlock (&connecting);
3986                 g_object_unref (msg);
3987                 return NULL;
3988         }
3989
3990         status = e_gw_connection_parse_response_status (response);
3991
3992         param = soup_soap_response_get_first_parameter_by_name (response, "session");
3993         if (!param) {
3994                 g_object_unref (response);
3995                 g_object_unref (msg);
3996                 g_object_unref (cnc);
3997                 g_static_mutex_unlock (&connecting);
3998                 return NULL;
3999         }
4000
4001         cnc->priv->uri = g_strdup (parent_cnc->priv->uri);
4002         cnc->priv->username = g_strdup (proxy);
4003         cnc->priv->password = NULL;
4004         cnc->priv->session_id = soup_soap_parameter_get_string_value (param);
4005
4006         /* retrieve user information */
4007         param = soup_soap_response_get_first_parameter_by_name (response, "entry");
4008
4009         if (param) {
4010                 char *param_value;
4011
4012                 subparam = soup_soap_parameter_get_first_child_by_name (param, "email");
4013                 if (subparam) {
4014                         param_value = soup_soap_parameter_get_string_value (subparam);
4015                         cnc->priv->user_email  = param_value;
4016                 }
4017
4018                 subparam = soup_soap_parameter_get_first_child_by_name (param, "name");
4019                 if (subparam) {
4020                         param_value = soup_soap_parameter_get_string_value (subparam);
4021                         cnc->priv->user_name = param_value;
4022                 }
4023
4024                 subparam = soup_soap_parameter_get_first_child_by_name (param, "uuid");
4025                 if (subparam) {
4026                         param_value = soup_soap_parameter_get_string_value (subparam);
4027                         cnc->priv->user_uuid = param_value;
4028                 }
4029
4030                 e_gw_proxy_parse_proxy_login_response (param, permissions);
4031         }
4032
4033         param = soup_soap_response_get_first_parameter_by_name (response, "gwVersion");
4034         if (param) {
4035                 char *param_value;
4036                 param_value = soup_soap_parameter_get_string_value (param);
4037                 cnc->priv->version = param_value;
4038         } else
4039                 cnc->priv->version = NULL;      
4040
4041         param = soup_soap_response_get_first_parameter_by_name (response, "serverUTCTime");
4042         if (param) 
4043                 cnc->priv->server_time = soup_soap_parameter_get_string_value (param);
4044
4045         /* add the connection to the loaded_connections_permissions hash table */
4046         hash_key = g_strdup_printf ("%s:%s@%s",
4047                         name,
4048                         "",
4049                         cnc->priv->uri);
4050
4051         g_hash_table_insert (loaded_connections_permissions, hash_key, cnc);
4052         permissions_key = g_strdup_printf ("%s:permissions", hash_key);
4053         g_hash_table_insert (loaded_connections_permissions, permissions_key, GINT_TO_POINTER(*permissions));
4054
4055         /* free memory */
4056         g_object_unref (response);
4057         g_object_unref (msg);
4058         g_free (name);
4059         g_static_mutex_unlock (&connecting);
4060         return cnc;
4061 }