evolution-data-server r10219 - in branches/camel-gobject: . addressbook addressbook/backends/file addressbook/backends/google addressbook/backends/groupwise addressbook/backends/ldap addressbook/backends/vcf addressbook/backends/webdav addressbook/libebook calendar calendar/backends/caldav calendar/backends/contacts calendar/backends/file calendar/backends/google calendar/backends/groupwise calendar/backends/http calendar/backends/weather calendar/libecal calendar/libedata-cal calendar/tests/ecal camel camel/providers/groupwise camel/providers/hula camel/providers/imap camel/providers/imap4 camel/providers/imapp camel/providers/local camel/providers/nntp camel/providers/pop3 camel/tests/mime-filter docs/reference/addressbook/libebook docs/reference/addressbook/libebook/tmpl docs/reference/calendar/libecal docs/reference/calendar/libedata-cal docs/reference/calendar/libedata-cal/tmpl docs/reference/camel docs/reference/camel/tmpl docs/reference/libedataserver docs/ref erence/libedataserver/tmpl docs/reference/libedataserverui docs/reference/libedataserverui/tmpl libebackend libedataserver libedataserverui po servers/exchange servers/exchange/lib servers/exchange/storage servers/google/libgdata servers/google/libgdata-google servers/groupwise src win32



Author: mbarnes
Date: Thu Apr 16 01:23:17 2009
New Revision: 10219
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=10219&view=rev

Log:
Merge revisions 9877:10218 from trunk.


Added:
   branches/camel-gobject/camel/providers/local/camel-local-private.c
      - copied unchanged from r10218, /trunk/camel/providers/local/camel-local-private.c
   branches/camel-gobject/docs/reference/libedataserverui/tmpl/e-category-completion.sgml
      - copied unchanged from r10218, /trunk/docs/reference/libedataserverui/tmpl/e-category-completion.sgml
   branches/camel-gobject/po/mai.po   (props changed)
      - copied unchanged from r10218, /trunk/po/mai.po
Modified:
   branches/camel-gobject/   (props changed)
   branches/camel-gobject/ChangeLog
   branches/camel-gobject/MAINTAINERS
   branches/camel-gobject/NEWS
   branches/camel-gobject/addressbook/ChangeLog
   branches/camel-gobject/addressbook/backends/file/e-book-backend-file.c
   branches/camel-gobject/addressbook/backends/google/google-book.c
   branches/camel-gobject/addressbook/backends/google/util.c
   branches/camel-gobject/addressbook/backends/groupwise/e-book-backend-groupwise.c
   branches/camel-gobject/addressbook/backends/ldap/e-book-backend-ldap.c
   branches/camel-gobject/addressbook/backends/vcf/e-book-backend-vcf.c
   branches/camel-gobject/addressbook/backends/webdav/e-book-backend-webdav.c
   branches/camel-gobject/addressbook/libebook/e-book-types.h
   branches/camel-gobject/addressbook/libebook/e-book-view-private.h
   branches/camel-gobject/addressbook/libebook/e-book-view.h
   branches/camel-gobject/addressbook/libebook/e-book.c
   branches/camel-gobject/addressbook/libebook/e-contact.c
   branches/camel-gobject/addressbook/libebook/e-contact.h
   branches/camel-gobject/addressbook/libebook/e-name-western.c
   branches/camel-gobject/addressbook/libebook/e-vcard.h
   branches/camel-gobject/calendar/   (props changed)
   branches/camel-gobject/calendar/ChangeLog
   branches/camel-gobject/calendar/Makefile.am
   branches/camel-gobject/calendar/backends/caldav/Makefile.am
   branches/camel-gobject/calendar/backends/caldav/e-cal-backend-caldav.c
   branches/camel-gobject/calendar/backends/contacts/Makefile.am
   branches/camel-gobject/calendar/backends/contacts/e-cal-backend-contacts.c
   branches/camel-gobject/calendar/backends/file/Makefile.am
   branches/camel-gobject/calendar/backends/file/e-cal-backend-file.c
   branches/camel-gobject/calendar/backends/google/Makefile.am
   branches/camel-gobject/calendar/backends/google/e-cal-backend-google-utils.c
   branches/camel-gobject/calendar/backends/google/e-cal-backend-google.c
   branches/camel-gobject/calendar/backends/groupwise/Makefile.am
   branches/camel-gobject/calendar/backends/groupwise/e-cal-backend-groupwise-utils.c
   branches/camel-gobject/calendar/backends/groupwise/e-cal-backend-groupwise.c
   branches/camel-gobject/calendar/backends/http/Makefile.am
   branches/camel-gobject/calendar/backends/http/e-cal-backend-http.c
   branches/camel-gobject/calendar/backends/weather/Makefile.am
   branches/camel-gobject/calendar/backends/weather/e-cal-backend-weather.c
   branches/camel-gobject/calendar/libecal/Makefile.am
   branches/camel-gobject/calendar/libecal/e-cal-check-timezones.c
   branches/camel-gobject/calendar/libecal/e-cal-component.c
   branches/camel-gobject/calendar/libecal/e-cal-recur.c
   branches/camel-gobject/calendar/libecal/e-cal-time-util.c
   branches/camel-gobject/calendar/libecal/e-cal.c
   branches/camel-gobject/calendar/libecal/libecal.pc.in
   branches/camel-gobject/calendar/libedata-cal/Makefile.am
   branches/camel-gobject/calendar/libedata-cal/e-cal-backend-cache.c
   branches/camel-gobject/calendar/libedata-cal/e-cal-backend-loader-factory.c
   branches/camel-gobject/calendar/libedata-cal/e-cal-backend-sync.c
   branches/camel-gobject/calendar/libedata-cal/e-cal-backend-util.c
   branches/camel-gobject/calendar/libedata-cal/e-cal-backend-util.h
   branches/camel-gobject/calendar/libedata-cal/e-cal-backend.c
   branches/camel-gobject/calendar/libedata-cal/e-cal-backend.h
   branches/camel-gobject/calendar/libedata-cal/e-data-cal-factory.c
   branches/camel-gobject/calendar/libedata-cal/libedata-cal.pc.in
   branches/camel-gobject/calendar/tests/ecal/Makefile.am
   branches/camel-gobject/calendar/tests/ecal/test-ecal.c
   branches/camel-gobject/camel/ChangeLog
   branches/camel-gobject/camel/camel-data-cache.c
   branches/camel-gobject/camel/camel-data-cache.h
   branches/camel-gobject/camel/camel-db.c
   branches/camel-gobject/camel/camel-disco-diary.c
   branches/camel-gobject/camel/camel-filter-driver.c
   branches/camel-gobject/camel/camel-filter-search.c
   branches/camel-gobject/camel/camel-folder-search.c
   branches/camel-gobject/camel/camel-folder-search.h
   branches/camel-gobject/camel/camel-folder-summary.c
   branches/camel-gobject/camel/camel-folder-summary.h
   branches/camel-gobject/camel/camel-folder.c
   branches/camel-gobject/camel/camel-folder.h
   branches/camel-gobject/camel/camel-gpg-context.c
   branches/camel-gobject/camel/camel-http-stream.c
   branches/camel-gobject/camel/camel-iconv.c
   branches/camel-gobject/camel/camel-index.h
   branches/camel-gobject/camel/camel-lock-client.c
   branches/camel-gobject/camel/camel-mime-filter-tohtml.c
   branches/camel-gobject/camel/camel-mime-filter-tohtml.h
   branches/camel-gobject/camel/camel-mime-part-utils.c
   branches/camel-gobject/camel/camel-mime-utils.c
   branches/camel-gobject/camel/camel-offline-folder.c
   branches/camel-gobject/camel/camel-private.h
   branches/camel-gobject/camel/camel-sasl-ntlm.c
   branches/camel-gobject/camel/camel-search-sql-sexp.c
   branches/camel-gobject/camel/camel-session.c
   branches/camel-gobject/camel/camel-session.h
   branches/camel-gobject/camel/camel-smime-context.c
   branches/camel-gobject/camel/camel-url-scanner.c
   branches/camel-gobject/camel/camel-vee-folder.c
   branches/camel-gobject/camel/camel-vee-store.c
   branches/camel-gobject/camel/camel-vee-summary.c
   branches/camel-gobject/camel/camel-vee-summary.h
   branches/camel-gobject/camel/providers/groupwise/ChangeLog
   branches/camel-gobject/camel/providers/groupwise/camel-groupwise-folder.c
   branches/camel-gobject/camel/providers/groupwise/camel-groupwise-journal.c
   branches/camel-gobject/camel/providers/groupwise/camel-groupwise-journal.h
   branches/camel-gobject/camel/providers/groupwise/camel-groupwise-provider.c
   branches/camel-gobject/camel/providers/groupwise/camel-groupwise-store.c
   branches/camel-gobject/camel/providers/groupwise/camel-groupwise-store.h
   branches/camel-gobject/camel/providers/groupwise/camel-groupwise-summary.c
   branches/camel-gobject/camel/providers/groupwise/camel-groupwise-summary.h
   branches/camel-gobject/camel/providers/hula/ChangeLog
   branches/camel-gobject/camel/providers/hula/camel-hula-provider.c
   branches/camel-gobject/camel/providers/imap/ChangeLog
   branches/camel-gobject/camel/providers/imap/camel-imap-folder.c
   branches/camel-gobject/camel/providers/imap/camel-imap-message-cache.c
   branches/camel-gobject/camel/providers/imap/camel-imap-message-cache.h
   branches/camel-gobject/camel/providers/imap/camel-imap-private.h
   branches/camel-gobject/camel/providers/imap/camel-imap-provider.c
   branches/camel-gobject/camel/providers/imap/camel-imap-store.c
   branches/camel-gobject/camel/providers/imap/camel-imap-summary.c
   branches/camel-gobject/camel/providers/imap4/ChangeLog
   branches/camel-gobject/camel/providers/imap4/camel-imap4-command.c
   branches/camel-gobject/camel/providers/imap4/camel-imap4-engine.c
   branches/camel-gobject/camel/providers/imap4/camel-imap4-folder.c
   branches/camel-gobject/camel/providers/imap4/camel-imap4-journal.c
   branches/camel-gobject/camel/providers/imap4/camel-imap4-provider.c
   branches/camel-gobject/camel/providers/imap4/camel-imap4-store.c
   branches/camel-gobject/camel/providers/imap4/camel-imap4-summary.c
   branches/camel-gobject/camel/providers/imapp/camel-imapp-driver.c
   branches/camel-gobject/camel/providers/local/ChangeLog
   branches/camel-gobject/camel/providers/local/Makefile.am
   branches/camel-gobject/camel/providers/local/camel-local-folder.c
   branches/camel-gobject/camel/providers/local/camel-local-private.h
   branches/camel-gobject/camel/providers/local/camel-local-summary.c
   branches/camel-gobject/camel/providers/local/camel-local-summary.h
   branches/camel-gobject/camel/providers/local/camel-maildir-folder.c
   branches/camel-gobject/camel/providers/local/camel-maildir-summary.h
   branches/camel-gobject/camel/providers/local/camel-mbox-folder.c
   branches/camel-gobject/camel/providers/local/camel-mbox-summary.c
   branches/camel-gobject/camel/providers/local/camel-mh-folder.c
   branches/camel-gobject/camel/providers/local/camel-spool-summary.c
   branches/camel-gobject/camel/providers/nntp/ChangeLog
   branches/camel-gobject/camel/providers/nntp/camel-nntp-folder.c
   branches/camel-gobject/camel/providers/nntp/camel-nntp-store.c
   branches/camel-gobject/camel/providers/pop3/camel-pop3-folder.c
   branches/camel-gobject/camel/tests/mime-filter/test-charset.c
   branches/camel-gobject/camel/tests/mime-filter/test-crlf.c
   branches/camel-gobject/camel/tests/mime-filter/test-tohtml.c
   branches/camel-gobject/camel/tests/mime-filter/test1.c
   branches/camel-gobject/configure.in
   branches/camel-gobject/docs/reference/addressbook/libebook/libebook-sections.txt
   branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-book-types.sgml
   branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-contact.sgml
   branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-vcard.sgml
   branches/camel-gobject/docs/reference/calendar/libecal/Makefile.am
   branches/camel-gobject/docs/reference/calendar/libedata-cal/Makefile.am
   branches/camel-gobject/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt
   branches/camel-gobject/docs/reference/calendar/libedata-cal/tmpl/e-cal-backend-util.sgml
   branches/camel-gobject/docs/reference/camel/camel-sections.txt
   branches/camel-gobject/docs/reference/camel/tmpl/camel-data-cache.sgml
   branches/camel-gobject/docs/reference/camel/tmpl/camel-folder-summary.sgml
   branches/camel-gobject/docs/reference/camel/tmpl/camel-folder.sgml
   branches/camel-gobject/docs/reference/camel/tmpl/camel-imap-message-cache.sgml
   branches/camel-gobject/docs/reference/camel/tmpl/camel-session.sgml
   branches/camel-gobject/docs/reference/camel/tmpl/camel-store.sgml
   branches/camel-gobject/docs/reference/camel/tmpl/camel-utf8.sgml
   branches/camel-gobject/docs/reference/camel/tmpl/camel-vee-summary.sgml
   branches/camel-gobject/docs/reference/libedataserver/libedataserver-sections.txt
   branches/camel-gobject/docs/reference/libedataserver/tmpl/e-proxy.sgml
   branches/camel-gobject/docs/reference/libedataserverui/libedataserverui-docs.sgml
   branches/camel-gobject/docs/reference/libedataserverui/libedataserverui-sections.txt
   branches/camel-gobject/libebackend/e-file-cache.c
   branches/camel-gobject/libedataserver/e-account.c
   branches/camel-gobject/libedataserver/e-iconv.c
   branches/camel-gobject/libedataserver/e-proxy.c
   branches/camel-gobject/libedataserver/e-proxy.h
   branches/camel-gobject/libedataserver/e-sexp.c
   branches/camel-gobject/libedataserver/e-source.c
   branches/camel-gobject/libedataserverui/ChangeLog
   branches/camel-gobject/libedataserverui/e-categories-dialog.c
   branches/camel-gobject/libedataserverui/e-cell-renderer-color.c
   branches/camel-gobject/libedataserverui/e-contact-store.h
   branches/camel-gobject/libedataserverui/e-destination-store.h
   branches/camel-gobject/libedataserverui/e-name-selector-dialog.c
   branches/camel-gobject/libedataserverui/e-name-selector-dialog.h
   branches/camel-gobject/libedataserverui/e-name-selector-entry.h
   branches/camel-gobject/libedataserverui/e-name-selector-list.c
   branches/camel-gobject/libedataserverui/e-name-selector-list.h
   branches/camel-gobject/libedataserverui/e-passwords.c
   branches/camel-gobject/libedataserverui/e-source-combo-box.c
   branches/camel-gobject/libedataserverui/e-source-option-menu.c
   branches/camel-gobject/libedataserverui/e-source-selector-dialog.c
   branches/camel-gobject/libedataserverui/e-source-selector.c
   branches/camel-gobject/libedataserverui/e-tree-model-generator.c
   branches/camel-gobject/libedataserverui/e-tree-model-generator.h
   branches/camel-gobject/po/ChangeLog
   branches/camel-gobject/po/LINGUAS
   branches/camel-gobject/po/POTFILES.in
   branches/camel-gobject/po/POTFILES.skip
   branches/camel-gobject/po/ar.po
   branches/camel-gobject/po/as.po
   branches/camel-gobject/po/bg.po
   branches/camel-gobject/po/bn_IN.po
   branches/camel-gobject/po/ca.po
   branches/camel-gobject/po/cs.po
   branches/camel-gobject/po/da.po
   branches/camel-gobject/po/de.po
   branches/camel-gobject/po/el.po
   branches/camel-gobject/po/en_GB.po
   branches/camel-gobject/po/es.po
   branches/camel-gobject/po/et.po
   branches/camel-gobject/po/eu.po
   branches/camel-gobject/po/fi.po
   branches/camel-gobject/po/fr.po
   branches/camel-gobject/po/gl.po
   branches/camel-gobject/po/gu.po
   branches/camel-gobject/po/he.po
   branches/camel-gobject/po/hi.po
   branches/camel-gobject/po/hu.po
   branches/camel-gobject/po/it.po
   branches/camel-gobject/po/ja.po
   branches/camel-gobject/po/kn.po
   branches/camel-gobject/po/ko.po
   branches/camel-gobject/po/lt.po
   branches/camel-gobject/po/ml.po
   branches/camel-gobject/po/mr.po
   branches/camel-gobject/po/nb.po
   branches/camel-gobject/po/nl.po
   branches/camel-gobject/po/or.po
   branches/camel-gobject/po/pa.po
   branches/camel-gobject/po/pl.po
   branches/camel-gobject/po/pt.po
   branches/camel-gobject/po/pt_BR.po
   branches/camel-gobject/po/ro.po
   branches/camel-gobject/po/ru.po
   branches/camel-gobject/po/sl.po
   branches/camel-gobject/po/sr.po
   branches/camel-gobject/po/sr latin po
   branches/camel-gobject/po/sv.po
   branches/camel-gobject/po/ta.po
   branches/camel-gobject/po/te.po
   branches/camel-gobject/po/th.po
   branches/camel-gobject/po/tr.po
   branches/camel-gobject/po/vi.po
   branches/camel-gobject/po/zh_HK.po
   branches/camel-gobject/po/zh_TW.po
   branches/camel-gobject/servers/exchange/ChangeLog
   branches/camel-gobject/servers/exchange/lib/Makefile.am
   branches/camel-gobject/servers/exchange/lib/e2k-context.c
   branches/camel-gobject/servers/exchange/storage/Makefile.am
   branches/camel-gobject/servers/exchange/storage/exchange-esource.c
   branches/camel-gobject/servers/exchange/storage/exchange-hierarchy-foreign.c
   branches/camel-gobject/servers/google/libgdata-google/ChangeLog
   branches/camel-gobject/servers/google/libgdata-google/Makefile.am
   branches/camel-gobject/servers/google/libgdata-google/gdata-google-service.c
   branches/camel-gobject/servers/google/libgdata-google/libgdata-google.pc.in
   branches/camel-gobject/servers/google/libgdata/ChangeLog
   branches/camel-gobject/servers/google/libgdata/Makefile.am
   branches/camel-gobject/servers/google/libgdata/libgdata.pc.in
   branches/camel-gobject/servers/groupwise/ChangeLog
   branches/camel-gobject/servers/groupwise/e-gw-connection.c
   branches/camel-gobject/servers/groupwise/e-gw-container.c
   branches/camel-gobject/servers/groupwise/e-gw-item.c
   branches/camel-gobject/servers/groupwise/e-gw-recur-utils.h
   branches/camel-gobject/src/Makefile.am
   branches/camel-gobject/src/server-interface-check.h
   branches/camel-gobject/win32/Makefile.am

Modified: branches/camel-gobject/MAINTAINERS
==============================================================================
--- branches/camel-gobject/MAINTAINERS	(original)
+++ branches/camel-gobject/MAINTAINERS	Thu Apr 16 01:23:17 2009
@@ -16,4 +16,3 @@
 
 Camel Maintainers:
 Matthew Barnes <mbarnes redhat com> 
-Sankar P <psankar novell com>

Modified: branches/camel-gobject/NEWS
==============================================================================
--- branches/camel-gobject/NEWS	(original)
+++ branches/camel-gobject/NEWS	Thu Apr 16 01:23:17 2009
@@ -1,3 +1,184 @@
+Evolution-Data-Server 2.26.0 2009-03-16	
+----------------------------------------
+
+What is in 2.26.0?
+
+	Support CalDAV for VTODO and VJOURNAL (Milan Crha)
+	Improved Camel/Sqlite support
+	Dropped libical fork and uses upstream libical
+	Exchange MAPI support for Exchange 2007 connectivity.
+	Mail summary database restructured for use by Tracker/Beagle
+	Loads of bug fixes
+
+Evolution-Data-Server 2.25.92 2009-03-02
+----------------------------------------
+
+Updated Translations:
+	Alexander Shopov (bg)
+	Andre Gondim (pt)
+	Arangel Angov (mk)
+	Changwoo Ryu (ko)
+	Chao-Hsiung Liao (zh)
+	Claude Paroz (fr)
+	Clytie Siddall (vi)
+	Daniel Nylander (sv)
+	David Planella (ca)
+	Duarte Loreto (pt)
+	Gabor Kelemen (hu)
+	Ilkka Tuohela (fi)
+	Inaki Larranaga Murgoitio (eu)
+	Ivar Smolin echo
+	Jani Monoses (ro)
+	Jiri Eischmann (cs)
+	Jorge Gonzalez (es)
+	Kenneth Nielsen (da)
+	Kjartan Maraas (nb)
+	Luca Ferretti (it)
+	Philip Withnall (en)
+	Robert Sedak (hr)
+	Sweta Kothari (gu)
+	Takeshi AIHANA (ja)
+	Theppitak Karoonboonyanan (th)
+	Vladimir Melo (pt)
+	Wadim Dziedzic (pl)
+	Wouter Bolsterlee (nl)
+
+Bug Fixes:
+	#266147 : Verify signature of the encrypted text, if any (Milan Crha)
+	#273233 : Show to user also reason why the operation failed (Milan Crha)
+	#477535 : Randomly mail status changes were not getting stored in server (Sankar P)
+	#534938 : Remember which IDs we added to the folder and ignore these in report of recent messages (Milan Crha)
+	#555888 : Use proxy configurable within Evolution (Milan Crha)
+	#563212 : Track state of the operation, three states WAITING, PROCESSING, CANCELLING and cancel or process only those WAITING (Milan Crha)
+	#567008 : Avoiding the clearing of the uids in the spool summary if forceindex is true (Jeff Cai)
+	#567861 : Two sources also differ when one has set color_spec and the other not (Milan Crha)
+	#569459 : Revert back to including <libical/ical*.h> (Suman Manjunath)
+	#570653 : Kill n_std_folders and use G_N_ELEMENTS (std_folders) instead (Matthew Barnes)
+	#570696 : Define GDATA_CFLAGS and GDATA_LIBS and explicitly require libsoup-2.4 and libxml-2.0 (Matthew Barnes)
+	#570765 : Do not store UTC to the component (Milan Crha)
+	#571046 : Always strip trailing white-spaces added during message transmission, before verifying message signature (Milan Crha)
+	#571726 : Fix a translatable string typo (Matthew Barnes)
+	#571761 : Stop using deprecated GtkType macros (Matthew Barnes)
+	#572268 : Do not create duplicate folder infos (Milan Crha)
+	#572566 : Do not set/access NULL pointers (Milan Crha)
+	#572950 : Fix ordering of -I compiler directives (Daniel Macks)
+	#573175 : Use a proper format string to call g_set_error with (Tobias Mueller)
+	#573240 : Do not disconnect on user canceled (Milan Crha)
+	#573497 : Use "%s" as format-string to g_set_error (Tobias Mueller)
+	#566984 : (Tom Parker)
+	#570696 : Remove unnecessary dependencies from libgdata (Daniel Macks)
+	#573183 : Use a gint64 for a format string with the macro PRId64 (Tobias Mueller)
+	#573494 : Use a const char[] instead of a const char* for a fixed sized format-string to increase auditability (Tobias Mueller)
+	#549838 : Entity-encode the text and target URL of links when formatting plain text mail to HTML for display (Matt McCutchen)
+
+Other contributions:
+	AC_HELP_STRING instead of AS_HELP_STRING (Tor Lillqvist)
+	Add a "no space" error (Ross Burton)
+	Add e_contact_field_id_from_vcard() (Ross Burton)
+	Add EVC_X_SIP and E_CONTACT_SIP (Ross Burton)
+	Comment too recent error codes (Milan Crha)
+	Fix -Wold-style-definition warnings (Andre Klapper)
+	Handle EContactName structures containing NULLs (Ross Burton)
+	Move e_book_view_set_book to -private (Ross Burton)
+	Recompute digests from the signed message content (Nalin Dahyabhai)
+	Some help comments for the future maintainers (Sankar P)
+	Include <libical/ical*.h> (Suman Manjunath)
+	Use correct server parameter for getting folder information (Sankar P)
+
+Evolution-Data-Server 2.25.90 2009-02-02
+----------------------------------------
+
+Updated Translations:
+	Andre Klapper (de)
+	Changwoo Ryu (ko)
+	David Planella (ca)
+	Gabor Kelemen (hu)
+	Laurent Coudeur and Claude Paroz (fr)
+	Matthew Barnes (PO)
+	Yair Hershkovitz (he)
+
+Bug Fixes:
+	#390198 : Free the exception object which was leaking. (Sankar P)
+	#464758 : Evolution crashes while moving mails to Junk in Groupwise (Sankar P)
+	#464878 (BNC) : When an HTML attachment contains an image tag with a source that returns a "HTTP/302 Moved Temporarily", that image is not displayed (Simon Brys)
+	#467075 (BNC) : Incorrect url is displayed in Evolution plain text mails when the url is surrounded by brackets (Simon Brys)
+	#467638 (BNC) : Fix the broken current_folder handling code. Lots of issues are fixed. some may remain yet. (Sankar P)
+	#470143	: GroupWise Container Crash (Sankar P)
+	#557348 : Search folders with "Include threads" do not update reliably (Srinivasa Ragavan)
+	#568332 : Sqlite vfs for async disk wrigte (Milan Crha)
+	#568561 : crash in summary_reloaded (Srinivasa Ragavan)
+	#569405 : Negated header criterion fails to match messages without the header (Matt McCutchen 2)
+	#569742 : Do not crash when open of the file failed. Also be thread safe with respect of filling global variables. (Milan Crha)
+	#569874 : Crash while deleting messages  (Srinivasa Ragavan)
+	#347287 : MVC for calendar. Store the current operation going on. (Chenthill Palanisamy)
+	#550414 : Corruption of mbox and failure to expunge (Hiroyuki Ikezoe)
+
+
+Other contributions:
+	Add libical to the calendar and server deps to ensure that it is available everywhere it is needed, and not checked if we're not building the calendar. (Ross Burton)
+	Fix compiler warning (Srinivasa Ragavan)
+	"GUI" executable on Windows to avoid console windows that annoy end-users. (Tor Lillqvist)
+	Include appropriate headers which otherwise cause build failures with strict compiler settings. (Suman Manjunath)
+	Remove some trailing whitespace. (Ross Burton)
+	Allow cross-compiling e-d-s for windows fix some win32 hickups. (Fridrich Strba)
+	Use G_DEFINE_TYPE. (Ross Burton)
+	Use GObject private data instead of g_new(). (Ross Burton)
+
+
+Evolution-Data-Server 2.25.5 2009-01-19
+---------------------------------------
+
+Updated Translations:
+	Andre Klapper (de)
+	Kjartan Maraas (nb)
+	Luca Ferretti (it)
+	Wadim Dziedzic (pl)
+
+Bug Fixes:
+	#303738 : Return AuthFailed when need auth, to ask for a password again, or return AuthRequired to indicate we require authentication. (Milan Crha)
+	#360813 : RFC 2445 - CREATED/DTSTAMP/LAST-MODIFIED always in UTC.  (Milan Crha)
+	#435599 : Don't do to displaying and creation of organization's contact in evolution.  (Ashish Shrivastava)
+	#439986 (bugzilla.novell.com) : Set the transparency on the cached object. (Chenthill Palanisamy)
+	#443296 (bugzilla.novell.com) : Free memory only after it is duped.  (Suman Manjunath)
+	#443544 (bugzilla.novell.com) : Send a 'Free' block to the frontend if there are no 'Busy' blocks. Also set the start/end of the Free/Busy range. (Suman Manjunath)
+	#463095 : Fix cinfo parsing logic (Simon Brys)
+	#501298 : Make _open function quick as much as possible, to not block the sync_backend lock for long, thus other threads can work with it too. Do not search a book when it wasn't opened correctly. Do not ref/unref backend in a structure which backend holds itself. (Milan Crha)
+	#518920 : Handle relative URIs in value of action attribute of form in form-based authentication. (Chow Loong Jin)
+	#554182 : Don't use 'authmech' for URL comparision. (Milan Crha)
+	#557348 : Re-did bits of threaded vfolder (Matt McCutchen)
+	#562200 : Define subclass of a GtkCellRendererToggle, which toggles itself only when user clicks over the toggle cell and not in any other case. of a GtkCellRendererToggle to prevent unnecessary toggling in a source selector when source itself doesn't have defined its color. (Milan Crha)
+	#564339 : Reduce the IO done during sync by not reading into memory locally cached files. (Robert Collins)
+	#564543 : Bump gtk_minimum_version to 2.14.0. (Matthew Barnes)
+	#564543 : Call soup_form_encode_hash() instead of soup_form_encode_urlencoded(). Call soup_session_add_feature() instead of soup_logger_attach(). Fix what we can with GSEAL_ENABLE defined. (Matthew Barnes)
+	#564954 : Fix SQL-ization of booleans and immediate-function confusion. (Matt McCutchen)
+	#566279 : Introduces a new API in Camel needed for implementing EPlugin of Bug #565091 (Philip Van Hoof  )
+	#565376 : Support more search options (Milan Crha)
+	#567384 : Remove unused variables. Comment out variables that are used by commented out code to silence compiler warnings. (Matthew Barnes)
+
+Other contributions:
+	DB Logging and DB Optimizations  (Srinivasa Ragavan  )
+	Manage GroupWise counts better. fix bugs in read-cursor elimination. A brand new flags handling code for GroupWise provider. (Sankar P)
+	Always send XEV headers with messages. (Srinivasa Ragavan)
+	Allowing devleoper to add migration code for in case the schema of Camel's summary SQLite data format changes. Also adds two columns, modified and created, to the summary data being stored and renames the column msg_security to dirty as requested by Srinivasa Ragavan and Sankar P.  (Philip Van Hoof)
+	Hack and debug log to get one hard to get imap crash. (Srinivasa Ragavan)
+	Fix for better vfolder flag syncing and count (Srinivasa Ragavan)
+	Sync using counting manually than the old approach (Srinivasa Ragavan)
+
+Evolution-Data-Server 2.25.4 2009-01-05
+---------------------------------------
+
+Bug Fixes:
+	#209514: (Novell Bugzilla) Addresses some missing mails issues. Optimization fixed (Sankar P)
+	#446290: Parallel clients support and (un)read count handling (Sankar P)
+	#448079: (Novell Bugzilla) Avoid invalid reads by validating optional fields (Sankar P, Simon Brys)
+	#449916: (Novell Bugzilla) Display multiple lines of an assinged asks or shared memo. (Bharath Acharya)
+	#462575: (Novell Bugzilla) Extend function to honor "Check in all folders" setting (Simon Brys)
+	#559153: Migration improvements (Sankar P)
+	#564652: Convert time from UTC properly. Leak a bit less (Milan Crha)
+
+Updated Translations:
+	Jorge Gonzalez (es)
+
 Evolution-Data-Server 2.25.3 2008-12-15
 ---------------------------------------
 

Modified: branches/camel-gobject/addressbook/backends/file/e-book-backend-file.c
==============================================================================
--- branches/camel-gobject/addressbook/backends/file/e-book-backend-file.c	(original)
+++ branches/camel-gobject/addressbook/backends/file/e-book-backend-file.c	Thu Apr 16 01:23:17 2009
@@ -174,10 +174,10 @@
 {
 	char time_string[100] = {0};
 	const struct tm *tm = NULL;
-	GTimeVal tv;
+	time_t t;
 
-	g_get_current_time (&tv);
-	tm = gmtime (&tv.tv_sec);
+	t = time(NULL);
+	tm = gmtime (&t);
 	if (tm)
 		strftime (time_string, 100, "%Y-%m-%dT%H:%M:%SZ", tm);
 	e_contact_set (contact, E_CONTACT_REV, time_string);

Modified: branches/camel-gobject/addressbook/backends/google/google-book.c
==============================================================================
--- branches/camel-gobject/addressbook/backends/google/google-book.c	(original)
+++ branches/camel-gobject/addressbook/backends/google/google-book.c	Thu Apr 16 01:23:17 2009
@@ -21,6 +21,7 @@
 
 #include <string.h>
 #include <libedata-book/e-book-backend-cache.h>
+#include <libedataserver/e-proxy.h>
 #include <gdata-service-iface.h>
 #include <gdata-google-service.h>
 
@@ -79,6 +80,7 @@
 
     gboolean offline;
     GDataService *service;
+    EProxy *proxy;
     guint refresh_interval;
     char *base_uri;
     /* FIXME - this one should not be needed */
@@ -446,7 +448,7 @@
 static void
 google_book_construct_base_uri (GoogleBook *book, gboolean use_ssl)
 {
-    const char *format = "%swww.google.com/m8/feeds/contacts/%s/base";
+    const char format[] = "%swww.google.com/m8/feeds/contacts/%s/base";
     char *esc_username;
     GoogleBookPrivate *priv = GET_PRIVATE (book);
 
@@ -533,6 +535,10 @@
         g_object_unref (priv->service);
         priv->service = NULL;
     }
+    if (priv->proxy) {
+	g_object_unref (priv->proxy);
+	priv->proxy = NULL;
+    }
     google_book_cache_destroy (GOOGLE_BOOK (object));
 
     if (G_OBJECT_CLASS (google_book_parent_class)->dispose)
@@ -726,6 +732,22 @@
                          NULL);
 }
 
+static void
+proxy_settings_changed (EProxy *proxy, gpointer user_data)
+{
+	SoupURI *proxy_uri = NULL;
+
+	GoogleBookPrivate *priv = (GoogleBookPrivate*) user_data;
+	if (!priv || !priv->base_uri)
+		return;
+
+	/* use proxy if necessary */
+	if (e_proxy_require_proxy_for_uri (proxy, priv->base_uri)) {
+		proxy_uri = e_proxy_peek_uri_for (proxy, priv->base_uri);
+	}
+	gdata_service_set_proxy (GDATA_SERVICE (priv->service), proxy_uri);
+}
+
 gboolean
 google_book_connect_to_google (GoogleBook *book, const char *password, GError **error)
 {
@@ -745,6 +767,12 @@
     }
 
     service = (GDataService*)gdata_google_service_new ("cp", "evolution-client-0.0.1");
+    priv->proxy = e_proxy_new ();
+    e_proxy_setup_proxy (priv->proxy);
+    priv->service = service;
+    proxy_settings_changed (priv->proxy, priv);
+    priv->service = NULL;
+
     gdata_service_set_credentials (GDATA_SERVICE (service), priv->username, password);
     gdata_google_service_authenticate (GDATA_GOOGLE_SERVICE (service), &soup_error);
 
@@ -752,8 +780,13 @@
         google_book_error_from_soup_error (soup_error, error,
                                            "Connecting to google failed");
         priv->service = NULL;
+	g_object_unref (service);
+	g_object_unref (priv->proxy);
+	priv->proxy = NULL;
         return FALSE;
     }
+
+    g_signal_connect (priv->proxy, "changed", G_CALLBACK (proxy_settings_changed), priv);
     priv->service = service;
 
     return google_book_cache_refresh_if_needed (book, error);
@@ -770,9 +803,15 @@
     priv = GET_PRIVATE (book);
 
     priv->offline = offline;
-    if (offline && priv->service) {
-        g_object_unref (priv->service);
-        priv->service = NULL;
+    if (offline) {
+	if (priv->service) {
+		g_object_unref (priv->service);
+		priv->service = NULL;
+	}
+	if (priv->proxy) {
+		g_object_unref (priv->proxy);
+		priv->proxy = NULL;
+	}
     }
     if (offline == FALSE) {
         if (priv->service) {

Modified: branches/camel-gobject/addressbook/backends/google/util.c
==============================================================================
--- branches/camel-gobject/addressbook/backends/google/util.c	(original)
+++ branches/camel-gobject/addressbook/backends/google/util.c	Thu Apr 16 01:23:17 2009
@@ -410,7 +410,7 @@
                         const struct RelTypeMap rel_type_map[],
                         int map_len)
 {
-    const char *format = "http://schemas.google.com/g/2005#%s";;
+    const char format[] = "http://schemas.google.com/g/2005#%s";;
 
     while (types) {
         int i;
@@ -485,7 +485,7 @@
 static char*
 google_im_protocol_from_field_name (const char* field_name)
 {
-    const char *format = "http://schemas.google.com/g/2005#%s";;
+    const char format[] = "http://schemas.google.com/g/2005#%s";;
 
     if (NULL == field_name ||
         strlen (field_name) < 3) {

Modified: branches/camel-gobject/addressbook/backends/groupwise/e-book-backend-groupwise.c
==============================================================================
--- branches/camel-gobject/addressbook/backends/groupwise/e-book-backend-groupwise.c	(original)
+++ branches/camel-gobject/addressbook/backends/groupwise/e-book-backend-groupwise.c	Thu Apr 16 01:23:17 2009
@@ -829,8 +829,10 @@
 
 	for ( ;temp != NULL; temp = g_list_next (temp)) {
 		EVCardAttribute *attr = temp->data;
+		EDestination *dest;
 		id = email = NULL;
-		EDestination *dest = e_destination_new ();
+
+		dest = e_destination_new ();
 
 		for (p = e_vcard_attribute_get_params (attr); p; p = p->next) {
 			EVCardAttributeParam *param = p->data;
@@ -1197,8 +1199,11 @@
 	int element_type;
 	int i;
 	gboolean is_contact_list;
+	gboolean is_organization;
 
+	is_organization = e_gw_item_get_item_type (item) == E_GW_ITEM_TYPE_ORGANISATION ? TRUE: FALSE;
 	is_contact_list = e_gw_item_get_item_type (item) == E_GW_ITEM_TYPE_GROUP ? TRUE: FALSE;
+
 	e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (is_contact_list));
 	if (is_contact_list)
 		e_contact_set (contact, E_CONTACT_LIST_SHOW_ADDRESSES, GINT_TO_POINTER (TRUE));
@@ -1208,9 +1213,11 @@
 
 		if(element_type == ELEMENT_TYPE_SIMPLE) {
 			if (mappings[i].field_id != E_CONTACT_BOOK_URI) {
-				value = e_gw_item_get_field_value (item, mappings[i].element_name);
-				if(value != NULL)
-					e_contact_set (contact, mappings[i].field_id, value);
+				if (!is_organization) {
+					value = e_gw_item_get_field_value (item, mappings[i].element_name);
+					if(value != NULL)
+						e_contact_set (contact, mappings[i].field_id, value);
+				}				
 			}
 		} else if (element_type == ELEMENT_TYPE_COMPLEX) {
 			if (mappings[i].field_id == E_CONTACT_CATEGORIES) {
@@ -1280,10 +1287,6 @@
 			element_type = mappings[i].element_type;
 			if (element_type == ELEMENT_TYPE_SIMPLE)  {
 				value =  e_contact_get(contact, mappings[i].field_id);
-				if (mappings[i].field_id == E_CONTACT_ORG) {
-					set_organization_in_gw_item (item, contact, egwb);
-					continue;
-				}
 				if (value != NULL)
 					e_gw_item_set_field_value (item, mappings[i].element_name, value);
 			} else if (element_type == ELEMENT_TYPE_COMPLEX) {
@@ -1423,7 +1426,6 @@
 	EGwItem *old_item;
 	int element_type;
 	char* value;
-	char *new_org, *old_org;
 	int i;
 
 	if (enable_debug)
@@ -1482,13 +1484,6 @@
 
 		if (e_contact_get (contact, E_CONTACT_IS_LIST))
 			set_member_changes (new_item, old_item, egwb);
-		new_org = e_gw_item_get_field_value (new_item, "organization");
-		old_org = e_gw_item_get_field_value (old_item, "organization");
-		if (new_org && *new_org) {
-
-			if ((old_org == NULL) || (old_org && strcmp (new_org, old_org)) != 0)
-				set_organization_in_gw_item (new_item, contact, egwb);
-		}
 
 		set_changes_in_gw_item (new_item, old_item);
 

Modified: branches/camel-gobject/addressbook/backends/ldap/e-book-backend-ldap.c
==============================================================================
--- branches/camel-gobject/addressbook/backends/ldap/e-book-backend-ldap.c	(original)
+++ branches/camel-gobject/addressbook/backends/ldap/e-book-backend-ldap.c	Thu Apr 16 01:23:17 2009
@@ -52,7 +52,7 @@
 #include "openldap-extract.h"
 #endif
 
-#define d(x) x
+#define d(x)
 
 #ifndef G_OS_WIN32
 

Modified: branches/camel-gobject/addressbook/backends/vcf/e-book-backend-vcf.c
==============================================================================
--- branches/camel-gobject/addressbook/backends/vcf/e-book-backend-vcf.c	(original)
+++ branches/camel-gobject/addressbook/backends/vcf/e-book-backend-vcf.c	Thu Apr 16 01:23:17 2009
@@ -54,7 +54,7 @@
 #define PAS_ID_PREFIX "pas-id-"
 #define FILE_FLUSH_TIMEOUT 5000
 
-#define d(x) x
+#define d(x)
 
 G_DEFINE_TYPE (EBookBackendVCF, e_book_backend_vcf, E_TYPE_BOOK_BACKEND_SYNC);
 
@@ -218,10 +218,10 @@
 {
 	char time_string[100] = {0};
 	const struct tm *tm = NULL;
-	GTimeVal tv;
+	time_t t;
 
-	g_get_current_time (&tv);
-	tm = gmtime (&tv.tv_sec);
+	t = time(NULL);
+	tm = gmtime (&t);
 	if (tm)
 		strftime (time_string, 100, "%Y-%m-%dT%H:%M:%SZ", tm);
 	e_contact_set (contact, E_CONTACT_REV, time_string);

Modified: branches/camel-gobject/addressbook/backends/webdav/e-book-backend-webdav.c
==============================================================================
--- branches/camel-gobject/addressbook/backends/webdav/e-book-backend-webdav.c	(original)
+++ branches/camel-gobject/addressbook/backends/webdav/e-book-backend-webdav.c	Thu Apr 16 01:23:17 2009
@@ -34,6 +34,7 @@
 
 #include <libedataserver/e-url.h> 
 #include <libedataserver/e-flag.h>
+#include <libedataserver/e-proxy.h>
 #include <libebook/e-contact.h>
 #include <libebook/e-address-western.h>
 
@@ -60,6 +61,7 @@
 	int                mode;
 	gboolean           marked_for_offline;
 	SoupSession       *session;
+	EProxy		  *proxy;
 	gchar             *uri;
 	char              *username;
 	char              *password;
@@ -960,6 +962,23 @@
 	}
 }
 
+static void
+proxy_settings_changed (EProxy *proxy, gpointer user_data)
+{
+	SoupURI *proxy_uri = NULL;
+	EBookBackendWebdavPrivate *priv = (EBookBackendWebdavPrivate *) user_data;
+
+	if (!priv || !priv->uri || !priv->session)
+		return;
+
+	/* use proxy if necessary */
+	if (e_proxy_require_proxy_for_uri (proxy, priv->uri)) {
+		proxy_uri = e_proxy_peek_uri_for (proxy, priv->uri);
+	}
+
+	g_object_set (priv->session, SOUP_SESSION_PROXY_URI, proxy_uri, NULL);
+}
+
 static GNOME_Evolution_Addressbook_CallStatus
 e_book_backend_webdav_load_source(EBookBackend *backend,
                                   ESource *source, gboolean only_if_exists)
@@ -1017,6 +1036,10 @@
 	                 webdav);
 
 	priv->session = session;
+	priv->proxy = e_proxy_new ();
+	e_proxy_setup_proxy (priv->proxy);
+	g_signal_connect (priv->proxy, "changed", G_CALLBACK (proxy_settings_changed), priv);
+	proxy_settings_changed (priv->proxy, priv);
 
 	e_book_backend_notify_auth_required(backend);
 	e_book_backend_set_is_loaded(backend, TRUE);
@@ -1092,6 +1115,7 @@
 	EBookBackendWebdavPrivate *priv   = webdav->priv;
 
 	g_object_unref(priv->session);
+	g_object_unref (priv->proxy);
 	g_object_unref(priv->cache);
 	g_free(priv->uri);
 	g_free(priv->username);

Modified: branches/camel-gobject/addressbook/libebook/e-book-types.h
==============================================================================
--- branches/camel-gobject/addressbook/libebook/e-book-types.h	(original)
+++ branches/camel-gobject/addressbook/libebook/e-book-types.h	Thu Apr 16 01:23:17 2009
@@ -44,7 +44,8 @@
 	E_BOOK_ERROR_OFFLINE_UNAVAILABLE,
 	E_BOOK_ERROR_OTHER_ERROR,
 	E_BOOK_ERROR_INVALID_SERVER_VERSION,
-	E_BOOK_ERROR_UNSUPPORTED_AUTHENTICATION_METHOD
+	E_BOOK_ERROR_UNSUPPORTED_AUTHENTICATION_METHOD,
+	E_BOOK_ERROR_NO_SPACE
 } EBookStatus;
 
 

Modified: branches/camel-gobject/addressbook/libebook/e-book-view-private.h
==============================================================================
--- branches/camel-gobject/addressbook/libebook/e-book-view-private.h	(original)
+++ branches/camel-gobject/addressbook/libebook/e-book-view-private.h	Thu Apr 16 01:23:17 2009
@@ -17,9 +17,10 @@
 #include "Evolution-DataServer-Addressbook.h"
 #include "e-book-view-listener.h"
 
-/* Creating a new addressbook. */
 EBookView *e_book_view_new (GNOME_Evolution_Addressbook_BookView corba_book_view, EBookViewListener *listener);
 
+void e_book_view_set_book (EBookView *book_view, struct _EBook *book);
+
 G_END_DECLS
 
 #endif /* ! __E_BOOK_VIEW_PRIVATE_H__ */

Modified: branches/camel-gobject/addressbook/libebook/e-book-view.h
==============================================================================
--- branches/camel-gobject/addressbook/libebook/e-book-view.h	(original)
+++ branches/camel-gobject/addressbook/libebook/e-book-view.h	Thu Apr 16 01:23:17 2009
@@ -61,7 +61,6 @@
 void               e_book_view_start                  (EBookView *book_view);
 void               e_book_view_stop                   (EBookView *book_view);
 
-void               e_book_view_set_book               (EBookView *book_view, struct _EBook *book);
 struct _EBook     *e_book_view_get_book               (EBookView *book_view);
 
 G_END_DECLS

Modified: branches/camel-gobject/addressbook/libebook/e-book.c
==============================================================================
--- branches/camel-gobject/addressbook/libebook/e-book.c	(original)
+++ branches/camel-gobject/addressbook/libebook/e-book.c	Thu Apr 16 01:23:17 2009
@@ -85,8 +85,15 @@
 
 static guint e_book_signals [LAST_SIGNAL];
 
+typedef enum {
+	STATE_WAITING,
+	STATE_PROCESSING,
+	STATE_CANCELLING
+} EBookOpState;
+
 typedef struct {
 	gint32 opid;
+	EBookOpState opstate;
 	gint idle_id;
 	gboolean synchronous;
 	EFlag *flag;
@@ -174,6 +181,7 @@
 	EBookOp *op = g_new0 (EBookOp, 1);
 
 	op->flag = e_flag_new ();
+	op->opstate = STATE_WAITING;
 
 	op->synchronous = sync;
 	if (sync)
@@ -200,6 +208,26 @@
 	return e_book_get_op (book, 0);
 }
 
+static EBookOp *
+e_book_find_op (EBook *book, guint32 opid, const char *func_name)
+{
+	EBookOp *op;
+
+	op = e_book_get_op (book, opid);
+
+	if (op == NULL) {
+		g_warning ("%s: Cannot find operation", func_name);
+	} else if (op->opstate != STATE_WAITING) {
+		/* returns only operations, which are waiting */
+		op = NULL;
+	} else {
+		/* set opstate to processing, thus it will not be canceled meanwhile */
+		op->opstate = STATE_PROCESSING;
+	}
+
+	return op;
+}
+
 static void
 e_book_op_free (EBookOp *op)
 {
@@ -421,11 +449,10 @@
 
 	g_mutex_lock (book->priv->mutex);
 
-	op = e_book_get_op (book, opid);
+	op = e_book_find_op (book, opid, G_STRFUNC);
 
 	if (op == NULL) {
 		g_mutex_unlock (book->priv->mutex);
-		g_warning ("e_book_response_add_contact: Cannot find operation ");
 		return;
 	}
 
@@ -907,11 +934,10 @@
 
 	g_mutex_lock (book->priv->mutex);
 
-	op = e_book_get_op (book, opid);
+	op = e_book_find_op (book, opid, G_STRFUNC);
 
 	if (op == NULL) {
 		g_mutex_unlock (book->priv->mutex);
-		g_warning ("e_book_response_get_required_fields: Cannot find operation ");
 		return;
 	}
 
@@ -949,11 +975,10 @@
 
 	g_mutex_lock (book->priv->mutex);
 
-	op = e_book_get_op (book, opid);
+	op = e_book_find_op (book, opid, G_STRFUNC);
 
 	if (op == NULL) {
 		g_mutex_unlock (book->priv->mutex);
-		g_warning ("e_book_response_get_supported_fields: Cannot find operation ");
 		return;
 	}
 
@@ -1130,11 +1155,10 @@
 
 	g_mutex_lock (book->priv->mutex);
 
-	op = e_book_get_op (book, opid);
+	op = e_book_find_op (book, opid, G_STRFUNC);
 
 	if (op == NULL) {
 		g_mutex_unlock (book->priv->mutex);
-		g_warning ("e_book_response_get_supported_auth_methods: Cannot find operation ");
 		return;
 	}
 
@@ -1503,11 +1527,10 @@
 
 	g_mutex_lock (book->priv->mutex);
 
-	op = e_book_get_op (book, opid);
+	op = e_book_find_op (book, opid, G_STRFUNC);
 
 	if (op == NULL) {
 		g_mutex_unlock (book->priv->mutex);
-		g_warning ("e_book_response_get_contact: Cannot find operation ");
 		return;
 	}
 
@@ -1983,11 +2006,10 @@
 
 	g_mutex_lock (book->priv->mutex);
 
-	op = e_book_get_op (book, opid);
+	op = e_book_find_op (book, opid, G_STRFUNC);
 
 	if (op == NULL) {
 		g_mutex_unlock (book->priv->mutex);
-		g_warning ("e_book_response_get_book_view: Cannot find operation ");
 		return;
 	}
 
@@ -2195,11 +2217,10 @@
 
 	g_mutex_lock (book->priv->mutex);
 
-	op = e_book_get_op (book, opid);
+	op = e_book_find_op (book, opid, G_STRFUNC);
 
 	if (op == NULL) {
 		g_mutex_unlock (book->priv->mutex);
-		g_warning ("e_book_response_get_contacts: Cannot find operation ");
 		return;
 	}
 
@@ -2398,11 +2419,10 @@
 
 	g_mutex_lock (book->priv->mutex);
 
-	op = e_book_get_op (book, opid);
+	op = e_book_find_op (book, opid, G_STRFUNC);
 
 	if (op == NULL) {
 		g_mutex_unlock (book->priv->mutex);
-		g_warning ("e_book_response_get_changes: Cannot find operation ");
 		return;
 	}
 
@@ -2474,11 +2494,10 @@
 	d(printf("e_book_response_generic\n"));
 	g_mutex_lock (book->priv->mutex);
 
-	op = e_book_get_op (book, opid);
+	op = e_book_find_op (book, opid, G_STRFUNC);
 
 	if (op == NULL) {
 		g_mutex_unlock (book->priv->mutex);
-		g_warning ("e_book_response_generic: Cannot find operation ");
 		return;
 	}
 
@@ -2517,6 +2536,11 @@
 		g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION,
 			     _("CORBA exception making \"%s\" call"),
 			     "Book::cancelOperation");
+		e_flag_set (op->flag);
+
+		g_mutex_lock (book->priv->mutex);
+		e_book_clear_op (book, op);
+		g_mutex_unlock (book->priv->mutex);
 		return FALSE;
 	}
 
@@ -2524,7 +2548,6 @@
 
 	if (status == E_BOOK_ERROR_OK) {
 		op->status = E_BOOK_ERROR_CANCELLED;
-		e_flag_set (op->flag);
 		rv = TRUE;
 	}
 	else {
@@ -2532,6 +2555,13 @@
 			     _("%s: could not cancel"), func_name);
 		rv = FALSE;
 	}
+	/* Always trigger the operation, we cannot put it back to queue, because
+	   the result could come just few ticks before, in the other thread. */
+	e_flag_set (op->flag);
+
+	g_mutex_lock (book->priv->mutex);
+	e_book_clear_op (book, op);
+	g_mutex_unlock (book->priv->mutex);
 
 	return rv;
 }
@@ -2563,6 +2593,16 @@
 
 	g_mutex_lock (book->priv->mutex);
 	op = e_book_get_current_sync_op (book);
+	if (op) {
+		if (op->opstate != STATE_WAITING) {
+			g_mutex_unlock (book->priv->mutex);
+			g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_COULD_NOT_CANCEL,
+				_("%s: could not cancel"), G_STRFUNC);
+			return FALSE;
+		}
+
+		op->opstate = STATE_CANCELLING;
+	}
 	g_mutex_unlock (book->priv->mutex);
 
 	return do_cancel (book, error, op, "e_book_cancel");
@@ -2592,6 +2632,17 @@
 			op = NULL;
 	}
 
+	if (op) {
+		if (op->opstate != STATE_WAITING) {
+			g_mutex_unlock (book->priv->mutex);
+			g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_COULD_NOT_CANCEL,
+				_("%s: could not cancel"), G_STRFUNC);
+			return FALSE;
+		}
+
+		op->opstate = STATE_CANCELLING;
+	}
+
 	g_mutex_unlock (book->priv->mutex);
 
 	return do_cancel (book, error, op, "e_book_cancel_async_op");
@@ -2792,11 +2843,10 @@
 
 	g_mutex_lock (book->priv->mutex);
 
-	op = e_book_get_op (book, opid);
+	op = e_book_find_op (book, opid, G_STRFUNC);
 
 	if (op == NULL) {
 		g_mutex_unlock (book->priv->mutex);
-		g_warning ("e_book_response_open: Cannot find operation ");
 		return;
 	}
 
@@ -2944,11 +2994,10 @@
 
 	g_mutex_lock (book->priv->mutex);
 
-	op = e_book_get_op (book, opid);
+	op = e_book_find_op (book, opid, G_STRFUNC);
 
 	if (op == NULL) {
 		g_mutex_unlock (book->priv->mutex);
-		g_warning ("e_book_response_remove: Cannot find operation ");
 		return;
 	}
 
@@ -3963,12 +4012,13 @@
 kill_remaining_ops (gpointer key, gpointer value, gpointer user_data)
 {
 	EBookOp *op = value;
+	EBook *book = user_data;
 
 	if (!op)
 		return;
 
 	find_key_value (key, value, NULL);
-	e_book_clear_op (op->book, op);
+	e_book_clear_op (book, op);
 }
 
 static void
@@ -4026,7 +4076,7 @@
 			g_object_unref (book->priv->source);
 
 		g_mutex_lock (book->priv->mutex);
-		g_hash_table_foreach (book->priv->id_to_op, kill_remaining_ops, NULL);
+		g_hash_table_foreach (book->priv->id_to_op, kill_remaining_ops, book);
 		g_hash_table_destroy (book->priv->id_to_op);
 		g_mutex_unlock (book->priv->mutex);
 

Modified: branches/camel-gobject/addressbook/libebook/e-contact.c
==============================================================================
--- branches/camel-gobject/addressbook/libebook/e-contact.c	(original)
+++ branches/camel-gobject/addressbook/libebook/e-contact.c	Thu Apr 16 01:23:17 2009
@@ -281,7 +281,9 @@
 	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_SKYPE_WORK_1,  EVC_X_SKYPE,  "im_skype_work_1",  N_("Skype Work Name 1"),         FALSE, "WORK", 0),
 	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_SKYPE_WORK_2,  EVC_X_SKYPE,  "im_skype_work_2",  N_("Skype Work Name 2"),         FALSE, "WORK", 1),
 	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_SKYPE_WORK_3,  EVC_X_SKYPE,  "im_skype_work_3",  N_("Skype Work Name 3"),         FALSE, "WORK", 2),
-	MULTI_LIST_FIELD (E_CONTACT_IM_SKYPE,  	  EVC_X_SKYPE,     "im_skype",     N_("Skype Name List"),         FALSE)
+	MULTI_LIST_FIELD (E_CONTACT_IM_SKYPE,  	  EVC_X_SKYPE,     "im_skype",     N_("Skype Name List"),         FALSE),
+
+	MULTI_LIST_FIELD (E_CONTACT_SIP, 	  EVC_X_SIP,    "sip",    N_("SIP address"),          FALSE),
 };
 
 #undef LIST_ELEM_STR_FIELD
@@ -597,11 +599,11 @@
 {
 	EContactName *name = data;
 
-	e_vcard_attribute_add_value (attr, name->family);
-	e_vcard_attribute_add_value (attr, name->given);
-	e_vcard_attribute_add_value (attr, name->additional);
-	e_vcard_attribute_add_value (attr, name->prefixes);
-	e_vcard_attribute_add_value (attr, name->suffixes);
+	e_vcard_attribute_add_value (attr, name->family ? name->family : "");
+	e_vcard_attribute_add_value (attr, name->given ? name->given : "");
+	e_vcard_attribute_add_value (attr, name->additional ? name->additional : "");
+	e_vcard_attribute_add_value (attr, name->prefixes ? name->prefixes : "");
+	e_vcard_attribute_add_value (attr, name->suffixes ? name->suffixes : "");
 
 	/* now find the attribute for FileAs.  if it's not present, fill it in */
 	attr = e_contact_get_first_attr (contact, EVC_X_FILE_AS);
@@ -1380,6 +1382,32 @@
 }
 
 /**
+ * e_contact_field_id_from_vcard:
+ * @vcard_field: a string representing a vCard field
+ *
+ * Gets the #EContactField corresponding to the @vcard_field.
+ *
+ * Return value: An #EContactField corresponding to @vcard_field, or %0 if it doesn't exist.
+ **/
+EContactField
+e_contact_field_id_from_vcard (const char *vcard_field)
+{
+	int i;
+
+	for (i = E_CONTACT_FIELD_FIRST; i < E_CONTACT_FIELD_LAST; i ++) {
+		if (field_info[i].vcard_field_name == NULL)
+			continue;
+		if (field_info[i].t & E_CONTACT_FIELD_TYPE_SYNTHETIC)
+			continue;
+		if (!strcmp (field_info[i].vcard_field_name, vcard_field))
+			return field_info[i].field_id;
+	}
+
+	g_warning ("unknown vCard field `%s'", vcard_field);
+	return 0;
+}
+
+/**
  * e_contact_get:
  * @contact: an #EContact
  * @field_id: an #EContactField

Modified: branches/camel-gobject/addressbook/libebook/e-contact.h
==============================================================================
--- branches/camel-gobject/addressbook/libebook/e-contact.h	(original)
+++ branches/camel-gobject/addressbook/libebook/e-contact.h	Thu Apr 16 01:23:17 2009
@@ -207,6 +207,8 @@
 	E_CONTACT_IM_SKYPE_WORK_3,     /* Synthetic string field */
 	E_CONTACT_IM_SKYPE,    	 	/* Multi-valued */
 
+	E_CONTACT_SIP,
+
 	E_CONTACT_FIELD_LAST,
 	E_CONTACT_FIELD_FIRST        = E_CONTACT_UID,
 
@@ -344,6 +346,7 @@
 const char*             e_contact_pretty_name      (EContactField field_id);
 const char*             e_contact_vcard_attribute  (EContactField field_id);
 EContactField           e_contact_field_id         (const char *field_name);
+EContactField           e_contact_field_id_from_vcard (const char *vcard_field);
 
 G_END_DECLS
 

Modified: branches/camel-gobject/addressbook/libebook/e-name-western.c
==============================================================================
--- branches/camel-gobject/addressbook/libebook/e-name-western.c	(original)
+++ branches/camel-gobject/addressbook/libebook/e-name-western.c	Thu Apr 16 01:23:17 2009
@@ -105,9 +105,6 @@
 	return g_string_free (words, FALSE);
 }
 
-/*
- * What the fuck is wrong with glib's MAX macro.
- */
 static int
 e_name_western_max (const int a, const int b)
 {

Modified: branches/camel-gobject/addressbook/libebook/e-vcard.h
==============================================================================
--- branches/camel-gobject/addressbook/libebook/e-vcard.h	(original)
+++ branches/camel-gobject/addressbook/libebook/e-vcard.h	Thu Apr 16 01:23:17 2009
@@ -83,6 +83,7 @@
 #define EVC_X_MSN           	"X-MSN"
 #define EVC_X_SKYPE           	"X-SKYPE"
 #define EVC_X_RADIO         	"X-EVOLUTION-RADIO"
+#define EVC_X_SIP           	"X-SIP"
 #define EVC_X_SPOUSE        	"X-EVOLUTION-SPOUSE"
 #define EVC_X_TELEX         	"X-EVOLUTION-TELEX"
 #define EVC_X_TTYTDD        	"X-EVOLUTION-TTYTDD"

Modified: branches/camel-gobject/calendar/Makefile.am
==============================================================================
--- branches/camel-gobject/calendar/Makefile.am	(original)
+++ branches/camel-gobject/calendar/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -1 +1 @@
-SUBDIRS = libical idl libecal libedata-cal backends tests
\ No newline at end of file
+SUBDIRS = idl libecal libedata-cal backends tests

Modified: branches/camel-gobject/calendar/backends/caldav/Makefile.am
==============================================================================
--- branches/camel-gobject/calendar/backends/caldav/Makefile.am	(original)
+++ branches/camel-gobject/calendar/backends/caldav/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -1,30 +1,26 @@
-INCLUDES =                                                      \
-	$(EVOLUTION_CALENDAR_CFLAGS)				\
-	-I$(top_srcdir)						\
-	-I$(top_srcdir)/calendar                                \
-	-I$(top_builddir)/calendar                              \
-	-I$(top_srcdir)/calendar/libical/src		        \
-	-I$(top_builddir)/calendar/libical/src		        \
-	-I$(top_srcdir)/calendar/libical/src/libical	        \
-	-I$(top_builddir)/calendar/libical/src/libical	        \
-	$(SOUP_CFLAGS)					        \
+INCLUDES = \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/calendar \
+	-I$(top_builddir)/calendar \
+	$(EVOLUTION_CALENDAR_CFLAGS) \
+	$(SOUP_CFLAGS) \
 	-DG_LOG_DOMAIN=\"e-cal-backend-caldav\"
 
 extension_LTLIBRARIES = libecalbackendcaldav.la
 
-libecalbackendcaldav_la_SOURCES =	\
-	e-cal-backend-caldav-factory.c	\
-	e-cal-backend-caldav-factory.h	\
-	e-cal-backend-caldav.c		\
-	e-cal-backend-caldav.h		
+libecalbackendcaldav_la_SOURCES = \
+	e-cal-backend-caldav-factory.c \
+	e-cal-backend-caldav-factory.h \
+	e-cal-backend-caldav.c \
+	e-cal-backend-caldav.h
 
-libecalbackendcaldav_la_LIBADD =						\
+libecalbackendcaldav_la_LIBADD = \
 	$(top_builddir)/calendar/libedata-cal/libedata-cal-1.2.la \
 	$(top_builddir)/calendar/libecal/libecal-1.2.la \
 	$(top_builddir)/libedataserver/libedataserver-1.2.la \
+	$(top_builddir)/libebackend/libebackend-1.2.la \
 	$(EVOLUTION_CALENDAR_LIBS) \
 	$(SOUP_LIBS)
 
-
-libecalbackendcaldav_la_LDFLAGS =		\
-	-module -avoid-version
+libecalbackendcaldav_la_LDFLAGS = \
+	-module -avoid-version $(NO_UNDEFINED)

Modified: branches/camel-gobject/calendar/backends/caldav/e-cal-backend-caldav.c
==============================================================================
--- branches/camel-gobject/calendar/backends/caldav/e-cal-backend-caldav.c	(original)
+++ branches/camel-gobject/calendar/backends/caldav/e-cal-backend-caldav.c	Thu Apr 16 01:23:17 2009
@@ -28,6 +28,7 @@
 #include <gconf/gconf-client.h>
 #include <glib/gi18n-lib.h>
 #include "libedataserver/e-xml-hash-utils.h"
+#include "libedataserver/e-proxy.h"
 #include <libecal/e-cal-recur.h>
 #include <libecal/e-cal-util.h>
 #include <libecal/e-cal-time-util.h>
@@ -46,7 +47,7 @@
 
 #include "e-cal-backend-caldav.h"
 
-#define d(x) x
+#define d(x)
 
 /* in seconds */
 #define DEFAULT_REFRESH_TIME 60
@@ -91,6 +92,7 @@
 
 	/* The main soup session  */
 	SoupSession *session;
+	EProxy *proxy;
 
 	/* well, guess what */
 	gboolean read_only;
@@ -201,7 +203,7 @@
 }
 
 static void
-caldav_debug_init ()
+caldav_debug_init (void)
 {
 	static GOnce debug_once = G_ONCE_INIT;
 
@@ -239,7 +241,7 @@
 		level = SOUP_LOGGER_LOG_MINIMAL;
 
 	logger = soup_logger_new (level, DEBUG_MAX_BODY_SIZE);
-	soup_logger_attach (logger, session);
+	soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger));
 	g_object_unref (logger);
 }
 
@@ -299,7 +301,7 @@
 	}
 
 	if (xprop) {
-		return icalproperty_get_value_as_string (xprop);
+		return icalproperty_get_value_as_string_r (xprop);
 	}
 
 	return NULL;
@@ -311,7 +313,10 @@
 {
 	icalcomponent *icomp;
 
+	g_return_if_fail (href != NULL);
+
 	icomp = e_cal_component_get_icalcomponent (comp);
+	g_return_if_fail (icomp != NULL);
 
 	icomp_x_prop_set (icomp, X_E_CALDAV "HREF", href);
 }
@@ -324,6 +329,7 @@
 
 	str = NULL;
 	icomp = e_cal_component_get_icalcomponent (comp);
+	g_return_val_if_fail (icomp != NULL, NULL);
 
 	str =  icomp_x_prop_get (icomp, X_E_CALDAV "HREF");
 
@@ -336,11 +342,12 @@
 {
 	icalcomponent *icomp;
 
+	g_return_if_fail (etag != NULL);
+
 	icomp = e_cal_component_get_icalcomponent (comp);
+	g_return_if_fail (icomp != NULL);
 
 	icomp_x_prop_set (icomp, X_E_CALDAV "ETAG", etag);
-
-
 }
 
 static char *
@@ -351,6 +358,7 @@
 
 	str = NULL;
 	icomp = e_cal_component_get_icalcomponent (comp);
+	g_return_val_if_fail (icomp != NULL, NULL);
 
 	str =  icomp_x_prop_get (icomp, X_E_CALDAV "ETAG");
 
@@ -428,7 +436,7 @@
 /* ************************************************************************* */
 
 static ECalBackendSyncStatus
-status_code_to_result (guint status_code)
+status_code_to_result (guint status_code, ECalBackendCalDAVPrivate  *priv)
 {
 	ECalBackendSyncStatus result;
 
@@ -447,7 +455,10 @@
 		break;
 
 	case 401:
-		result = GNOME_Evolution_Calendar_AuthenticationRequired;
+		if (priv && priv->need_auth)
+			result = GNOME_Evolution_Calendar_AuthenticationFailed;
+		else
+			result = GNOME_Evolution_Calendar_AuthenticationRequired;
 		break;
 
 	default:
@@ -787,75 +798,6 @@
 		soup_auth_authenticate (auth, priv->username, priv->password);
 }
 
-static gint
-caldav_ignore_host(gconstpointer a, gconstpointer b)
-{
-	gchar *hostname = (gchar*)a,
-	      *ignore = (gchar*)b;
-
-	if (hostname && ignore)
-	  return strcmp(hostname, ignore);
-        return -1;
-}
-
-static void
-caldav_set_session_proxy(ECalBackendCalDAVPrivate *priv)
-{
-	GConfClient *conf_client;
-	SoupURI *uri_base;
-
- 	if (priv->session == NULL)
- 		return;
-
-	uri_base = soup_uri_new (priv->uri);
-	if (uri_base == NULL)
-		return;
-
-	/* set the outbound HTTP proxy, if configuration is set to do so */
-	conf_client = gconf_client_get_default ();
-	if (gconf_client_get_bool (conf_client, "/system/http_proxy/use_http_proxy", NULL)) {
-		char *server, *proxy_uri;
-		int port;
- 		GSList *ignore = gconf_client_get_list (conf_client,
-  							"/system/http_proxy/ignore_hosts",
-  		                                	GCONF_VALUE_STRING, NULL);
-  		if (ignore == NULL ||
-  		    g_slist_find_custom(ignore, uri_base->host, caldav_ignore_host) == NULL) {
-  			server = gconf_client_get_string (conf_client, "/system/http_proxy/host", NULL);
-			port = gconf_client_get_int (conf_client, "/system/http_proxy/port", NULL);
-
-			if (server && server[0]) {
-				SoupURI *suri;
-				if (gconf_client_get_bool (conf_client, "/system/http_proxy/use_authentication", NULL)) {
-					char *user, *password;
-					user = gconf_client_get_string (conf_client,
-									"/system/http_proxy/authentication_user",
-									NULL);
-					password = gconf_client_get_string (conf_client,
-									    "/system/http_proxy/authentication_password",
-									    NULL);
-
-					proxy_uri = g_strdup_printf("http://%s:%s %s:%d", user, password, server, port);
-					g_free (user);
-					g_free (password);
-				} else
-					proxy_uri = g_strdup_printf ("http://%s:%d";, server, port);
-
-				suri = soup_uri_new (proxy_uri);
-				g_object_set (G_OBJECT (priv->session), SOUP_SESSION_PROXY_URI, suri, NULL);
-
-				soup_uri_free (suri);
-				g_free (server);
-				g_free (proxy_uri);
-			}
-		}
- 		g_slist_foreach(ignore, (GFunc) g_free, NULL);
-		g_slist_free(ignore);
-	}
-	soup_uri_free (uri_base);
-}
-
-
 /* ************************************************************************* */
 /* direct CalDAV server access functions */
 
@@ -951,7 +893,7 @@
 
 		g_object_unref (message);
 
-		return status_code_to_result (status_code);
+		return status_code_to_result (status_code, priv);
 	}
 
 	/* parse the dav header, we are intreseted in the
@@ -1060,7 +1002,8 @@
 		return FALSE;
 
 	doc = xmlNewDoc ((xmlChar *) "1.0");
-	root = xmlNewNode (NULL, (xmlChar *) "propfind");
+	root = xmlNewDocNode (doc, NULL, (xmlChar *) "propfind", NULL);
+	xmlDocSetRootElement (doc, root);
 	nsdav = xmlNewNs (root, (xmlChar *) "DAV:", NULL);
 	ns = xmlNewNs (root, (xmlChar *) "http://calendarserver.org/ns/";, (xmlChar *) "CS");
 
@@ -1139,10 +1082,10 @@
 	/* Maybe we should just do a g_strdup_printf here? */
 	/* Prepare request body */
 	doc = xmlNewDoc ((xmlChar *) "1.0");
-	root = xmlNewNode (NULL, (xmlChar *) "calendar-query");
-	nscd = xmlNewNs (root, (xmlChar *) "urn:ietf:params:xml:ns:caldav",
-			 (xmlChar *) "C");
+	root = xmlNewDocNode (doc, NULL, (xmlChar *) "calendar-query", NULL);
+	nscd = xmlNewNs (root, (xmlChar *) "urn:ietf:params:xml:ns:caldav", (xmlChar *) "C");
 	xmlSetNs (root, nscd);
+	xmlDocSetRootElement (doc, root);
 
 	/* Add webdav tags */
 	nsdav = xmlNewNs (root, (xmlChar *) "DAV:", (xmlChar *) "D");
@@ -1224,20 +1167,23 @@
 
 	uri = caldav_generate_uri (cbdav, object->href);
 	message = soup_message_new (SOUP_METHOD_GET, uri);
-	g_free (uri);
-	if (message == NULL)
+	if (message == NULL) {
+		g_free (uri);
 		return GNOME_Evolution_Calendar_NoSuchCal;
+	}
 
 	soup_message_headers_append (message->request_headers,
 				     "User-Agent", "Evolution/" VERSION);
 
 	send_and_handle_redirection (priv->session, message, NULL);
 
-	if (! SOUP_STATUS_IS_SUCCESSFUL (message->status_code)) {
-		result = status_code_to_result (message->status_code);
+	if (!SOUP_STATUS_IS_SUCCESSFUL (message->status_code)) {
+		guint status_code = message->status_code;
 		g_object_unref (message);
-		g_warning ("Could not fetch object from server\n");
-		return result;
+
+		g_warning ("Could not fetch object '%s' from server, status:%d (%s)", uri, status_code, soup_status_get_phrase (status_code) ? soup_status_get_phrase (status_code) : "Unknown code");
+		g_free (uri);
+		return status_code_to_result (status_code, priv);
 	}
 
 	hdr = soup_message_headers_get (message->response_headers, "Content-Type");
@@ -1245,7 +1191,8 @@
 	if (hdr == NULL || g_ascii_strncasecmp (hdr, "text/calendar", 13)) {
 		result = GNOME_Evolution_Calendar_InvalidObject;
 		g_object_unref (message);
-		g_warning ("Object to fetch not of type text/calendar");
+		g_warning ("Object to fetch '%s' not of type text/calendar", uri);
+		g_free (uri);
 		return result;
 	}
 
@@ -1255,8 +1202,9 @@
 		g_free (object->etag);
 		object->etag = quote_etag (hdr);
 	} else if (!object->etag) {
-		g_warning ("UUHH no ETag, now that's bad!");
+		g_warning ("UUHH no ETag, now that's bad! (at '%s')", uri);
 	}
+	g_free (uri);
 
 	g_free (object->cdata);
 	object->cdata = g_strdup (message->response_body->data);
@@ -1322,18 +1270,28 @@
 	}
 
 	/* FIXME: sepcial case precondition errors ?*/
-	result = status_code_to_result (message->status_code);
+	result = status_code_to_result (message->status_code, priv);
 
 	if (result == GNOME_Evolution_Calendar_Success) {
-		hdr = soup_message_headers_get (message->response_headers,
-						"ETag");
-	}
+		hdr = soup_message_headers_get (message->response_headers, "ETag");
+		if (hdr != NULL) {
+			g_free (object->etag);
+			object->etag = quote_etag (hdr);
+		} else {
+			/* no ETag header returned, check for it with a GET */
+			hdr = soup_message_headers_get (message->response_headers, "Location");
+			if (hdr) {
+				/* reflect possible href change first */
+				char *file = strrchr (hdr, '/');
+
+				if (file) {
+					g_free (object->href);
+					object->href = soup_uri_encode (file + 1, NULL);
+				}
+			}
 
-	if (hdr != NULL) {
-		g_free (object->etag);
-		object->etag = quote_etag (hdr);
-	} else {
-		g_warning ("Ups no Etag in put response");
+			result = caldav_server_get_object (cbdav, object);
+		}
 	}
 
 	g_object_unref (message);
@@ -1369,7 +1327,7 @@
 
 	send_and_handle_redirection (priv->session, message, NULL);
 
-	result = status_code_to_result (message->status_code);
+	result = status_code_to_result (message->status_code, priv);
 
 	g_object_unref (message);
 
@@ -1398,10 +1356,8 @@
 	res  = TRUE;
 	result  = caldav_server_get_object (cbdav, object);
 
-	if (result != GNOME_Evolution_Calendar_Success) {
-		g_warning ("Could not fetch object from server");
+	if (result != GNOME_Evolution_Calendar_Success)
 		return FALSE;
-	}
 
 	priv = E_CAL_BACKEND_CALDAV_GET_PRIVATE (cbdav);
 
@@ -1542,6 +1498,8 @@
 
 		if (res) {
 			cobjs = g_list_remove (cobjs, ccomp);
+			if (ccomp)
+				g_object_unref (ccomp);
 		}
 
 		caldav_object_free (object, FALSE);
@@ -1765,6 +1723,26 @@
 		priv->uri = g_strdup (uri);
 	}
 
+	if (priv->uri) {
+		SoupURI *suri = soup_uri_new (priv->uri);
+
+		/* properly encode uri */
+		if (suri && suri->path) {
+			char *tmp = soup_uri_encode (suri->path, NULL);
+			char *path = soup_uri_normalize (tmp, "/");
+
+			soup_uri_set_path (suri, path);
+
+			g_free (tmp);
+			g_free (path);
+			g_free (priv->uri);
+
+			priv->uri = soup_uri_to_string (suri, FALSE);
+		}
+
+		soup_uri_free (suri);
+	}
+
 	/* remove trailing slashes... */
 	len = strlen (priv->uri);
 	while (len--) {
@@ -1830,6 +1808,23 @@
 	return result;
 }
 
+static void
+proxy_settings_changed (EProxy *proxy, gpointer user_data)
+{
+	SoupURI *proxy_uri = NULL;
+	ECalBackendCalDAVPrivate *priv = (ECalBackendCalDAVPrivate *) user_data;
+
+	if (!priv || !priv->uri || !priv->session)
+		return;
+
+	/* use proxy if necessary */
+	if (e_proxy_require_proxy_for_uri (proxy, priv->uri)) {
+		proxy_uri = e_proxy_peek_uri_for (proxy, priv->uri);
+	}
+
+	g_object_set (priv->session, SOUP_SESSION_PROXY_URI, proxy_uri, NULL);
+}
+
 static ECalBackendSyncStatus
 caldav_do_open (ECalBackendSync *backend,
 		EDataCal        *cal,
@@ -1883,7 +1878,7 @@
 
 	if (priv->mode == CAL_MODE_REMOTE) {
 		/* set forward proxy */
-		caldav_set_session_proxy (priv);
+		proxy_settings_changed (priv->proxy, priv);
 
 		status = caldav_server_open_calendar (cbdav);
 
@@ -1967,7 +1962,8 @@
 		calcomp = icalcomponent_new_clone (icomp);
 	}
 
-	objstr = icalcomponent_as_ical_string (calcomp);
+	objstr = icalcomponent_as_ical_string_r (calcomp);
+	icalcomponent_free (calcomp);
 
 	g_assert (objstr);
 
@@ -2056,7 +2052,7 @@
 	}
 
 	/* Set the created and last modified times on the component */
-	current = icaltime_from_timet (time (NULL), 0);
+	current = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
 	e_cal_component_set_created (comp, &current);
 	e_cal_component_set_last_modified (comp, &current);
 
@@ -2065,7 +2061,6 @@
 
 	if (online) {
 		CalDAVObject object;
-		const char *id = NULL;
 
 		href = e_cal_component_gen_href (comp);
 		
@@ -2074,12 +2069,12 @@
 		object.cdata = pack_cobj (cbdav, comp);
 
 		status = caldav_server_put_object (cbdav, &object);
+		if (status == GNOME_Evolution_Calendar_Success) {
+			e_cal_component_set_href (comp, object.href);
+			e_cal_component_set_etag (comp, object.etag);
+		}
 
-		e_cal_component_get_uid (comp, &id);
-		e_cal_component_set_href (comp, object.href);
-		e_cal_component_set_etag (comp, object.etag);
 		caldav_object_free (&object, FALSE);
-
 	} else {
 		/* mark component as out of synch */
 		e_cal_component_set_synch_state (comp,
@@ -2139,7 +2134,7 @@
 	}
 
 	/* Set the last modified time on the component */
-	current = icaltime_from_timet (time (NULL), 0);
+	current = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
 	e_cal_component_set_last_modified (comp, &current);
 
 	/* sanitize the component*/
@@ -2161,11 +2156,12 @@
 		object.cdata = pack_cobj (cbdav, comp);
 
 		status = caldav_server_put_object (cbdav, &object);
+		if (status == GNOME_Evolution_Calendar_Success) {
+			e_cal_component_set_href (comp, object.href);
+			e_cal_component_set_etag (comp, object.etag);
+		}
 
-		e_cal_component_set_href (comp, object.href);
-		e_cal_component_set_etag (comp, object.etag);
 		caldav_object_free (&object, FALSE);
-
 	} else {
 		/* mark component as out of synch */
 		e_cal_component_set_synch_state (comp,
@@ -2244,8 +2240,10 @@
 			caldav_object.cdata = pack_cobj (cbdav, cache_comp);
 
 			status = caldav_server_put_object (cbdav, &caldav_object);
-			e_cal_component_set_href (cache_comp, caldav_object.href);
-			e_cal_component_set_etag (cache_comp, caldav_object.etag);
+			if (status == GNOME_Evolution_Calendar_Success) {
+				e_cal_component_set_href (cache_comp, caldav_object.href);
+				e_cal_component_set_etag (cache_comp, caldav_object.etag);
+			}
 		} else
 			status = caldav_server_delete_object (cbdav, &caldav_object);
 
@@ -2341,12 +2339,13 @@
 	char                     *rid;
 	char                     *ostr;
 	char                     *oostr;
+	gboolean                  is_declined;
 
 	priv = E_CAL_BACKEND_CALDAV_GET_PRIVATE (cbdav);
 	backend = E_CAL_BACKEND (cbdav);
 
 	/* ctime, mtime */
-	now = icaltime_from_timet (time (NULL), 0);
+	now = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
 	e_cal_component_set_created (ecomp, &now);
 	e_cal_component_set_last_modified (ecomp, &now);
 
@@ -2371,6 +2370,7 @@
 		case ICAL_METHOD_REQUEST:
 		case ICAL_METHOD_REPLY:
 
+		is_declined = e_cal_backend_user_declined (e_cal_component_get_icalcomponent (ecomp));
 		if (online) {
 			CalDAVObject object = { NULL, };
 
@@ -2384,21 +2384,34 @@
 				object.href  = href;
 				object.etag  = etag;
 
-			} else {
+			} else if (!is_declined) {
 				object.href = e_cal_component_gen_href (ecomp);
 			}
 
-			object.cdata = pack_cobj (cbdav, ecomp);
-			status = caldav_server_put_object (cbdav, &object);
-			e_cal_component_set_href (ecomp, object.href);
-			e_cal_component_set_etag (ecomp, object.etag);
-			caldav_object_free (&object, FALSE);
+			if (!is_declined || ccomp) {
+				if (!is_declined) {
+					object.cdata = pack_cobj (cbdav, ecomp);
+					status = caldav_server_put_object (cbdav, &object);
+
+					if (status == GNOME_Evolution_Calendar_Success) {
+						e_cal_component_set_href (ecomp, object.href);
+						e_cal_component_set_etag (ecomp, object.etag);
+					}
+				} else {
+					object.cdata = NULL;
+					status = caldav_server_delete_object (cbdav, &object);
+				}
+				caldav_object_free (&object, FALSE);
+			}
 		} else {
-			ECalComponentSyncState sstate;
+			ECalComponentSyncState sstate = E_CAL_COMPONENT_IN_SYNCH;
 
 			if (ccomp) {
-				sstate = E_CAL_COMPONENT_LOCALLY_MODIFIED;
-			} else {
+				if (!is_declined)
+					sstate = E_CAL_COMPONENT_LOCALLY_MODIFIED;
+				else
+					sstate = E_CAL_COMPONENT_LOCALLY_DELETED;
+			} else if (!is_declined) {
 				sstate = E_CAL_COMPONENT_LOCALLY_CREATED;
 			}
 
@@ -2410,18 +2423,21 @@
 			break;
 		}
 
-		e_cal_backend_cache_put_component (priv->cache, ecomp);
+		if (!is_declined)
+			e_cal_backend_cache_put_component (priv->cache, ecomp);
+		else
+			e_cal_backend_cache_remove_component (priv->cache, uid, rid);
 
 		if (ccomp) {
-
-			e_cal_backend_notify_object_modified (backend,
-							      ostr,
-							      oostr);
-
-		} else {
-
-			e_cal_backend_notify_object_created (backend,
-							     ostr);
+			if (!is_declined)
+				e_cal_backend_notify_object_modified (backend, ostr, oostr);
+			else {
+				id = e_cal_component_get_id (ccomp);
+				e_cal_backend_notify_object_removed (E_CAL_BACKEND (backend), id, oostr, NULL);
+				e_cal_component_free_id (id);
+			}
+		} else if (!is_declined) {
+			e_cal_backend_notify_object_created (backend, ostr);
 		}
 
 		break;
@@ -2469,11 +2485,11 @@
 							      rid);
 
 			id = e_cal_component_get_id (ccomp);
-
 			e_cal_backend_notify_object_removed (E_CAL_BACKEND (backend),
 							     id,
 							     oostr,
 							     ostr);
+			e_cal_component_free_id (id);
 			break;
 
 		default:
@@ -2482,7 +2498,6 @@
 			break;
 	}
 
-	g_object_unref (ecomp);
 	g_free (ostr);
 	g_free (oostr);
 	g_free (rid);
@@ -2533,9 +2548,13 @@
 
 	if (status == GNOME_Evolution_Calendar_Success) {
 		for (iter = timezones; iter; iter = iter->next) {
-			icaltimezone *zone = iter->data;
+			icaltimezone *zone = icaltimezone_new ();
+
+			if (icaltimezone_set_component (zone, iter->data))
+				e_cal_backend_cache_put_timezone (priv->cache, zone);
+			else
+				icalcomponent_free (iter->data);
 
-			e_cal_backend_cache_put_timezone (priv->cache, zone);
 			icaltimezone_free (zone, TRUE);
 		}
 	}
@@ -2690,7 +2709,7 @@
 		return GNOME_Evolution_Calendar_InvalidObject;
 	}
 
-	*object = icalcomponent_as_ical_string (icalcomp);
+	*object = icalcomponent_as_ical_string_r (icalcomp);
 
 	return GNOME_Evolution_Calendar_Success;
 }
@@ -3039,6 +3058,7 @@
 	}
 
 	g_object_unref (priv->session);
+	g_object_unref (priv->proxy);
 
 	g_free (priv->username);
 	g_free (priv->password);
@@ -3080,7 +3100,6 @@
 		(* G_OBJECT_CLASS (parent_class)->finalize) (object);
 }
 
-
 static void
 e_cal_backend_caldav_init (ECalBackendCalDAV *cbdav)
 {
@@ -3088,6 +3107,9 @@
 	priv = E_CAL_BACKEND_CALDAV_GET_PRIVATE (cbdav);
 
 	priv->session = soup_session_sync_new ();
+	priv->proxy = e_proxy_new ();
+	e_proxy_setup_proxy (priv->proxy);
+	g_signal_connect (priv->proxy, "changed", G_CALLBACK (proxy_settings_changed), priv);
 
 	if (G_UNLIKELY (caldav_debug_show (DEBUG_MESSAGE)))
 		caldav_debug_setup (priv->session);

Modified: branches/camel-gobject/calendar/backends/contacts/Makefile.am
==============================================================================
--- branches/camel-gobject/calendar/backends/contacts/Makefile.am	(original)
+++ branches/camel-gobject/calendar/backends/contacts/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -4,10 +4,6 @@
 	-I$(top_builddir)				\
 	-I$(top_srcdir)/calendar			\
 	-I$(top_builddir)/calendar			\
-	-I$(top_srcdir)/calendar/libical/src		\
-	-I$(top_builddir)/calendar/libical/src		\
-	-I$(top_srcdir)/calendar/libical/src/libical	\
-	-I$(top_builddir)/calendar/libical/src/libical	\
 	-I$(top_srcdir)/addressbook			\
 	-I$(top_builddir)/addressbook			\
 	$(EVOLUTION_CALENDAR_CFLAGS)

Modified: branches/camel-gobject/calendar/backends/contacts/e-cal-backend-contacts.c
==============================================================================
--- branches/camel-gobject/calendar/backends/contacts/e-cal-backend-contacts.c	(original)
+++ branches/camel-gobject/calendar/backends/contacts/e-cal-backend-contacts.c	Thu Apr 16 01:23:17 2009
@@ -31,7 +31,9 @@
 #include "e-cal-backend-contacts.h"
 
 #include <glib/gi18n-lib.h>
+#include <gconf/gconf-client.h>
 #include "libedataserver/e-xml-hash-utils.h"
+#include "libedataserver/e-flag.h"
 #include <libecal/e-cal-recur.h>
 #include <libecal/e-cal-util.h>
 #include <libedata-cal/e-cal-backend-util.h>
@@ -43,6 +45,13 @@
 
 static ECalBackendSyncClass *parent_class;
 
+typedef enum
+{
+	CAL_DAYS,
+	CAL_HOURS,
+	CAL_MINUTES
+} CalUnits;
+
 /* Private part of the ECalBackendContacts structure */
 struct _ECalBackendContactsPrivate {
         ESourceList  *addressbook_sources;
@@ -55,6 +64,18 @@
 
 	GHashTable *zones;
 	icaltimezone *default_zone;
+
+	EFlag   *init_done_flag; /* is set, when the init thread gone */
+
+	/* properties related to track alarm settings for this backend */
+	GConfClient *conf_client;
+	guint notifyid1;
+	guint notifyid2;
+	guint notifyid3;
+	guint update_alarms_id;
+	gboolean alarm_enabled;
+	int alarm_interval;
+	CalUnits alarm_units;
 };
 
 typedef struct _BookRecord {
@@ -79,8 +100,8 @@
 static void contacts_changed_cb (EBookView *book_view, const GList *contacts, gpointer user_data);
 static void contacts_added_cb   (EBookView *book_view, const GList *contacts, gpointer user_data);
 static void contacts_removed_cb (EBookView *book_view, const GList *contact_ids, gpointer user_data);
-static ECalBackendSyncStatus
-e_cal_backend_contacts_add_timezone (ECalBackendSync *backend, EDataCal *cal, const char *tzobj);
+static ECalBackendSyncStatus e_cal_backend_contacts_add_timezone (ECalBackendSync *backend, EDataCal *cal, const char *tzobj);
+static void setup_alarm (ECalBackendContacts *cbc, ECalComponent *comp);
 
 /* BookRecord methods */
 static BookRecord *
@@ -91,9 +112,17 @@
         EBookQuery *query;
         EBookView  *book_view;
         BookRecord *br;
+	GError     *error = NULL;
 
 	book = e_book_new (source, NULL);
-        e_book_open (book, TRUE, NULL);
+        if (!book || !e_book_open (book, TRUE, &error) || error) {
+		g_object_unref (book);
+		if (error) {
+			g_warning ("%s: Failed to open book, error: %s", G_STRFUNC, error->message);
+			g_error_free (error);
+		}
+		return NULL;
+	}
 
         /* Create book view */
         fields = g_list_append (fields, (char*)e_contact_field_name (E_CONTACT_FILE_AS));
@@ -142,7 +171,7 @@
         ContactRecord *cr = g_new0 (ContactRecord, 1);
 	char *comp_str;
 
-        cr->cbc = g_object_ref (cbc);
+        cr->cbc = cbc;
         cr->contact = contact;
         cr->comp_birthday = create_birthday (cbc, contact);
         cr->comp_anniversary = create_anniversary (cbc, contact);
@@ -198,7 +227,6 @@
 		g_object_unref (G_OBJECT (cr->comp_anniversary));
 	}
 
-	g_object_unref (cr->cbc);
         g_free (cr);
 }
 
@@ -214,7 +242,7 @@
 {
         ContactRecordCB *cb_data = g_new (ContactRecordCB, 1);
 
-        cb_data->cbc = g_object_ref (cbc);
+        cb_data->cbc = cbc;
         cb_data->sexp = sexp;
         cb_data->result = NULL;
 
@@ -254,6 +282,9 @@
         BookRecord *br = book_record_new (cbc, source);
         const char *uid = e_source_peek_uid (source);
 
+	if (!br)
+		return;
+
         g_hash_table_insert (cbc->priv->addressbooks, g_strdup (uid), br);
 }
 
@@ -403,6 +434,161 @@
 	return ret;
 }
 
+static void
+manage_comp_alarm_update (ECalBackendContacts *cbc, ECalComponent *comp)
+{
+	char *old_comp, *new_comp;
+
+	g_return_if_fail (cbc != NULL);
+	g_return_if_fail (comp != NULL);
+
+	old_comp = e_cal_component_get_as_string (comp);
+	setup_alarm (cbc, comp);
+	new_comp = e_cal_component_get_as_string (comp);
+
+	/* check if component changed and notify if so */
+	if (old_comp && new_comp && !g_str_equal (old_comp, new_comp))
+		e_cal_backend_notify_object_modified (E_CAL_BACKEND (cbc), old_comp, new_comp);
+
+	g_free (old_comp);
+	g_free (new_comp);
+}
+
+static void
+update_alarm_cb (gpointer key, gpointer value, gpointer user_data)
+{
+	ECalBackendContacts *cbc = user_data;
+        ContactRecord   *record = value;
+
+	g_return_if_fail (cbc != NULL);
+	g_return_if_fail (record != NULL);
+
+        if (record->comp_birthday)
+		manage_comp_alarm_update (cbc, record->comp_birthday);
+
+        if (record->comp_anniversary)
+                manage_comp_alarm_update (cbc, record->comp_anniversary);
+}
+
+static gboolean
+update_tracked_alarms_cb (gpointer user_data)
+{
+	ECalBackendContacts *cbc = user_data;
+
+	g_return_val_if_fail (cbc != NULL, FALSE);
+
+	g_hash_table_foreach (cbc->priv->tracked_contacts, update_alarm_cb, cbc);
+	cbc->priv->update_alarms_id = 0;
+
+	return FALSE;
+}
+
+static void
+alarm_config_changed_cb (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data)
+{
+	ECalBackendContacts *cbc = user_data;
+
+	g_return_if_fail (cbc != NULL);
+
+	setup_alarm (cbc, NULL);
+
+	if (!cbc->priv->update_alarms_id)
+		cbc->priv->update_alarms_id = g_idle_add (update_tracked_alarms_cb, cbc);
+}
+
+/* When called with NULL, then just refresh local static variables on setup change from the user. */
+static void
+setup_alarm (ECalBackendContacts *cbc, ECalComponent *comp)
+{
+	ECalComponentAlarm *alarm;
+	ECalComponentAlarmTrigger trigger;
+	ECalComponentText summary;
+
+	g_return_if_fail (cbc != NULL);
+
+	if (!comp || cbc->priv->alarm_interval == -1) {
+		char *str;
+
+		#define BA_CONF_DIR		"/apps/evolution/calendar/other"
+		#define BA_CONF_ENABLED		BA_CONF_DIR "/use_ba_reminder"
+		#define BA_CONF_INTERVAL	BA_CONF_DIR "/ba_reminder_interval"
+		#define BA_CONF_UNITS		BA_CONF_DIR "/ba_reminder_units"
+
+		if (cbc->priv->alarm_interval == -1) {
+			/* initial setup, hook callback for changes too */
+			gconf_client_add_dir (cbc->priv->conf_client, BA_CONF_DIR, GCONF_CLIENT_PRELOAD_NONE, NULL);
+			cbc->priv->notifyid1 = gconf_client_notify_add (cbc->priv->conf_client, BA_CONF_ENABLED,  alarm_config_changed_cb, cbc, NULL, NULL);
+			cbc->priv->notifyid2 = gconf_client_notify_add (cbc->priv->conf_client, BA_CONF_INTERVAL, alarm_config_changed_cb, cbc, NULL, NULL);
+			cbc->priv->notifyid3 = gconf_client_notify_add (cbc->priv->conf_client, BA_CONF_UNITS,    alarm_config_changed_cb, cbc, NULL, NULL);
+		}
+
+		cbc->priv->alarm_enabled = gconf_client_get_bool (cbc->priv->conf_client, BA_CONF_ENABLED, NULL);
+		cbc->priv->alarm_interval = gconf_client_get_int (cbc->priv->conf_client, BA_CONF_INTERVAL, NULL);
+
+		str = gconf_client_get_string (cbc->priv->conf_client, BA_CONF_UNITS, NULL);
+		if (str && !strcmp (str, "days"))
+			cbc->priv->alarm_units = CAL_DAYS;
+		else if (str && !strcmp (str, "hours"))
+			cbc->priv->alarm_units = CAL_HOURS;
+		else
+			cbc->priv->alarm_units = CAL_MINUTES;
+
+		g_free (str);
+
+		if (cbc->priv->alarm_interval <= 0)
+			cbc->priv->alarm_interval = 1;
+
+		if (!comp)
+			return;
+
+		#undef BA_CONF_DIR
+		#undef BA_CONF_ENABLED
+		#undef BA_CONF_INTERVAL
+		#undef BA_CONF_UNITS
+	}
+
+	/* ensure no alarms left */
+	e_cal_component_remove_all_alarms (comp);
+
+	/* do not want alarms, return */
+	if (!cbc->priv->alarm_enabled)
+		return;
+
+	alarm = e_cal_component_alarm_new ();
+	e_cal_component_get_summary (comp, &summary);
+	e_cal_component_alarm_set_description (alarm, &summary);
+	e_cal_component_alarm_set_action (alarm, E_CAL_COMPONENT_ALARM_DISPLAY);
+
+	trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START;
+
+	memset (&trigger.u.rel_duration, 0, sizeof (trigger.u.rel_duration));
+
+	trigger.u.rel_duration.is_neg = TRUE;
+
+	switch (cbc->priv->alarm_units) {
+	case CAL_MINUTES:
+		trigger.u.rel_duration.minutes = cbc->priv->alarm_interval;
+		break;
+
+	case CAL_HOURS:
+		trigger.u.rel_duration.hours = cbc->priv->alarm_interval;
+		break;
+
+	case CAL_DAYS:
+		trigger.u.rel_duration.days = cbc->priv->alarm_interval;
+		break;
+
+	default:
+		g_warning ("%s: wrong units %d\n", G_STRFUNC, cbc->priv->alarm_units);
+		e_cal_component_alarm_free (alarm);
+		return;
+	}
+
+	e_cal_component_alarm_set_trigger (alarm, trigger);
+	e_cal_component_add_alarm (comp, alarm);
+	e_cal_component_alarm_free (alarm);
+}
+
 /* Contact -> Event creator */
 static ECalComponent *
 create_component (ECalBackendContacts *cbc, const char *uid, EContactDate *cdate, const char *summary)
@@ -467,6 +653,9 @@
 	/* Birthdays/anniversaries are shown as free time */
 	e_cal_component_set_transparency (cal_comp, E_CAL_COMPONENT_TRANSP_TRANSPARENT);
 
+	/* setup alarms if required */
+	setup_alarm (cbc, cal_comp);
+
         /* Don't forget to call commit()! */
 	e_cal_component_commit_sequence (cal_comp);
 
@@ -653,7 +842,7 @@
 	icalcomponent_set_dtstart (vfb, icaltime_from_timet_with_zone (start, FALSE, utc_zone));
 	icalcomponent_set_dtend (vfb, icaltime_from_timet_with_zone (end, FALSE, utc_zone));
 
-	calobj = icalcomponent_as_ical_string (vfb);
+	calobj = icalcomponent_as_ical_string_r (vfb);
 	*freebusy = g_list_append (NULL, calobj);
 	icalcomponent_free (vfb);
 
@@ -721,6 +910,32 @@
 	return GNOME_Evolution_Calendar_Success;
 }
 
+static gpointer
+init_sources_cb (ECalBackendContacts *cbc)
+{
+        ECalBackendContactsPrivate *priv;
+        GSList *i;
+
+	g_return_val_if_fail (cbc != NULL, FALSE);
+
+	priv = cbc->priv;
+
+	/* Create address books for existing sources */
+        for (i = e_source_list_peek_groups (priv->addressbook_sources); i; i = i->next) {
+                ESourceGroup *source_group = E_SOURCE_GROUP (i->data);
+
+                source_group_added_cb (priv->addressbook_sources, source_group, cbc);
+        }
+
+        /* Listen for source list changes */
+        g_signal_connect (priv->addressbook_sources, "group_added", G_CALLBACK (source_group_added_cb), cbc);
+        g_signal_connect (priv->addressbook_sources, "group_removed", G_CALLBACK (source_group_removed_cb), cbc);
+
+	e_flag_set (priv->init_done_flag);
+
+	return NULL;
+}
+
 static ECalBackendSyncStatus
 e_cal_backend_contacts_open (ECalBackendSync *backend, EDataCal *cal,
 			     gboolean only_if_exists,
@@ -728,8 +943,7 @@
 {
         ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (backend);
         ECalBackendContactsPrivate *priv = cbc->priv;
-
-        GSList *i;
+	GError *error = NULL;
 
         if (priv->addressbook_loaded)
                 return GNOME_Evolution_Calendar_Success;
@@ -743,18 +957,18 @@
 		g_hash_table_insert (priv->zones, g_strdup (icaltimezone_get_tzid (zone)), zone);
 	}
 
-	/* Create address books for existing sources */
-        for (i = e_source_list_peek_groups (priv->addressbook_sources); i; i = i->next) {
-                ESourceGroup *source_group = E_SOURCE_GROUP (i->data);
+	/* initialize addressbook sources in new thread to make this function quick as much as possible */
+	if (!g_thread_create ((GThreadFunc)init_sources_cb, cbc, FALSE, &error)) {
+		e_flag_set (priv->init_done_flag);
+		g_warning ("%s: Cannot create thread to initialize sources! (%s)", G_STRFUNC, error ? error->message : "Unknown error");
+		if (error)
+			g_error_free (error);
 
-                source_group_added_cb (priv->addressbook_sources, source_group, cbc);
-        }
-
-        /* Listen for source list changes */
-        g_signal_connect (priv->addressbook_sources, "group_added", G_CALLBACK (source_group_added_cb), cbc);
-        g_signal_connect (priv->addressbook_sources, "group_removed", G_CALLBACK (source_group_removed_cb), cbc);
+		return GNOME_Evolution_Calendar_OtherError;
+	}
 
         priv->addressbook_loaded = TRUE;
+
         return GNOME_Evolution_Calendar_Success;
 }
 
@@ -788,7 +1002,7 @@
 	if (!icalcomp)
 		return GNOME_Evolution_Calendar_InvalidObject;
 
-	*object = icalcomponent_as_ical_string (icalcomp);
+	*object = icalcomponent_as_ical_string_r (icalcomp);
 
 	return GNOME_Evolution_Calendar_Success;
 }
@@ -801,7 +1015,7 @@
 	ECalBackendContactsPrivate *priv;
 	icalcomponent *tz_comp;
 	icaltimezone *zone;
-	char *tzid;
+	const char *tzid;
 
 	cbcontacts = (ECalBackendContacts *) backend;
 
@@ -948,6 +1162,17 @@
 	cbc = E_CAL_BACKEND_CONTACTS (object);
 	priv = cbc->priv;
 
+	if (priv->init_done_flag) {
+		e_flag_wait (priv->init_done_flag);
+		e_flag_free (priv->init_done_flag);
+		priv->init_done_flag = NULL;
+	}
+
+	if (priv->update_alarms_id) {
+		g_source_remove (priv->update_alarms_id);
+		priv->update_alarms_id = 0;
+	}
+
 	if (priv->default_zone && priv->default_zone != icaltimezone_get_utc_timezone ()) {
 		icaltimezone_free (priv->default_zone, 1);
 	}
@@ -957,6 +1182,14 @@
 	g_hash_table_destroy (priv->addressbooks);
         g_hash_table_destroy (priv->tracked_contacts);
         g_hash_table_destroy (priv->zones);
+	if (priv->notifyid1)
+		gconf_client_notify_remove (priv->conf_client, priv->notifyid1);
+	if (priv->notifyid2)
+		gconf_client_notify_remove (priv->conf_client, priv->notifyid2);
+	if (priv->notifyid3)
+		gconf_client_notify_remove (priv->conf_client, priv->notifyid3);
+
+	g_object_unref (priv->conf_client);
 
 	g_free (priv);
 	cbc->priv = NULL;
@@ -982,6 +1215,15 @@
 
 	priv->zones = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_zone);
 	priv->default_zone = icaltimezone_get_utc_timezone ();
+	priv->init_done_flag = e_flag_new ();
+	priv->conf_client = gconf_client_get_default ();
+	priv->notifyid1 = 0;
+	priv->notifyid2 = 0;
+	priv->notifyid3 = 0;
+	priv->update_alarms_id = 0;
+	priv->alarm_enabled = FALSE;
+	priv->alarm_interval = -1;
+	priv->alarm_units = CAL_MINUTES;
 
 	cbc->priv = priv;
 

Modified: branches/camel-gobject/calendar/backends/file/Makefile.am
==============================================================================
--- branches/camel-gobject/calendar/backends/file/Makefile.am	(original)
+++ branches/camel-gobject/calendar/backends/file/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -4,10 +4,6 @@
 	-I$(top_builddir)				\
 	-I$(top_srcdir)/calendar			\
 	-I$(top_builddir)/calendar			\
-	-I$(top_srcdir)/calendar/libical/src		\
-	-I$(top_builddir)/calendar/libical/src		\
-	-I$(top_srcdir)/calendar/libical/src/libical	\
-	-I$(top_builddir)/calendar/libical/src/libical	\
 	$(EVOLUTION_CALENDAR_CFLAGS)
 
 extension_LTLIBRARIES = libecalbackendfile.la

Modified: branches/camel-gobject/calendar/backends/file/e-cal-backend-file.c
==============================================================================
--- branches/camel-gobject/calendar/backends/file/e-cal-backend-file.c	(original)
+++ branches/camel-gobject/calendar/backends/file/e-cal-backend-file.c	Thu Apr 16 01:23:17 2009
@@ -171,7 +171,7 @@
 		goto error;
 	}
 
-	buf = icalcomponent_as_ical_string (priv->icalcomp);
+	buf = icalcomponent_as_ical_string_r (priv->icalcomp);
 	g_output_stream_write_all (G_OUTPUT_STREAM (stream), buf, strlen (buf) * sizeof (char), NULL, NULL, &e);
 	g_free (buf);
 
@@ -738,7 +738,7 @@
 		if (!old_icomp)
 			return;
 
-		old_obj_str = icalcomponent_as_ical_string (old_icomp);
+		old_obj_str = icalcomponent_as_ical_string_r (old_icomp);
 		if (!old_obj_str)
 			return;
 
@@ -773,7 +773,7 @@
 		if (!new_icomp)
 			return;
 
-		new_obj_str = icalcomponent_as_ical_string (new_icomp);
+		new_obj_str = icalcomponent_as_ical_string_r (new_icomp);
 		if (!new_obj_str)
 			return;
 
@@ -785,8 +785,8 @@
 		if (!old_icomp || !new_icomp)
 			return;
 
-		old_obj_str = icalcomponent_as_ical_string (old_icomp);
-		new_obj_str = icalcomponent_as_ical_string (new_icomp);
+		old_obj_str = icalcomponent_as_ical_string_r (old_icomp);
+		new_obj_str = icalcomponent_as_ical_string_r (new_icomp);
 		if (!old_obj_str || !new_obj_str)
 			return;
 
@@ -907,6 +907,104 @@
 	return full_uri;
 }
 
+static gboolean
+add_timezone (icalcomponent *icalcomp, icaltimezone *tzone)
+{
+	GSList *to_remove = NULL, *r;
+	icalcomponent *subcomp;
+	icaltimezone *zone;
+	gboolean add = TRUE, have_same = FALSE;
+	const char *tzid;
+	char *cmp;
+
+	g_return_val_if_fail (icalcomp != NULL, FALSE);
+
+	/* it's fine to have passed in NULL tzcomp; for example UTC timezone does this */
+	if (!tzone || !icaltimezone_get_component (tzone))
+		return FALSE;
+
+	tzid = icaltimezone_get_tzid (tzone);
+	if (!tzid)
+		return FALSE;
+
+	cmp = icalcomponent_as_ical_string_r (icaltimezone_get_component (tzone));
+	zone = icaltimezone_new ();
+
+	for (subcomp = icalcomponent_get_first_component (icalcomp, ICAL_VTIMEZONE_COMPONENT);
+	     subcomp;
+	     subcomp = icalcomponent_get_next_component (icalcomp, ICAL_VTIMEZONE_COMPONENT)) {
+		if (!icaltimezone_set_component (zone, icalcomponent_new_clone (subcomp))) {
+			to_remove = g_slist_prepend (to_remove, subcomp);
+		} else if (icaltimezone_get_tzid (zone) && g_str_equal (tzid, icaltimezone_get_tzid (zone))) {
+			/* there is a timezone component with the same tzid already */
+			if (have_same) {
+				to_remove = g_slist_prepend (to_remove, subcomp);
+			} else {
+				char *str = icalcomponent_as_ical_string_r (subcomp);
+
+				/* not the best way how to compare two components, but don't have better */
+				if (str && g_str_equal (cmp, str)) {
+					have_same = TRUE;
+					add = FALSE;
+				} else {
+					to_remove = g_slist_prepend (to_remove, subcomp);
+				}
+
+				g_free (str);
+			}
+		}
+	}
+
+	g_free (cmp);
+
+	for (r = to_remove; r; r = r->next) {
+		icalcomponent_remove_component (icalcomp, r->data);
+	}
+
+	if (g_slist_length (to_remove) > 1) {
+		/* there were more than once tzid as this,
+		   thus check for duplicities for all of timezones there */
+		GHashTable *known = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+		GSList *rem2 = NULL;
+
+		for (subcomp = icalcomponent_get_first_component (icalcomp, ICAL_VTIMEZONE_COMPONENT);
+		     subcomp;
+		     subcomp = icalcomponent_get_next_component (icalcomp, ICAL_VTIMEZONE_COMPONENT)) {
+			if (!icaltimezone_set_component (zone, icalcomponent_new_clone (subcomp))) {
+				rem2 = g_slist_prepend (rem2, subcomp);
+			} else {
+				const char *tzid2 = icaltimezone_get_tzid (zone);
+
+				/* check all but not the one which was checked above */
+				if (tzid2 && !g_str_equal (tzid, tzid2)) {
+					if (g_hash_table_lookup (known, tzid2) == NULL) {
+						/* the first component of this tzid, keep it */
+						g_hash_table_insert (known, g_strdup (tzid2), GINT_TO_POINTER (1));
+					} else {
+						/* it's there already, remove it */
+						rem2 = g_slist_prepend (rem2, subcomp);
+					}
+				}
+			}
+		}
+
+		for (r = rem2; r; r = r->next) {
+			icalcomponent_remove_component (icalcomp, r->data);
+		}
+
+		g_slist_free (rem2);
+		g_hash_table_unref (known);
+	}
+
+	icaltimezone_free (zone, TRUE);
+	g_slist_free (to_remove);
+
+	if (add)
+		icalcomponent_add_component (icalcomp, icalcomponent_new_clone (icaltimezone_get_component (tzone)));
+
+	return add || to_remove != NULL;
+}
+
 /* Open handler for the file backend */
 static ECalBackendSyncStatus
 e_cal_backend_file_open (ECalBackendSync *backend, EDataCal *cal, gboolean only_if_exists,
@@ -945,10 +1043,7 @@
 	}
 
 	if (status == GNOME_Evolution_Calendar_Success) {
-		if (priv->default_zone) {
-			icalcomponent *icalcomp = icaltimezone_get_component (priv->default_zone);
-
-			icalcomponent_add_component (priv->icalcomp, icalcomponent_new_clone (icalcomp));
+		if (priv->default_zone && add_timezone (priv->icalcomp, priv->default_zone)) {
 			save (cbfile);
 		}
 	}
@@ -1145,7 +1240,7 @@
 				return GNOME_Evolution_Calendar_ObjectNotFound;
                         }
 
-			*object = icalcomponent_as_ical_string (icalcomp);
+			*object = icalcomponent_as_ical_string_r (icalcomp);
 
 			icalcomponent_free (icalcomp);
 		}
@@ -1162,7 +1257,7 @@
 			/* add all detached recurrences */
 			g_hash_table_foreach (obj_data->recurrences, (GHFunc) add_detached_recur_to_vcalendar, icalcomp);
 
-			*object = icalcomponent_as_ical_string (icalcomp);
+			*object = icalcomponent_as_ical_string_r (icalcomp);
 
 			icalcomponent_free (icalcomp);
 		} else
@@ -1209,7 +1304,7 @@
 		return GNOME_Evolution_Calendar_InvalidObject;
 	}
 
-	*object = icalcomponent_as_ical_string (icalcomp);
+	*object = icalcomponent_as_ical_string_r (icalcomp);
 
 	g_static_rec_mutex_unlock (&priv->idle_save_rmutex);
 	return GNOME_Evolution_Calendar_Success;
@@ -1556,7 +1651,7 @@
 	if (users == NULL) {
 		if (e_cal_backend_mail_account_get_default (&address, &name)) {
 			vfb = create_user_free_busy (cbfile, address, name, start, end);
-			calobj = icalcomponent_as_ical_string (vfb);
+			calobj = icalcomponent_as_ical_string_r (vfb);
 			*freebusy = g_list_append (*freebusy, calobj);
 			icalcomponent_free (vfb);
 			g_free (address);
@@ -1567,7 +1662,7 @@
 			address = l->data;
 			if (e_cal_backend_mail_account_is_valid (address, &name)) {
 				vfb = create_user_free_busy (cbfile, address, name, start, end);
-				calobj = icalcomponent_as_ical_string (vfb);
+				calobj = icalcomponent_as_ical_string_r (vfb);
 				*freebusy = g_list_append (*freebusy, calobj);
 				icalcomponent_free (vfb);
 				g_free (name);
@@ -1857,7 +1952,7 @@
 	e_cal_component_set_icalcomponent (comp, icalcomp);
 
 	/* Set the created and last modified times on the component */
-	current = icaltime_from_timet (time (NULL), 0);
+	current = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
 	e_cal_component_set_created (comp, &current);
 	e_cal_component_set_last_modified (comp, &current);
 
@@ -1963,7 +2058,7 @@
 	e_cal_component_set_icalcomponent (comp, icalcomp);
 
 	/* Set the last modified time on the component */
-	current = icaltime_from_timet (time (NULL), 0);
+	current = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
 	e_cal_component_set_last_modified (comp, &current);
 
 	/* sanitize the component*/
@@ -2080,62 +2175,7 @@
 		rid = NULL;
 		break;
 	case CALOBJ_MOD_ALL :
-		/* in this case, we blow away all recurrences, and start over
-		   with a clean component */
-
-		if (e_cal_util_component_has_recurrences (icalcomp) && rid && *rid) {
-			icaltimetype start, recur = icaltime_from_string (rid);
-
-			start = icalcomponent_get_dtstart (icalcomp);
-
-			/* This means its a instance generated from master object. So replace
-			    the dates stored dates from the master object */
-			if (!recur.zone)
-				recur.zone = start.zone;
-
-			if (icaltime_compare_date_only (start, recur) == 0) {
-				icaltimetype end = icalcomponent_get_dtend (icalcomp);
-				ECalComponentDateTime m_sdate, m_endate;
-
-				e_cal_component_get_dtstart (obj_data->full_object, &m_sdate);
-				e_cal_component_get_dtend (obj_data->full_object, &m_endate);
-
-				if (icaltime_compare (start, recur) != 0 ||
-				    !m_endate.value ||
-				    icaltime_compare (end, *(m_endate.value)) != 0) {
-
-					m_sdate.value->hour = start.hour;
-					m_sdate.value->minute = start.minute;
-					m_sdate.value->second = start.second;
-
-					if (!m_endate.value) {
-						/* create one if not exists and make same date
-						   and time zone like start */
-						m_endate.value = g_new (struct icaltimetype, 1);
-						*m_endate.value = *m_sdate.value;
-
-						if (m_endate.tzid)
-							g_free ((char*)m_endate.tzid);
-
-						m_endate.tzid = g_strdup (m_sdate.tzid);
-					}
-
-					m_endate.value->hour = end.hour;
-					m_endate.value->minute = end.minute;
-					m_endate.value->second = end.second;
-				}
-
-				e_cal_component_set_dtstart (comp, &m_sdate);
-				e_cal_component_set_dtend (comp, &m_endate);
-				e_cal_component_set_recurid (comp, NULL);
-				e_cal_component_commit_sequence (comp);
-
-				e_cal_component_free_datetime (&m_sdate);
-				e_cal_component_free_datetime (&m_endate);
-			}
-			e_cal_component_set_recurid (comp, NULL);
-			*new_object = e_cal_component_get_as_string (comp);
-		}
+		*new_object = e_cal_component_get_as_string (comp);
 
 		/* Remove the old version */
 		if (old_object)
@@ -2559,6 +2599,7 @@
 		const char *uid;
 		char *object, *old_object, *rid, *new_object;
 		ECalBackendFileObject *obj_data;
+		gboolean is_declined;
 
 		subcomp = l->data;
 
@@ -2567,7 +2608,7 @@
 		e_cal_component_set_icalcomponent (comp, subcomp);
 
 		/* Set the created and last modified times on the component */
-		current = icaltime_from_timet (time (NULL), 0);
+		current = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
 		e_cal_component_set_created (comp, &current);
 		e_cal_component_set_last_modified (comp, &current);
 
@@ -2583,8 +2624,10 @@
 		case ICAL_METHOD_PUBLISH:
 		case ICAL_METHOD_REQUEST:
 		case ICAL_METHOD_REPLY:
+			is_declined = e_cal_backend_user_declined (subcomp);
+
 			/* handle attachments */
-			if (e_cal_component_has_attachments (comp))
+			if (!is_declined && e_cal_component_has_attachments (comp))
 				fetch_attachments (backend, comp);
 			obj_data = g_hash_table_lookup (priv->comp_uid_hash, uid);
 			if (obj_data) {
@@ -2593,13 +2636,27 @@
 					remove_instance (cbfile, obj_data, rid);
 				else
 					remove_component (cbfile, uid, obj_data);
-				add_component (cbfile, comp, FALSE);
+
+				if (!is_declined)
+					add_component (cbfile, comp, FALSE);
 
 				object = e_cal_component_get_as_string (comp);
-				e_cal_backend_notify_object_modified (E_CAL_BACKEND (backend), old_object, object);
+				if (!is_declined)
+					e_cal_backend_notify_object_modified (E_CAL_BACKEND (backend), old_object, object);
+				else {
+					ECalComponentId *id = e_cal_component_get_id (comp);
+
+					if (rid)
+						e_cal_backend_notify_object_removed (E_CAL_BACKEND (backend), id, old_object, object);
+					else
+						e_cal_backend_notify_object_removed (E_CAL_BACKEND (backend), id, old_object, NULL);
+
+					e_cal_component_free_id (id);
+				}
+
 				g_free (object);
 				g_free (old_object);
-			} else {
+			} else if (!is_declined) {
 				add_component (cbfile, comp, FALSE);
 
 				object = e_cal_component_get_as_string (comp);

Modified: branches/camel-gobject/calendar/backends/google/Makefile.am
==============================================================================
--- branches/camel-gobject/calendar/backends/google/Makefile.am	(original)
+++ branches/camel-gobject/calendar/backends/google/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -4,10 +4,6 @@
 	-I$(top_builddir)				\
 	-I$(top_srcdir)/calendar			\
 	-I$(top_builddir)/calendar			\
-	-I$(top_srcdir)/calendar/libical/src		\
-	-I$(top_builddir)/calendar/libical/src		\
-	-I$(top_srcdir)/calendar/libical/src/libical	\
-	-I$(top_builddir)/calendar/libical/src/libical	\
 	-I$(top_srcdir)/servers/google/libgdata		\
 	-I$(top_builddir)/servers/google/libgdata	\
 	-I$(top_srcdir)/servers/google/libgdata-google	\

Modified: branches/camel-gobject/calendar/backends/google/e-cal-backend-google-utils.c
==============================================================================
--- branches/camel-gobject/calendar/backends/google/e-cal-backend-google-utils.c	(original)
+++ branches/camel-gobject/calendar/backends/google/e-cal-backend-google-utils.c	Thu Apr 16 01:23:17 2009
@@ -50,7 +50,7 @@
 #include <libecal/e-cal-time-util.h>
 
 
-#include <libical/icaltimezone.h>
+#include <libical/ical.h>
 #include <libsoup/soup-misc.h>
 
 #include "e-cal-backend-google.h"
@@ -305,7 +305,9 @@
 
 	if (!feed) {
 		g_critical ("%s, Authentication Failed \n ", G_STRLOC);
-		return GNOME_Evolution_Calendar_AuthenticationFailed;
+		if (username || password)
+			return GNOME_Evolution_Calendar_AuthenticationFailed;
+		return GNOME_Evolution_Calendar_AuthenticationRequired;
 	}
 
 	entries = gdata_feed_get_entries (feed);

Modified: branches/camel-gobject/calendar/backends/google/e-cal-backend-google.c
==============================================================================
--- branches/camel-gobject/calendar/backends/google/e-cal-backend-google.c	(original)
+++ branches/camel-gobject/calendar/backends/google/e-cal-backend-google.c	Thu Apr 16 01:23:17 2009
@@ -249,7 +249,7 @@
 	if (!icalcomp)
 		return GNOME_Evolution_Calendar_InvalidObject;
 
-	*object = icalcomponent_as_ical_string (icalcomp);
+	*object = icalcomponent_as_ical_string_r (icalcomp);
 
 	return GNOME_Evolution_Calendar_Success;
 }
@@ -544,8 +544,7 @@
 	GSList *comps = NULL, *l = NULL;
 	icalproperty_method method;
 	icalproperty *icalprop;
-	gboolean instances = TRUE, found = FALSE;
-	icalparameter_partstat pstatus = 0;
+	gboolean instances = TRUE, found = FALSE, is_declined;
 
 	priv = cbgo->priv;
 	icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);	
@@ -561,15 +560,17 @@
 		}
 		icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
 	}
-	
+
+	is_declined = e_cal_backend_user_declined (icalcomp);
+
 	comp = e_cal_component_new ();
 	e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
 	method = icalcomponent_get_method (icalcomp);	
 
 	/* Attachments */
-	if (e_cal_component_has_attachments (comp)) 
+	if (!is_declined && e_cal_component_has_attachments (comp))
 		fetch_attachments (cbgo, comp);
-	 
+
 	/* Sent to Server */
 	item = e_go_item_from_cal_component (cbgo, comp);	
 	entry =	e_go_item_get_entry (item);
@@ -617,7 +618,7 @@
 	for (l = comps; l != NULL; l = l->next) {
 		ECalComponent *component = E_CAL_COMPONENT (l->data);
 
-		if (pstatus == ICAL_PARTSTAT_DECLINED) {
+		if (is_declined) {
 			ECalComponentId *id = e_cal_component_get_id (component);
 
 			if (e_cal_backend_cache_remove_component (priv->cache, id->uid, id->rid)) {
@@ -1317,7 +1318,7 @@
 
 	/* use proxy if necessary */
 	if (e_proxy_require_proxy_for_uri (proxy, priv->uri)) {
-		proxy_uri = e_proxy_peek_uri (proxy);
+		proxy_uri = e_proxy_peek_uri_for (proxy, priv->uri);
 	}
 	gdata_service_set_proxy (GDATA_SERVICE (priv->service), proxy_uri);
 }
@@ -1408,7 +1409,7 @@
  * Return value: The type id of the #ECalBackendGoogle class.
  **/
 GType
-e_cal_backend_google_get_type ()
+e_cal_backend_google_get_type (void)
 {
 	static	GType e_cal_backend_google_type = 0;
 
@@ -1499,6 +1500,7 @@
 e_cal_backend_google_set_uri (ECalBackendGoogle *cbgo, gchar *uri)
 {
 	ECalBackendGooglePrivate *priv;
+	SoupURI *proxy_uri = NULL;
 
 	g_return_if_fail (cbgo != NULL);
 	g_return_if_fail (E_IS_CAL_BACKEND_GOOGLE(cbgo));
@@ -1508,10 +1510,10 @@
 
 	/* use proxy if necessary */
 	if (e_proxy_require_proxy_for_uri (priv->proxy, priv->uri)) {
-		SoupURI *proxy_uri = e_proxy_peek_uri (priv->proxy);
-
-		gdata_service_set_proxy (GDATA_SERVICE (priv->service), proxy_uri);
+		proxy_uri = e_proxy_peek_uri_for (priv->proxy, priv->uri);
 	}
+
+	gdata_service_set_proxy (GDATA_SERVICE (priv->service), proxy_uri);
 }
 
 /**

Modified: branches/camel-gobject/calendar/backends/groupwise/Makefile.am
==============================================================================
--- branches/camel-gobject/calendar/backends/groupwise/Makefile.am	(original)
+++ branches/camel-gobject/calendar/backends/groupwise/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -4,10 +4,6 @@
 	-I$(top_builddir)				\
 	-I$(top_srcdir)/calendar			\
 	-I$(top_builddir)/calendar			\
-	-I$(top_srcdir)/calendar/libical/src		\
-	-I$(top_builddir)/calendar/libical/src		\
-	-I$(top_srcdir)/calendar/libical/src/libical	\
-	-I$(top_builddir)/calendar/libical/src/libical	\
 	-I$(top_srcdir)/servers/groupwise		\
 	-I$(top_builddir)/servers/groupwise		\
 	$(EVOLUTION_CALENDAR_CFLAGS)			\

Modified: branches/camel-gobject/calendar/backends/groupwise/e-cal-backend-groupwise-utils.c
==============================================================================
--- branches/camel-gobject/calendar/backends/groupwise/e-cal-backend-groupwise-utils.c	(original)
+++ branches/camel-gobject/calendar/backends/groupwise/e-cal-backend-groupwise-utils.c	Thu Apr 16 01:23:17 2009
@@ -59,6 +59,16 @@
 	return TRUE;
 }
 
+static gboolean
+get_recur_count (ECalComponent *comp, time_t instance_start, time_t instance_end, gpointer data)
+{
+	int *count = (int *) data;
+
+	*count = *count + 1;
+
+	return TRUE;
+}
+
 static icaltimezone *
 resolve_tzid_cb (const char *tzid, gpointer data)
 {
@@ -176,7 +186,7 @@
 				icaltime_adjust (&temp, i, 0, 0, 0);
 				icaltime_set_timezone (&temp, default_zone);
 				temp = icaltime_convert_to_zone (temp, utc);
-				value = icaltime_as_ical_string (temp);
+				value = icaltime_as_ical_string_r (temp);
 				e_gw_item_set_reply_within (item, value);
 				g_free (value);
 			}
@@ -187,7 +197,7 @@
 			icaltime_adjust (&temp, atoi (x_val), 0, 0, 0);
 			icaltime_set_timezone (&temp, default_zone);
 			temp = icaltime_convert_to_zone (temp, utc);
-			expire = icaltime_as_ical_string (temp);
+			expire = icaltime_as_ical_string_r (temp);
 			e_gw_item_set_expires (item, expire);
 			g_free (expire);
 
@@ -197,7 +207,7 @@
 			temp = icaltime_from_string (x_val);
 			icaltime_set_timezone (&temp, default_zone);
 			temp = icaltime_convert_to_zone (temp, utc);
-			delay = icaltime_as_ical_string (temp);
+			delay = icaltime_as_ical_string_r (temp);
 			e_gw_item_set_delay_until (item, delay);
 			g_free (delay);
 
@@ -326,8 +336,6 @@
 			continue;
 		}
 
-		g_free (attach_filename_full);
-
 		attach_item = g_new0 (EGwItemAttachment, 1);
 		/* FIXME the member does not follow the naming convention.
 		 * Should be fixed in e-gw-item*/
@@ -340,6 +348,7 @@
 		attach_item->data = encoded_data;
 		attach_item->size = strlen (encoded_data);
 
+		g_free (attach_filename_full);
 		g_free (file_contents);
 		attach_list = g_slist_append (attach_list, attach_item);
 	}
@@ -474,6 +483,24 @@
 
 }
 
+static int 
+get_actual_count (ECalComponent *comp, ECalBackendGroupwise *cbgw)
+{
+	int count = 0;	
+	icaltimezone *dzone, *utc;
+
+
+	dzone = e_cal_backend_groupwise_get_default_zone (cbgw);
+	utc = icaltimezone_get_utc_timezone ();
+
+	if (dzone)
+		e_cal_recur_generate_instances (comp, -1, -1,get_recur_count, &count, resolve_tzid_cb, NULL, (icaltimezone *) dzone);
+	else
+		e_cal_recur_generate_instances (comp, -1, -1,get_recur_count, &count, resolve_tzid_cb, NULL, utc);
+
+	return count;
+}
+
 static void
 set_rrule_from_comp (ECalComponent *comp, EGwItem *item, ECalBackendGroupwise *cbgw)
 {
@@ -506,10 +533,14 @@
 			default:
 				break;
 		}
-		if (ical_recur->count != 0)
-			item_rrule->count = ical_recur->count;
-		else
-			item_rrule->until =  icaltime_as_ical_string (ical_recur->until);
+
+		if (ical_recur->count != 0) {
+			if (ical_recur->freq != ICAL_DAILY_RECURRENCE)
+				item_rrule->count = get_actual_count (comp, cbgw);
+			else
+				item_rrule->count = ical_recur->count;
+		} else
+			item_rrule->until =  icaltime_as_ical_string_r (ical_recur->until);
 
 		item_rrule->interval = ical_recur->interval;
 
@@ -522,6 +553,8 @@
 			item_rrule->by_year_day[i] = ical_recur->by_year_day[i];
 		for (i = 0; i < ICAL_BY_MONTH_SIZE; i++)
 			item_rrule->by_month[i] = ical_recur->by_month[i];
+		for (i = 0; i < ICAL_BY_SETPOS_SIZE; i++)
+			item_rrule->by_setpos[i] = ical_recur->by_set_pos[i];
 
 		e_gw_item_set_rrule (item, item_rrule);
 
@@ -541,7 +574,7 @@
 					if (!icaltime_get_timezone (*(dt->value)))
 						icaltime_set_timezone (dt->value, default_zone ? default_zone : utc);
 					itt_utc = icaltime_convert_to_zone (*dt->value, utc);
-					item_exdate_list = g_slist_append (item_exdate_list, icaltime_as_ical_string (itt_utc));
+					item_exdate_list = g_slist_append (item_exdate_list, icaltime_as_ical_string_r (itt_utc));
 				}
 			}
 			e_gw_item_set_exdate_list (item, item_exdate_list);
@@ -612,7 +645,7 @@
 			if (!icaltime_get_timezone (*dt.value))
 				icaltime_set_timezone (dt.value, default_zone ? default_zone : utc);
 			itt_utc = icaltime_convert_to_zone (*dt.value, utc);
-			value = icaltime_as_ical_string (itt_utc);
+			value = icaltime_as_ical_string_r (itt_utc);
 			e_gw_item_set_end_date (item, value);
 			g_free (value);
 			e_cal_component_free_datetime (&dt);
@@ -629,7 +662,7 @@
 			if (!icaltime_get_timezone (*dt.value))
 				icaltime_set_timezone (dt.value, default_zone);
 			itt_utc = icaltime_convert_to_zone (*dt.value, utc);
-			value = icaltime_as_ical_string (itt_utc);
+			value = icaltime_as_ical_string_r (itt_utc);
 			e_gw_item_set_due_date (item,  value);
 			g_free (value);
 			e_cal_component_free_datetime (&dt);
@@ -707,7 +740,7 @@
 		if (!icaltime_get_timezone (*dt.value))
 			icaltime_set_timezone (dt.value, default_zone);
 		itt_utc = icaltime_convert_to_zone (*dt.value, utc);
-		value = icaltime_as_ical_string (itt_utc);
+		value = icaltime_as_ical_string_r (itt_utc);
 		e_gw_item_set_start_date (item, value);
 		g_free (value);
 	} else if (e_gw_item_get_item_type (item) == E_GW_ITEM_TYPE_APPOINTMENT) {
@@ -730,14 +763,14 @@
 		if (!icaltime_get_timezone (*dt.value))
 			icaltime_set_timezone (dt.value, default_zone);
 		itt_utc = icaltime_convert_to_zone (*dt.value, utc);
-		value = icaltime_as_ical_string (itt_utc);
+		value = icaltime_as_ical_string_r (itt_utc);
 		e_gw_item_set_creation_date (item, value);
 		g_free (value);
 	} else {
 		struct icaltimetype itt;
 
 		e_cal_component_get_dtstamp (comp, &itt);
-		value = icaltime_as_ical_string (itt);
+		value = icaltime_as_ical_string_r (itt);
 		e_gw_item_set_creation_date (item, value);
 		g_free (value);
 	}
@@ -1086,18 +1119,13 @@
 	t = e_gw_item_get_creation_date (item);
 	if (t) {
 		itt_utc = icaltime_from_string (t);
-		if (!icaltime_get_timezone (itt_utc))
-			icaltime_set_timezone (&itt_utc, icaltimezone_get_utc_timezone());
-		if (default_zone) {
-			itt = icaltime_convert_to_zone (itt_utc, default_zone);
-			icaltime_set_timezone (&itt, default_zone);
-			e_cal_component_set_created (comp, &itt);
-			e_cal_component_set_dtstamp (comp, &itt);
 
-		} else {
-			e_cal_component_set_created (comp, &itt_utc);
-			e_cal_component_set_dtstamp (comp, &itt_utc);
-		}
+		/* RFC 2445 - CREATED/DTSTAMP/LAST-MODIFIED always in UTC */
+		icaltimezone_convert_time (&itt_utc, (icaltimezone*) icaltime_get_timezone (itt_utc), icaltimezone_get_utc_timezone ());
+		icaltime_set_timezone (&itt_utc, icaltimezone_get_utc_timezone ());
+
+		e_cal_component_set_created (comp, &itt_utc);
+		e_cal_component_set_dtstamp (comp, &itt_utc);
 	}
 
 	/* categories */
@@ -1625,10 +1653,10 @@
 
 	utc = icaltimezone_get_utc_timezone ();
 	icaltime = icaltime_from_timet_with_zone (start, FALSE, utc);
-	start_date = icaltime_as_ical_string (icaltime);
+	start_date = icaltime_as_ical_string_r (icaltime);
 
 	icaltime = icaltime_from_timet_with_zone (end, FALSE, utc);
-	end_date = icaltime_as_ical_string (icaltime);
+	end_date = icaltime_as_ical_string_r (icaltime);
 
         e_gw_message_write_string_parameter (msg, "startDate", NULL, start_date);
         e_gw_message_write_string_parameter (msg, "endDate", NULL, end_date);
@@ -1785,6 +1813,7 @@
 		ECalComponentAttendee attendee;
 		GSList *attendee_list = NULL;
 		icalcomponent *icalcomp = NULL;
+		icaltimetype start_time, end_time;
 
 		tmp = soup_soap_parameter_get_first_child_by_name (subparam, "email");
 		if (tmp)
@@ -1801,6 +1830,11 @@
 		e_cal_component_commit_sequence (comp);
 		icalcomp = e_cal_component_get_icalcomponent (comp);
 
+		start_time = icaltime_from_timet_with_zone (start, 0, default_zone ? default_zone : NULL);
+		end_time = icaltime_from_timet_with_zone (end, 0, default_zone ? default_zone : NULL);
+		icalcomponent_set_dtstart (icalcomp, start_time);
+		icalcomponent_set_dtend (icalcomp, end_time);
+
 		memset (&attendee, 0, sizeof (ECalComponentAttendee));
 		if (name)
 			attendee.cn = name;
@@ -1829,7 +1863,24 @@
 			return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
 		}
 
-		for (subparam_block = soup_soap_parameter_get_first_child_by_name (param_blocks, "block");
+		subparam_block = soup_soap_parameter_get_first_child_by_name (param_blocks, "block");
+		/* The GW server only returns 'Busy', 'OOF' and 'Tentative' periods. The rest are 
+		 * assumed to be 'Free' periods. In case of an attendee having only 'Free' periods, 
+		 * ensure to send a block to the frontend saying so. */
+		if (subparam_block == NULL) {
+			struct icalperiodtype ipt;
+			icaltimetype sitt, eitt;
+			icalproperty *icalprop;
+			sitt = icaltime_from_timet_with_zone (start, 0, default_zone ? default_zone : NULL);
+			ipt.start = sitt;
+			eitt = icaltime_from_timet_with_zone (end, 0, default_zone ? default_zone : NULL);
+			ipt.end = eitt;
+			icalprop = icalproperty_new_freebusy (ipt);
+			icalproperty_set_parameter_from_string (icalprop, "FBTYPE", "FREE");
+			icalcomponent_add_property(icalcomp, icalprop);
+		}
+
+		for (;
 		     subparam_block != NULL;
 		     subparam_block = soup_soap_parameter_get_next_child_by_name (subparam_block, "block")) {
 
@@ -1846,7 +1897,7 @@
 			if (tmp) {
 				start = soup_soap_parameter_get_string_value (tmp);
 				t = e_gw_connection_get_date_from_string (start);
-				itt = icaltime_from_timet_with_zone (t, 0, default_zone ? default_zone : NULL);
+				itt = icaltime_from_timet_with_zone (t, 0, icaltimezone_get_utc_timezone ());
 				ipt.start = itt;
 				g_free (start);
 			}
@@ -1855,7 +1906,7 @@
 			if (tmp) {
 				end = soup_soap_parameter_get_string_value (tmp);
 				t = e_gw_connection_get_date_from_string (end);
-				itt = icaltime_from_timet_with_zone (t, 0, default_zone ? default_zone : NULL);
+				itt = icaltime_from_timet_with_zone (t, 0, icaltimezone_get_utc_timezone ());
 				ipt.end = itt;
 				g_free (end);
 			}
@@ -2088,7 +2139,7 @@
 			char *value;
 			tt = icaltime_today ();
 			icaltime_adjust (&tt, gopts->delay_until, 0, 0, 0);
-			value = icaltime_as_ical_string (tt);
+			value = icaltime_as_ical_string_r (tt);
 		} else
 			value = g_strdup ("none");
 		e_source_set_property (source, "delay-delivery", value);

Modified: branches/camel-gobject/calendar/backends/groupwise/e-cal-backend-groupwise.c
==============================================================================
--- branches/camel-gobject/calendar/backends/groupwise/e-cal-backend-groupwise.c	(original)
+++ branches/camel-gobject/calendar/backends/groupwise/e-cal-backend-groupwise.c	Thu Apr 16 01:23:17 2009
@@ -545,7 +545,7 @@
 			if (!tt.is_date) {
 				tt = icaltime_convert_to_zone (tt, priv->default_zone);
 				icaltime_set_timezone (&tt, priv->default_zone);
-				rid = icaltime_as_ical_string (tt);
+				rid = icaltime_as_ical_string_r (tt);
 				temp = rid;
 			} else
 				rid = calid->ical_id;
@@ -1574,7 +1574,7 @@
         if (!icalcomp)
                 return GNOME_Evolution_Calendar_InvalidObject;
 
-        *object = icalcomponent_as_ical_string (icalcomp);
+        *object = icalcomponent_as_ical_string_r (icalcomp);
 
         return GNOME_Evolution_Calendar_Success;
 }
@@ -2581,8 +2581,12 @@
 				e_cal_component_free_id (id);
 			} else {
 				char *comp_str = NULL;
+				ECalComponentTransparency transp;
 
 				change_status (component, pstatus, e_gw_connection_get_user_email (priv->cnc));
+				e_cal_component_get_transparency (comp, &transp);
+				e_cal_component_set_transparency (component, transp);
+				
 				e_cal_backend_cache_put_component (priv->cache, component);
 				comp_str = e_cal_component_get_as_string (component);
 

Modified: branches/camel-gobject/calendar/backends/http/Makefile.am
==============================================================================
--- branches/camel-gobject/calendar/backends/http/Makefile.am	(original)
+++ branches/camel-gobject/calendar/backends/http/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -4,10 +4,6 @@
 	-I$(top_builddir)				\
 	-I$(top_srcdir)/calendar			\
 	-I$(top_builddir)/calendar			\
-	-I$(top_srcdir)/calendar/libical/src		\
-	-I$(top_builddir)/calendar/libical/src		\
-	-I$(top_srcdir)/calendar/libical/src/libical	\
-	-I$(top_builddir)/calendar/libical/src/libical	\
 	$(EVOLUTION_CALENDAR_CFLAGS)			\
 	$(SOUP_CFLAGS)
 

Modified: branches/camel-gobject/calendar/backends/http/e-cal-backend-http.c
==============================================================================
--- branches/camel-gobject/calendar/backends/http/e-cal-backend-http.c	(original)
+++ branches/camel-gobject/calendar/backends/http/e-cal-backend-http.c	Thu Apr 16 01:23:17 2009
@@ -27,6 +27,7 @@
 #include <gconf/gconf-client.h>
 #include <glib/gi18n-lib.h>
 #include "libedataserver/e-xml-hash-utils.h"
+#include "libedataserver/e-proxy.h"
 #include <libecal/e-cal-recur.h>
 #include <libecal/e-cal-util.h>
 #include <libecal/e-cal-time-util.h>
@@ -338,14 +339,14 @@
 				e_cal_component_get_uid (comp, &uid);
 				/* middle (void*) cast only because of 'dereferencing type-punned pointer will break strict-aliasing rules' */
 				if (g_hash_table_lookup_extended (old_cache, uid, (void **)(void*)&orig_key, (void **)(void*)&orig_value)) {
-					obj = icalcomponent_as_ical_string (subcomp);
+					obj = icalcomponent_as_ical_string_r (subcomp);
 					e_cal_backend_notify_object_modified (E_CAL_BACKEND (cbhttp),
 									      orig_value,
 									      obj);
 					g_free (obj);
 					g_hash_table_remove (old_cache, uid);
 				} else {
-					obj = icalcomponent_as_ical_string (subcomp);
+					obj = icalcomponent_as_ical_string_r (subcomp);
 					e_cal_backend_notify_object_created (E_CAL_BACKEND (cbhttp),
 									     obj);
 					g_free (obj);
@@ -424,9 +425,18 @@
 
 	priv->is_loading = TRUE;
 
+	if (priv->uri == NULL) {
+		ESource *source = e_cal_backend_get_source (E_CAL_BACKEND (cbhttp));
+		const char *secure_prop = e_source_get_property (source, "use_ssl");
+
+		priv->uri = webcal_to_http_method (e_cal_backend_get_uri (E_CAL_BACKEND (cbhttp)),
+		                                   (secure_prop && g_str_equal(secure_prop, "1")));
+	}
+
 	/* create the Soup session if not already created */
 	if (!priv->soup_session) {
-		GConfClient *conf_client;
+		EProxy *proxy;
+		SoupURI *proxy_uri = NULL;
 
 		priv->soup_session = soup_session_async_new ();
 
@@ -434,51 +444,15 @@
 				  G_CALLBACK (soup_authenticate), cbhttp);
 
 		/* set the HTTP proxy, if configuration is set to do so */
-		conf_client = gconf_client_get_default ();
-		if (gconf_client_get_bool (conf_client, "/system/http_proxy/use_http_proxy", NULL)) {
-			char *server, *proxy_uri;
-			int port;
-
-			server = gconf_client_get_string (conf_client, "/system/http_proxy/host", NULL);
-			port = gconf_client_get_int (conf_client, "/system/http_proxy/port", NULL);
-
-			if (server && server[0]) {
-				SoupURI *suri;
-				if (gconf_client_get_bool (conf_client, "/system/http_proxy/use_authentication", NULL)) {
-					char *user, *password;
-
-					user = gconf_client_get_string (conf_client,
-									"/system/http_proxy/authentication_user",
-									NULL);
-					password = gconf_client_get_string (conf_client,
-									    "/system/http_proxy/authentication_password",
-									    NULL);
-
-					proxy_uri = g_strdup_printf("http://%s:%s %s:%d", user, password, server, port);
-
-					g_free (user);
-					g_free (password);
-				} else
-					proxy_uri = g_strdup_printf ("http://%s:%d";, server, port);
-
-				suri = soup_uri_new (proxy_uri);
-				g_object_set (G_OBJECT (priv->soup_session), SOUP_SESSION_PROXY_URI, suri, NULL);
-
-				soup_uri_free (suri);
-				g_free (server);
-				g_free (proxy_uri);
-			}
+		proxy = e_proxy_new ();
+		e_proxy_setup_proxy (proxy);
+		if (e_proxy_require_proxy_for_uri (proxy, priv->uri)) {
+			proxy_uri = e_proxy_peek_uri_for (proxy, priv->uri);
 		}
 
-		g_object_unref (conf_client);
-	}
-
-	if (priv->uri == NULL) {
-		ESource *source = e_cal_backend_get_source (E_CAL_BACKEND (cbhttp));
-		const char *secure_prop = e_source_get_property (source, "use_ssl");
+		g_object_set (G_OBJECT (priv->soup_session), SOUP_SESSION_PROXY_URI, proxy_uri, NULL);
 
-		priv->uri = webcal_to_http_method (e_cal_backend_get_uri (E_CAL_BACKEND (cbhttp)),
-		                                   (secure_prop && g_str_equal(secure_prop, "1")));
+		g_object_unref (proxy);
 	}
 
 	/* create message to be sent to server */
@@ -711,7 +685,7 @@
 
 	kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
 	icalcomp = e_cal_util_new_component (kind);
-	*object = icalcomponent_as_ical_string (icalcomp);
+	*object = icalcomponent_as_ical_string_r (icalcomp);
 	icalcomponent_free (icalcomp);
 
 	return GNOME_Evolution_Calendar_Success;
@@ -769,7 +743,7 @@
 	if (!icalcomp)
 		return GNOME_Evolution_Calendar_InvalidObject;
 
-	*object = icalcomponent_as_ical_string (icalcomp);
+	*object = icalcomponent_as_ical_string_r (icalcomp);
 
 	return GNOME_Evolution_Calendar_Success;
 }
@@ -1070,7 +1044,7 @@
         if (users == NULL) {
 		if (e_cal_backend_mail_account_get_default (&address, &name)) {
                         vfb = create_user_free_busy (cbhttp, address, name, start, end);
-                        calobj = icalcomponent_as_ical_string (vfb);
+                        calobj = icalcomponent_as_ical_string_r (vfb);
                         *freebusy = g_list_append (*freebusy, calobj);
                         icalcomponent_free (vfb);
                         g_free (address);
@@ -1082,7 +1056,7 @@
                         address = l->data;
                         if (e_cal_backend_mail_account_is_valid (address, &name)) {
                                 vfb = create_user_free_busy (cbhttp, address, name, start, end);
-                                calobj = icalcomponent_as_ical_string (vfb);
+                                calobj = icalcomponent_as_ical_string_r (vfb);
                                 *freebusy = g_list_append (*freebusy, calobj);
                                 icalcomponent_free (vfb);
                                 g_free (name);

Modified: branches/camel-gobject/calendar/backends/weather/Makefile.am
==============================================================================
--- branches/camel-gobject/calendar/backends/weather/Makefile.am	(original)
+++ branches/camel-gobject/calendar/backends/weather/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -4,10 +4,6 @@
 	-I$(top_builddir)				\
 	-I$(top_srcdir)/calendar			\
 	-I$(top_builddir)/calendar			\
-	-I$(top_srcdir)/calendar/libical/src		\
-	-I$(top_builddir)/calendar/libical/src		\
-	-I$(top_srcdir)/calendar/libical/src/libical	\
-	-I$(top_builddir)/calendar/libical/src/libical	\
 	-I$(top_srcdir)/addressbook			\
 	-I$(top_builddir)/addressbook			\
 	-DE_DATA_SERVER_PREFIX=\"$(prefix)\"		\

Modified: branches/camel-gobject/calendar/backends/weather/e-cal-backend-weather.c
==============================================================================
--- branches/camel-gobject/calendar/backends/weather/e-cal-backend-weather.c	(original)
+++ branches/camel-gobject/calendar/backends/weather/e-cal-backend-weather.c	Thu Apr 16 01:23:17 2009
@@ -159,7 +159,7 @@
 		icomp = e_cal_component_get_icalcomponent (E_CAL_COMPONENT (l->data));
 		id = e_cal_component_get_id (E_CAL_COMPONENT (l->data));
 
-		obj = icalcomponent_as_ical_string (icomp);
+		obj = icalcomponent_as_ical_string_r (icomp);
 		e_cal_backend_notify_object_removed (E_CAL_BACKEND (cbw),
 			id,
 			obj,
@@ -178,7 +178,7 @@
 
 		e_cal_backend_cache_put_component (priv->cache, comp);
 		icomp = e_cal_component_get_icalcomponent (comp);
-		obj = icalcomponent_as_ical_string (icomp);
+		obj = icalcomponent_as_ical_string_r (icomp);
 		e_cal_backend_notify_object_created (E_CAL_BACKEND (cbw), obj);
 		g_free (obj);
 
@@ -195,7 +195,7 @@
 					if (comp) {
 						e_cal_backend_cache_put_component (priv->cache, comp);
 						icomp = e_cal_component_get_icalcomponent (comp);
-						obj = icalcomponent_as_ical_string (icomp);
+						obj = icalcomponent_as_ical_string_r (icomp);
 						e_cal_backend_notify_object_created (E_CAL_BACKEND (cbw), obj);
 						g_free (obj);
 					}
@@ -606,7 +606,7 @@
 	if (!icalcomp)
 		return GNOME_Evolution_Calendar_InvalidObject;
 
-	*object = icalcomponent_as_ical_string (icalcomp);
+	*object = icalcomponent_as_ical_string_r (icalcomp);
 
 	return GNOME_Evolution_Calendar_Success;
 }
@@ -688,7 +688,7 @@
 	icalcomponent_set_dtstart (vfb, icaltime_from_timet_with_zone (start, FALSE, utc_zone));
 	icalcomponent_set_dtend (vfb, icaltime_from_timet_with_zone (end, FALSE, utc_zone));
 
-	calobj = icalcomponent_as_ical_string (vfb);
+	calobj = icalcomponent_as_ical_string_r (vfb);
 	*freebusy = g_list_append (NULL, calobj);
 	icalcomponent_free (vfb);
 

Modified: branches/camel-gobject/calendar/libecal/Makefile.am
==============================================================================
--- branches/camel-gobject/calendar/libecal/Makefile.am	(original)
+++ branches/camel-gobject/calendar/libecal/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -6,10 +6,7 @@
 	-I.. 						\
 	-I$(top_builddir)				\
 	-I$(top_builddir)/calendar/libecal		\
-	-I$(top_srcdir)/calendar/libical/src		\
-	-I$(top_builddir)/calendar/libical/src		\
-	-I$(top_srcdir)/calendar/libical/src/libical	\
-	-I$(top_builddir)/calendar/libical/src/libical	\
+	$(LIBICAL_CFLAGS)				\
 	$(EVOLUTION_CALENDAR_CFLAGS)
 
 # The corba stubs and skels
@@ -55,14 +52,12 @@
 	e-cal-view-listener.h	\
 	e-cal-view-private.h
 
-libecal_1_2_la_LIBADD =									\
-	$(top_builddir)/calendar/libical/src/libical/libical-evolution.la		\
-	$(top_builddir)/calendar/libical/src/libicalvcal/libicalvcal-evolution.la	\
-	$(top_builddir)/calendar/libical/src/libicalss/libicalss-evolution.la		\
-	$(top_builddir)/libedataserver/libedataserver-1.2.la \
+libecal_1_2_la_LIBADD = 					\
+	$(top_builddir)/libedataserver/libedataserver-1.2.la 	\
+	$(LIBICAL_LIBS)						\
 	$(EVOLUTION_CALENDAR_LIBS)
 
-libecal_1_2_la_LDFLAGS = 								\
+libecal_1_2_la_LDFLAGS = 					\
 	-version-info $(LIBECAL_CURRENT):$(LIBECAL_REVISION):$(LIBECAL_AGE) $(NO_UNDEFINED)
 
 libecalincludedir = $(privincludedir)/libecal

Modified: branches/camel-gobject/calendar/libecal/e-cal-check-timezones.c
==============================================================================
--- branches/camel-gobject/calendar/libecal/e-cal-check-timezones.c	(original)
+++ branches/camel-gobject/calendar/libecal/e-cal-check-timezones.c	Thu Apr 16 01:23:17 2009
@@ -17,19 +17,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-#ifndef HANDLE_LIBICAL_MEMORY
-# define HANDLE_LIBICAL_MEMORY 1
-#endif
 #include <libical/ical.h>
 
-#ifdef LIBICAL_MEMFIXES
-/* avoid dependency on icalstrdup.h, works when compiling as part of EDS >= 2.22 */
-# define ical_strdup(_x) (_x)
-#else
-/* use icalstrdup.h to get runtime detection of memory fix patch */
-# include "libical/icalstrdup.h"
-#endif
-
 #include "e-cal-check-timezones.h"
 #include <libecal/e-cal.h>
 #include <string.h>
@@ -298,7 +287,7 @@
                 } else {
                     int counter;
 
-                    zonestr = ical_strdup(icalcomponent_as_ical_string(subcomp));
+                    zonestr = icalcomponent_as_ical_string_r(subcomp);
 
                     /* check for collisions with existing timezones */
                     for (counter = 0;
@@ -321,7 +310,7 @@
                             }
                         }
                         g_free(buffer);
-                        buffer = ical_strdup(icalcomponent_as_ical_string(icaltimezone_get_component(existing_zone)));
+                        buffer = icalcomponent_as_ical_string_r(icaltimezone_get_component(existing_zone));
 
                         if (counter) {
                             char *fulltzid = g_strdup_printf("TZID:%s", value);

Modified: branches/camel-gobject/calendar/libecal/e-cal-component.c
==============================================================================
--- branches/camel-gobject/calendar/libecal/e-cal-component.c	(original)
+++ branches/camel-gobject/calendar/libecal/e-cal-component.c	Thu Apr 16 01:23:17 2009
@@ -1263,7 +1263,7 @@
 	/* Ensure that the user has committed the new SEQUENCE */
 	g_return_val_if_fail (priv->need_sequence_inc == FALSE, NULL);
 
-	str = icalcomponent_as_ical_string (priv->icalcomp);
+	str = icalcomponent_as_ical_string_r (priv->icalcomp);
 
 	return str;
 }
@@ -3588,7 +3588,7 @@
         e_cal_component_free_range (&range);
 
         return icaltime_is_valid_time (tt) && !icaltime_is_null_time (tt) ?
-                icaltime_as_ical_string (tt) : g_strdup ("0");
+                icaltime_as_ical_string_r (tt) : g_strdup ("0");
 }
 
 /**

Modified: branches/camel-gobject/calendar/libecal/e-cal-recur.c
==============================================================================
--- branches/camel-gobject/calendar/libecal/e-cal-recur.c	(original)
+++ branches/camel-gobject/calendar/libecal/e-cal-recur.c	Thu Apr 16 01:23:17 2009
@@ -285,7 +285,8 @@
 
 
 static gboolean cal_object_get_rdate_end	(CalObjTime	*occ,
-						 GArray		*rdate_periods);
+						 GArray		*rdate_periods,
+						 icaltimezone	*zone);
 static void	cal_object_compute_duration	(CalObjTime	*start,
 						 CalObjTime	*end,
 						 gint		*days,
@@ -1203,18 +1204,17 @@
 	for (elem = rdates; elem; elem = elem->next) {
 		ECalComponentPeriod *p;
 		CalObjRecurrenceDate rdate;
+		struct icaltimetype tt;
 
 		p = elem->data;
 
-		/* FIXME: We currently assume RDATEs are in the same timezone
-		   as DTSTART. We should get the RDATE timezone and convert
-		   to the DTSTART timezone first. */
-		cotime.year     = p->start.year;
-		cotime.month    = p->start.month - 1;
-		cotime.day      = p->start.day;
-		cotime.hour     = p->start.hour;
-		cotime.minute   = p->start.minute;
-		cotime.second   = p->start.second;
+		tt = icaltime_convert_to_zone(p->start, zone);
+		cotime.year     = tt.year;
+		cotime.month    = tt.month - 1;
+		cotime.day      = tt.day;
+		cotime.hour     = tt.hour;
+		cotime.minute   = tt.minute;
+		cotime.second   = tt.second;
 		cotime.flags    = FALSE;
 
 		/* If the rdate is after the current chunk we set finished
@@ -1345,7 +1345,7 @@
 			/* If it is an RDATE, we see if the end date or
 			   duration was set. If not, we use the same duration
 			   as the original occurrence. */
-			if (!cal_object_get_rdate_end (occ, rdate_periods)) {
+			if (!cal_object_get_rdate_end (occ, rdate_periods, zone)) {
 				cal_obj_time_add_days (occ, duration_days);
 				cal_obj_time_add_seconds (occ,
 							  duration_seconds);
@@ -1400,7 +1400,8 @@
    is set it returns FALSE and the default duration will be used. */
 static gboolean
 cal_object_get_rdate_end	(CalObjTime	*occ,
-				 GArray		*rdate_periods)
+				 GArray		*rdate_periods,
+				 icaltimezone	*zone)
 {
 	CalObjRecurrenceDate *rdate = NULL;
 	ECalComponentPeriod *p;
@@ -1433,15 +1434,14 @@
 
 	p = rdate->period;
 	if (p->type == E_CAL_COMPONENT_PERIOD_DATETIME) {
-		/* FIXME: We currently assume RDATEs are in the same timezone
-		   as DTSTART. We should get the RDATE timezone and convert
-		   to the DTSTART timezone first. */
-		occ->year     = p->u.end.year;
-		occ->month    = p->u.end.month - 1;
-		occ->day      = p->u.end.day;
-		occ->hour     = p->u.end.hour;
-		occ->minute   = p->u.end.minute;
-		occ->second   = p->u.end.second;
+		struct icaltimetype tt =
+			icaltime_convert_to_zone(p->u.end, zone);
+		occ->year     = tt.year;
+		occ->month    = tt.month - 1;
+		occ->day      = tt.day;
+		occ->hour     = tt.hour;
+		occ->minute   = tt.minute;
+		occ->second   = tt.second;
 		occ->flags    = FALSE;
 	} else {
 		cal_obj_time_add_days (occ, p->u.duration.weeks * 7
@@ -4004,7 +4004,7 @@
 	utc_zone = icaltimezone_get_utc_timezone ();
 	icaltime = icaltime_from_timet_with_zone (end_date, FALSE, utc_zone);
 	value = icalvalue_new_datetime (icaltime);
-	end_date_string = icalvalue_as_ical_string (value);
+	end_date_string = icalvalue_as_ical_string_r (value);
 	icalvalue_free (value);
 
 	/* If we already have an X-EVOLUTION-ENDDATE parameter, set the value

Modified: branches/camel-gobject/calendar/libecal/e-cal-time-util.c
==============================================================================
--- branches/camel-gobject/calendar/libecal/e-cal-time-util.c	(original)
+++ branches/camel-gobject/calendar/libecal/e-cal-time-util.c	Thu Apr 16 01:23:17 2009
@@ -580,11 +580,10 @@
 {
 	gchar *ret;
 	struct tm stm;
-	const char *fmt;
+	const char fmt[] = "%04d%02d%02dT%02d%02d%02dZ";
 
 	gmtime_r (&t, &stm);
 	ret = g_malloc (ISODATE_LENGTH);
-	fmt = "%04d%02d%02dT%02d%02d%02dZ";
 	g_snprintf (ret, ISODATE_LENGTH, fmt, (stm.tm_year+1900), (stm.tm_mon+1), stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec);
 
 	return ret;

Modified: branches/camel-gobject/calendar/libecal/e-cal.c
==============================================================================
--- branches/camel-gobject/calendar/libecal/e-cal.c	(original)
+++ branches/camel-gobject/calendar/libecal/e-cal.c	Thu Apr 16 01:23:17 2009
@@ -60,6 +60,7 @@
 	gboolean bool;
 	char *string;
 
+	char *op_str;
 	ECalView *query;
 	ECalViewListener *listener;
 } ECalendarOp;
@@ -179,7 +180,7 @@
 	else {                                                          \
                 const char *msg;                                        \
                 msg = e_cal_get_error_message ((status));          \
-		g_set_error ((error), E_CALENDAR_ERROR, (status), msg, (status));	\
+		g_set_error ((error), E_CALENDAR_ERROR, (status), "%s", msg);	\
 		return FALSE;						\
 	}				}G_STMT_END
 
@@ -300,13 +301,14 @@
 /* EBookOp calls */
 
 static ECalendarOp*
-e_calendar_new_op (ECal *ecal)
+e_calendar_new_op (ECal *ecal, const char *str)
 {
 	ECalendarOp *op = g_new0 (ECalendarOp, 1);
 
 	op->done = e_flag_new ();
 
 	ecal->priv->current_op = op;
+	op->op_str = g_strdup (str);
 
 	return op;
 }
@@ -315,7 +317,7 @@
 e_calendar_get_op (ECal *ecal)
 {
 	if (!ecal->priv->current_op) {
-		g_warning (G_STRLOC ": Unexpected response");
+		g_warning ("%s", G_STRLOC ": Unexpected response");
 		return NULL;
 	}
 
@@ -327,6 +329,7 @@
 {
 	/* XXX more stuff here */
 	e_flag_free (op->done);
+	g_free (op->op_str);
 	g_free (op);
 }
 
@@ -334,7 +337,7 @@
 e_calendar_remove_op (ECal *ecal, ECalendarOp *op)
 {
 	if (ecal->priv->current_op != op)
-		g_warning (G_STRLOC ": Cannot remove op, it's not current");
+		g_warning ("%s", G_STRLOC ": Cannot remove op, it's not current");
 
 	ecal->priv->current_op = NULL;
 }
@@ -358,7 +361,7 @@
 
 		result = CORBA_Object_is_nil (factory, &ev);
 		if (BONOBO_EX (&ev)) {
-			g_message (G_STRLOC ": could not see if a factory was nil");
+			g_message ("%s", G_STRLOC ": could not see if a factory was nil");
 			CORBA_exception_free (&ev);
 
 			continue;
@@ -369,7 +372,7 @@
 
 		CORBA_Object_release (factory, &ev);
 		if (BONOBO_EX (&ev)) {
-			g_message (G_STRLOC ": could not release a factory");
+			g_message ("%s", G_STRLOC ": could not release a factory");
 			CORBA_exception_free (&ev);
 		}
 	}
@@ -391,7 +394,7 @@
 	CORBA_exception_init (&ev);
 	result = CORBA_Object_is_nil (priv->cal, &ev);
 	if (BONOBO_EX (&ev)) {
-		g_message (G_STRLOC ": could not see if the "
+		g_message ("%s", G_STRLOC ": could not see if the "
 			   "calendar ecal interface object was nil");
 		priv->cal = CORBA_OBJECT_NIL;
 		CORBA_exception_free (&ev);
@@ -484,7 +487,7 @@
 	op = e_calendar_get_op (ecal);
 
 	if (op == NULL) {
-		g_warning (G_STRLOC ": Cannot find operation ");
+		g_warning ("%s", G_STRLOC ": Cannot find operation ");
 		return;
 	}
 
@@ -503,7 +506,7 @@
 	op = e_calendar_get_op (ecal);
 
 	if (op == NULL) {
-		g_warning (G_STRLOC ": Cannot find operation ");
+		g_warning ("%s", G_STRLOC ": Cannot find operation ");
 		return;
 	}
 
@@ -522,7 +525,7 @@
 	op = e_calendar_get_op (ecal);
 
 	if (op == NULL) {
-		g_warning (G_STRLOC ": Cannot find operation ");
+		g_warning ("%s", G_STRLOC ": Cannot find operation ");
 		return;
 	}
 
@@ -541,7 +544,7 @@
 	op = e_calendar_get_op (ecal);
 
 	if (op == NULL) {
-		g_warning (G_STRLOC ": Cannot find operation ");
+		g_warning ("%s", G_STRLOC ": Cannot find operation ");
 		return;
 	}
 
@@ -559,7 +562,7 @@
 	op = e_calendar_get_op (ecal);
 
 	if (op == NULL) {
-		g_warning (G_STRLOC ": Cannot find operation ");
+		g_warning ("%s", G_STRLOC ": Cannot find operation ");
 		return;
 	}
 
@@ -577,7 +580,7 @@
 	op = e_calendar_get_op (ecal);
 
 	if (op == NULL) {
-		g_warning (G_STRLOC ": Cannot find operation ");
+		g_warning ("%s", G_STRLOC ": Cannot find operation ");
 		return;
 	}
 
@@ -1310,7 +1313,7 @@
 
 /* one-time start up for libecal */
 static void
-e_cal_activate ()
+e_cal_activate (void)
 {
 	static GStaticMutex e_cal_lock = G_STATIC_MUTEX_INIT;
 	static gboolean activated = FALSE;
@@ -1643,7 +1646,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 	/* start the open operation */
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "open_calendar");
 
 	g_mutex_unlock (priv->mutex);
 
@@ -1898,7 +1901,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "cal_remove");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -2153,7 +2156,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "get_read_only");
 
 	/* set it to true so that op does not emit cond signals for all notifications
 	   from the backend */
@@ -2226,7 +2229,7 @@
 			E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 		}
 
-		our_op = e_calendar_new_op (ecal);
+		our_op = e_calendar_new_op (ecal, "get_cal_address");
 
 		g_mutex_unlock (ecal->priv->mutex);
 
@@ -2297,7 +2300,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "get_alarm_address");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -2364,7 +2367,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "get_ldap_attribute");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -2421,7 +2424,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "load_static_capabilities");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -2654,7 +2657,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "get_default_object");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -2729,7 +2732,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "get_attachments_for_comp");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -2800,7 +2803,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "get_object");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -2911,7 +2914,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "get_objects_for_uid");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -3054,7 +3057,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "get_changes");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -3148,7 +3151,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "get_object_list");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -3275,7 +3278,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "get_freebusy");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -3744,6 +3747,7 @@
 	ECalComponentDateTime datetime;
 	icaltimezone *start_zone;
 	struct instances_info *instances_hold;
+	gboolean is_single_instance = FALSE;
 
 	g_return_if_fail (E_IS_CAL (ecal));
 	g_return_if_fail (start >= 0);
@@ -3755,9 +3759,12 @@
 	comp = e_cal_component_new ();
 	e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
 
+	if (!e_cal_component_has_recurrences (comp))
+		is_single_instance = TRUE;
+
 	/*If the backend stores it as individual instances and does not
 	 * have a master object - do not expand*/
-	if (e_cal_get_static_capability (ecal, CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER)) {
+	if (is_single_instance || e_cal_get_static_capability (ecal, CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER)) {
 
 		/*return the same instance */
 		result = (* cb)  (comp, icaltime_as_timet_with_zone (icalcomponent_get_dtstart (icalcomp), ecal->priv->default_zone),
@@ -4024,7 +4031,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "discard_alarm");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -4109,7 +4116,7 @@
 	if (!vtimezone_comp)
 		return;
 
-	vtimezone_as_string = icalcomponent_as_ical_string (vtimezone_comp);
+	vtimezone_as_string = icalcomponent_as_ical_string_r (vtimezone_comp);
 
 	g_hash_table_insert (data->timezone_hash, (char*) tzid,
 			     vtimezone_as_string);
@@ -4190,7 +4197,7 @@
 			      vcal_string);
 
 	/* Get the string for the VEVENT/VTODO. */
-	obj_string = icalcomponent_as_ical_string (icalcomp);
+	obj_string = icalcomponent_as_ical_string_r (icalcomp);
 
 	/* If there were any timezones to send, create a complete VCALENDAR,
 	   else just send the VEVENT/VTODO string. */
@@ -4265,13 +4272,13 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "create_object");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
 	CORBA_exception_init (&ev);
 
-	obj = icalcomponent_as_ical_string (icalcomp);
+	obj = icalcomponent_as_ical_string_r (icalcomp);
 	GNOME_Evolution_Calendar_Cal_createObject (priv->cal, obj, &ev);
 	if (BONOBO_EX (&ev)) {
 		e_calendar_remove_op (ecal, our_op);
@@ -4346,13 +4353,13 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "modify_object");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
 	CORBA_exception_init (&ev);
 
-	obj = icalcomponent_as_ical_string (icalcomp);
+	obj = icalcomponent_as_ical_string_r (icalcomp);
 	GNOME_Evolution_Calendar_Cal_modifyObject (priv->cal, obj, mod, &ev);
 	if (BONOBO_EX (&ev)) {
 		e_calendar_remove_op (ecal, our_op);
@@ -4424,7 +4431,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "remove_object_with_mod");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -4513,13 +4520,13 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "receive_objects");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
 	CORBA_exception_init (&ev);
 
-	obj = icalcomponent_as_ical_string (icalcomp);
+	obj = icalcomponent_as_ical_string_r (icalcomp);
 	GNOME_Evolution_Calendar_Cal_receiveObjects (priv->cal, obj, &ev);
 	if (BONOBO_EX (&ev)) {
 		e_calendar_remove_op (ecal, our_op);
@@ -4585,13 +4592,13 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "send_objects");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
 	CORBA_exception_init (&ev);
 
-	obj = icalcomponent_as_ical_string (icalcomp);
+	obj = icalcomponent_as_ical_string_r (icalcomp);
 	GNOME_Evolution_Calendar_Cal_sendObjects (priv->cal, obj, &ev);
 	if (BONOBO_EX (&ev)) {
 		e_calendar_remove_op (ecal, our_op);
@@ -4672,7 +4679,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "get_timezone");
 
 	g_mutex_unlock (priv->mutex);
 
@@ -4836,7 +4843,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "add_timezone");
 
 	g_mutex_unlock (priv->mutex);
 
@@ -4858,7 +4865,7 @@
 	}
 
 	/* convert icaltimezone into a string */
-	tzobj = icalcomponent_as_ical_string (icalcomp);
+	tzobj = icalcomponent_as_ical_string_r (icalcomp);
 
 	/* call the backend */
 	CORBA_exception_init (&ev);
@@ -4923,7 +4930,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "get_query");
 
 	g_mutex_unlock (ecal->priv->mutex);
 
@@ -4995,7 +5002,7 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
 	}
 
-	our_op = e_calendar_new_op (ecal);
+	our_op = e_calendar_new_op (ecal, "set_default_timezone");
 
 	g_mutex_unlock (priv->mutex);
 
@@ -5009,7 +5016,7 @@
 	}
 
 	/* convert icaltimezone into a string */
-	tzobj = icalcomponent_as_ical_string (icalcomp);
+	tzobj = icalcomponent_as_ical_string_r (icalcomp);
 
 	/* call the backend */
 	CORBA_exception_init (&ev);

Modified: branches/camel-gobject/calendar/libecal/libecal.pc.in
==============================================================================
--- branches/camel-gobject/calendar/libecal/libecal.pc.in	(original)
+++ branches/camel-gobject/calendar/libecal/libecal.pc.in	Thu Apr 16 01:23:17 2009
@@ -13,6 +13,6 @@
 Name: libecal
 Description: Client library for evolution calendars
 Version: @VERSION@
-Requires: libbonobo-2.0 >= @LIBBONOBO_REQUIRED@ libedataserver-1.2
+Requires: libbonobo-2.0 >= @LIBBONOBO_REQUIRED@ libical >= @LIBICAL_REQUIRED@ libedataserver-1.2
 Libs: -L${libdir} -lecal-1.2
-Cflags: -I${privincludedir}
+Cflags: -I${privincludedir} @LIBICAL_EXTRA_CFLAGS@

Modified: branches/camel-gobject/calendar/libedata-cal/Makefile.am
==============================================================================
--- branches/camel-gobject/calendar/libedata-cal/Makefile.am	(original)
+++ branches/camel-gobject/calendar/libedata-cal/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -1,13 +1,11 @@
 INCLUDES =						\
 	-DG_LOG_DOMAIN=\"libedata-cal\"			\
+	-DBASE_VERSION=\""$(BASE_VERSION)"\"		\
 	-I$(top_srcdir)					\
 	-I$(top_builddir)				\
 	-I$(top_srcdir)/calendar			\
 	-I$(top_builddir)/calendar			\
-	-I$(top_srcdir)/calendar/libical/src		\
-	-I$(top_builddir)/calendar/libical/src		\
-	-I$(top_srcdir)/calendar/libical/src/libical	\
-	-I$(top_builddir)/calendar/libical/src/libical	\
+	$(LIBICAL_CFLAGS)				\
 	$(EVOLUTION_CALENDAR_CFLAGS)
 
 CORBA_GENERATED_H =				\
@@ -48,8 +46,9 @@
 
 libedata_cal_1_2_la_LIBADD =					\
 	$(top_builddir)/calendar/libecal/libecal-1.2.la		\
-	$(top_builddir)/libedataserver/libedataserver-1.2.la \
-	$(top_builddir)/libebackend/libebackend-1.2.la \
+	$(top_builddir)/libedataserver/libedataserver-1.2.la 	\
+	$(top_builddir)/libebackend/libebackend-1.2.la 		\
+	$(LIBICAL_LIBS)						\
 	$(EVOLUTION_CALENDAR_LIBS)
 
 libedata_cal_1_2_la_LDFLAGS = 								\

Modified: branches/camel-gobject/calendar/libedata-cal/e-cal-backend-cache.c
==============================================================================
--- branches/camel-gobject/calendar/libedata-cal/e-cal-backend-cache.c	(original)
+++ branches/camel-gobject/calendar/libedata-cal/e-cal-backend-cache.c	Thu Apr 16 01:23:17 2009
@@ -618,7 +618,7 @@
 	if (!icalcomp)
 		return FALSE;
 
-	obj = icalcomponent_as_ical_string (icalcomp);
+	obj = icalcomponent_as_ical_string_r (icalcomp);
 	if (e_file_cache_get_object (E_FILE_CACHE (cache), icaltimezone_get_tzid ((icaltimezone *)zone))) {
 		retval = e_file_cache_replace_object (E_FILE_CACHE (cache),
 						      icaltimezone_get_tzid ((icaltimezone *)zone),
@@ -667,7 +667,7 @@
 	if (!icalcomp)
 		return FALSE;
 
-	obj = icalcomponent_as_ical_string (icalcomp);
+	obj = icalcomponent_as_ical_string_r (icalcomp);
 	if (e_file_cache_get_object (E_FILE_CACHE (cache), "default_zone")) {
 		retval = e_file_cache_replace_object (E_FILE_CACHE (cache), "default_zone",
 						      obj);

Modified: branches/camel-gobject/calendar/libedata-cal/e-cal-backend-loader-factory.c
==============================================================================
--- branches/camel-gobject/calendar/libedata-cal/e-cal-backend-loader-factory.c	(original)
+++ branches/camel-gobject/calendar/libedata-cal/e-cal-backend-loader-factory.c	Thu Apr 16 01:23:17 2009
@@ -16,7 +16,7 @@
 #include "e-cal-backend-loader-factory.h"
 
 static GObjectClass *parent_class = NULL;
-	
+
 static void
 e_cal_backend_loader_factory_instance_init (ECalBackendLoaderFactory *factory)
 {

Modified: branches/camel-gobject/calendar/libedata-cal/e-cal-backend-sync.c
==============================================================================
--- branches/camel-gobject/calendar/libedata-cal/e-cal-backend-sync.c	(original)
+++ branches/camel-gobject/calendar/libedata-cal/e-cal-backend-sync.c	Thu Apr 16 01:23:17 2009
@@ -11,6 +11,7 @@
 #endif
 
 #include "e-cal-backend-sync.h"
+#include <libical/icaltz-util.h>
 
 struct _ECalBackendSyncPrivate {
 	GMutex *sync_mutex;
@@ -536,7 +537,7 @@
 	/* Old backends might be using the set_default_timezone */
 	if (!E_CAL_BACKEND_SYNC_GET_CLASS (backend)->set_default_zone_sync) {
 		icalcomponent *icalcomp = icalparser_parse_string (tz);
-		char *tzid = NULL;
+		const char *tzid = NULL;
 		icaltimezone *zone = icaltimezone_new ();
 
 		if (icalcomp) {
@@ -892,25 +893,35 @@
 		}
 
 		if (slashes == 1) {
+			icalcomponent *icalcomp = NULL, *free_comp = NULL;
+
 			icaltimezone *zone = icaltimezone_get_builtin_timezone (tzid);
+			if (!zone) {
+				/* Try fetching the timezone from zone directory. There are some timezones like MST, US/Pacific etc. which do not appear in
+				zone.tab, so they will not be available in the libical builtin timezone */
+				icalcomp = free_comp = icaltzutil_fetch_timezone (tzid);
+			}
+
+			if (zone)
+				icalcomp = icaltimezone_get_component (zone);
 
-			if (zone) {
-				icalcomponent *icalcomp = icaltimezone_get_component (zone);
+			if (icalcomp) {
+				icalcomponent *clone = icalcomponent_new_clone (icalcomp);
+				icalproperty *prop;
+
+				prop = icalcomponent_get_first_property (clone, ICAL_TZID_PROPERTY);
+				if (prop) {
+					/* change tzid to our, because the component has the buildin tzid */
+					icalproperty_set_tzid (prop, tzid);
 
-				if (icalcomp) {
-					icalcomponent *clone = icalcomponent_new_clone (icalcomp);
-					icalproperty *prop;
-
-					prop = icalcomponent_get_first_property (clone, ICAL_TZID_PROPERTY);
-					if (prop) {
-						/* change tzid to our, because the component has the buildin tzid */
-						icalproperty_set_tzid (prop, tzid);
-
-						object = icalcomponent_as_ical_string (clone);
-					}
-					icalcomponent_free (clone);
+					object = icalcomponent_as_ical_string_r (clone);
+					status = GNOME_Evolution_Calendar_Success;
 				}
+				icalcomponent_free (clone);
 			}
+			
+			if (free_comp)	
+				icalcomponent_free (free_comp);
 		}
 
 		/* also cache this timezone to backend */

Modified: branches/camel-gobject/calendar/libedata-cal/e-cal-backend-util.c
==============================================================================
--- branches/camel-gobject/calendar/libedata-cal/e-cal-backend-util.c	(original)
+++ branches/camel-gobject/calendar/libedata-cal/e-cal-backend-util.c	Thu Apr 16 01:23:17 2009
@@ -44,9 +44,13 @@
 {
 	const EAccount *account;
 
-	/* FIXME I think this leaks the gconf client */
-	if (accounts == NULL)
-		accounts = e_account_list_new(gconf_client_get_default());
+	if (accounts == NULL) {
+		GConfClient *gconf = gconf_client_get_default ();
+
+		accounts = e_account_list_new (gconf);
+
+		g_object_unref (gconf);
+	}
 
 	account = e_account_list_get_default(accounts);
 	if (account) {
@@ -71,9 +75,13 @@
 {
 	const EAccount *account;
 
-	/* FIXME I think this leaks the gconf client */
-	if (accounts == NULL)
-		accounts = e_account_list_new(gconf_client_get_default());
+	if (accounts == NULL) {
+		GConfClient *gconf = gconf_client_get_default ();
+
+		accounts = e_account_list_new (gconf);
+
+		g_object_unref (gconf);
+	}
 
 	account = e_account_list_find(accounts, E_ACCOUNT_FIND_ID_ADDRESS, user);
 	if (account)
@@ -142,3 +150,90 @@
 
 	return NULL;
 }
+
+/**
+ * is_attendee_declined:
+ * @param icalcomp Component where to check the attendee list.
+ * @param email Attendee's email to look for.
+ * @return Whether the required attendee declined or not.
+ *         It's not necessary to have this attendee in the list.
+ **/
+static gboolean
+is_attendee_declined (icalcomponent *icalcomp, const char *email)
+{
+	icalproperty *prop;
+	icalparameter *param;
+
+	g_return_val_if_fail (icalcomp != NULL, FALSE);
+	g_return_val_if_fail (email != NULL, FALSE);
+
+	for (prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
+	     prop != NULL;
+	     prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY)) {
+		const char *attendee;
+		char *text = NULL;
+
+		attendee = icalproperty_get_value_as_string_r (prop);
+		if (!attendee)
+			continue;
+
+		if (!g_ascii_strncasecmp (attendee, "mailto:";, 7))
+			text = g_strdup (attendee + 7);
+		text = g_strstrip (text);
+
+		if (!g_ascii_strcasecmp (email, text)) {
+			g_free (text);
+			break;
+		}
+		g_free (text);
+	}
+
+	if (!prop)
+		return FALSE;
+
+	param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER);
+
+	return param && icalparameter_get_partstat (param) == ICAL_PARTSTAT_DECLINED;
+}
+
+/**
+ * e_cal_backend_user_declined:
+ * @param icalcomp Component where to check.
+ * @return Whether icalcomp contains attendee with a mail same as any of configured
+ *         enabled mail account and whether this user declined.
+ **/
+gboolean
+e_cal_backend_user_declined (icalcomponent *icalcomp)
+{
+	gboolean res = FALSE;
+	EAccountList *accounts;
+	GConfClient *gconf;
+
+	g_return_val_if_fail (icalcomp != NULL, FALSE);
+
+	gconf = gconf_client_get_default ();
+	accounts = e_account_list_new (gconf);
+
+	if (accounts) {
+		EIterator *it;
+
+		for (it = e_list_get_iterator (E_LIST (accounts)); e_iterator_is_valid (it); e_iterator_next (it)) {
+			EAccount *account = (EAccount *) e_iterator_get (it);
+
+			if (account && account->enabled && e_account_get_string (account, E_ACCOUNT_ID_ADDRESS)) {
+				res = is_attendee_declined (icalcomp, e_account_get_string (account, E_ACCOUNT_ID_ADDRESS));
+
+				if (res)
+					break;
+			}
+		}
+
+		g_object_unref (it);
+		g_object_unref (accounts);
+	}
+
+	g_object_unref (gconf);
+
+	return res;
+}
+

Modified: branches/camel-gobject/calendar/libedata-cal/e-cal-backend-util.h
==============================================================================
--- branches/camel-gobject/calendar/libedata-cal/e-cal-backend-util.h	(original)
+++ branches/camel-gobject/calendar/libedata-cal/e-cal-backend-util.h	Thu Apr 16 01:23:17 2009
@@ -35,6 +35,8 @@
 
 const char *e_cal_backend_status_to_string (GNOME_Evolution_Calendar_CallStatus status);
 
+gboolean e_cal_backend_user_declined (icalcomponent *icalcomp);
+
 G_END_DECLS
 
 #endif

Modified: branches/camel-gobject/calendar/libedata-cal/e-cal-backend.c
==============================================================================
--- branches/camel-gobject/calendar/libedata-cal/e-cal-backend.c	(original)
+++ branches/camel-gobject/calendar/libedata-cal/e-cal-backend.c	Thu Apr 16 01:23:17 2009
@@ -30,6 +30,8 @@
 
 
 
+G_DEFINE_TYPE (ECalBackend, e_cal_backend, G_TYPE_OBJECT);
+
 /* Private part of the CalBackend structure */
 struct _ECalBackendPrivate {
 	/* The source for this backend */
@@ -57,6 +59,11 @@
 	int last_percent_notified;
 };
 
+#define E_CAL_BACKEND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_CAL_BACKEND, ECalBackendPrivate))
+
+/* For convenience */
+#define CLASS(backend) (E_CAL_BACKEND_GET_CLASS(backend))
+
 /* Property IDs */
 enum props {
 	PROP_0,
@@ -74,46 +81,10 @@
 };
 static guint e_cal_backend_signals[LAST_SIGNAL];
 
-static void e_cal_backend_class_init (ECalBackendClass *class);
-static void e_cal_backend_init (ECalBackend *backend);
 static void e_cal_backend_finalize (GObject *object);
 
-#define CLASS(backend) (E_CAL_BACKEND_CLASS (G_OBJECT_GET_CLASS (backend)))
-
-static GObjectClass *parent_class;
-
 
 
-/**
- * e_cal_backend_get_type:
- *
- * Registers the #ECalBackend class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the #ECalBackend class.
- **/
-GType
-e_cal_backend_get_type (void)
-{
-	static GType e_cal_backend_type = 0;
-
-	if (!e_cal_backend_type) {
-		static GTypeInfo info = {
-                        sizeof (ECalBackendClass),
-                        (GBaseInitFunc) NULL,
-                        (GBaseFinalizeFunc) NULL,
-                        (GClassInitFunc) e_cal_backend_class_init,
-                        NULL, NULL,
-                        sizeof (ECalBackend),
-                        0,
-                        (GInstanceInitFunc) e_cal_backend_init,
-                };
-		e_cal_backend_type = g_type_register_static (G_TYPE_OBJECT, "ECalBackend", &info, 0);
-	}
-
-	return e_cal_backend_type;
-}
-
 static void
 e_cal_backend_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
 {
@@ -190,8 +161,6 @@
 {
 	GObjectClass *object_class;
 
-	parent_class = (GObjectClass *) g_type_class_peek_parent (class);
-
 	object_class = (GObjectClass *) class;
 
 	object_class->set_property = e_cal_backend_set_property;
@@ -268,6 +237,8 @@
 	class->get_timezone = NULL;
 	class->add_timezone = NULL;
 	class->set_default_timezone = NULL;
+
+	g_type_class_add_private (class, sizeof (ECalBackendPrivate));
 }
 
 /* Object initialization func for the calendar backend */
@@ -276,7 +247,7 @@
 {
 	ECalBackendPrivate *priv;
 
-	priv = g_new0 (ECalBackendPrivate, 1);
+	priv = E_CAL_BACKEND_GET_PRIVATE (backend);
 	backend->priv = priv;
 
 	priv->clients = NULL;
@@ -305,9 +276,8 @@
 
 	g_free (priv->uri);
 	g_object_unref (priv->source);
-	g_free (priv);
 
-	G_OBJECT_CLASS (parent_class)->finalize (object);
+	G_OBJECT_CLASS (e_cal_backend_parent_class)->finalize (object);
 }
 
 
@@ -1404,22 +1374,22 @@
 }
 
 
-void 
+void
 e_cal_backend_notify_objects_added (ECalBackend *backend, EDataCalView *query, const GList *objects)
 {
-	e_data_cal_view_notify_objects_added (query, objects);	
+	e_data_cal_view_notify_objects_added (query, objects);
 }
 
-void 
+void
 e_cal_backend_notify_objects_removed (ECalBackend *backend, EDataCalView *query, const GList *ids)
 {
-	e_data_cal_view_notify_objects_removed (query, ids);	
+	e_data_cal_view_notify_objects_removed (query, ids);
 }
 
-void 
+void
 e_cal_backend_notify_objects_modified (ECalBackend *backend, EDataCalView *query, const GList *objects)
 {
-	e_data_cal_view_notify_objects_modified (query, objects);	
+	e_data_cal_view_notify_objects_modified (query, objects);
 }
 
 /**

Modified: branches/camel-gobject/calendar/libedata-cal/e-cal-backend.h
==============================================================================
--- branches/camel-gobject/calendar/libedata-cal/e-cal-backend.h	(original)
+++ branches/camel-gobject/calendar/libedata-cal/e-cal-backend.h	Thu Apr 16 01:23:17 2009
@@ -42,6 +42,7 @@
 				     ECalBackendClass))
 #define E_IS_CAL_BACKEND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_BACKEND))
 #define E_IS_CAL_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_BACKEND))
+#define E_CAL_BACKEND_GET_CLASS(obj) (E_CAL_BACKEND_CLASS (G_OBJECT_GET_CLASS (obj)))
 
 typedef struct _ECalBackendPrivate ECalBackendPrivate;
 

Modified: branches/camel-gobject/calendar/libedata-cal/e-data-cal-factory.c
==============================================================================
--- branches/camel-gobject/calendar/libedata-cal/e-data-cal-factory.c	(original)
+++ branches/camel-gobject/calendar/libedata-cal/e-data-cal-factory.c	Thu Apr 16 01:23:17 2009
@@ -475,7 +475,7 @@
 
 	for (l= methods; l != NULL; l = g_slist_next (l)) {
 		char *method_str;
-		
+
 		method = l->data;
 
 		method_str = g_ascii_strdown (method, -1);

Modified: branches/camel-gobject/calendar/libedata-cal/libedata-cal.pc.in
==============================================================================
--- branches/camel-gobject/calendar/libedata-cal/libedata-cal.pc.in	(original)
+++ branches/camel-gobject/calendar/libedata-cal/libedata-cal.pc.in	Thu Apr 16 01:23:17 2009
@@ -13,6 +13,6 @@
 Name: libedata-cal
 Description: Backend library for evolution calendars
 Version: @VERSION@
-Requires: libbonobo-2.0 >= @LIBBONOBO_REQUIRED@ libedataserver-1.2 libebackend-1.2 libecal-1.2 gio-2.0
+Requires: libbonobo-2.0 >= @LIBBONOBO_REQUIRED@ libical >= @LIBICAL_REQUIRED@ libedataserver-1.2 libebackend-1.2 libecal-1.2 gio-2.0
 Libs: -L${libdir} -ledata-cal-1.2 -lecal-1.2
 Cflags: -I${privincludedir}

Modified: branches/camel-gobject/calendar/tests/ecal/Makefile.am
==============================================================================
--- branches/camel-gobject/calendar/tests/ecal/Makefile.am	(original)
+++ branches/camel-gobject/calendar/tests/ecal/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -4,10 +4,7 @@
 	-I$(top_builddir)				\
 	-I$(top_srcdir)/calendar			\
 	-I$(top_builddir)/calendar			\
-	-I$(top_srcdir)/calendar/libical/src		\
-	-I$(top_builddir)/calendar/libical/src		\
-	-I$(top_srcdir)/calendar/libical/src/libical	\
-	-I$(top_builddir)/calendar/libical/src/libical	\
+	$(LIBICAL_CFLAGS)				\
 	$(EVOLUTION_CALENDAR_CFLAGS)
 
 EXTRA_DIST =                          \
@@ -27,7 +24,7 @@
 	-DG_LOG_DOMAIN=\"test-ecal\"
 test_ecal_LDADD =								\
 	$(top_builddir)/calendar/libecal/libecal-1.2.la				\
-	$(top_builddir)/calendar/libical/src/libical/libical-evolution.la	\
+	$(LIBICAL_LIBS)								\
 	$(EVOLUTION_CALENDAR_LIBS)
 
 test_recur_SOURCES = test-recur.c
@@ -36,7 +33,7 @@
 	-DG_LOG_DOMAIN=\"test-ecal\"
 test_recur_LDADD =								\
 	$(top_builddir)/calendar/libecal/libecal-1.2.la				\
-	$(top_builddir)/calendar/libical/src/libical/libical-evolution.la	\
+	$(LIBICAL_LIBS)								\
 	$(EVOLUTION_CALENDAR_LIBS)
 
 test_search_SOURCES = test-search.c
@@ -45,5 +42,5 @@
 	-DG_LOG_DOMAIN=\"test-ecal\"
 test_search_LDADD =								\
 	$(top_builddir)/calendar/libecal/libecal-1.2.la				\
-	$(top_builddir)/calendar/libical/src/libical/libical-evolution.la	\
+	$(LIBICAL_LIBS)								\
 	$(EVOLUTION_CALENDAR_LIBS)

Modified: branches/camel-gobject/calendar/tests/ecal/test-ecal.c
==============================================================================
--- branches/camel-gobject/calendar/tests/ecal/test-ecal.c	(original)
+++ branches/camel-gobject/calendar/tests/ecal/test-ecal.c	Thu Apr 16 01:23:17 2009
@@ -115,7 +115,7 @@
 		printf ("\n");
 
 		for (l = objects; l; l = l->next) {
-			char *obj = icalcomponent_as_ical_string (l->data);
+			char *obj = icalcomponent_as_ical_string_r (l->data);
 			printf ("------------------------------\n");
 			printf ("%s", obj);
 			printf ("------------------------------\n");
@@ -537,7 +537,7 @@
 	GError *error = NULL;
 	char *ical_string;
 	if (e_cal_get_default_object (client, &icalcomp, &error)) {
-		ical_string = icalcomponent_as_ical_string (icalcomp);
+		ical_string = icalcomponent_as_ical_string_r (icalcomp);
 		cl_printf (client, "Obtained default object: %s\n", ical_string);
 		g_free (ical_string);
 		tests_passed++;
@@ -594,7 +594,7 @@
 		return error->message;
 	}
 
-	actual = icalcomponent_as_ical_string (icalcomp);
+	actual = icalcomponent_as_ical_string_r (icalcomp);
 	compare = !strcmp (actual, EXPECTED);
 
 	g_free (actual);

Modified: branches/camel-gobject/camel/camel-data-cache.c
==============================================================================
--- branches/camel-gobject/camel/camel-data-cache.c	(original)
+++ branches/camel-gobject/camel/camel-data-cache.c	Thu Apr 16 01:23:17 2009
@@ -350,6 +350,28 @@
 	return stream;
 }
 
+
+/**
+ * camel_data_cache_get_filename:
+ * @cdc: A #CamelDataCache
+ * @path: Path to the (sub) cache the item exists in.
+ * @key: Key for the cache item.
+ * @ex: 
+ * 
+ * Lookup the filename for an item in the cache
+ * 
+ * Return value: The filename for a cache item
+ **/
+gchar *
+camel_data_cache_get_filename (CamelDataCache *cdc, const char *path, const char *key, CamelException *ex)
+{
+	char *real;
+
+	real = data_cache_path(cdc, FALSE, path, key);
+
+	return real;
+}
+
 /**
  * camel_data_cache_remove:
  * @cdc: A #CamelDataCache

Modified: branches/camel-gobject/camel/camel-data-cache.h
==============================================================================
--- branches/camel-gobject/camel/camel-data-cache.h	(original)
+++ branches/camel-gobject/camel/camel-data-cache.h	Thu Apr 16 01:23:17 2009
@@ -99,6 +99,9 @@
 int             camel_data_cache_clear(CamelDataCache *cache,
 				       const char *path, CamelException *ex);
 
+gchar *         camel_data_cache_get_filename(CamelDataCache *cdc, 
+					      const char *path, const char *key, CamelException *ex);
+
 /* Standard Camel function */
 GType camel_data_cache_get_type (void);
 

Modified: branches/camel-gobject/camel/camel-db.c
==============================================================================
--- branches/camel-gobject/camel/camel-db.c	(original)
+++ branches/camel-gobject/camel/camel-db.c	Thu Apr 16 01:23:17 2009
@@ -36,9 +36,314 @@
 
 #include "camel-debug.h"
 
+/* how long to wait before invoking sync on the file */
+#define SYNC_TIMEOUT_SECONDS 5
+
+static sqlite3_vfs *old_vfs = NULL;
+
+typedef struct {
+	sqlite3_file parent;
+	sqlite3_file *old_vfs_file; /* pointer to old_vfs' file */
+	GAsyncQueue *queue;
+	GThread *thread;
+	guint timeout_id;
+	gint flags;
+} CamelSqlite3File;
+
+static int
+call_old_file_Sync (CamelSqlite3File *cFile, int flags)
+{
+	g_return_val_if_fail (old_vfs != NULL, SQLITE_ERROR);
+	g_return_val_if_fail (cFile != NULL, SQLITE_ERROR);
+
+	g_return_val_if_fail (cFile->old_vfs_file->pMethods != NULL, SQLITE_ERROR);
+	return cFile->old_vfs_file->pMethods->xSync (cFile->old_vfs_file, flags);
+}
+
+/* This special flag tells the sync request thread to exit.
+ * Just have to make sure it does not collide with SQLite's
+ * own synchronization flags (SQLITE_SYNC_xxx). */
+#define SYNC_THREAD_EXIT 0x100000
+
+static gpointer
+sync_request_thread_cb (CamelSqlite3File *cFile)
+{
+	gpointer data;
+	gint flags = 0;
+
+	g_async_queue_ref (cFile->queue);
+
+	while (TRUE) {
+		/* Block until a request arrives. */
+		data = g_async_queue_pop (cFile->queue);
+
+		/* Make sure we can safely deference. */
+		if (data == NULL)
+			continue;
+
+		/* Extract flags and discard request. */
+		flags = *((gint *) data);
+		g_slice_free (gint, data);
+
+		/* Check for exit request. */
+		if (flags & SYNC_THREAD_EXIT)
+			break;
+
+		/* Got a boneafide sync request.
+		 * Do it, but ignore errors. */
+		call_old_file_Sync (cFile, flags);
+	}
+
+	/* Clear the exit flag. */
+	flags &= ~SYNC_THREAD_EXIT;
+
+	/* One more for the road? */
+	if (flags != 0 && getenv ("CAMEL_NO_SYNC_ON_CLOSE") == NULL)
+		call_old_file_Sync (cFile, flags);
+
+	g_async_queue_unref (cFile->queue);
+
+	return NULL;
+}
+
+static gboolean
+sync_push_request (CamelSqlite3File *cFile)
+{
+	gint *data;
+
+	/* The queue itself does not need to be locked yet,
+	 * but we use its mutex to safely manipulate flags. */
+	g_async_queue_lock (cFile->queue);
+
+	/* We can't just cast the flags to a pointer because
+	 * g_async_queue_push() won't take NULLs, and flags
+	 * may be zero.  So we have to allocate memory to
+	 * send an integer.  Bother. */
+	data = g_slice_new (gint);
+	*data = cFile->flags;
+	cFile->flags = 0;
+
+	g_async_queue_push_unlocked (cFile->queue, data);
+
+	cFile->timeout_id = 0;
+
+	g_async_queue_unlock (cFile->queue);
+
+	return FALSE;
+}
+
+#define def_subclassed(_nm, _params, _call)			\
+static int							\
+camel_sqlite3_file_ ## _nm _params				\
+{								\
+	CamelSqlite3File *cFile;				\
+								\
+	g_return_val_if_fail (old_vfs != NULL, SQLITE_ERROR);	\
+	g_return_val_if_fail (pFile != NULL, SQLITE_ERROR);	\
+								\
+	cFile = (CamelSqlite3File *) pFile;		\
+	g_return_val_if_fail (cFile->old_vfs_file->pMethods != NULL, SQLITE_ERROR);	\
+	return cFile->old_vfs_file->pMethods->_nm _call;	\
+}
+
+def_subclassed (xRead, (sqlite3_file *pFile, void *pBuf, int iAmt, sqlite3_int64 iOfst), (cFile->old_vfs_file, pBuf, iAmt, iOfst))
+def_subclassed (xWrite, (sqlite3_file *pFile, const void *pBuf, int iAmt, sqlite3_int64 iOfst), (cFile->old_vfs_file, pBuf, iAmt, iOfst))
+def_subclassed (xTruncate, (sqlite3_file *pFile, sqlite3_int64 size), (cFile->old_vfs_file, size))
+def_subclassed (xFileSize, (sqlite3_file *pFile, sqlite3_int64 *pSize), (cFile->old_vfs_file, pSize))
+def_subclassed (xLock, (sqlite3_file *pFile, int lockType), (cFile->old_vfs_file, lockType))
+def_subclassed (xUnlock, (sqlite3_file *pFile, int lockType), (cFile->old_vfs_file, lockType))
+def_subclassed (xFileControl, (sqlite3_file *pFile, int op, void *pArg), (cFile->old_vfs_file, op, pArg))
+def_subclassed (xSectorSize, (sqlite3_file *pFile), (cFile->old_vfs_file))
+def_subclassed (xDeviceCharacteristics, (sqlite3_file *pFile), (cFile->old_vfs_file))
+
+#undef def_subclassed
+
+static int
+camel_sqlite3_file_xCheckReservedLock (sqlite3_file *pFile, int *pResOut)
+{
+	CamelSqlite3File *cFile;
+
+	g_return_val_if_fail (old_vfs != NULL, SQLITE_ERROR);
+	g_return_val_if_fail (pFile != NULL, SQLITE_ERROR);
+
+	cFile = (CamelSqlite3File *) pFile;
+	g_return_val_if_fail (cFile->old_vfs_file->pMethods != NULL, SQLITE_ERROR);
+
+	/* check version in runtime */
+	if (sqlite3_libversion_number () < 3006000)
+		return ((int (*)(sqlite3_file *)) (cFile->old_vfs_file->pMethods->xCheckReservedLock)) (cFile->old_vfs_file);
+	else
+		return ((int (*)(sqlite3_file *, int *)) (cFile->old_vfs_file->pMethods->xCheckReservedLock)) (cFile->old_vfs_file, pResOut);
+}
+
+static int
+camel_sqlite3_file_xClose (sqlite3_file *pFile)
+{
+	CamelSqlite3File *cFile;
+	int res;
+
+	g_return_val_if_fail (old_vfs != NULL, SQLITE_ERROR);
+	g_return_val_if_fail (pFile != NULL, SQLITE_ERROR);
+
+	cFile = (CamelSqlite3File *) pFile;
+
+	/* The queue itself does not need to be locked yet,
+	 * but we use its mutex to safely manipulate flags. */
+	g_async_queue_lock (cFile->queue);
+
+	/* Tell the sync request thread to exit.  It may do
+	 * one last sync before exiting, so preserve any sync
+	 * flags that have accumulated. */
+	cFile->flags |= SYNC_THREAD_EXIT;
+
+	/* Cancel any pending sync requests. */
+	if (cFile->timeout_id > 0)
+		g_source_remove (cFile->timeout_id);
+
+	/* Unlock the queue before pushing the exit request. */
+	g_async_queue_unlock (cFile->queue);
+
+	/* Push the exit request. */
+	sync_push_request (cFile);
+
+	/* Wait for the thread to exit. */
+	g_thread_join (cFile->thread);
+	cFile->thread = NULL;
+
+	/* Now we can safely destroy the queue. */
+	g_async_queue_unref (cFile->queue);
+	cFile->queue = NULL;
+
+	if (cFile->old_vfs_file->pMethods)
+		res = cFile->old_vfs_file->pMethods->xClose (cFile->old_vfs_file);
+	else
+		res = SQLITE_OK;
+
+	g_free (cFile->old_vfs_file);
+	cFile->old_vfs_file = NULL;
+
+	return res;
+}
+
+static int 
+camel_sqlite3_file_xSync (sqlite3_file *pFile, int flags)
+{
+	CamelSqlite3File *cFile;
+
+	g_return_val_if_fail (old_vfs != NULL, SQLITE_ERROR);
+	g_return_val_if_fail (pFile != NULL, SQLITE_ERROR);
+
+	cFile = (CamelSqlite3File *) pFile;
+
+	/* The queue itself does not need to be locked yet,
+	 * but we use its mutex to safely manipulate flags. */
+	g_async_queue_lock (cFile->queue);
+
+	/* If a sync request is already scheduled, accumulate flags. */
+	cFile->flags |= flags;
+
+	/* Cancel any pending sync requests. */
+	if (cFile->timeout_id > 0)
+		g_source_remove (cFile->timeout_id);
+
+	/* Wait SYNC_TIMEOUT_SECONDS before we actually sync. */
+	cFile->timeout_id = g_timeout_add_seconds (
+		SYNC_TIMEOUT_SECONDS, (GSourceFunc)
+		sync_push_request, cFile);
+
+	g_async_queue_unlock (cFile->queue);
+
+	return SQLITE_OK;
+}
+
+static int
+camel_sqlite3_vfs_xOpen (sqlite3_vfs *pVfs, const char *zPath, sqlite3_file *pFile, int flags, int *pOutFlags)
+{
+	static GStaticRecMutex only_once_lock = G_STATIC_REC_MUTEX_INIT;
+	static sqlite3_io_methods io_methods = {0};
+	CamelSqlite3File *cFile;
+	GError *error = NULL;
+	int res;
+
+	g_return_val_if_fail (old_vfs != NULL, -1);
+	g_return_val_if_fail (pFile != NULL, -1);
+
+	cFile = (CamelSqlite3File *)pFile;
+	cFile->old_vfs_file = g_malloc0 (old_vfs->szOsFile);
+	cFile->queue = g_async_queue_new ();
+
+	/* Spawn a joinable thread to listen for sync requests. */
+	cFile->thread = g_thread_create (
+		(GThreadFunc) sync_request_thread_cb, cFile, TRUE, &error);
+	if (error != NULL) {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
+
+	res = old_vfs->xOpen (old_vfs, zPath, cFile->old_vfs_file, flags, pOutFlags);
+
+	g_static_rec_mutex_lock (&only_once_lock);
+
+	/* cFile->old_vfs_file->pMethods is NULL when open failed for some reason,
+	   thus do not initialize our structure when do not know the version */
+	if (io_methods.xClose == NULL && cFile->old_vfs_file->pMethods) {
+		/* initialize our subclass function only once */
+		io_methods.iVersion = cFile->old_vfs_file->pMethods->iVersion;
+
+		/* check version in compile time */
+		#if SQLITE_VERSION_NUMBER < 3006000
+		io_methods.xCheckReservedLock = (int (*)(sqlite3_file *)) camel_sqlite3_file_xCheckReservedLock;
+		#else
+		io_methods.xCheckReservedLock = camel_sqlite3_file_xCheckReservedLock;
+		#endif
+
+		#define use_subclassed(x) io_methods.x = camel_sqlite3_file_ ## x
+		use_subclassed (xClose);
+		use_subclassed (xRead);
+		use_subclassed (xWrite);
+		use_subclassed (xTruncate);
+		use_subclassed (xSync);
+		use_subclassed (xFileSize);
+		use_subclassed (xLock);
+		use_subclassed (xUnlock);
+		use_subclassed (xFileControl);
+		use_subclassed (xSectorSize);
+		use_subclassed (xDeviceCharacteristics);
+		#undef use_subclassed
+	}
+
+	g_static_rec_mutex_unlock (&only_once_lock);
+
+	cFile->parent.pMethods = &io_methods;
+
+	return res;
+}
+
+static gpointer
+init_sqlite_vfs (void)
+{
+	static sqlite3_vfs vfs = { 0 };
+
+	old_vfs = sqlite3_vfs_find (NULL);
+	g_return_val_if_fail (old_vfs != NULL, NULL);
+
+	memcpy (&vfs, old_vfs, sizeof (sqlite3_vfs));
+
+	vfs.szOsFile = sizeof (CamelSqlite3File);
+	vfs.zName = "camel_sqlite3_vfs";
+	vfs.xOpen = camel_sqlite3_vfs_xOpen;
+
+	sqlite3_vfs_register (&vfs, 1);
+
+	return NULL;
+}
+
 #define d(x) if (camel_debug("sqlite")) x
 #define START(stmt) 	if (camel_debug("dbtime")) { g_print ("\n===========\nDB SQL operation [%s] started\n", stmt); if (!cdb->priv->timer) { cdb->priv->timer = g_timer_new (); } else { g_timer_reset(cdb->priv->timer);} }
 #define END 	if (camel_debug("dbtime")) { g_timer_stop (cdb->priv->timer); g_print ("DB Operation ended. Time Taken : %f\n###########\n", g_timer_elapsed (cdb->priv->timer, NULL)); }
+#define STARTTS(stmt) 	if (camel_debug("dbtimets")) { g_print ("\n===========\nDB SQL operation [%s] started\n", stmt); if (!cdb->priv->timer) { cdb->priv->timer = g_timer_new (); } else { g_timer_reset(cdb->priv->timer);} }
+#define ENDTS 	if (camel_debug("dbtimets")) { g_timer_stop (cdb->priv->timer); g_print ("DB Operation ended. Time Taken : %f\n###########\n", g_timer_elapsed (cdb->priv->timer, NULL)); }
+
 
 struct _CamelDBPrivate {
 	GTimer *timer;
@@ -87,11 +392,14 @@
 CamelDB *
 camel_db_open (const char *path, CamelException *ex)
 {
+	static GOnce vfs_once = G_ONCE_INIT;
 	CamelDB *cdb;
 	sqlite3 *db;
 	char *cache;
 	int ret;
 
+	g_once (&vfs_once, (GThreadFunc) init_sqlite_vfs, NULL);
+
 	CAMEL_DB_USE_SHARED_CACHE;
 	
 	ret = sqlite3_open(path, &db);
@@ -128,6 +436,15 @@
 	camel_db_command (cdb, cache, NULL);
 	g_free (cache);
 
+	camel_db_command (cdb, "ATTACH DATABASE ':memory:' AS mem", NULL);
+
+	if (g_getenv("CAMEL_SQLITE_IN_MEMORY") != NULL) {
+		/* Optionally turn off Journaling, this gets over fsync issues, but could be risky */
+		camel_db_command (cdb, "PRAGMA main.journal_mode = off", NULL);
+		camel_db_command (cdb, "PRAGMA temp_store = memory", NULL);
+	}
+
+
 	sqlite3_busy_timeout (cdb->db, CAMEL_DB_SLEEP_INTERVAL);
 
 	return cdb;
@@ -195,6 +512,8 @@
 		g_static_rec_mutex_lock (&trans_lock);
 
 	g_mutex_lock (cdb->lock);
+	STARTTS("BEGIN");
+
 	return (cdb_sql_exec (cdb->db, "BEGIN", ex));
 }
 
@@ -205,9 +524,8 @@
 	if (!cdb)
 		return -1;
 
-	START("COMMIT");
 	ret = cdb_sql_exec (cdb->db, "COMMIT", ex);
-	END;
+	ENDTS;
 	g_mutex_unlock (cdb->lock);
 	if (g_getenv("SQLITE_TRANSLOCK"))
 		g_static_rec_mutex_unlock (&trans_lock);
@@ -250,7 +568,7 @@
 		return -1;
 
 	g_mutex_lock (cdb->lock);
-	START("BEGIN");
+	STARTTS("BEGIN");
 	ret = cdb_sql_exec (cdb->db, "BEGIN", ex);
 	if (ret)
 		goto end;
@@ -265,7 +583,7 @@
 	}
 
 	ret = cdb_sql_exec (cdb->db, "COMMIT", ex);
-	END;
+	ENDTS;
 end:
 	g_mutex_unlock (cdb->lock);
 	return ret;
@@ -439,7 +757,7 @@
 	if (!cdb)
 		return -1;
 	
-	query = sqlite3_mprintf ("SELECT COUNT (*) FROM %Q", table_name);
+	query = sqlite3_mprintf ("SELECT COUNT (*) FROM %Q where read=0 or read=1", table_name);
 
 	ret = camel_db_count_message_info (cdb, query, count, ex);
 	sqlite3_free (query);
@@ -769,18 +1087,17 @@
 	return ((camel_db_command (cdb, query, ex)));
 }
 
-int 
-camel_db_prepare_message_info_table (CamelDB *cdb, const char *folder_name, CamelException *ex)
+
+
+static int
+camel_db_create_message_info_table (CamelDB *cdb, const char *folder_name, CamelException *ex)
 {
 	int ret;
 	char *table_creation_query, *safe_index;
 
 	/* README: It is possible to compress all system flags into a single column and use just as userflags but that makes querying for other applications difficult an d bloats the parsing code. Instead, it is better to bloat the tables. Sqlite should have some optimizations for sparse columns etc. */
-
-	table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS %Q (  uid TEXT PRIMARY KEY , flags INTEGER , msg_type INTEGER , read INTEGER , deleted INTEGER , replied INTEGER , important INTEGER , junk INTEGER , attachment INTEGER , msg_security INTEGER , size INTEGER , dsent NUMERIC , dreceived NUMERIC , subject TEXT , mail_from TEXT , mail_to TEXT , mail_cc TEXT , mlist TEXT , followup_flag TEXT , followup_completed_on TEXT , followup_due_by TEXT , part TEXT , labels TEXT , usertags TEXT , cinfo TEXT , bdata TEXT )", folder_name);
-
+	table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS %Q (  uid TEXT PRIMARY KEY , flags INTEGER , msg_type INTEGER , read INTEGER , deleted INTEGER , replied INTEGER , important INTEGER , junk INTEGER , attachment INTEGER , dirty INTEGER , size INTEGER , dsent NUMERIC , dreceived NUMERIC , subject TEXT , mail_from TEXT , mail_to TEXT , mail_cc TEXT , mlist TEXT , followup_flag TEXT , followup_completed_on TEXT , followup_due_by TEXT , part TEXT , labels TEXT , usertags TEXT , cinfo TEXT , bdata TEXT, created TEXT, modified TEXT )", folder_name);
 	ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
-
 	sqlite3_free (table_creation_query);
 
 	/* FIXME: sqlize folder_name before you create the index */
@@ -810,10 +1127,141 @@
 	ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
 	g_free (safe_index);
 	sqlite3_free (table_creation_query);
-	
+
 	return ret;
 }
 
+static int
+camel_db_migrate_folder_prepare (CamelDB *cdb, const char *folder_name, gint version, CamelException *ex)
+{
+	int ret = 0;
+	char *table_creation_query;
+
+	/* Migration stage one: storing the old data */
+
+	if (version < 1) {
+		/* Between version 0-1 the following things are changed
+		 * ADDED: created: time
+		 * ADDED: modified: time
+		 * RENAMED: msg_security to dirty 
+		 * */
+
+		table_creation_query = sqlite3_mprintf ("DROP TABLE IF EXISTS 'mem.%q'", folder_name);
+		ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
+		sqlite3_free (table_creation_query);
+
+		table_creation_query = sqlite3_mprintf ("CREATE TEMP TABLE IF NOT EXISTS 'mem.%q' (  uid TEXT PRIMARY KEY , flags INTEGER , msg_type INTEGER , read INTEGER , deleted INTEGER , replied INTEGER , important INTEGER , junk INTEGER , attachment INTEGER , dirty INTEGER , size INTEGER , dsent NUMERIC , dreceived NUMERIC , subject TEXT , mail_from TEXT , mail_to TEXT , mail_cc TEXT , mlist TEXT , followup_flag TEXT , followup_completed_on TEXT , followup_due_by TEXT , part TEXT , labels TEXT , usertags TEXT , cinfo TEXT , bdata TEXT, created TEXT, modified TEXT )", folder_name);
+		ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
+		sqlite3_free (table_creation_query);
+
+		table_creation_query = sqlite3_mprintf ("INSERT INTO 'mem.%q' SELECT uid , flags , msg_type , read , deleted , replied , important , junk , attachment , msg_security , size , dsent , dreceived , subject , mail_from , mail_to , mail_cc , mlist , followup_flag , followup_completed_on , followup_due_by , part , labels , usertags , cinfo , bdata , strftime(\"%%s\", 'now'), strftime(\"%%s\", 'now') FROM %Q", folder_name, folder_name);
+		ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
+		sqlite3_free (table_creation_query);
+
+		table_creation_query = sqlite3_mprintf ("DROP TABLE IF EXISTS %Q", folder_name);
+		ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
+		sqlite3_free (table_creation_query);
+
+		ret = camel_db_create_message_info_table (cdb, folder_name, ex);
+		camel_exception_clear (ex);
+	}
+
+	/* Add later version migrations here */
+
+	return ret;
+}
+
+static int
+camel_db_migrate_folder_recreate (CamelDB *cdb, const char *folder_name, gint version, CamelException *ex)
+{
+	int ret = 0;
+	char *table_creation_query;
+
+	/* Migration stage two: writing back the old data */
+
+	if (version < 1) {
+		table_creation_query = sqlite3_mprintf ("INSERT INTO %Q SELECT uid , flags , msg_type , read , deleted , replied , important , junk , attachment , dirty , size , dsent , dreceived , subject , mail_from , mail_to , mail_cc , mlist , followup_flag , followup_completed_on , followup_due_by , part , labels , usertags , cinfo , bdata, created, modified FROM 'mem.%q'", folder_name, folder_name);
+		ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
+		sqlite3_free (table_creation_query);
+
+		table_creation_query = sqlite3_mprintf ("DROP TABLE 'mem.%q'", folder_name);
+		ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
+		sqlite3_free (table_creation_query);
+	}
+
+	/* Add later version migrations here */
+
+	return ret;
+}
+
+static int
+camel_db_write_folder_version (CamelDB *cdb, const char *folder_name, int old_version, CamelException *ex)
+{
+	int ret = 0;
+	char *version_creation_query;
+	char *version_insert_query;
+
+	version_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS '%q_version' ( version TEXT )", folder_name);
+
+	if (old_version == -1)
+		version_insert_query = sqlite3_mprintf ("INSERT INTO '%q_version' VALUES ('1')", folder_name);
+	else
+		version_insert_query = sqlite3_mprintf ("UPDATE '%q_version' SET version='1'", folder_name);
+
+	ret = camel_db_add_to_transaction (cdb, version_creation_query, ex);
+	ret = camel_db_add_to_transaction (cdb, version_insert_query, ex);
+
+	sqlite3_free (version_creation_query);
+	sqlite3_free (version_insert_query);
+
+	return ret;
+}
+
+static int
+camel_db_get_folder_version (CamelDB *cdb, const char *folder_name, CamelException *ex)
+{
+	int version = -1, ret;
+	char *query;
+	sqlite3_stmt *stmt = NULL;
+
+	query = sqlite3_mprintf ("SELECT version FROM '%q_version'", folder_name);
+
+	ret = sqlite3_prepare_v2 (cdb->db, query, -1, &stmt, NULL);
+
+	if (ret == SQLITE_OK)
+		ret = sqlite3_step (stmt);
+	if (ret == SQLITE_ROW || ret == SQLITE_OK)
+		version = sqlite3_column_int (stmt, 0);
+
+	sqlite3_finalize (stmt);
+
+	sqlite3_free (query);
+
+	return version;
+}
+
+int 
+camel_db_prepare_message_info_table (CamelDB *cdb, const char *folder_name, CamelException *ex)
+{
+	int ret, current_version;
+
+	/* Make sure we have the table already */
+	ret = camel_db_create_message_info_table (cdb, folder_name, ex);
+
+	/* Migration stage zero: version fetch */
+	current_version = camel_db_get_folder_version (cdb, folder_name, ex);
+
+	/* Migration stage one: storing the old data if necessary */
+	ret = camel_db_migrate_folder_prepare (cdb, folder_name, current_version, ex);
+
+	/* Migration stage two: rewriting the old data if necessary */
+	ret = camel_db_migrate_folder_recreate (cdb, folder_name, current_version, ex);
+
+	/* Final step: (over)write the current version label */
+	ret = camel_db_write_folder_version (cdb, folder_name, current_version, ex);
+
+	return ret;
+}
 
 int 
 camel_db_write_fresh_message_info_record (CamelDB *cdb, const char *folder_name, CamelMIRecord *record, CamelException *ex)
@@ -821,7 +1269,6 @@
 	return write_mir (cdb, folder_name, record, ex, FALSE);
 }
 
-
 int
 camel_db_write_message_info_record (CamelDB *cdb, const char *folder_name, CamelMIRecord *record, CamelException *ex)
 {
@@ -837,21 +1284,21 @@
 
 	/* FIXME: We should migrate from this DELETE followed by INSERT model to an INSERT OR REPLACE model as pointed out by pvanhoof */
 
-	/* NB: UGLIEST Hack. We can't modify the schema now. We are using msg_security (an unsed one to notify of FLAGGED/Dirty infos */
+	/* NB: UGLIEST Hack. We can't modify the schema now. We are using dirty (an unsed one to notify of FLAGGED/Dirty infos */
 
-	ins_query = sqlite3_mprintf ("INSERT INTO %Q VALUES (%Q, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %ld, %ld, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q )", 
+	ins_query = sqlite3_mprintf ("INSERT OR REPLACE INTO %Q VALUES (%Q, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %lld, %lld, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, strftime(\"%%s\", 'now'), strftime(\"%%s\", 'now') )", 
 			folder_name, record->uid, record->flags,
 			record->msg_type, record->read, record->deleted, record->replied,
 			record->important, record->junk, record->attachment, record->dirty,
-			record->size, record->dsent, record->dreceived,
+			record->size, (long long) record->dsent, (long long) record->dreceived,
 			record->subject, record->from, record->to,
 			record->cc, record->mlist, record->followup_flag,
 			record->followup_completed_on, record->followup_due_by, 
 			record->part, record->labels, record->usertags,
 			record->cinfo, record->bdata);
 
-	if (delete_old_record)
-			del_query = sqlite3_mprintf ("DELETE FROM %Q WHERE uid = %Q", folder_name, record->uid);
+	//if (delete_old_record)
+	//		del_query = sqlite3_mprintf ("DELETE FROM %Q WHERE uid = %Q", folder_name, record->uid);
 
 #if 0
 	char *upd_query;
@@ -861,14 +1308,14 @@
 	g_free (upd_query);
 #else
 
-	if (delete_old_record)
-			ret = camel_db_add_to_transaction (cdb, del_query, ex);
+	//if (delete_old_record)
+	//		ret = camel_db_add_to_transaction (cdb, del_query, ex);
 	ret = camel_db_add_to_transaction (cdb, ins_query, ex);
 
 #endif
 
-	if (delete_old_record)
-			sqlite3_free (del_query);
+	//if (delete_old_record)
+	//		sqlite3_free (del_query);
 	sqlite3_free (ins_query);
 
 	return ret;
@@ -1002,14 +1449,51 @@
 	return (ret);
 }
 
+static int
+camel_db_create_deleted_table (CamelDB *cdb, CamelException *ex)
+{
+	int ret;
+	char *table_creation_query;
+	table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS Deletes (id INTEGER primary key AUTOINCREMENT not null, uid TEXT, time TEXT, mailbox TEXT)");
+	ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
+	sqlite3_free (table_creation_query);
+	return ret;
+}
+
+static int
+camel_db_trim_deleted_table (CamelDB *cdb, CamelException *ex)
+{
+	int ret = 0;
+
+	/* TODO: We need a mechanism to get rid of very old deletes, or something
+	 * that keeps the list trimmed at a certain max (deleting upfront when
+	 * appending at the back) */
+
+	return ret;
+}
+
 int
 camel_db_delete_uid (CamelDB *cdb, const char *folder, const char *uid, CamelException *ex)
 {
-	char *tab = sqlite3_mprintf ("DELETE FROM %Q WHERE uid = %Q", folder, uid);
+	char *tab;
 	int ret;
 
-	ret = camel_db_command (cdb, tab, ex);
+	camel_db_begin_transaction (cdb, ex);
+
+	ret = camel_db_create_deleted_table (cdb, ex);
+
+	tab = sqlite3_mprintf ("INSERT OR REPLACE INTO Deletes (uid, mailbox, time) SELECT uid, %Q, strftime(\"%%s\", 'now') FROM %Q WHERE uid = %Q", folder, folder, uid);
+	ret = camel_db_add_to_transaction (cdb, tab, ex);
 	sqlite3_free (tab);
+
+	ret = camel_db_trim_deleted_table (cdb, ex);
+
+	tab = sqlite3_mprintf ("DELETE FROM %Q WHERE uid = %Q", folder, uid);
+	ret = camel_db_add_to_transaction (cdb, tab, ex);
+	sqlite3_free (tab);
+
+	ret = camel_db_end_transaction (cdb, ex);
+
 	CAMEL_DB_RELEASE_SQLITE_MEMORY;
 	return ret;
 }
@@ -1019,9 +1503,25 @@
 {
 	char *tmp;
 	int ret;
+	char *tab;
 	gboolean first = TRUE;
 	GString *str = g_string_new ("DELETE FROM ");
 	GSList *iterator;
+	GString *ins_str = NULL;
+		
+	if (strcmp (field, "vuid") != 0)
+		ins_str = g_string_new ("INSERT OR REPLACE INTO Deletes (uid, mailbox, time) SELECT uid, ");
+
+	camel_db_begin_transaction (cdb, ex);
+
+	if (ins_str)
+		ret = camel_db_create_deleted_table (cdb, ex);
+
+	if (ins_str) {
+		tab = sqlite3_mprintf ("%Q, strftime(\"%%s\", 'now') FROM %Q WHERE %s IN (", folder_name, folder_name, field);
+		g_string_append_printf (ins_str, "%s ", tab);
+		sqlite3_free (tab);
+	}
 
 	tmp = sqlite3_mprintf ("%Q WHERE %s IN (", folder_name, field); 
 	g_string_append_printf (str, "%s ", tmp);
@@ -1037,17 +1537,33 @@
 
 		if (first == TRUE) {
 			g_string_append_printf (str, " %s ", tmp);
+			if (ins_str)
+				g_string_append_printf (ins_str, " %s ", tmp);	
 			first = FALSE;
-		} else
+		} else {
 			g_string_append_printf (str, ", %s ", tmp);
+			if (ins_str)
+				g_string_append_printf (ins_str, ", %s ", tmp);
+		}
 
 		sqlite3_free (tmp);
 	}
 
 	g_string_append (str, ")");
+	if (ins_str) {
+		g_string_append (ins_str, ")");
+		ret = camel_db_add_to_transaction (cdb, ins_str->str, ex);
+		ret = camel_db_trim_deleted_table (cdb, ex);
+	}
+
+	ret = camel_db_add_to_transaction (cdb, str->str, ex);
+
+	ret = camel_db_end_transaction (cdb, ex);
 
-	ret = camel_db_command (cdb, str->str, ex);
 	CAMEL_DB_RELEASE_SQLITE_MEMORY;
+
+	if (ins_str)
+		g_string_free (ins_str, TRUE);
 	g_string_free (str, TRUE);
 
 	return ret;
@@ -1056,6 +1572,9 @@
 int
 camel_db_delete_uids (CamelDB *cdb, const char * folder_name, GSList *uids, CamelException *ex)
 {
+	if(!uids || !uids->data)
+		return 0;
+
 	return cdb_delete_ids (cdb, folder_name, uids, "", "uid", ex);
 }
 
@@ -1072,13 +1591,24 @@
 
 	char *folders_del;
 	char *msginfo_del;
+	char *tab;
 
 	folders_del = sqlite3_mprintf ("DELETE FROM folders WHERE folder_name = %Q", folder);
 	msginfo_del = sqlite3_mprintf ("DELETE FROM %Q ", folder);
 
 	camel_db_begin_transaction (cdb, ex);
+
+	ret = camel_db_create_deleted_table (cdb, ex);
+
+	tab = sqlite3_mprintf ("INSERT OR REPLACE INTO Deletes (uid, mailbox, time) SELECT uid, %Q, strftime(\"%%s\", 'now') FROM %Q", folder, folder);
+	ret = camel_db_add_to_transaction (cdb, tab, ex);
+	sqlite3_free (tab);
+
+	ret = camel_db_trim_deleted_table (cdb, ex);
+
 	camel_db_add_to_transaction (cdb, msginfo_del, ex);
 	camel_db_add_to_transaction (cdb, folders_del, ex);
+
 	ret = camel_db_end_transaction (cdb, ex);
 
 	sqlite3_free (folders_del);
@@ -1092,15 +1622,28 @@
 {
 	int ret;
 	char *del;
+	char *tab;
+
+	camel_db_begin_transaction (cdb, ex);
+
+	ret = camel_db_create_deleted_table (cdb, ex);
+
+	tab = sqlite3_mprintf ("INSERT OR REPLACE INTO Deletes (uid, mailbox, time) SELECT uid, %Q, strftime(\"%%s\", 'now') FROM %Q", folder, folder);
+	ret = camel_db_add_to_transaction (cdb, tab, ex);
+	sqlite3_free (tab);
+
+	ret = camel_db_trim_deleted_table (cdb, ex);
 
 	del = sqlite3_mprintf ("DELETE FROM folders WHERE folder_name = %Q", folder);
-	ret = camel_db_command (cdb, del, ex);
+	ret = camel_db_add_to_transaction (cdb, del, ex);
 	sqlite3_free (del);
 	
 	del = sqlite3_mprintf ("DROP TABLE %Q ", folder);
-	ret = camel_db_command (cdb, del, ex);
+	ret = camel_db_add_to_transaction (cdb, del, ex);
 	sqlite3_free (del);
 
+	ret = camel_db_end_transaction (cdb, ex);
+
 	CAMEL_DB_RELEASE_SQLITE_MEMORY;
 	return ret;	
 }
@@ -1109,16 +1652,32 @@
 camel_db_rename_folder (CamelDB *cdb, const char *old_folder, const char *new_folder, CamelException *ex)
 {
 	int ret;
-	char *cmd;
+	char *cmd, *tab;
+
+	camel_db_begin_transaction (cdb, ex);
+
+	ret = camel_db_create_deleted_table (cdb, ex);
+
+	tab = sqlite3_mprintf ("INSERT OR REPLACE INTO Deletes (uid, mailbox, time) SELECT uid, %Q, strftime(\"%%s\", 'now') FROM %Q", old_folder, old_folder);
+	ret = camel_db_add_to_transaction (cdb, tab, ex);
+	sqlite3_free (tab);
+
+	ret = camel_db_trim_deleted_table (cdb, ex);
 
 	cmd = sqlite3_mprintf ("ALTER TABLE %Q RENAME TO  %Q", old_folder, new_folder);
-	ret = camel_db_command (cdb, cmd, ex);
+	ret = camel_db_add_to_transaction (cdb, cmd, ex);
+	sqlite3_free (cmd);
+
+	cmd = sqlite3_mprintf ("UPDATE %Q SET modified=strftime(\"%%s\", 'now'), created=strftime(\"%%s\", 'now')", new_folder);
+	ret = camel_db_add_to_transaction (cdb, cmd, ex);
 	sqlite3_free (cmd);
 
 	cmd = sqlite3_mprintf ("UPDATE folders SET folder_name = %Q WHERE folder_name = %Q", new_folder, old_folder);
-	ret = camel_db_command (cdb, cmd, ex);
+	ret = camel_db_add_to_transaction (cdb, cmd, ex);
 	sqlite3_free (cmd);
-	
+
+	ret = camel_db_end_transaction (cdb, ex);
+
 	CAMEL_DB_RELEASE_SQLITE_MEMORY;
 	return ret;	
 }
@@ -1164,7 +1723,7 @@
 flags INTEGER ,
 msg_type INTEGER ,
 replied INTEGER ,
-msg_security INTEGER ,
+dirty INTEGER ,
 size INTEGER ,
 dsent NUMERIC ,
 dreceived NUMERIC ,
@@ -1228,7 +1787,7 @@
 	ret = camel_db_command (cdb, cmd, ex);
 	sqlite3_free (cmd);
 
-	cmd = sqlite3_mprintf ("CREATE TEMPORARY TABLE %Q (  uid TEXT PRIMARY KEY , flags INTEGER , msg_type INTEGER , read INTEGER , deleted INTEGER , replied INTEGER , important INTEGER , junk INTEGER , attachment INTEGER , msg_security INTEGER , size INTEGER , dsent NUMERIC , dreceived NUMERIC , subject TEXT , mail_from TEXT , mail_to TEXT , mail_cc TEXT , mlist TEXT , followup_flag TEXT , followup_completed_on TEXT , followup_due_by TEXT , part TEXT , labels TEXT , usertags TEXT , cinfo TEXT , bdata TEXT )", CAMEL_DB_IN_MEMORY_TABLE);
+	cmd = sqlite3_mprintf ("CREATE TEMPORARY TABLE %Q (  uid TEXT PRIMARY KEY , flags INTEGER , msg_type INTEGER , read INTEGER , deleted INTEGER , replied INTEGER , important INTEGER , junk INTEGER , attachment INTEGER , dirty INTEGER , size INTEGER , dsent NUMERIC , dreceived NUMERIC , subject TEXT , mail_from TEXT , mail_to TEXT , mail_cc TEXT , mlist TEXT , followup_flag TEXT , followup_completed_on TEXT , followup_due_by TEXT , part TEXT , labels TEXT , usertags TEXT , cinfo TEXT , bdata TEXT )", CAMEL_DB_IN_MEMORY_TABLE);
 	ret = camel_db_command (cdb, cmd, ex);
 	if (ret != 0 )
 		abort ();

Modified: branches/camel-gobject/camel/camel-disco-diary.c
==============================================================================
--- branches/camel-gobject/camel/camel-disco-diary.c	(original)
+++ branches/camel-gobject/camel/camel-disco-diary.c	Thu Apr 16 01:23:17 2009
@@ -127,7 +127,7 @@
 	d(printf("diary log: %s\n", diary->file?"ok":"no file!"));
 
 	/* You may already be a loser. */
-	if (!diary && !diary->file)
+	if (!diary || !diary->file)
 		return;
 
 	status = camel_file_util_encode_uint32 (diary->file, action);

Modified: branches/camel-gobject/camel/camel-filter-driver.c
==============================================================================
--- branches/camel-gobject/camel/camel-filter-driver.c	(original)
+++ branches/camel-gobject/camel/camel-filter-driver.c	Thu Apr 16 01:23:17 2009
@@ -101,7 +101,6 @@
 	/* run-time data */
 	GHashTable *folders;       /* folders that message has been copied to */
 	int closed;		   /* close count */
-	GHashTable *forwards;      /* addresses that have been forwarded the message */
 	GHashTable *only_once;     /* actions to run only-once */
 	
 	gboolean terminated;       /* message processing was terminated */
@@ -137,7 +136,7 @@
 static int close_folders (CamelFilterDriver *d);
 
 static ESExpResult *do_delete (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *);
-static ESExpResult *mark_forward (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *);
+static ESExpResult *do_forward_to (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *);
 static ESExpResult *do_copy (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *);
 static ESExpResult *do_move (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *);
 static ESExpResult *do_stop (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *);
@@ -161,7 +160,7 @@
 				   doesn't execute everything, 0 otherwise */
 } symbols[] = {
 	{ "delete",            (ESExpFunc *) do_delete,    0 },
-	{ "forward-to",        (ESExpFunc *) mark_forward, 0 },
+	{ "forward-to",        (ESExpFunc *) do_forward_to, 0 },
 	{ "copy-to",           (ESExpFunc *) do_copy,      0 },
 	{ "move-to",           (ESExpFunc *) do_move,      0 },
 	{ "stop",              (ESExpFunc *) do_stop,      0 },
@@ -447,14 +446,25 @@
 }
 
 static ESExpResult *
-mark_forward (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *driver)
+do_forward_to (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriver *driver)
 {
-	/*struct _CamelFilterDriverPrivate *p = _PRIVATE (driver);*/
-	
+	struct _CamelFilterDriverPrivate *p = _PRIVATE (driver);
+
 	d(fprintf (stderr, "marking message for forwarding\n"));
-	/* FIXME: do stuff here */
-	camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Forward");
-	
+
+	/* requires one parameter, string with a destination address */
+	if (argc < 1 || argv[0]->type != ESEXP_RES_STRING)
+		return NULL;
+
+	/* make sure we have the message... */
+	if (p->message == NULL) {
+		if (!(p->message = camel_folder_get_message (p->source, p->uid, p->ex)))
+			return NULL;
+	}
+
+	camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Forward message to '%s'", argv[0]->value.string);
+	camel_session_forward_to (p->session, p->source, p->message, argv[0]->value.string, p->ex);
+
 	return NULL;
 }
 

Modified: branches/camel-gobject/camel/camel-filter-search.c
==============================================================================
--- branches/camel-gobject/camel/camel-filter-search.c	(original)
+++ branches/camel-gobject/camel/camel-filter-search.c	Thu Apr 16 01:23:17 2009
@@ -578,7 +578,7 @@
 		g_ptr_array_free (args, TRUE);
 
 		camel_exception_setv (fms->ex, CAMEL_EXCEPTION_SYSTEM,
-				      _("Failed to create create child process '%s': %s"),
+				      _("Failed to create child process '%s': %s"),
 				      argv[0]->value.string, error->message);
 		g_error_free (error);
 		return -1;

Modified: branches/camel-gobject/camel/camel-folder-search.c
==============================================================================
--- branches/camel-gobject/camel/camel-folder-search.c	(original)
+++ branches/camel-gobject/camel/camel-folder-search.c	Thu Apr 16 01:23:17 2009
@@ -41,6 +41,7 @@
 #include "camel-exception.h"
 #include "camel-folder-search.h"
 #include "camel-folder-thread.h"
+#include "camel-iconv.h"
 #include "camel-medium.h"
 #include "camel-mime-message.h"
 #include "camel-multipart.h"
@@ -74,9 +75,13 @@
 static ESExpResult *search_header_starts_with(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search);
 static ESExpResult *search_header_ends_with(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search);
 static ESExpResult *search_header_exists(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search);
+static ESExpResult *search_header_soundex(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search);
+static ESExpResult *search_header_regex(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search);
+static ESExpResult *search_header_full_regex(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search);
 static ESExpResult *search_match_all(struct _ESExp *f, int argc, struct _ESExpTerm **argv, CamelFolderSearch *search);
 static ESExpResult *search_match_threads(struct _ESExp *f, int argc, struct _ESExpTerm **argv, CamelFolderSearch *s);
 static ESExpResult *search_body_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search);
+static ESExpResult *search_body_regex(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search);
 static ESExpResult *search_user_flag(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
 static ESExpResult *search_user_tag(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
 static ESExpResult *search_system_flag(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
@@ -85,6 +90,7 @@
 static ESExpResult *search_get_current_date(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
 static ESExpResult *search_get_size(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
 static ESExpResult *search_uid(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
+static ESExpResult *search_message_location(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
 
 static ESExpResult *search_dummy(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search);
 
@@ -106,11 +112,15 @@
 	klass->match_all = search_match_all;
 	klass->match_threads = search_match_threads;
 	klass->body_contains = search_body_contains;
+	klass->body_regex = search_body_regex;
 	klass->header_contains = search_header_contains;
 	klass->header_matches = search_header_matches;
 	klass->header_starts_with = search_header_starts_with;
 	klass->header_ends_with = search_header_ends_with;
 	klass->header_exists = search_header_exists;
+	klass->header_soundex = search_header_soundex;
+	klass->header_regex = search_header_regex;
+	klass->header_full_regex = search_header_full_regex;
 	klass->user_tag = search_user_tag;
 	klass->user_flag = search_user_flag;
 	klass->system_flag = search_system_flag;
@@ -119,6 +129,7 @@
 	klass->get_current_date = search_get_current_date;
 	klass->get_size = search_get_size;
 	klass->uid = search_uid;
+	klass->message_location = search_message_location;
 }
 
 static void
@@ -187,11 +198,15 @@
 	{ "match-all", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, match_all), 3 },
 	{ "match-threads", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, match_threads), 3 },
 	{ "body-contains", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, body_contains), 1 },
+	{ "body-regex",  CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, body_regex), 1  },
 	{ "header-contains", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, header_contains), 1 },
 	{ "header-matches", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, header_matches), 1 },
 	{ "header-starts-with", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, header_starts_with), 1 },
 	{ "header-ends-with", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, header_ends_with), 1 },
 	{ "header-exists", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, header_exists), 1 },
+	{ "header-soundex", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, header_soundex), 1 },
+	{ "header-regex", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, header_regex), 1 },
+	{ "header-full-regex", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, header_full_regex), 1 },
 	{ "user-tag", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, user_tag), 1 },
 	{ "user-flag", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, user_flag), 1 },
 	{ "system-flag", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, system_flag), 1 },
@@ -200,6 +215,7 @@
 	{ "get-current-date", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, get_current_date), 1 },
 	{ "get-size", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, get_size), 1 },
 	{ "uid", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, uid), 1 },
+	{ "message-location", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, message_location), 1 },
 };
 
 void
@@ -521,6 +537,24 @@
 	return count;
 }
 
+static gboolean
+do_search_in_memory (const char *expr)
+{
+	/* if the expression contains any of these tokens, then perform a memory search, instead of the SQL one */
+	const char *in_memory_tokens[] = { "body-contains", "body-regex", "match-threads", "message-location", "header-soundex", "header-regex", "header-full-regex", "header-contains", NULL };
+	int i;
+
+	if (!expr)
+		return FALSE;
+
+	for (i = 0; in_memory_tokens [i]; i++) {
+		if (strstr (expr, in_memory_tokens [i]))
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
 /**
  * camel_folder_search_search:
  * @search: 
@@ -550,7 +584,7 @@
 	p->ex = ex;
 
 	/* We route body-contains / thread based search and uid search through memory and not via db. */
-	if (uids || strstr((const char *) expr, "body-contains") || strstr((const char *) expr, "match-threads")) {
+	if (uids || do_search_in_memory (expr)) {
 		/* setup our search list only contains those we're interested in */
 		search->summary = camel_folder_get_summary(search->folder);
 
@@ -975,6 +1009,23 @@
 	return r;
 }
 
+static CamelMimeMessage *
+get_current_message (CamelFolderSearch *search)
+{
+	CamelException x = CAMEL_EXCEPTION_INITIALISER;
+	CamelMimeMessage *res;
+
+	if (!search || !search->folder || !search->current)
+		return NULL;
+
+	res = camel_folder_get_message (search->folder, search->current->uid, &x);
+
+	if (!res)
+		camel_exception_clear (&x);
+
+	return res;
+}
+
 static ESExpResult *
 check_header (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search, camel_search_match_t how)
 {
@@ -987,11 +1038,13 @@
 	if (search->current && argc>1
 	    && argv[0]->type == ESEXP_RES_STRING) {
 		char *headername;
-		const char *header = NULL;
+		const char *header = NULL, *charset = NULL;
 		char strbuf[32];
 		int i, j;
 		camel_search_t type = CAMEL_SEARCH_TYPE_ASIS;
 		struct _camel_search_words *words;
+		CamelMimeMessage *message = NULL;
+		struct _camel_header_raw *raw_header;
 
 		/* only a subset of headers are supported .. */
 		headername = argv[0]->value.string;
@@ -1014,8 +1067,15 @@
 			header = camel_message_info_mlist(search->current);
 			type = CAMEL_SEARCH_TYPE_MLIST;
 		} else {
-			e_sexp_resultv_free(f, argc, argv);
-			e_sexp_fatal_error(f, _("Performing query on unknown header: %s"), headername);
+			message = get_current_message (search);
+			if (message) {
+				CamelContentType *ct = camel_mime_part_get_content_type (CAMEL_MIME_PART (message));
+
+				if (ct) {
+					charset = camel_content_type_param (ct, "charset");
+					charset = camel_iconv_charset_name (charset);
+				}
+			}
 		}
 
 		if (header == NULL)
@@ -1031,14 +1091,34 @@
 					words = camel_search_words_split((const unsigned char *) argv[i]->value.string);
 					truth = TRUE;
 					for (j=0;j<words->len && truth;j++) {
-						truth = camel_search_header_match(header, words->words[j]->word, how, type, NULL);
+						if (message) {
+							for (raw_header = ((CamelMimePart *)message)->headers; raw_header; raw_header = raw_header->next) {
+								if (!g_ascii_strcasecmp (raw_header->name, headername)) {
+									if (camel_search_header_match (raw_header->value, words->words[j]->word, how, type, charset))
+										break;;
+								}
+							}
+
+							truth = raw_header != NULL;
+						} else
+							truth = camel_search_header_match(header, words->words[j]->word, how, type, charset);
 					}
 					camel_search_words_free(words);
 				} else {
-					truth = camel_search_header_match(header, argv[i]->value.string, how, type, NULL);
+					if (message) {
+						for (raw_header = ((CamelMimePart *)message)->headers; raw_header && !truth; raw_header = raw_header->next) {
+							if (!g_ascii_strcasecmp (raw_header->name, headername)) {
+								truth = camel_search_header_match(raw_header->value, argv[i]->value.string, how, type, charset);
+							}
+						}
+					} else
+						truth = camel_search_header_match(header, argv[i]->value.string, how, type, charset);
 				}
 			}
 		}
+
+		if (message)
+			camel_object_unref (message);
 	}
 	/* TODO: else, find all matches */
 
@@ -1100,25 +1180,117 @@
 	return r;
 }
 
+static ESExpResult *
+search_header_soundex (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search)
+{
+	return check_header (f, argc, argv, search, CAMEL_SEARCH_MATCH_SOUNDEX);
+}
+
+static ESExpResult *
+search_header_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search)
+{
+	ESExpResult *r;
+	CamelMimeMessage *msg;
+
+	msg = get_current_message (search);
+
+	if (msg) {
+		regex_t pattern;
+		const char *contents;
+
+		r = e_sexp_result_new (f, ESEXP_RES_BOOL);
+
+		if (argc > 1 && argv[0]->type == ESEXP_RES_STRING
+		    && (contents = camel_medium_get_header (CAMEL_MEDIUM (msg), argv[0]->value.string))
+		    && camel_search_build_match_regex (&pattern, CAMEL_SEARCH_MATCH_REGEX|CAMEL_SEARCH_MATCH_ICASE, argc-1, argv+1, search->priv->ex) == 0) {
+			r->value.bool = regexec (&pattern, contents, 0, NULL, 0) == 0;
+			regfree (&pattern);
+		} else
+			r->value.bool = FALSE;
+
+		camel_object_unref (msg);
+	} else {
+		r = e_sexp_result_new (f, ESEXP_RES_ARRAY_PTR);
+		r->value.ptrarray = g_ptr_array_new();
+	}
+
+	return r;
+}
+
+static gchar *
+get_full_header (CamelMimeMessage *message)
+{
+	CamelMimePart *mp = CAMEL_MIME_PART (message);
+	GString *str = g_string_new ("");
+	struct _camel_header_raw *h;
+	
+	for (h = mp->headers; h; h = h->next) {
+		if (h->value != NULL) {
+			g_string_append (str, h->name);
+			if (isspace (h->value[0]))
+				g_string_append (str, ":");
+			else
+				g_string_append (str, ": ");
+			g_string_append (str, h->value);
+			g_string_append_c (str, '\n');
+		}
+	}
+	
+	return g_string_free (str, FALSE);
+}
+
+static ESExpResult *
+search_header_full_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search)
+{
+	ESExpResult *r;
+	CamelMimeMessage *msg;
+
+	msg = get_current_message (search);
+
+	if (msg) {
+		regex_t pattern;
+
+		r = e_sexp_result_new (f, ESEXP_RES_BOOL);
+
+		if (camel_search_build_match_regex (&pattern, CAMEL_SEARCH_MATCH_REGEX|CAMEL_SEARCH_MATCH_ICASE|CAMEL_SEARCH_MATCH_NEWLINE, argc, argv, search->priv->ex) == 0) {
+			char *contents;
+
+			contents = get_full_header (msg);
+			r->value.bool = regexec (&pattern, contents, 0, NULL, 0) == 0;
+
+			g_free (contents);
+			regfree (&pattern);
+		} else
+			r->value.bool = FALSE;
+
+		camel_object_unref (msg);
+	} else {
+		r = e_sexp_result_new (f, ESEXP_RES_ARRAY_PTR);
+		r->value.ptrarray = g_ptr_array_new();
+	}
+
+	return r;
+}
+
 /* this is just to OR results together */
-struct _glib_sux_donkeys {
+struct IterData {
 	int count;
 	GPtrArray *uids;
 };
 
 /* or, store all unique values */
 static void
-g_lib_sux_htor(char *key, int value, struct _glib_sux_donkeys *fuckup)
+htor(char *key, int value, struct IterData *iter_data)
 {
-	g_ptr_array_add(fuckup->uids, key);
+	g_ptr_array_add(iter_data->uids, key);
 }
 
 /* and, only store duplicates */
 static void
-g_lib_sux_htand(char *key, int value, struct _glib_sux_donkeys *fuckup)
+htand(char *key, int value, struct IterData *iter_data)
 {
-	if (value == fuckup->count)
-		g_ptr_array_add(fuckup->uids, key);
+	if (value == iter_data->count)
+		g_ptr_array_add(iter_data->uids, key);
 }
 
 static int
@@ -1163,7 +1335,7 @@
 {
 	GPtrArray *result = g_ptr_array_new();
 	GHashTable *ht = g_hash_table_new(g_str_hash, g_str_equal);
-	struct _glib_sux_donkeys lambdafoo;
+	struct IterData lambdafoo;
 	CamelIndexCursor *wc, *nc;
 	const char *word, *name;
 	int i;
@@ -1193,7 +1365,7 @@
 
 		lambdafoo.uids = result;
 		lambdafoo.count = (1<<words->len) - 1;
-		g_hash_table_foreach(ht, (GHFunc)g_lib_sux_htand, &lambdafoo);
+		g_hash_table_foreach(ht, (GHFunc)htand, &lambdafoo);
 		g_hash_table_destroy(ht);
 	}
 
@@ -1310,7 +1482,7 @@
 	CamelException *ex = search->priv->ex;
 	struct _camel_search_words *words;
 	ESExpResult *r;
-	struct _glib_sux_donkeys lambdafoo;
+	struct IterData lambdafoo;
 
 	if (search->current) {	
 		int truth = FALSE;
@@ -1367,7 +1539,7 @@
 				}
 			}
 			lambdafoo.uids = r->value.ptrarray;
-			g_hash_table_foreach(ht, (GHFunc)g_lib_sux_htor, &lambdafoo);
+			g_hash_table_foreach(ht, (GHFunc)htor, &lambdafoo);
 			g_hash_table_destroy(ht);
 		}
 	}
@@ -1376,6 +1548,58 @@
 }
 
 static ESExpResult *
+search_body_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search)
+{
+	ESExpResult *r;
+	CamelMimeMessage *msg = get_current_message (search);
+
+	if (msg) {
+		regex_t pattern;
+
+		r = e_sexp_result_new (f, ESEXP_RES_BOOL);
+	
+		if (camel_search_build_match_regex (&pattern, CAMEL_SEARCH_MATCH_ICASE|CAMEL_SEARCH_MATCH_REGEX|CAMEL_SEARCH_MATCH_NEWLINE, argc, argv, search->priv->ex) == 0) {
+			r->value.bool = camel_search_message_body_contains ((CamelDataWrapper *) msg, &pattern);
+			regfree (&pattern);
+		} else
+			r->value.bool = FALSE;
+
+		camel_object_unref (msg);
+	} else {
+		regex_t pattern;
+
+		r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR);
+		r->value.ptrarray = g_ptr_array_new ();
+
+		if (camel_search_build_match_regex (&pattern, CAMEL_SEARCH_MATCH_ICASE|CAMEL_SEARCH_MATCH_REGEX|CAMEL_SEARCH_MATCH_NEWLINE, argc, argv, search->priv->ex) == 0) {
+			int i;
+			GPtrArray *v = search->summary_set?search->summary_set:search->summary;
+			CamelException x = CAMEL_EXCEPTION_INITIALISER;
+			CamelMimeMessage *message;
+
+			for (i = 0; i < v->len; i++) {
+				char *uid = g_ptr_array_index(v, i);
+
+				message = camel_folder_get_message (search->folder, uid, &x);
+				if (message) {
+					if (camel_search_message_body_contains ((CamelDataWrapper *) message, &pattern)) {
+						g_ptr_array_add (r->value.ptrarray, uid);
+					}
+
+					camel_object_unref ((CamelObject *)message);
+				} else {
+					camel_exception_clear (&x);
+				}
+			}
+		
+			regfree (&pattern);
+		}
+	}
+	
+	return r;
+}
+
+static ESExpResult *
 search_user_flag(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search)
 {
 	ESExpResult *r;
@@ -1560,3 +1784,43 @@
 	g_ptr_array_add (matches, (gpointer) camel_pstring_strdup (cols [0]));
 	return 0;
 }
+
+static ESExpResult *
+search_message_location (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search)
+{
+	ESExpResult *r;
+	gboolean same = FALSE;
+
+	if (argc == 1 && argv[0]->type == ESEXP_RES_STRING) {
+		if (argv[0]->value.string && search->folder && search->folder->parent_store && camel_folder_get_full_name (search->folder)) {
+			CamelFolderInfo *fi = camel_store_get_folder_info (search->folder->parent_store, camel_folder_get_full_name (search->folder), 0, NULL);
+			if (fi) {
+				same = g_str_equal (fi->uri ? fi->uri : "", argv[0]->value.string);
+
+				camel_store_free_folder_info (search->folder->parent_store, fi);
+			}
+		}
+	}
+
+	if (search->current) {
+		r = e_sexp_result_new (f, ESEXP_RES_BOOL);
+		r->value.bool = same ? TRUE : FALSE;
+	} else {
+		r = e_sexp_result_new (f, ESEXP_RES_ARRAY_PTR);
+		r->value.ptrarray = g_ptr_array_new ();
+
+		if (same) {
+			/* all matches */
+			int i;
+			GPtrArray *v = search->summary_set ? search->summary_set : search->summary;
+
+			for (i = 0; i < v->len; i++) {
+				char *uid = g_ptr_array_index (v, i);
+
+				g_ptr_array_add (r->value.ptrarray, uid);
+			}
+		}
+	}
+
+	return r;
+}

Modified: branches/camel-gobject/camel/camel-folder-search.h
==============================================================================
--- branches/camel-gobject/camel/camel-folder-search.h	(original)
+++ branches/camel-gobject/camel/camel-folder-search.h	Thu Apr 16 01:23:17 2009
@@ -74,6 +74,9 @@
 	/* (body-contains "string1" "string2" ...) Returns a list of matches, or true if in single-message mode */
 	ESExpResult * (*body_contains)(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
 
+	/* (body-regex "regex") Returns a list of matches, or true if in single-message mode */
+	ESExpResult * (*body_regex)(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
+
 	/* (header-contains "headername" "string1" ...) List of matches, or true if in single-message mode */
 	ESExpResult * (*header_contains)(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
 	
@@ -89,6 +92,15 @@
 	/* (header-exists "headername") */
 	ESExpResult * (*header_exists)(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
 	
+	/* (header-soundex "headername" "string") */
+	ESExpResult * (*header_soundex)(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
+
+	/* (header-regex "headername" "regex_string") */
+	ESExpResult * (*header_regex)(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
+
+	/* (header-full-regex "regex") */
+	ESExpResult * (*header_full_regex)(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
+
 	/* (user-flag "flagname" "flagname" ...) If one of user-flag set */
 	ESExpResult * (*user_flag)(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
 
@@ -112,6 +124,10 @@
 
 	/* (uid "uid" ...) True if the uid is in the list */
 	ESExpResult * (*uid)(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
+	
+	/* (message-location "folder_string") True if the message is in the folder's full name "folder_string" */
+	ESExpResult * (*message_location)(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s);
+	
 };
 
 GType		camel_folder_search_get_type	(void);

Modified: branches/camel-gobject/camel/camel-folder-summary.c
==============================================================================
--- branches/camel-gobject/camel/camel-folder-summary.c	(original)
+++ branches/camel-gobject/camel/camel-folder-summary.c	Thu Apr 16 01:23:17 2009
@@ -579,8 +579,10 @@
 
 	
 		ret = camel_db_read_message_info_record_with_uid (cdb, folder_name, uid, &data, camel_read_mir_callback, &ex);
-		if (ret != 0)
+		if (ret != 0) {
+			camel_exception_clear (&ex);
 			return NULL;
+		}
 		
 		CAMEL_SUMMARY_LOCK(s, summary_lock);
 		CAMEL_SUMMARY_LOCK(s, ref_lock);
@@ -920,8 +922,6 @@
 	if (!g_getenv("CAMEL_FREE_INFOS") && !s->timeout_handle) 
 		s->timeout_handle = g_timeout_add_seconds (SUMMARY_CACHE_DROP, (GSourceFunc) cfs_try_release_memory, s);
 
-	d(printf("Triggering summary_reloaded on %s %p\n", s->folder->full_name, s));
-	camel_object_trigger_event(s, "summary_reloaded", s);
 	return ret == 0 ? 0 : -1;
 }
 
@@ -1371,9 +1371,10 @@
 			}
 	}
 
-	/* Reset the flags */
+	/* Reset the dirty flag which decides if the changes are synced to the DB or not. 
+	The FOLDER_FLAGGED should be used to check if the changes are synced to the server. 
+	So, dont unset the FOLDER_FLAGGED flag */
 	mi->dirty = FALSE;
-	mi->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
 	
 	camel_db_camel_mir_free (mir);	
 }
@@ -1776,7 +1777,8 @@
 	/* FIXME[disk-summary] SHould we ref it or redesign it later on */
 	/* The uid array should have its own memory. We will unload the infos when not reqd.*/
 	g_ptr_array_add (s->uids, (gpointer) camel_pstring_strdup((camel_message_info_uid(info))));
-	
+	g_hash_table_replace (_PRIVATE(s)->flag_cache, (char *)info->uid, GUINT_TO_POINTER(camel_message_info_flags(info)));
+
 	g_hash_table_insert (s->loaded_infos, (gpointer) camel_message_info_uid (info), info);
 	s->flags |= CAMEL_SUMMARY_DIRTY;
 
@@ -1807,9 +1809,13 @@
 		g_ptr_array_add (s->uids, (char *) camel_pstring_strdup(camel_message_info_uid(info)));
 	
 	g_hash_table_insert (s->loaded_infos, (char *) camel_message_info_uid (info), info);
+	if (load) {
+		g_hash_table_replace (_PRIVATE(s)->flag_cache, (char *)info->uid, GUINT_TO_POINTER(camel_message_info_flags(info)));
+	}
+
 	if (!load)
 		s->flags |= CAMEL_SUMMARY_DIRTY;
-
+	
 	CAMEL_SUMMARY_UNLOCK(s, summary_lock);	
 }
 
@@ -3675,7 +3681,7 @@
 		if (!calendar_header)
 			calendar_header = camel_mime_parser_header (mp, "X-Calendar-Attachment", NULL);
 
-		if (calendar_header)
+		if (calendar_header || camel_content_type_is (ct, "text", "calendar"))
 			camel_message_info_set_user_flag (msginfo, "$has_cal", TRUE);
 
 		if (p->index && camel_content_type_is(ct, "text", "*")) {
@@ -3850,7 +3856,7 @@
 			break;
 	}
 
-	if (header)
+	if (header || camel_content_type_is (ct, "text", "calendar"))
 		camel_message_info_set_user_flag (msginfo, "$has_cal", TRUE);
 
 	/* using the object types is more accurate than using the mime/types */
@@ -4685,7 +4691,8 @@
 		if (((junk && !(mi->flags & CAMEL_MESSAGE_DELETED)))||  (deleted && !(mi->flags & CAMEL_MESSAGE_JUNK)) )
 			mi->summary->visible_count -= junk ? junk : deleted;
 	}
-
+	if (mi->uid)
+		g_hash_table_replace (_PRIVATE(mi->summary)->flag_cache, (char *)mi->uid, GUINT_TO_POINTER(mi->flags));
 	if (mi->summary && mi->summary->folder && mi->uid) {
 		CamelFolderChangeInfo *changes = camel_folder_change_info_new();
 
@@ -4700,7 +4707,11 @@
 	return TRUE;
 }
 
-
+void
+camel_folder_summary_update_flag_cache (CamelFolderSummary *s, const char *uid, guint32 flag)
+{
+	g_hash_table_replace (_PRIVATE(s)->flag_cache, (char *) uid, GUINT_TO_POINTER(flag));	
+}
 /**
  * camel_message_info_set_flags:
  * @mi: a #CamelMessageInfo
@@ -4905,6 +4916,4 @@
 
 	klass->info_set_flags = info_set_flags;
 	
-	camel_object_class_add_event(camel_object_class, "summary_reloaded", NULL);
-	
 }

Modified: branches/camel-gobject/camel/camel-folder-summary.h
==============================================================================
--- branches/camel-gobject/camel/camel-folder-summary.h	(original)
+++ branches/camel-gobject/camel/camel-folder-summary.h	Thu Apr 16 01:23:17 2009
@@ -408,6 +408,7 @@
 GHashTable *camel_folder_summary_get_hashtable(CamelFolderSummary *s);
 void camel_folder_summary_free_hashtable (GHashTable *ht);
 GHashTable *camel_folder_summary_get_flag_cache (CamelFolderSummary *summary);
+void camel_folder_summary_update_flag_cache (CamelFolderSummary *s, const char *uid, guint32 flag);
 
 /* basically like strings, but certain keywords can be compressed and de-cased */
 int camel_folder_summary_encode_token(FILE *out, const char *str);

Modified: branches/camel-gobject/camel/camel-folder.c
==============================================================================
--- branches/camel-gobject/camel/camel-folder.c	(original)
+++ branches/camel-gobject/camel/camel-folder.c	Thu Apr 16 01:23:17 2009
@@ -88,6 +88,7 @@
 			    CamelException *ex);
 
 static GPtrArray        *get_uids            (CamelFolder *folder);
+static GPtrArray 	*get_uncached_uids   (CamelFolder *, GPtrArray * uids, CamelException *);
 static void              free_uids           (CamelFolder *folder,
 					      GPtrArray *array);
 static void              sort_uids           (CamelFolder *folder,
@@ -121,6 +122,10 @@
 static gboolean        folder_changed        (CamelObject *object,
 					      gpointer event_data);
 
+static char*           get_filename          (CamelFolder *folder, 
+					      const char *uid, 
+					      CamelException *ex);
+
 static CamelFolderQuotaInfo *get_quota_info  (CamelFolder *folder);
 
 static void
@@ -148,6 +153,7 @@
 	camel_folder_class->set_message_user_tag = set_message_user_tag;
 	camel_folder_class->get_message = get_message;
 	camel_folder_class->get_uids = get_uids;
+	camel_folder_class->get_uncached_uids = get_uncached_uids;
 	camel_folder_class->free_uids = free_uids;
 	camel_folder_class->sort_uids = sort_uids;
 	camel_folder_class->get_summary = get_summary;
@@ -163,9 +169,11 @@
 	camel_folder_class->delete = delete;
 	camel_folder_class->rename = folder_rename;
 	camel_folder_class->freeze = freeze;
+	camel_folder_class->sync_message = NULL;
 	camel_folder_class->thaw = thaw;
 	camel_folder_class->is_frozen = is_frozen;
 	camel_folder_class->get_quota_info = get_quota_info;
+	camel_folder_class->get_filename = get_filename;
 
 	/* virtual method overload */
 	camel_object_class->getv = folder_getv;
@@ -233,6 +241,19 @@
 	return camel_folder_type;
 }
 
+static char*
+get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	w(g_warning ("CamelFolder::get_filename not implemented for '%s'",
+		     camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder))));
+	return g_strdup ("/dev/null");
+}
+
+char *
+camel_folder_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	return CF_CLASS (folder)->get_filename (folder, uid, ex);
+}
 
 /**
  * camel_folder_construct:
@@ -1137,12 +1158,38 @@
 	return ret;
 }
 
+/**
+ * camel_folder_sync_message:
+ * @folder: a #CamelFolder object
+ * @uid: the UID
+ * @ex: a #CamelException
+ *
+ * Ensure that a message identified by UID has been synced in the folder (so
+ * that camel_folder_get_message on it later will work in offline mode).
+ *
+ * Returns: void.
+ **/
+void
+camel_folder_sync_message (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	CAMEL_FOLDER_REC_LOCK(folder, lock);
+
+	/* Use the sync_message method if the class implements it. */
+	if (CF_CLASS (folder)->sync_message)
+		CF_CLASS (folder)->sync_message (folder, uid, ex);
+	else {
+		CamelMimeMessage *message;
+		message = CF_CLASS (folder)->get_message (folder, uid, ex);
+		if (message)
+			  camel_object_unref(message);
+	}
+	CAMEL_FOLDER_REC_UNLOCK(folder, lock);
+}
+
 static GPtrArray *
 get_uids(CamelFolder *folder)
 {
-	GPtrArray *array;
-	int i, j, count;
-
 	g_return_val_if_fail(folder->summary != NULL, g_ptr_array_new ());
 
 	return camel_folder_summary_array (folder->summary);
@@ -1200,6 +1247,41 @@
 }
 
 
+/**
+ * Default: return the uids we are given.
+ */
+static GPtrArray *
+get_uncached_uids (CamelFolder *folder, GPtrArray * uids, CamelException *ex)
+{
+	GPtrArray *result;
+	int i;
+
+	result = g_ptr_array_new();
+
+	g_ptr_array_set_size(result, uids->len);
+	for (i = 0; i < uids->len; i++)
+	    result->pdata[i] = (char *)camel_pstring_strdup(uids->pdata[i]);
+	return result;
+}
+
+/**
+ * camel_folder_get_uncached_uids:
+ * @folder: a #CamelFolder object
+ * @uids: the array of uids to filter down to uncached ones.
+ *
+ * Returns the known-uncached uids from a list of uids. It may return uids
+ * which are locally cached but should never filter out a uid which is not
+ * locally cached. Free the result by called #camel_folder_free_uids.
+ * Frees the array of UIDs returned by #camel_folder_get_uids.
+ **/
+GPtrArray *
+camel_folder_get_uncached_uids (CamelFolder *folder, GPtrArray * uids, CamelException *ex)
+{
+	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
+	return CF_CLASS (folder)->get_uncached_uids(folder, uids, ex);
+}
+
+
 static int
 uidcmp (const void *v0, const void *v1)
 {

Modified: branches/camel-gobject/camel/camel-folder.h
==============================================================================
--- branches/camel-gobject/camel/camel-folder.h	(original)
+++ branches/camel-gobject/camel/camel-folder.h	Thu Apr 16 01:23:17 2009
@@ -211,6 +211,11 @@
 	
 	CamelFolderQuotaInfo * (*get_quota_info) (CamelFolder *folder);
 	guint32	(*count_by_expression) (CamelFolder *, const char *, CamelException *);
+	void (*sync_message)  (CamelFolder *folder,
+                               const char *uid, 
+                               CamelException *ex);
+        GPtrArray * (*get_uncached_uids)(CamelFolder *, GPtrArray * uids, CamelException *);
+	char * (*get_filename) (CamelFolder *, const char *uid, CamelException *);
 } CamelFolderClass;
 
 /* Standard Camel function */
@@ -303,12 +308,18 @@
 CamelMimeMessage * camel_folder_get_message           (CamelFolder *folder, 
 						       const char *uid, 
 						       CamelException *ex);
+void               camel_folder_sync_message          (CamelFolder *folder, 
+						       const char *uid, 
+						       CamelException *ex);
 #define camel_folder_delete_message(folder, uid) \
 	camel_folder_set_message_flags (folder, uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN)
 
 GPtrArray *        camel_folder_get_uids              (CamelFolder *folder);
 void               camel_folder_free_uids             (CamelFolder *folder,
 						       GPtrArray *array);
+GPtrArray *        camel_folder_get_uncached_uids     (CamelFolder *,
+                                                       GPtrArray * uids,
+                                                       CamelException *);
 void               camel_folder_sort_uids             (CamelFolder *folder,
 						       GPtrArray *uids);
 
@@ -353,6 +364,8 @@
 void camel_folder_free_shallow (CamelFolder *folder, GPtrArray *array);
 void camel_folder_free_deep    (CamelFolder *folder, GPtrArray *array);
 
+char * camel_folder_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
+
 /* update functions for change info */
 CamelFolderChangeInfo *	camel_folder_change_info_new		(void);
 void			camel_folder_change_info_clear		(CamelFolderChangeInfo *info);

Modified: branches/camel-gobject/camel/camel-gpg-context.c
==============================================================================
--- branches/camel-gobject/camel/camel-gpg-context.c	(original)
+++ branches/camel-gobject/camel/camel-gpg-context.c	Thu Apr 16 01:23:17 2009
@@ -896,6 +896,16 @@
 				/* FIXME: save this state? */
 			}
 			break;
+		case GPG_CTX_MODE_DECRYPT:
+			if (!strncmp ((char *) status, "BEGIN_DECRYPTION", 16)) {
+				/* nothing to do... but we know to expect data on stdout soon */
+				break;
+			} else if (!strncmp ((char *) status, "END_DECRYPTION", 14)) {
+				/* nothing to do, but we know the end is near? */
+				break;
+			}
+			/* let if fall through to verify possible signatures too */
+			/* break; */
 		case GPG_CTX_MODE_VERIFY:
 			if (!strncmp ((char *) status, "TRUST_", 6)) {
 				status += 6;
@@ -937,13 +947,6 @@
 				return -1;
 			}
 			break;
-		case GPG_CTX_MODE_DECRYPT:
-			if (!strncmp ((char *) status, "BEGIN_DECRYPTION", 16)) {
-				/* nothing to do... but we know to expect data on stdout soon */
-			} else if (!strncmp ((char *) status, "END_DECRYPTION", 14)) {
-				/* nothing to do, but we know the end is near? */
-			}
-			break;
 		case GPG_CTX_MODE_IMPORT:
 			/* noop */
 			break;
@@ -1433,9 +1436,11 @@
 	char *sigfile = NULL;
 	CamelContentType *ct;
 	CamelMimePart *sigpart;
-	CamelStream *istream = NULL;
+	CamelStream *istream = NULL, *canon_stream;
 	CamelMultipart *mps;
-	
+	CamelStreamFilter *filter;
+	CamelMimeFilter *canon;
+
 	mps = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)ipart);
 	ct = ((CamelDataWrapper *)mps)->mime_type;
 	
@@ -1522,11 +1527,26 @@
 	}
 	
 	camel_stream_reset(istream);
+	canon_stream = camel_stream_mem_new ();
+
+	/* strip trailing white-spaces */
+	filter = camel_stream_filter_new_with_stream (canon_stream);
+	canon = camel_mime_filter_canon_new (CAMEL_MIME_FILTER_CANON_CRLF | CAMEL_MIME_FILTER_CANON_STRIP);
+	camel_stream_filter_add (filter, canon);
+	camel_object_unref (canon);
+
+	camel_stream_write_to_stream (istream, (CamelStream *)filter);
+
+	camel_object_unref (filter);
+	camel_stream_reset (istream);
+
+	camel_stream_reset (canon_stream);
+
 	gpg = gpg_ctx_new (context->session);
 	gpg_ctx_set_mode (gpg, GPG_CTX_MODE_VERIFY);
 	if (sigfile)
                 gpg_ctx_set_sigfile (gpg, sigfile);
-	gpg_ctx_set_istream (gpg, istream);
+	gpg_ctx_set_istream (gpg, canon_stream);
 	
 	if (gpg_ctx_op_start (gpg) == -1) {
 		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
@@ -1563,6 +1583,7 @@
 		g_free (sigfile);
 	}
 	g_object_unref(istream);
+	camel_object_unref (canon_stream);
 	
 	return validity;
 	

Modified: branches/camel-gobject/camel/camel-http-stream.c
==============================================================================
--- branches/camel-gobject/camel/camel-http-stream.c	(original)
+++ branches/camel-gobject/camel/camel-http-stream.c	Thu Apr 16 01:23:17 2009
@@ -425,14 +425,20 @@
 		if (http_connect (http, http->proxy ? http->proxy : http->url) == NULL)
 			return -1;
 		
-		if (http_method_invoke (http) == -1)
+		if (http_method_invoke (http) == -1) {
+			http_disconnect(http);
 			return -1;
+		}
 		
-		if (http_get_statuscode (http) == -1)
+		if (http_get_statuscode (http) == -1) {
+			http_disconnect(http);
 			return -1;
+		}
 		
-		if (http_get_headers (http) == -1)
+		if (http_get_headers (http) == -1) {
+			http_disconnect(http);
 			return -1;
+		}
 		
 		switch (http->statuscode) {
 		case 200:
@@ -481,6 +487,9 @@
 		}
 	}
 	
+	if (n == 0)
+		return 0;
+	
 	nread = camel_mime_parser_read (http->parser, &parser_buf, n);
 	
 	if (nread > 0)
@@ -540,13 +549,7 @@
 	g_return_val_if_fail (CAMEL_IS_HTTP_STREAM (http_stream), NULL);
 
 	if (!http_stream->content_type && !http_stream->raw) {
-		if (http_connect (http_stream, http_stream->proxy ? http_stream->proxy : http_stream->url) == NULL)
-			return NULL;
-
-		if (http_method_invoke (http_stream) == -1)
-			return NULL;
-
-		if (http_get_headers (http_stream) == -1)
+		if (stream_read (CAMEL_STREAM (http_stream), NULL, 0) == -1)
 			return NULL;
 	}
 

Modified: branches/camel-gobject/camel/camel-iconv.c
==============================================================================
--- branches/camel-gobject/camel/camel-iconv.c	(original)
+++ branches/camel-gobject/camel/camel-iconv.c	Thu Apr 16 01:23:17 2009
@@ -193,7 +193,6 @@
 }
 
 
-/* fucking glib... */
 static const char *
 e_strdown (char *str)
 {

Modified: branches/camel-gobject/camel/camel-index.h
==============================================================================
--- branches/camel-gobject/camel/camel-index.h	(original)
+++ branches/camel-gobject/camel/camel-index.h	Thu Apr 16 01:23:17 2009
@@ -24,26 +24,69 @@
 #include <camel/camel-exception.h>
 #include <camel/camel-object.h>
 
-#define CAMEL_INDEX(obj)         G_TYPE_CHECK_INSTANCE_CAST (obj, camel_index_get_type (), CamelIndex)
-#define CAMEL_INDEX_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, camel_index_get_type (), CamelIndexClass)
-#define CAMEL_IS_INDEX(obj)      G_TYPE_CHECK_INSTANCE_TYPE (obj, camel_index_get_type ())
+/* Standard GObject macros */
+#define CAMEL_TYPE_INDEX \
+	(camel_index_get_type ())
+#define CAMEL_INDEX(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), CAMEL_TYPE_INDEX, CamelIndex))
+#define CAMEL_INDEX_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), CAMEL_TYPE_INDEX, CamelIndexClass))
+#define CAMEL_IS_INDEX(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), CAMEL_TYPE_INDEX))
+#define CAMEL_IS_INDEX_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), CAMEL_TYPE_INDEX))
+#define CAMEL_INDEX_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), CAMEL_TYPE_INDEX, CamelIndexClass))
+
+#define CAMEL_TYPE_INDEX_NAME \
+	(camel_index_name_get_type ())
+#define CAMEL_INDEX_NAME(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), CAMEL_TYPE_INDEX_NAME, CamelIndexName))
+#define CAMEL_INDEX_NAME_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), CAMEL_TYPE_INDEX_NAME, CamelIndexNameClass))
+#define CAMEL_IS_INDEX_NAME(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), CAMEL_TYPE_INDEX_NAME))
+#define CAMEL_IS_INDEX_NAME_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), CAMEL_TYPE_INDEX_NAME))
+#define CAMEL_INDEX_NAME_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), CAMEL_TYPE_INDEX_NAME, CamelIndexNameClass))
+
+#define CAMEL_TYPE_INDEX_CURSOR \
+	(camel_index_cursor_get_type ())
+#define CAMEL_INDEX_CURSOR(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), CAMEL_TYPE_INDEX_CURSOR, CamelIndexCursor))
+#define CAMEL_INDEX_CURSOR_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), CAMEL_TYPE_INDEX_CURSOR, CamelIndexCursorClass))
+#define CAMEL_IS_INDEX_CURSOR(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), CAMEL_TYPE_INDEX_CURSOR))
+#define CAMEL_IS_INDEX_CURSOR_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), CAMEL_TYPE_INDEX_CURSOR))
+#define CAMEL_INDEX_CURSOR_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), CAMEL_TYPE_INDEX_CURSOR, CamelIndexCursorClass))
 
 G_BEGIN_DECLS
 
 typedef struct _CamelIndex      CamelIndex;
 typedef struct _CamelIndexClass CamelIndexClass;
 
-#define CAMEL_INDEX_NAME(obj)         G_TYPE_CHECK_INSTANCE_CAST (obj, camel_index_name_get_type (), CamelIndexName)
-#define CAMEL_INDEX_NAME_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, camel_index_name_get_type (), CamelIndexNameClass)
-#define CAMEL_IS_INDEX_NAME(obj)      G_TYPE_CHECK_INSTANCE_TYPE (obj, camel_index_name_get_type ())
-
 typedef struct _CamelIndexName      CamelIndexName;
 typedef struct _CamelIndexNameClass CamelIndexNameClass;
 
-#define CAMEL_INDEX_CURSOR(obj)         G_TYPE_CHECK_INSTANCE_CAST (obj, camel_index_cursor_get_type (), CamelIndexCursor)
-#define CAMEL_INDEX_CURSOR_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, camel_index_cursor_get_type (), CamelIndexCursorClass)
-#define CAMEL_IS_INDEX_CURSOR(obj)      G_TYPE_CHECK_INSTANCE_TYPE (obj, camel_index_cursor_get_type ())
-
 typedef struct _CamelIndexCursor      CamelIndexCursor;
 typedef struct _CamelIndexCursorClass CamelIndexCursorClass;
 

Modified: branches/camel-gobject/camel/camel-lock-client.c
==============================================================================
--- branches/camel-gobject/camel/camel-lock-client.c	(original)
+++ branches/camel-gobject/camel/camel-lock-client.c	Thu Apr 16 01:23:17 2009
@@ -40,7 +40,7 @@
 
 #define d(x)
 
-/* dunno where this fucking thing is got from */
+/* dunno where this thing is got from */
 /* see also camel-lock.c */
 #define _(x) (x)
 
@@ -138,7 +138,6 @@
 		for (i=3;i<255;i++)
 			     close(i);
 		execl(CAMEL_LIBEXECDIR "/camel-lock-helper-" API_VERSION, "camel-lock-helper", NULL);
-		d(fprintf(stderr, "shit, couldn't exec lock helper!\n"));
 		/* it'll pick this up when it tries to use us */
 		exit(255);
 	default:

Modified: branches/camel-gobject/camel/camel-mime-filter-tohtml.c
==============================================================================
--- branches/camel-gobject/camel/camel-mime-filter-tohtml.c	(original)
+++ branches/camel-gobject/camel/camel-mime-filter-tohtml.c	Thu Apr 16 01:23:17 2009
@@ -134,6 +134,18 @@
 	return filter->outbuf + offset;
 }
 
+static char *
+append_string_verbatim (CamelMimeFilter *filter, const char *str, char *outptr, char **outend)
+{
+	size_t len = strlen (str);
+
+	outptr = check_size (filter, outptr, outend, len);
+	memcpy(outptr, str, len);
+	outptr += len;
+
+	return outptr;
+}
+
 static int
 citation_depth (const char *in)
 {
@@ -303,7 +315,7 @@
 		
 #define CONVERT_URLS (CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS | CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES)
 		if (html->flags & CONVERT_URLS) {
-			size_t matchlen, buflen, len;
+			size_t matchlen, len;
 			urlmatch_t match;
 			
 			len = inptr - start;
@@ -319,25 +331,30 @@
 					
 					matchlen = match.um_eo - match.um_so;
 					
-					buflen = 20 + strlen (match.prefix) + matchlen + matchlen;
-					outptr = check_size (filter, outptr, &outend, buflen);
-					
 					/* write out the href tag */
-					outptr = g_stpcpy (outptr, "<a href=\"");
-					outptr = g_stpcpy (outptr, match.prefix);
-					memcpy (outptr, start, matchlen);
-					outptr += matchlen;
-					outptr = g_stpcpy (outptr, "\">");
+					outptr = append_string_verbatim (filter, "<a href=\"", outptr, &outend);
+					/* prefix shouldn't need escaping, but let's be safe */
+					outptr = writeln (filter,
+							(const unsigned char *)match.prefix,
+							(const unsigned char *)match.prefix + strlen (match.prefix),
+							outptr, &outend);
+					outptr = writeln (filter,
+							(const unsigned char *)start,
+							(const unsigned char *)start + matchlen,
+							outptr, &outend);
+					outptr = append_string_verbatim (filter, "\">", outptr, &outend);
 					
 					/* now write the matched string */
-					memcpy (outptr, start, matchlen);
+					outptr = writeln (filter,
+							(const unsigned char *)start,
+							(const unsigned char *)start + matchlen,
+							outptr, &outend);
 					html->column += matchlen;
-					outptr += matchlen;
 					start += matchlen;
 					len -= matchlen;
 					
 					/* close the href tag */
-					outptr = g_stpcpy (outptr, "</a>");
+					outptr = append_string_verbatim (filter, "</a>", outptr, &outend);
 				} else {
 					/* nothing matched so write out the remainder of this line buffer */
 					outptr = writeln (filter, (const unsigned char *)start, (const unsigned char *)start + len, outptr, &outend);

Modified: branches/camel-gobject/camel/camel-mime-filter-tohtml.h
==============================================================================
--- branches/camel-gobject/camel/camel-mime-filter-tohtml.h	(original)
+++ branches/camel-gobject/camel/camel-mime-filter-tohtml.h	Thu Apr 16 01:23:17 2009
@@ -68,7 +68,7 @@
 CamelMimeFilter *camel_mime_filter_tohtml_new (guint32 flags, guint32 colour);
 
 
-/* utility functions to replace e_text_to_html shit */
+/* utility functions to replace e_text_to_html */
 
 char *camel_text_to_html (const char *in, guint32 flags, guint32 colour);
 

Modified: branches/camel-gobject/camel/camel-mime-part-utils.c
==============================================================================
--- branches/camel-gobject/camel/camel-mime-part-utils.c	(original)
+++ branches/camel-gobject/camel/camel-mime-part-utils.c	Thu Apr 16 01:23:17 2009
@@ -94,7 +94,7 @@
 	switch (camel_mime_parser_state (mp)) {
 	case CAMEL_MIME_PARSER_STATE_HEADER:
 		d(printf("Creating body part\n"));
-		/* multipart/signed is some fucked up type that we must treat as binary data, fun huh, idiots. */
+		/* multipart/signed is some type that we must treat as binary data. */
 		if (camel_content_type_is (ct, "multipart", "signed")) {
 			content = (CamelDataWrapper *) camel_multipart_signed_new ();
 			camel_multipart_construct_from_parser ((CamelMultipart *) content, mp);

Modified: branches/camel-gobject/camel/camel-mime-utils.c
==============================================================================
--- branches/camel-gobject/camel/camel-mime-utils.c	(original)
+++ branches/camel-gobject/camel/camel-mime-utils.c	Thu Apr 16 01:23:17 2009
@@ -3683,7 +3683,6 @@
 	111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
 };
 
-/* hrm, is there a library for this shit? */
 static struct {
 	char *name;
 	int offset;

Modified: branches/camel-gobject/camel/camel-offline-folder.c
==============================================================================
--- branches/camel-gobject/camel/camel-offline-folder.c	(original)
+++ branches/camel-gobject/camel/camel-offline-folder.c	Thu Apr 16 01:23:17 2009
@@ -247,8 +247,7 @@
 offline_folder_downsync (CamelOfflineFolder *offline, const char *expression, CamelException *ex)
 {
 	CamelFolder *folder = (CamelFolder *) offline;
-	CamelMimeMessage *message;
-	GPtrArray *uids;
+	GPtrArray *uids, *uncached_uids = NULL;
 	int i;
 	
 	camel_operation_start (NULL, _("Syncing messages in folder '%s' to disk"), folder->full_name);
@@ -257,27 +256,29 @@
 		uids = camel_folder_search_by_expression (folder, expression, ex);
 	else
 		uids = camel_folder_get_uids (folder);
-	
-	if (!uids) {
-		camel_operation_end (NULL);
-		return;
+
+	if (!uids)
+	  	goto done;
+	uncached_uids = camel_folder_get_uncached_uids(folder, uids, ex);
+	if (uids) {
+		if (expression)
+			camel_folder_search_free (folder, uids);
+		else
+			camel_folder_free_uids (folder, uids);
 	}
 	
-	for (i = 0; i < uids->len; i++) {
-		int pc = i * 100 / uids->len;
-		
-		message = camel_folder_get_message (folder, uids->pdata[i], ex);
+	if (!uncached_uids)
+		goto done;
+	
+	for (i = 0; i < uncached_uids->len; i++) {
+		int pc = i * 100 / uncached_uids->len;
+		camel_folder_sync_message (folder, uncached_uids->pdata[i], ex);
 		camel_operation_progress (NULL, pc);
-		if (message == NULL)
-			break;
-		
-		g_object_unref (message);
 	}
-	
-	if (expression)
-		camel_folder_search_free (folder, uids);
-	else
-		camel_folder_free_uids (folder, uids);
+
+done:
+	if (uncached_uids)
+		camel_folder_free_uids(folder, uncached_uids);
 	
 	camel_operation_end (NULL);
 }

Modified: branches/camel-gobject/camel/camel-private.h
==============================================================================
--- branches/camel-gobject/camel/camel-private.h	(original)
+++ branches/camel-gobject/camel/camel-private.h	Thu Apr 16 01:23:17 2009
@@ -158,6 +158,7 @@
 	GMutex *summary_lock;		/* for locking vfolder summary */
 	GMutex *subfolder_lock;		/* for locking the subfolder list */
 	GMutex *changed_lock;		/* for locking the folders-changed list */
+	int unread_vfolder;
 };
 
 #define CAMEL_VEE_FOLDER_LOCK(f, l) \

Modified: branches/camel-gobject/camel/camel-sasl-ntlm.c
==============================================================================
--- branches/camel-gobject/camel/camel-sasl-ntlm.c	(original)
+++ branches/camel-gobject/camel/camel-sasl-ntlm.c	Thu Apr 16 01:23:17 2009
@@ -74,9 +74,8 @@
 
 #define NTLM_REQUEST "NTLMSSP\x00\x01\x00\x00\x00\x06\x82\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00"
 
-#define NTLM_CHALLENGE_NONCE_OFFSET      24
-#define NTLM_CHALLENGE_DOMAIN_OFFSET     48
-#define NTLM_CHALLENGE_DOMAIN_LEN_OFFSET 44
+#define NTLM_CHALLENGE_DOMAIN_OFFSET		12
+#define NTLM_CHALLENGE_NONCE_OFFSET		24
 
 #define NTLM_RESPONSE_HEADER         "NTLMSSP\x00\x03\x00\x00\x00"
 #define NTLM_RESPONSE_FLAGS          "\x82\x01"
@@ -93,22 +92,60 @@
 				  guchar results[24]);
 static void ntlm_lanmanager_hash (const char *password, char hash[21]);
 static void ntlm_nt_hash         (const char *password, char hash[21]);
-static void ntlm_set_string      (GByteArray *ba, int offset,
-				  const char *data, int len);
+
+typedef struct {
+	guint16 length;
+	guint16 allocated;
+	guint32 offset;
+} SecurityBuffer;
+
+static GString *
+ntlm_get_string (GByteArray *ba, int offset)
+{
+	SecurityBuffer *secbuf;
+	GString *string;
+	gchar *buf_string;
+	guint16 buf_length;
+	guint32 buf_offset;
+
+	secbuf = (SecurityBuffer *) &ba->data[offset];
+	buf_length = GUINT16_FROM_LE (secbuf->length);
+	buf_offset = GUINT32_FROM_LE (secbuf->offset);
+
+	if (ba->len < buf_offset + buf_length)
+		return NULL;
+
+	string = g_string_sized_new (buf_length);
+	buf_string = (gchar *) &ba->data[buf_offset];
+	g_string_append_len (string, buf_string, buf_length);
+
+	return string;
+}
+
+static void
+ntlm_set_string (GByteArray *ba, int offset, const char *data, int len)
+{
+	SecurityBuffer *secbuf;
+
+	secbuf = (SecurityBuffer *) &ba->data[offset];
+	secbuf->length = GUINT16_TO_LE (len);
+	secbuf->offset = GUINT32_TO_LE (ba->len);
+	secbuf->allocated = secbuf->length;
+
+	g_byte_array_append (ba, (guint8 *) data, len);
+}
 
 static GByteArray *
 ntlm_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex)
 {
 	GByteArray *ret;
 	guchar nonce[8], hash[21], lm_resp[24], nt_resp[24];
+	GString *domain;
 
 	ret = g_byte_array_new ();
 
-	if (!token || !token->len) {
-		g_byte_array_append (ret, (guint8 *) NTLM_REQUEST,
-				     sizeof (NTLM_REQUEST) - 1);
-		return ret;
-	}
+	if (!token || token->len < NTLM_CHALLENGE_NONCE_OFFSET + 8)
+		goto fail;
 
 	memcpy (nonce, token->data + NTLM_CHALLENGE_NONCE_OFFSET, 8);
 	ntlm_lanmanager_hash (sasl->service->url->passwd, (char *) hash);
@@ -116,7 +153,11 @@
 	ntlm_nt_hash (sasl->service->url->passwd, (char *) hash);
 	ntlm_calc_response (hash, nonce, nt_resp);
 
-	ret = g_byte_array_new ();
+	domain = ntlm_get_string (token, NTLM_CHALLENGE_DOMAIN_OFFSET);
+	if (domain == NULL)
+		goto fail;
+
+	/* Don't jump to 'fail' label after this point. */
 	g_byte_array_set_size (ret, NTLM_RESPONSE_BASE_SIZE);
 	memset (ret->data, 0, NTLM_RESPONSE_BASE_SIZE);
 	memcpy (ret->data, NTLM_RESPONSE_HEADER,
@@ -125,8 +166,7 @@
 		NTLM_RESPONSE_FLAGS, sizeof (NTLM_RESPONSE_FLAGS) - 1);
 
 	ntlm_set_string (ret, NTLM_RESPONSE_DOMAIN_OFFSET,
-			 (const char *) token->data + NTLM_CHALLENGE_DOMAIN_OFFSET,
-			 atoi ((char *) token->data + NTLM_CHALLENGE_DOMAIN_LEN_OFFSET));
+			 domain->str, domain->len);
 	ntlm_set_string (ret, NTLM_RESPONSE_USER_OFFSET,
 			 sasl->service->url->user,
 			 strlen (sasl->service->url->user));
@@ -138,6 +178,18 @@
 			 (const char *) nt_resp, sizeof (nt_resp));
 
 	sasl->authenticated = TRUE;
+
+	g_string_free (domain, TRUE);
+
+	goto exit;
+
+fail:
+	/* If the challenge is malformed, restart authentication.
+	 * XXX A malicious server could make this loop indefinitely. */
+	g_byte_array_append (ret, (guint8 *) NTLM_REQUEST,
+			     sizeof (NTLM_REQUEST) - 1);
+
+exit:
 	return ret;
 }
 
@@ -201,17 +253,6 @@
 	g_free (buf);
 }
 
-static void
-ntlm_set_string (GByteArray *ba, int offset, const char *data, int len)
-{
-	ba->data[offset    ] = ba->data[offset + 2] =  len       & 0xFF;
-	ba->data[offset + 1] = ba->data[offset + 3] = (len >> 8) & 0xFF;
-	ba->data[offset + 4] =  ba->len       & 0xFF;
-	ba->data[offset + 5] = (ba->len >> 8) & 0xFF;
-	g_byte_array_append (ba, (guint8 *) data, len);
-}
-
-
 #define KEYBITS(k,s) \
         (((k[(s)/8] << ((s)%8)) & 0xFF) | (k[(s)/8+1] >> (8-(s)%8)))
 

Modified: branches/camel-gobject/camel/camel-search-sql-sexp.c
==============================================================================
--- branches/camel-gobject/camel/camel-search-sql-sexp.c	(original)
+++ branches/camel-gobject/camel/camel-search-sql-sexp.c	Thu Apr 16 01:23:17 2009
@@ -297,11 +297,11 @@
 	ESExpResult *r;
 
 	d(printf("executing match-all: %d", argc));
-	if (argv[0]->type != ESEXP_TERM_TIME)
+	if (argv[0]->type != ESEXP_TERM_BOOL)
 		r = e_sexp_term_eval(f, argv[0]);
 	else {
 		r = e_sexp_result_new(f, ESEXP_RES_STRING);
-		r->value.string = g_strdup("");
+		r->value.string = g_strdup(argv[0]->value.bool ? "1" : "0");
 	}
 
 	return r;
@@ -371,7 +371,7 @@
 					value = get_db_safe_string (tstr);
 					g_free (tstr);
 				}
-				str = g_strdup_printf("(%s LIKE %s)", headername, value);
+				str = g_strdup_printf("(%s IS NOT NULL AND %s LIKE %s)", headername, headername, value);
 				g_free(value);
 			}
 		}
@@ -562,7 +562,7 @@
 static struct {
 	char *name;
 	ESExpFunc *func;
-	int builtin :1;
+	int immediate :1;
 } symbols[] = {
 	{ "and", (ESExpFunc *) func_and, 1 },
 	{ "or", (ESExpFunc *) func_or, 1},
@@ -571,8 +571,8 @@
 	{ ">", (ESExpFunc *)eval_gt, 1},
 	{ "<", (ESExpFunc *)eval_lt, 1},
 
-	{ "match-all", (ESExpFunc *)match_all, 0 },
-	{ "match-threads", (ESExpFunc *)match_threads, 0 },
+	{ "match-all", (ESExpFunc *)match_all, 1 },
+	{ "match-threads", (ESExpFunc *)match_threads, 1 },
 /* 	{ "body-contains", body_contains}, */ /* We don't store body on the db. */
 	{ "header-contains", header_contains, 0},
 	{ "header-matches", header_matches, 0},
@@ -603,8 +603,12 @@
 	sexp = e_sexp_new();
 
 	for(i=0;i<sizeof(symbols)/sizeof(symbols[0]);i++) {
-		e_sexp_add_function(sexp, 0, symbols[i].name,
-				    symbols[i].func, NULL);
+		if (symbols[i].immediate)
+			e_sexp_add_ifunction(sexp, 0, symbols[i].name,
+					    symbols[i].func, NULL);
+		else
+			e_sexp_add_function(sexp, 0, symbols[i].name,
+					    symbols[i].func, NULL);
 	}
 
 	e_sexp_input_text (sexp, sql, strlen (sql));

Modified: branches/camel-gobject/camel/camel-session.c
==============================================================================
--- branches/camel-gobject/camel/camel-session.c	(original)
+++ branches/camel-gobject/camel/camel-session.c	Thu Apr 16 01:23:17 2009
@@ -48,6 +48,8 @@
 #include "camel-string-utils.h"
 #include "camel-transport.h"
 #include "camel-url.h"
+#include "camel-folder.h"
+#include "camel-mime-message.h"
 
 #define d(x)
 
@@ -66,6 +68,7 @@
 static int session_thread_queue(CamelSession *session, CamelSessionThreadMsg *msg, int flags);
 static void session_thread_wait(CamelSession *session, int id);
 static void session_thread_status(CamelSession *session, CamelSessionThreadMsg *msg, const char *text, int pc);
+static void session_forward_to (CamelSession *session, CamelFolder *folder, CamelMimeMessage *message, const char *address, CamelException *ex);
 
 static void
 camel_session_init (CamelSession *session)
@@ -120,6 +123,8 @@
 	camel_session_class->thread_wait = session_thread_wait;
 	camel_session_class->thread_status = session_thread_status;
 
+	camel_session_class->forward_to = session_forward_to;
+
 	camel_object_class_add_event((CamelObjectClass *)camel_session_class, "online", NULL);
 }
 
@@ -809,3 +814,27 @@
 
 	return session->priv->junk_headers;
 }
+
+static void
+session_forward_to (CamelSession *session, CamelFolder *folder, CamelMimeMessage *message, const char *address, CamelException *ex)
+{
+	if (ex)
+		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Camel session doesn't support forwarding of a message."));
+}
+
+/**
+ * camel_session_forward_to:
+ * Forwards message to some address(es) in a given type. The meaning of the forward_type defines session itself.
+ * @session #CameSession. 
+ * @folder #CamelFolder where is @message located.
+ * @message Message to forward.
+ * @address Where forward to.
+ * @ex Exception.
+ **/
+void
+camel_session_forward_to (CamelSession *session, CamelFolder *folder, CamelMimeMessage *message, const char *address, CamelException *ex)
+{
+	g_return_if_fail (CAMEL_IS_SESSION (session));
+	
+	CS_CLASS (session)->forward_to (session, folder, message, address, ex);
+}

Modified: branches/camel-gobject/camel/camel-session.h
==============================================================================
--- branches/camel-gobject/camel/camel-session.h	(original)
+++ branches/camel-gobject/camel/camel-session.h	Thu Apr 16 01:23:17 2009
@@ -118,6 +118,11 @@
 					      int pc);
 	gboolean        (*lookup_addressbook)(CamelSession *session,
 					      const char *name);
+	void		(*forward_to)        (CamelSession *session,
+					      struct _CamelFolder *folder,
+					      struct _CamelMimeMessage *message,
+					      const char *address,
+					      CamelException *ex);
 } CamelSessionClass;
 
 
@@ -224,6 +229,12 @@
 gboolean           camel_session_lookup_addressbook (CamelSession *session,
 						     const char *name);
 
+void		   camel_session_forward_to         (CamelSession *session,
+						     struct _CamelFolder *folder,
+					             struct _CamelMimeMessage *message,
+						     const char *address,
+						     CamelException *ex);
+
 G_END_DECLS
 
 #endif /* CAMEL_SESSION_H */

Modified: branches/camel-gobject/camel/camel-smime-context.c
==============================================================================
--- branches/camel-gobject/camel/camel-smime-context.c	(original)
+++ branches/camel-gobject/camel/camel-smime-context.c	Thu Apr 16 01:23:17 2009
@@ -38,8 +38,10 @@
 #include <certdb.h>
 #include <pkcs11.h>
 #include <smime.h>
+#include <secerr.h>
 #include <pkcs11t.h>
 #include <pk11func.h>
+#include <secoid.h>
 
 #include <errno.h>
 
@@ -215,6 +217,214 @@
 	return CAMEL_CIPHER_HASH_DEFAULT;
 }
 
+static const char *
+nss_error_to_string (long errorcode)
+{
+	#define cs(a,b) case a: return b;
+	
+	switch (errorcode) {
+	cs (SEC_ERROR_IO, "An I/O error occurred during security authorization.")
+	cs (SEC_ERROR_LIBRARY_FAILURE, "security library failure.")
+	cs (SEC_ERROR_BAD_DATA, "security library: received bad data.")
+	cs (SEC_ERROR_OUTPUT_LEN, "security library: output length error.")
+	cs (SEC_ERROR_INPUT_LEN, "security library has experienced an input length error.")
+	cs (SEC_ERROR_INVALID_ARGS, "security library: invalid arguments.")
+	cs (SEC_ERROR_INVALID_ALGORITHM, "security library: invalid algorithm.")
+	cs (SEC_ERROR_INVALID_AVA, "security library: invalid AVA.")
+	cs (SEC_ERROR_INVALID_TIME, "Improperly formatted time string.")
+	cs (SEC_ERROR_BAD_DER, "security library: improperly formatted DER-encoded message.")
+	cs (SEC_ERROR_BAD_SIGNATURE, "Peer's certificate has an invalid signature.")
+	cs (SEC_ERROR_EXPIRED_CERTIFICATE, "Peer's Certificate has expired.")
+	cs (SEC_ERROR_REVOKED_CERTIFICATE, "Peer's Certificate has been revoked.")
+	cs (SEC_ERROR_UNKNOWN_ISSUER, "Peer's Certificate issuer is not recognized.")
+	cs (SEC_ERROR_BAD_KEY, "Peer's public key is invalid.")
+	cs (SEC_ERROR_BAD_PASSWORD, "The security password entered is incorrect.")
+	cs (SEC_ERROR_RETRY_PASSWORD, "New password entered incorrectly.  Please try again.")
+	cs (SEC_ERROR_NO_NODELOCK, "security library: no nodelock.")
+	cs (SEC_ERROR_BAD_DATABASE, "security library: bad database.")
+	cs (SEC_ERROR_NO_MEMORY, "security library: memory allocation failure.")
+	cs (SEC_ERROR_UNTRUSTED_ISSUER, "Peer's certificate issuer has been marked as not trusted by the user.")
+	cs (SEC_ERROR_UNTRUSTED_CERT, "Peer's certificate has been marked as not trusted by the user.")
+	cs (SEC_ERROR_DUPLICATE_CERT, "Certificate already exists in your database.")
+	cs (SEC_ERROR_DUPLICATE_CERT_NAME, "Downloaded certificate's name duplicates one already in your database.")
+	cs (SEC_ERROR_ADDING_CERT, "Error adding certificate to database.")
+	cs (SEC_ERROR_FILING_KEY, "Error refiling the key for this certificate.")
+	cs (SEC_ERROR_NO_KEY, "The private key for this certificate cannot be found in key database")
+	cs (SEC_ERROR_CERT_VALID, "This certificate is valid.")
+	cs (SEC_ERROR_CERT_NOT_VALID, "This certificate is not valid.")
+	cs (SEC_ERROR_CERT_NO_RESPONSE, "Cert Library: No Response")
+	cs (SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, "The certificate issuer's certificate has expired.  Check your system date and time.")
+	cs (SEC_ERROR_CRL_EXPIRED, "The CRL for the certificate's issuer has expired.  Update it or check your system date and time.")
+	cs (SEC_ERROR_CRL_BAD_SIGNATURE, "The CRL for the certificate's issuer has an invalid signature.")
+ 	cs (SEC_ERROR_CRL_INVALID, "New CRL has an invalid format.")
+	cs (SEC_ERROR_EXTENSION_VALUE_INVALID, "Certificate extension value is invalid.")
+	cs (SEC_ERROR_EXTENSION_NOT_FOUND, "Certificate extension not found.")
+	cs (SEC_ERROR_CA_CERT_INVALID, "Issuer certificate is invalid.")
+	cs (SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, "Certificate path length constraint is invalid.")
+	cs (SEC_ERROR_CERT_USAGES_INVALID, "Certificate usages field is invalid.")
+	cs (SEC_INTERNAL_ONLY, "**Internal ONLY module**")
+	cs (SEC_ERROR_INVALID_KEY, "The key does not support the requested operation.")
+	cs (SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, "Certificate contains unknown critical extension.")
+	cs (SEC_ERROR_OLD_CRL, "New CRL is not later than the current one.")
+	cs (SEC_ERROR_NO_EMAIL_CERT, "Not encrypted or signed: you do not yet have an email certificate.")
+	cs (SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, "Not encrypted: you do not have certificates for each of the recipients.")
+	cs (SEC_ERROR_NOT_A_RECIPIENT, "Cannot decrypt: you are not a recipient, or matching certificate and private key not found.")
+	cs (SEC_ERROR_PKCS7_KEYALG_MISMATCH, "Cannot decrypt: key encryption algorithm does not match your certificate.")
+	cs (SEC_ERROR_PKCS7_BAD_SIGNATURE, "Signature verification failed: no signer found, too many signers found, or improper or corrupted data.")
+	cs (SEC_ERROR_UNSUPPORTED_KEYALG, "Unsupported or unknown key algorithm.")
+	cs (SEC_ERROR_DECRYPTION_DISALLOWED, "Cannot decrypt: encrypted using a disallowed algorithm or key size.")
+	cs (XP_SEC_FORTEZZA_BAD_CARD, "Fortezza card has not been properly initialized.  Please remove it and return it to your issuer.")
+	cs (XP_SEC_FORTEZZA_NO_CARD, "No Fortezza cards Found")
+	cs (XP_SEC_FORTEZZA_NONE_SELECTED, "No Fortezza card selected")
+	cs (XP_SEC_FORTEZZA_MORE_INFO, "Please select a personality to get more info on")
+	cs (XP_SEC_FORTEZZA_PERSON_NOT_FOUND, "Personality not found")
+	cs (XP_SEC_FORTEZZA_NO_MORE_INFO, "No more information on that Personality")
+	cs (XP_SEC_FORTEZZA_BAD_PIN, "Invalid Pin")
+	cs (XP_SEC_FORTEZZA_PERSON_ERROR, "Couldn't initialize Fortezza personalities.")
+	cs (SEC_ERROR_NO_KRL, "No KRL for this site's certificate has been found.")
+	cs (SEC_ERROR_KRL_EXPIRED, "The KRL for this site's certificate has expired.")
+	cs (SEC_ERROR_KRL_BAD_SIGNATURE, "The KRL for this site's certificate has an invalid signature.")
+	cs (SEC_ERROR_REVOKED_KEY, "The key for this site's certificate has been revoked.")
+	cs (SEC_ERROR_KRL_INVALID, "New KRL has an invalid format.")
+	cs (SEC_ERROR_NEED_RANDOM, "security library: need random data.")
+	cs (SEC_ERROR_NO_MODULE, "security library: no security module can perform the requested operation.")
+	cs (SEC_ERROR_NO_TOKEN, "The security card or token does not exist, needs to be initialized, or has been removed.")
+	cs (SEC_ERROR_READ_ONLY, "security library: read-only database.")
+	cs (SEC_ERROR_NO_SLOT_SELECTED, "No slot or token was selected.")
+	cs (SEC_ERROR_CERT_NICKNAME_COLLISION, "A certificate with the same nickname already exists.")
+	cs (SEC_ERROR_KEY_NICKNAME_COLLISION, "A key with the same nickname already exists.")
+	cs (SEC_ERROR_SAFE_NOT_CREATED, "error while creating safe object")
+	cs (SEC_ERROR_BAGGAGE_NOT_CREATED, "error while creating baggage object")
+	cs (XP_JAVA_REMOVE_PRINCIPAL_ERROR, "Couldn't remove the principal")
+	cs (XP_JAVA_DELETE_PRIVILEGE_ERROR, "Couldn't delete the privilege")
+	cs (XP_JAVA_CERT_NOT_EXISTS_ERROR, "This principal doesn't have a certificate")
+	cs (SEC_ERROR_BAD_EXPORT_ALGORITHM, "Required algorithm is not allowed.")
+	cs (SEC_ERROR_EXPORTING_CERTIFICATES, "Error attempting to export certificates.")
+	cs (SEC_ERROR_IMPORTING_CERTIFICATES, "Error attempting to import certificates.")
+	cs (SEC_ERROR_PKCS12_DECODING_PFX, "Unable to import.  Decoding error.  File not valid.")
+	cs (SEC_ERROR_PKCS12_INVALID_MAC, "Unable to import.  Invalid MAC.  Incorrect password or corrupt file.")
+	cs (SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, "Unable to import.  MAC algorithm not supported.")
+	cs (SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE, "Unable to import.  Only password integrity and privacy modes supported.")
+	cs (SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, "Unable to import.  File structure is corrupt.")
+	cs (SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, "Unable to import.  Encryption algorithm not supported.")
+	cs (SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, "Unable to import.  File version not supported.")
+	cs (SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT, "Unable to import.  Incorrect privacy password.")
+	cs (SEC_ERROR_PKCS12_CERT_COLLISION, "Unable to import.  Same nickname already exists in database.")
+	cs (SEC_ERROR_USER_CANCELLED, "The user pressed cancel.")
+	cs (SEC_ERROR_PKCS12_DUPLICATE_DATA, "Not imported, already in database.")
+	cs (SEC_ERROR_MESSAGE_SEND_ABORTED, "Message not sent.")
+	cs (SEC_ERROR_INADEQUATE_KEY_USAGE, "Certificate key usage inadequate for attempted operation.")
+	cs (SEC_ERROR_INADEQUATE_CERT_TYPE, "Certificate type not approved for application.")
+	cs (SEC_ERROR_CERT_ADDR_MISMATCH, "Address in signing certificate does not match address in message headers.")
+	cs (SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, "Unable to import.  Error attempting to import private key.")
+	cs (SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, "Unable to import.  Error attempting to import certificate chain.")
+	cs (SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, "Unable to export.  Unable to locate certificate or key by nickname.")
+	cs (SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, "Unable to export.  Private Key could not be located and exported.")
+	cs (SEC_ERROR_PKCS12_UNABLE_TO_WRITE, "Unable to export.  Unable to write the export file.")
+	cs (SEC_ERROR_PKCS12_UNABLE_TO_READ, "Unable to import.  Unable to read the import file.")
+	cs (SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, "Unable to export.  Key database corrupt or deleted.")
+	cs (SEC_ERROR_KEYGEN_FAIL, "Unable to generate public/private key pair.")
+	cs (SEC_ERROR_INVALID_PASSWORD, "Password entered is invalid.  Please pick a different one.")
+	cs (SEC_ERROR_RETRY_OLD_PASSWORD, "Old password entered incorrectly.  Please try again.")
+	cs (SEC_ERROR_BAD_NICKNAME, "Certificate nickname already in use.")
+	cs (SEC_ERROR_NOT_FORTEZZA_ISSUER, "Peer FORTEZZA chain has a non-FORTEZZA Certificate.")
+	cs (SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY, "A sensitive key cannot be moved to the slot where it is needed.")
+	cs (SEC_ERROR_JS_INVALID_MODULE_NAME, "Invalid module name.")
+	cs (SEC_ERROR_JS_INVALID_DLL, "Invalid module path/filename")
+	cs (SEC_ERROR_JS_ADD_MOD_FAILURE, "Unable to add module")
+	cs (SEC_ERROR_JS_DEL_MOD_FAILURE, "Unable to delete module")
+	cs (SEC_ERROR_OLD_KRL, "New KRL is not later than the current one.")
+	cs (SEC_ERROR_CKL_CONFLICT, "New CKL has different issuer than current CKL.  Delete current CKL.")
+	cs (SEC_ERROR_CERT_NOT_IN_NAME_SPACE, "The Certifying Authority for this certificate is not permitted to issue a certificate with this name.")
+	cs (SEC_ERROR_KRL_NOT_YET_VALID, "The key revocation list for this certificate is not yet valid.")
+	cs (SEC_ERROR_CRL_NOT_YET_VALID, "The certificate revocation list for this certificate is not yet valid.")
+	cs (SEC_ERROR_UNKNOWN_CERT, "The requested certificate could not be found.")
+	cs (SEC_ERROR_UNKNOWN_SIGNER, "The signer's certificate could not be found.")
+	cs (SEC_ERROR_CERT_BAD_ACCESS_LOCATION,	 "The location for the certificate status server has invalid format.")
+	cs (SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE, "The OCSP response cannot be fully decoded; it is of an unknown type.")
+	cs (SEC_ERROR_OCSP_BAD_HTTP_RESPONSE, "The OCSP server returned unexpected/invalid HTTP data.")
+	cs (SEC_ERROR_OCSP_MALFORMED_REQUEST, "The OCSP server found the request to be corrupted or improperly formed.")
+	cs (SEC_ERROR_OCSP_SERVER_ERROR, "The OCSP server experienced an internal error.")
+	cs (SEC_ERROR_OCSP_TRY_SERVER_LATER, "The OCSP server suggests trying again later.")
+	cs (SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, "The OCSP server requires a signature on this request.")
+	cs (SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, "The OCSP server has refused this request as unauthorized.")
+	cs (SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, "The OCSP server returned an unrecognizable status.")
+	cs (SEC_ERROR_OCSP_UNKNOWN_CERT, "The OCSP server has no status for the certificate.")
+	cs (SEC_ERROR_OCSP_NOT_ENABLED, "You must enable OCSP before performing this operation.")
+	cs (SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER, "You must set the OCSP default responder before performing this operation.")
+	cs (SEC_ERROR_OCSP_MALFORMED_RESPONSE, "The response from the OCSP server was corrupted or improperly formed.")
+	cs (SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE, "The signer of the OCSP response is not authorized to give status for this certificate.")
+	cs (SEC_ERROR_OCSP_FUTURE_RESPONSE, "The OCSP response is not yet valid (contains a date in the future).")
+	cs (SEC_ERROR_OCSP_OLD_RESPONSE, "The OCSP response contains out-of-date information.")
+	cs (SEC_ERROR_DIGEST_NOT_FOUND, "The CMS or PKCS #7 Digest was not found in signed message.")
+	cs (SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE, "The CMS or PKCS #7 Message type is unsupported.")
+	cs (SEC_ERROR_MODULE_STUCK, "PKCS #11 module could not be removed because it is still in use.")
+	cs (SEC_ERROR_BAD_TEMPLATE, "Could not decode ASN.1 data. Specified template was invalid.")
+	cs (SEC_ERROR_CRL_NOT_FOUND, "No matching CRL was found.")
+	cs (SEC_ERROR_REUSED_ISSUER_AND_SERIAL, "You are attempting to import a cert with the same issuer/serial as an existing cert, but that is not the same cert.")
+	cs (SEC_ERROR_BUSY, "NSS could not shutdown. Objects are still in use.")
+	cs (SEC_ERROR_EXTRA_INPUT, "DER-encoded message contained extra unused data.")
+	cs (SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE, "Unsupported elliptic curve.")
+	cs (SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, "Unsupported elliptic curve point form.")
+	cs (SEC_ERROR_UNRECOGNIZED_OID, "Unrecognized Object Identifier.")
+	cs (SEC_ERROR_OCSP_INVALID_SIGNING_CERT, "Invalid OCSP signing certificate in OCSP response.")
+	cs (SEC_ERROR_REVOKED_CERTIFICATE_CRL, "Certificate is revoked in issuer's certificate revocation list.")
+	cs (SEC_ERROR_REVOKED_CERTIFICATE_OCSP, "Issuer's OCSP responder reports certificate is revoked.")
+	cs (SEC_ERROR_CRL_INVALID_VERSION, "Issuer's Certificate Revocation List has an unknown version number.")
+	cs (SEC_ERROR_CRL_V1_CRITICAL_EXTENSION, "Issuer's V1 Certificate Revocation List has a critical extension.")
+	cs (SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION, "Issuer's V2 Certificate Revocation List has an unknown critical extension.")
+	cs (SEC_ERROR_UNKNOWN_OBJECT_TYPE, "Unknown object type specified.")
+	cs (SEC_ERROR_INCOMPATIBLE_PKCS11, "PKCS #11 driver violates the spec in an incompatible way.")
+	cs (SEC_ERROR_NO_EVENT, "No new slot event is available at this time.")
+	cs (SEC_ERROR_CRL_ALREADY_EXISTS, "CRL already exists.")
+	cs (SEC_ERROR_NOT_INITIALIZED, "NSS is not initialized.")
+	cs (SEC_ERROR_TOKEN_NOT_LOGGED_IN, "The operation failed because the PKCS#11 token is not logged in.")
+	cs (SEC_ERROR_OCSP_RESPONDER_CERT_INVALID, "Configured OCSP responder's certificate is invalid.")
+	cs (SEC_ERROR_OCSP_BAD_SIGNATURE, "OCSP response has an invalid signature.")
+
+	#if defined(NSS_VMAJOR) && defined(NSS_VMINOR) && defined(NSS_VPATCH) && (NSS_VMAJOR > 3 || (NSS_VMAJOR == 3 && NSS_VMINOR > 12) || (NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH >= 2))
+	cs (SEC_ERROR_OUT_OF_SEARCH_LIMITS, "Cert validation search is out of search limits")
+	cs (SEC_ERROR_INVALID_POLICY_MAPPING, "Policy mapping contains anypolicy")
+	cs (SEC_ERROR_POLICY_VALIDATION_FAILED, "Cert chain fails policy validation")
+	cs (SEC_ERROR_UNKNOWN_AIA_LOCATION_TYPE, "Unknown location type in cert AIA extension")
+	cs (SEC_ERROR_BAD_HTTP_RESPONSE, "Server returned bad HTTP response")
+	cs (SEC_ERROR_BAD_LDAP_RESPONSE, "Server returned bad LDAP response")
+	cs (SEC_ERROR_FAILED_TO_ENCODE_DATA, "Failed to encode data with ASN1 encoder")
+	cs (SEC_ERROR_BAD_INFO_ACCESS_LOCATION, "Bad information access location in cert extension")
+	cs (SEC_ERROR_LIBPKIX_INTERNAL, "Libpkix internal error occured during cert validation.")
+	cs (SEC_ERROR_PKCS11_GENERAL_ERROR, "A PKCS #11 module returned CKR_GENERAL_ERROR, indicating that an unrecoverable error has occurred.")
+	cs (SEC_ERROR_PKCS11_FUNCTION_FAILED, "A PKCS #11 module returned CKR_FUNCTION_FAILED, indicating that the requested function could not be performed.  Trying the same operation again might succeed.")
+	cs (SEC_ERROR_PKCS11_DEVICE_ERROR, "A PKCS #11 module returned CKR_DEVICE_ERROR, indicating that a problem has occurred with the token or slot.")
+	#endif
+	}
+
+	#undef cs
+
+	return NULL;
+}
+
+static void
+set_nss_error (CamelException *ex, const char *def_error)
+{
+	long err_code;
+
+	g_return_if_fail (def_error != NULL);
+
+	err_code = PORT_GetError ();
+
+	if (!err_code) {
+		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, def_error);
+	} else {
+		const char *err_str;
+
+		err_str = nss_error_to_string (err_code);
+		if (!err_str)
+			err_str = "Uknown error.";
+
+		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, "%s (%d) - %s", err_str, (int) err_code, def_error);
+	}
+}
+
 static NSSCMSMessage *
 sm_signing_cmsmessage(CamelSMIMEContext *context, const char *nick, SECOidTag hash, int detached, CamelException *ex)
 {
@@ -236,43 +446,43 @@
 
 	cmsg = NSS_CMSMessage_Create(NULL); /* create a message on its own pool */
 	if (cmsg == NULL) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS message"));
+		set_nss_error (ex, _("Cannot create CMS message"));
 		goto fail;
 	}
 
 	if ((sigd = NSS_CMSSignedData_Create(cmsg)) == NULL) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS signed data"));
+		set_nss_error (ex, _("Cannot create CMS signed data"));
 		goto fail;
 	}
 
 	cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
 	if (NSS_CMSContentInfo_SetContent_SignedData(cmsg, cinfo, sigd) != SECSuccess) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach CMS signed data"));
+		set_nss_error (ex, _("Cannot attach CMS signed data"));
 		goto fail;
 	}
 
 	/* if !detatched, the contentinfo will alloc a data item for us */
 	cinfo = NSS_CMSSignedData_GetContentInfo(sigd);
 	if (NSS_CMSContentInfo_SetContent_Data(cmsg, cinfo, NULL, detached) != SECSuccess) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach CMS data"));
+		set_nss_error (ex, _("Cannot attach CMS data"));
 		goto fail;
 	}
 
 	signerinfo = NSS_CMSSignerInfo_Create(cmsg, cert, hash);
 	if (signerinfo == NULL) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS Signer information"));
+		set_nss_error (ex, _("Cannot create CMS Signer information"));
 		goto fail;
 	}
 
 	/* we want the cert chain included for this one */
 	if (NSS_CMSSignerInfo_IncludeCerts(signerinfo, NSSCMSCM_CertChain, certUsageEmailSigner) != SECSuccess) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot find certificate chain"));
+		set_nss_error (ex, _("Cannot find certificate chain"));
 		goto fail;
 	}
 
 	/* SMIME RFC says signing time should always be added */
 	if (NSS_CMSSignerInfo_AddSigningTime(signerinfo, PR_Now()) != SECSuccess) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot add CMS Signing time"));
+		set_nss_error (ex, _("Cannot add CMS Signing time"));
 		goto fail;
 	}
 
@@ -313,23 +523,23 @@
 		}
 
 		if (NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(signerinfo, enccert, p->certdb) != SECSuccess) {
-			camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot add SMIMEEncKeyPrefs attribute"));
+			set_nss_error (ex, _("Cannot add SMIMEEncKeyPrefs attribute"));
 			goto fail;
 		}
 
 		if (NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs(signerinfo, enccert, p->certdb) != SECSuccess) {
-			camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot add MS SMIMEEncKeyPrefs attribute"));
+			set_nss_error (ex, _("Cannot add MS SMIMEEncKeyPrefs attribute"));
 			goto fail;
 		}
 
 		if (ekpcert != NULL && NSS_CMSSignedData_AddCertificate(sigd, ekpcert) != SECSuccess) {
-			camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot add encryption certificate"));
+			set_nss_error (ex, _("Cannot add encryption certificate"));
 			goto fail;
 		}
 	}
 
 	if (NSS_CMSSignedData_AddSignerInfo(sigd, signerinfo) != SECSuccess) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot add CMS Signer information"));
+		set_nss_error (ex, _("Cannot add CMS Signer information"));
 		goto fail;
 	}
 
@@ -399,18 +609,18 @@
 				   NULL, NULL,     /* decrypt key callback */
 				   NULL, NULL );   /* detached digests    */
 	if (!enc) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create encoder context"));
+		set_nss_error (ex, _("Cannot create encoder context"));
 		goto fail;
 	}
 
 	if (NSS_CMSEncoder_Update(enc, (char *) ((CamelStreamMem *)istream)->buffer->data, ((CamelStreamMem *)istream)->buffer->len) != SECSuccess) {
 		NSS_CMSEncoder_Cancel(enc);
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to add data to CMS encoder"));
+		set_nss_error (ex, _("Failed to add data to CMS encoder"));
 		goto fail;
 	}
 
 	if (NSS_CMSEncoder_Finish(enc) != SECSuccess) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to encode data"));
+		set_nss_error (ex, _("Failed to encode data"));
 		goto fail;
 	}
 
@@ -533,62 +743,67 @@
 	for (i = 0; i < count; i++) {
 		NSSCMSContentInfo *cinfo = NSS_CMSMessage_ContentLevel(cmsg, i);
 		SECOidTag typetag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
+		int which_digest;
 
 		switch (typetag) {
 		case SEC_OID_PKCS7_SIGNED_DATA:
 			sigd = (NSSCMSSignedData *)NSS_CMSContentInfo_GetContent(cinfo);
 			if (sigd == NULL) {
-				camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("No signed data in signature"));
+				set_nss_error (ex, _("No signed data in signature"));
 				goto fail;
 			}
 
-			/* need to build digests of the content */
-			if (!NSS_CMSSignedData_HasDigests(sigd)) {
-				if (extstream == NULL) {
-					camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Digests missing from enveloped data"));
-					goto fail;
-				}
+			if (extstream == NULL) {
+				set_nss_error (ex, _("Digests missing from enveloped data"));
+				goto fail;
+			}
 
-				if ((poolp = PORT_NewArena(1024)) == NULL) {
-					camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, g_strerror (ENOMEM));
-					goto fail;
-				}
+			if ((poolp = PORT_NewArena(1024)) == NULL) {
+				set_nss_error (ex, g_strerror (ENOMEM));
+				goto fail;
+			}
 
-				digestalgs = NSS_CMSSignedData_GetDigestAlgs(sigd);
-				
-				digcx = NSS_CMSDigestContext_StartMultiple(digestalgs);
-				if (digcx == NULL) {
-					camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot calculate digests"));
-					goto fail;
-				}
+			digestalgs = NSS_CMSSignedData_GetDigestAlgs(sigd);
+			
+			digcx = NSS_CMSDigestContext_StartMultiple(digestalgs);
+			if (digcx == NULL) {
+				set_nss_error (ex, _("Cannot calculate digests"));
+				goto fail;
+			}
+
+			mem = (CamelStreamMem *)camel_stream_mem_new();
+			camel_stream_write_to_stream(extstream, (CamelStream *)mem);
+			NSS_CMSDigestContext_Update(digcx, mem->buffer->data, mem->buffer->len);
+			g_object_unref(mem);
 
-				mem = (CamelStreamMem *)camel_stream_mem_new();
-				camel_stream_write_to_stream(extstream, (CamelStream *)mem);
-				NSS_CMSDigestContext_Update(digcx, mem->buffer->data, mem->buffer->len);
-				g_object_unref(mem);
+			if (NSS_CMSDigestContext_FinishMultiple(digcx, poolp, &digests) != SECSuccess) {
+				set_nss_error (ex, _("Cannot calculate digests"));
+				goto fail;
+			}
 
-				if (NSS_CMSDigestContext_FinishMultiple(digcx, poolp, &digests) != SECSuccess) {
-					camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot calculate digests"));
+			for (which_digest = 0; digests[which_digest] != NULL; which_digest++) {
+				SECOidData *digest_alg = SECOID_FindOID (&digestalgs[which_digest]->algorithm);
+				if (digest_alg == NULL) {
+					set_nss_error (ex, _("Cannot set message digests"));
 					goto fail;
 				}
-
-				if (NSS_CMSSignedData_SetDigests(sigd, digestalgs, digests) != SECSuccess) {
-					camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot set message digests"));
+				if (NSS_CMSSignedData_SetDigestValue (sigd, digest_alg->offset, digests[which_digest]) != SECSuccess) {
+					set_nss_error (ex, _("Cannot set message digests"));
 					goto fail;
 				}
-
-				PORT_FreeArena(poolp, PR_FALSE);
-				poolp = NULL;
 			}
 
+			PORT_FreeArena(poolp, PR_FALSE);
+			poolp = NULL;
+
 			/* import all certificates present */
 			if (NSS_CMSSignedData_ImportCerts(sigd, p->certdb, certUsageEmailSigner, PR_TRUE) != SECSuccess) {
-				camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Certificate import failed"));
+				set_nss_error (ex, _("Certificate import failed"));
 				goto fail;
 			}
 
 			if (NSS_CMSSignedData_ImportCerts(sigd, p->certdb, certUsageEmailRecipient, PR_TRUE) != SECSuccess) {
-				camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Certificate import failed"));
+				set_nss_error (ex, _("Certificate import failed"));
 				goto fail;
 			}
 
@@ -605,7 +820,7 @@
 				}
 			} else {
 				if (!NSS_CMSSignedData_HasDigests(sigd)) {
-					camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot find signature digests"));
+					set_nss_error (ex, _("Cannot find signature digests"));
 					goto fail;
 				}
 
@@ -722,10 +937,10 @@
 	(void)NSS_CMSDecoder_Update(dec, (char *) mem->buffer->data, mem->buffer->len);
 	cmsg = NSS_CMSDecoder_Finish(dec);
 	if (cmsg == NULL) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Decoder failed"));
+		set_nss_error (ex, _("Decoder failed"));
 		goto fail;
 	}
-	
+
 	valid = sm_verify_cmsg(context, cmsg, constream, ex);
 	
 	NSS_CMSMessage_Destroy(cmsg);
@@ -760,14 +975,14 @@
 
 	poolp = PORT_NewArena(1024);
 	if (poolp == NULL) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, g_strerror (ENOMEM));
+		set_nss_error (ex, g_strerror (ENOMEM));
 		return -1;
 	}
 
 	/* Lookup all recipients certs, for later working */
 	recipient_certs = (CERTCertificate **)PORT_ArenaZAlloc(poolp, sizeof(*recipient_certs[0])*(recipients->len + 1));
 	if (recipient_certs == NULL) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, g_strerror (ENOMEM));
+		set_nss_error (ex, g_strerror (ENOMEM));
 		goto fail;
 	}
 
@@ -781,7 +996,7 @@
 
 	/* Find a common algorithm, probably 3DES anyway ... */
 	if (NSS_SMIMEUtil_FindBulkAlgForRecipients(recipient_certs, &bulkalgtag, &bulkkeysize) != SECSuccess) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot find common bulk encryption algorithm"));
+		set_nss_error (ex, _("Cannot find common bulk encryption algorithm"));
 		goto fail;
 	}
 
@@ -789,8 +1004,7 @@
 	type = PK11_AlgtagToMechanism(bulkalgtag);
 	slot = PK11_GetBestSlot(type, context);
 	if (slot == NULL) {
-		/* PORT_GetError(); ?? */
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot allocate slot for encryption bulk key"));
+		set_nss_error (ex, _("Cannot allocate slot for encryption bulk key"));
 		goto fail;
 	}
 
@@ -801,25 +1015,25 @@
 	/* msg->envelopedData->data */
 	cmsg = NSS_CMSMessage_Create(NULL);
 	if (cmsg == NULL) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS Message"));
+		set_nss_error (ex, _("Cannot create CMS Message"));
 		goto fail;
 	}
 
 	envd = NSS_CMSEnvelopedData_Create(cmsg, bulkalgtag, bulkkeysize);
 	if (envd == NULL) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS Enveloped data"));
+		set_nss_error (ex, _("Cannot create CMS Enveloped data"));
 		goto fail;
 	}
 
 	cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
 	if (NSS_CMSContentInfo_SetContent_EnvelopedData(cmsg, cinfo, envd) != SECSuccess) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach CMS Enveloped data"));
+		set_nss_error (ex, _("Cannot attach CMS Enveloped data"));
 		goto fail;
 	}
 
 	cinfo = NSS_CMSEnvelopedData_GetContentInfo(envd);
 	if (NSS_CMSContentInfo_SetContent_Data(cmsg, cinfo, NULL, PR_FALSE) != SECSuccess) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach CMS data object"));
+		set_nss_error (ex, _("Cannot attach CMS data object"));
 		goto fail;
 	}
 
@@ -828,12 +1042,12 @@
 		NSSCMSRecipientInfo *ri = NSS_CMSRecipientInfo_Create(cmsg, recipient_certs[i]);
 
 		if (ri == NULL) {
-			camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS Recipient information"));
+			set_nss_error (ex, _("Cannot create CMS Recipient information"));
 			goto fail;
 		}
 
 		if (NSS_CMSEnvelopedData_AddRecipient(envd, ri) != SECSuccess) {
-			camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot add CMS Recipient information"));
+			set_nss_error (ex, _("Cannot add CMS Recipient information"));
 			goto fail;
 		}
 	}
@@ -847,7 +1061,7 @@
 				   sm_decrypt_key, bulkkey,
 				   NULL, NULL);
 	if (enc == NULL) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create encoder context"));
+		set_nss_error (ex, _("Cannot create encoder context"));
 		goto fail;
 	}
 
@@ -858,13 +1072,13 @@
 	if (NSS_CMSEncoder_Update(enc, (char *) mem->buffer->data, mem->buffer->len) != SECSuccess) {
 		NSS_CMSEncoder_Cancel(enc);
 		g_object_unref(mem);
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to add data to encoder"));
+		set_nss_error (ex, _("Failed to add data to encoder"));
 		goto fail;
 	}
 	g_object_unref(mem);
 
 	if (NSS_CMSEncoder_Finish(enc) != SECSuccess) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to encode data"));
+		set_nss_error (ex, _("Failed to encode data"));
 		goto fail;
 	}
 
@@ -939,20 +1153,22 @@
 				   NULL, NULL); /* decrypt key callback */
 
 	if (NSS_CMSDecoder_Update(dec, (char *) istream->buffer->data, istream->buffer->len) != SECSuccess) {
-		printf("decoder update failed\n");
+		cmsg = NULL;
+	} else {
+		cmsg = NSS_CMSDecoder_Finish(dec);
 	}
+
 	g_object_unref(istream);
 
-	cmsg = NSS_CMSDecoder_Finish(dec);
 	if (cmsg == NULL) {
-		camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Decoder failed, error %d"), PORT_GetError());
+		set_nss_error (ex, _("Decoder failed"));
 		goto fail;
 	}
 
 #if 0
 	/* not sure if we really care about this? */
 	if (!NSS_CMSMessage_IsEncrypted(cmsg)) {
-		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("S/MIME Decrypt: No encrypted content found"));
+		set_nss_error (ex, _("S/MIME Decrypt: No encrypted content found"));
 		NSS_CMSMessage_Destroy(cmsg);
 		goto fail;
 	}
@@ -962,7 +1178,8 @@
 	camel_data_wrapper_construct_from_stream((CamelDataWrapper *)opart, ostream);
 
 	if (NSS_CMSMessage_IsSigned(cmsg)) {
-		valid = sm_verify_cmsg(context, cmsg, NULL, ex);
+		camel_stream_reset (ostream);
+		valid = sm_verify_cmsg (context, cmsg, ostream, ex);
 	} else {
 		valid = camel_cipher_validity_new();
 		valid->encrypt.description = g_strdup(_("Encrypted content"));

Modified: branches/camel-gobject/camel/camel-url-scanner.c
==============================================================================
--- branches/camel-gobject/camel/camel-url-scanner.c	(original)
+++ branches/camel-gobject/camel/camel-url-scanner.c	Thu Apr 16 01:23:17 2009
@@ -460,7 +460,7 @@
 	 * punctuation, so strip any trailing
 	 * punctuation off. Also strip off any closing
 	 * double-quotes. */
-	while (inptr > pos && strchr (",.:;?!-|}]\"", inptr[-1]))
+	while (inptr > pos && strchr (",.:;?!-|}])\"", inptr[-1]))
 		inptr--;
 
 

Modified: branches/camel-gobject/camel/camel-vee-folder.c
==============================================================================
--- branches/camel-gobject/camel/camel-vee-folder.c	(original)
+++ branches/camel-gobject/camel/camel-vee-folder.c	Thu Apr 16 01:23:17 2009
@@ -83,9 +83,6 @@
 static void subfolder_deleted(CamelFolder *f, void *event_data, CamelVeeFolder *vf);
 static void folder_renamed(CamelFolder *f, const char *old, CamelVeeFolder *vf);
 
-static void folder_changed_remove_uid(CamelFolder *sub, const char *uid, const char hash[8], int keep, CamelVeeFolder *vf);
-static void summary_reloaded(CamelObject *o, void *event_data, void *data);
-
 static CamelFolderClass *camel_vee_folder_parent;
 
 GType
@@ -221,19 +218,12 @@
 
 	d(printf("camel_vee_folder_add_folder(%s, %s)\n", ((CamelFolder *)vf)->full_name, sub->full_name));
 
-	cache = camel_folder_summary_cache_size(sub->summary);
-	if (!cache) {
-		camel_object_hook_event(sub->summary, "summary_reloaded", summary_reloaded, vf);
-		g_hash_table_insert(vf->loaded, sub, GINT_TO_POINTER(1));
-	}
 	camel_object_hook_event((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc)folder_changed, vf);
 	camel_object_hook_event((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc)subfolder_deleted, vf);
 	camel_object_hook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc)folder_renamed, vf);
 
 	((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->add_folder(vf, sub);
 	
-	if (cache) 
-		summary_reloaded((CamelObject *) sub->summary, (void *)sub->summary, (void *)vf);
 }
 
 /**
@@ -266,10 +256,7 @@
 	camel_object_unhook_event((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf);
 	camel_object_unhook_event((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf);
 	camel_object_unhook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc) folder_renamed, vf);
-	if (GPOINTER_TO_INT(g_hash_table_lookup (vf->loaded, sub))) {
-		g_hash_table_remove (vf->loaded, sub);		
-		camel_object_unhook_event((CamelObject *)sub->summary, "summary_reloaded", (CamelObjectEventHookFunc) summary_reloaded, vf);
-	}
+
 	
 	p->folders = g_list_remove(p->folders, sub);
 	
@@ -516,6 +503,7 @@
 	CamelFIRecord * record = g_new0 (CamelFIRecord, 1);
 	CamelDB *db;
 	char *table_name;
+	guint32 visible, unread, deleted, junked, junked_not_deleted;
 
 	/* We do this during write, so lets use write handle, though we gonna read */
 	db = s->folder->parent_store->cdb_w;
@@ -530,7 +518,14 @@
 	record->time = s->time;
 
 	record->saved_count = s->uids->len;
-	if (!(((CamelVeeSummary *) s)->force_counts) && !g_getenv("FORCE_VFOLDER_COUNT")) {
+	camel_object_get(s->folder, NULL,
+				 CAMEL_FOLDER_DELETED, &deleted,
+				 CAMEL_FOLDER_VISIBLE, &visible,
+				 CAMEL_FOLDER_JUNKED, &junked,
+				 CAMEL_FOLDER_JUNKED_NOT_DELETED, &junked_not_deleted,
+				 CAMEL_FOLDER_UNREAD, &unread, NULL);
+	if (1) { /* We always would do this. Just refactor the code again. */ 
+		//!(((CamelVeeSummary *) s)->force_counts) && !g_getenv("FORCE_VFOLDER_COUNT")) {
 		/* We should be in sync always. so use the count. Don't search.*/
 		record->junk_count = s->junk_count;
 		record->deleted_count = s->deleted_count;
@@ -597,6 +592,7 @@
 
 		node = node->next;
 	}
+
 #if 0
 	/* Seems like we are doing something wrong with this, as folder_changed happens after this, the counts are misleading.
 	 * Anyways we do a force sync on exit, it should be all fine.
@@ -605,13 +601,37 @@
 	camel_db_write_folder_info_record (folder->parent_store->cdb, record, ex);
 	g_free (record);
 #endif	
+	/* It makes no sense to clear the folders_changed list without
+	 * actually rebuilding. */
+#if 0
 	if (node == NULL) {
 		CAMEL_VEE_FOLDER_LOCK(vf, changed_lock);
 		g_list_free(p->folders_changed);
 		p->folders_changed = NULL;
 		CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock);
 	}
-
+#endif
+	if (vf->priv->unread_vfolder == 1) {
+		/* Cleanup Junk/Trash uids */
+		int i, count;
+		count = folder->summary->uids->len;
+		GSList *del = NULL;
+
+		for (i=0; i < count; i++) {
+			CamelVeeMessageInfo *mi = camel_folder_summary_index (folder->summary, i);
+			if (mi->old_flags & CAMEL_MESSAGE_DELETED) {
+				del = g_slist_prepend (del, (gpointer) camel_pstring_strdup(((CamelMessageInfo *)mi)->uid));
+				camel_folder_summary_remove_index_fast (folder->summary, i);
+				count--;
+				i--;
+
+			}
+			camel_message_info_free (mi);
+		}
+		camel_db_delete_vuids (folder->parent_store->cdb_w, folder->full_name, "", del, ex);
+		g_slist_foreach (del, (GFunc) camel_pstring_free, NULL);
+		g_slist_free (del);			
+	}
 	CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
 
 	camel_object_state_write(vf);
@@ -839,8 +859,21 @@
 /* ********************************************************************** *
    utility functions */
 
-#define COUNT_ADD_EXPR(lval, sexpr) expr = g_strdup_printf("and (%s %s)", vf->expression, sexpr); lval += count_folder(f, expr, ex); g_free(expr);
-#define COUNT_DEL_EXPR(lval, sexpr) expr = g_strdup_printf("and (%s %s)", vf->expression, sexpr); lval -= count_folder(ssummary->folder, expr, NULL); g_free(expr);
+/* A "correlating" expression has the property that whether a message matches
+ * depends on the other messages being searched.  folder_changed_change on a
+ * vfolder with a correlating expression may not make all the necessary updates,
+ * so the query is redone on the entire changed source folder the next time
+ * the vfolder is opened.
+ * 
+ * The only current example of a correlating expression is one that uses
+ * "match-threads". */
+static gboolean
+expression_is_correlating(const char *expr)
+{
+	/* XXX: Actually parse the expression to avoid triggering on
+	 * "match-threads" in the text the user is searching for! */
+	return (strstr(expr, "match-threads") != NULL);
+}
 
 /* must be called with summary_lock held */
 static CamelVeeMessageInfo *
@@ -865,7 +898,6 @@
 	GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
 	CamelFolderSummary *ssummary = source->summary;
 	int killun = FALSE;
-	char *expr;
 	
 	if (vf == folder_unmatched)
 		return;
@@ -966,12 +998,6 @@
 
 	if (last != -1)
 		camel_folder_summary_remove_range(folder->summary, start, last);
-	
-	COUNT_DEL_EXPR(folder->summary->junk_count, "(match-all (system-flag  \"junk\"))");
-	COUNT_DEL_EXPR(folder->summary->deleted_count, "(match-all (system-flag  \"deleted\"))");
-	COUNT_DEL_EXPR(folder->summary->unread_count, "(match-all (not (system-flag  \"Seen\")))");
-	COUNT_DEL_EXPR(folder->summary->visible_count, "(match-all (and (not (system-flag \"deleted\")) (not (system-flag \"junk\"))))");
-	COUNT_DEL_EXPR(folder->summary->junk_not_deleted_count, "(match-all (and (not (system-flag \"deleted\")) (system-flag \"junk\")))");
 				
 	if (folder_unmatched) {
 		if (camel_folder_change_info_changed(folder_unmatched->changes)) {
@@ -1006,7 +1032,7 @@
 	char hash[8];
 	CamelVeeFolder *folder_unmatched;
 	GHashTable *unmatched_uids;
-	gboolean rebuilt;
+	gboolean rebuilt, correlating;
 };
 
 static void
@@ -1045,7 +1071,7 @@
 		/* FIXME[disk-summary] Handle exceptions */
 		/* FIXME[disk-summary] Make all these as transactions, just
 		 * testing atm */
-		if (u->rebuilt)
+		if (u->rebuilt && !u->correlating)
 			camel_db_add_to_vfolder_transaction (((CamelFolder *) u->vf)->parent_store->cdb_w, ((CamelFolder *) u->vf)->full_name, (char *) camel_message_info_uid(mi), NULL);
 		if (!CAMEL_IS_VEE_FOLDER(u->source) && u->unmatched_uids != NULL) {
 			if (g_hash_table_lookup_extended(u->unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
@@ -1076,6 +1102,11 @@
 	CamelFolderSummary *ssummary = source->summary;
 	gboolean rebuilded = FALSE;
 	char *shash; 
+
+	/* Since the source of a correlating vfolder has to be requeried in
+	 * full every time it changes, caching the results in the db is not
+	 * worth the effort.  Thus, DB use is conditioned on !correlating. */
+	gboolean correlating = expression_is_correlating(vf->expression);
 	
 	if (vf == folder_unmatched)
 		return 0;
@@ -1089,30 +1120,30 @@
 	if (vf->expression == NULL) {
 		match = g_ptr_array_new();
 	} else {
-		/* Load the folder results from the DB. */
-		match = camel_vee_summary_get_ids ((CamelVeeSummary *)folder->summary, u.hash);
-		d(printf("len = %d %d for %s %s\n", match ? match->len:0, rebuilded, source->full_name, shash));
-		if (!match) {
-			char *expr;
+		if (!correlating) {
+			/* Load the folder results from the DB. */
+			match = camel_vee_summary_get_ids ((CamelVeeSummary *)folder->summary, u.hash);
+		}
+		if (correlating ||
+			/* We take this to mean the results have not been cached.
+			 * XXX: It will also trigger if the result set is empty. */
+			match == NULL) {
 			match = camel_folder_search_by_expression(f, vf->expression, ex);
-			if (match == NULL)
+			if (match == NULL) /* Search failed */
 				return 0;
 			rebuilded = TRUE;
-			/* Update the counts */
-			COUNT_ADD_EXPR(folder->summary->junk_count, "(match-all (system-flag  \"junk\"))");
-			COUNT_ADD_EXPR(folder->summary->deleted_count, "(match-all (system-flag  \"deleted\"))");
-			COUNT_ADD_EXPR(folder->summary->unread_count, "(match-all (not (system-flag  \"Seen\")))");
-			COUNT_ADD_EXPR(folder->summary->visible_count, "(match-all (and (not (system-flag \"deleted\")) (not (system-flag \"junk\"))))");
-			COUNT_ADD_EXPR(folder->summary->junk_not_deleted_count, "(match-all (and (not (system-flag \"deleted\")) (system-flag \"junk\")))");
 		}
 		
 	}
+	dd(printf("vee_rebuild_folder(%s <- %s %s): match %d, correlating %d, rebuilded %d\n",
+		folder->full_name, source->full_name, shash, match->len, correlating, rebuilded));
 
 	u.source = source;
 	u.vf = vf;
 	u.folder_unmatched = folder_unmatched;
 	u.unmatched_uids = unmatched_uids;
 	u.rebuilt = rebuilded;
+	u.correlating = correlating;
 
 	CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
 
@@ -1191,13 +1222,13 @@
 		camel_folder_summary_remove_range(folder->summary, start, last);
 
 	/* now matchhash contains any new uid's, add them, etc */
-	if (rebuilded) {
+	if (rebuilded && !correlating) {
 		camel_db_begin_transaction (folder->parent_store->cdb_w, NULL);
 
 	}
 	g_hash_table_foreach(matchhash, (GHFunc)folder_added_uid, &u);
 
-	if (rebuilded)
+	if (rebuilded && !correlating)
 		camel_db_end_transaction (folder->parent_store->cdb_w, NULL);
 	
 	if (folder_unmatched != NULL) {
@@ -1243,7 +1274,8 @@
 	
 	/* Del the unwanted things from the summary, we don't hold any locks now. */
 	if (del_list) {
-		camel_db_delete_vuids(folder->parent_store->cdb_w, folder->full_name, shash, del_list, NULL);
+		if (!correlating)
+			camel_db_delete_vuids(folder->parent_store->cdb_w, folder->full_name, shash, del_list, NULL);
 		((CamelVeeSummary *)folder->summary)->force_counts = TRUE;
 		g_slist_foreach (del_list, (GFunc) camel_pstring_free, NULL);
 		g_slist_free (del_list);	
@@ -1275,95 +1307,10 @@
 	return 0;
 }
 
-/*
-
-  (match-folder "folder1" "folder2")
-
- */
-
-static void
-update_summary (CamelVeeMessageInfo *mi, guint32 flags, guint32 oldflags, gboolean add, gboolean use_old)
-{
-	int unread=0, deleted=0, junk=0;
-	CamelFolderSummary *summary = ((CamelMessageInfo *) mi)->summary;
-	
-	if (!(flags & CAMEL_MESSAGE_SEEN) && !(flags & CAMEL_MESSAGE_JUNK))
-		unread = 1;
-	
-	if (flags & CAMEL_MESSAGE_DELETED)
-		deleted = 1;
-
-	if (flags & CAMEL_MESSAGE_JUNK)
-		junk = 1;
-
-	d(printf("folder: %s %d %d: %p:%s\n", summary->folder->full_name, oldflags, add, mi, ((CamelMessageInfo *)mi)->uid));
-	d(printf("%d %d %d\n%d %d %d\n", !(flags & CAMEL_MESSAGE_SEEN), flags & CAMEL_MESSAGE_DELETED, flags & CAMEL_MESSAGE_JUNK, !(oldflags & CAMEL_MESSAGE_SEEN), oldflags & CAMEL_MESSAGE_DELETED, oldflags & CAMEL_MESSAGE_JUNK));
-	
-	if (!use_old) {
-		if (add) {
-			if (unread)
-				summary->unread_count += unread;
-			if (deleted)
-				summary->deleted_count += deleted;
-			if (junk)
-				summary->junk_count += junk;
-			if (junk && !deleted)
-				summary->junk_not_deleted_count += junk;
-			summary->visible_count++;
-			if (junk ||  deleted) 
-				summary->visible_count -= junk ? junk : deleted;
-
-			summary->saved_count++;		
-		} else  {
-			oldflags = use_old ? oldflags : flags;
-			unread = deleted = junk = 0;
-			if (!(oldflags & CAMEL_MESSAGE_SEEN) && !(oldflags & CAMEL_MESSAGE_JUNK))
-				unread -= 1;
-
-			if (oldflags & CAMEL_MESSAGE_DELETED)
-				deleted -= 1;
-
-			if (oldflags & CAMEL_MESSAGE_JUNK)
-				junk -= 1;			
-
-			if (unread)
-				summary->unread_count += unread;
-			if (deleted)
-				summary->deleted_count += deleted;
-			if (junk)
-				summary->junk_count += junk;
-			if (junk && !deleted)
-				summary->junk_not_deleted_count += junk;
-			if (!junk && !deleted)
-				summary->visible_count--;
-
-			summary->saved_count--;		
-		}
-	} else {
-		if (!(oldflags & CAMEL_MESSAGE_SEEN) && !(oldflags & CAMEL_MESSAGE_JUNK))
-			unread -= 1;
-
-		if (oldflags & CAMEL_MESSAGE_DELETED)
-			deleted -= 1;
-
-		if (oldflags & CAMEL_MESSAGE_JUNK)
-			junk -= 1;
-		if (unread)
-			summary->unread_count += unread;
-		if (deleted)
-			summary->deleted_count += deleted;
-		if (junk)
-			summary->junk_count += junk;
-		if (junk && !deleted)
-			summary->junk_not_deleted_count += junk;
-		if (junk ||  deleted) 
-			summary->visible_count -= junk ? junk : deleted;
-	}
-}
 		
 /* Hold all these with summary lock and unmatched summary lock held */
 static void
-folder_changed_add_uid(CamelFolder *sub, const char *uid, const char hash[8], CamelVeeFolder *vf)
+folder_changed_add_uid(CamelFolder *sub, const char *uid, const char hash[8], CamelVeeFolder *vf, gboolean use_db)
 {
 	CamelFolder *folder = (CamelFolder *)vf;	
 	CamelVeeMessageInfo *vinfo;
@@ -1379,10 +1326,9 @@
 		return;
 	
 	vuid = camel_message_info_uid(vinfo);
-	camel_db_add_to_vfolder_transaction (folder->parent_store->cdb_w, folder->full_name, (char *)vuid, NULL);
+	if (use_db)
+		camel_db_add_to_vfolder_transaction (folder->parent_store->cdb_w, folder->full_name, (char *)vuid, NULL);
 	camel_folder_change_info_add_uid(vf->changes,  vuid);
-	/* old flags and new flags should  be same, since we sync all times  */
-	update_summary (vinfo, camel_message_info_flags(vinfo), 0, TRUE, FALSE);
 	if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && folder_unmatched != NULL) {
 		if (g_hash_table_lookup_extended(unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
 			n = GPOINTER_TO_INT (oldval);
@@ -1400,7 +1346,7 @@
 }
 
 static void
-folder_changed_remove_uid(CamelFolder *sub, const char *uid, const char hash[8], int keep, CamelVeeFolder *vf)
+folder_changed_remove_uid(CamelFolder *sub, const char *uid, const char hash[8], int keep, CamelVeeFolder *vf, gboolean use_db)
 {
 	CamelFolder *folder = (CamelFolder *)vf;
 	char *vuid, *oldkey;
@@ -1414,14 +1360,10 @@
 	memcpy(vuid, hash, 8);
 	strcpy(vuid+8, uid);
 
-	vinfo = (CamelVeeMessageInfo *) camel_folder_summary_uid (((CamelFolder *) vf)->summary, vuid);
-	if (vinfo) {
-		update_summary (vinfo, vinfo->old_flags, 0, FALSE, FALSE);
-		camel_message_info_free((CamelMessageInfo *)vinfo);
-	}
 	camel_folder_change_info_remove_uid(vf->changes, vuid);
-        /* FIXME[disk-summary] Handle exception */
-	camel_db_delete_uid_from_vfolder_transaction (folder->parent_store->cdb_w, folder->full_name, vuid, NULL);
+	if (use_db)
+		/* FIXME[disk-summary] Handle exception */
+		camel_db_delete_uid_from_vfolder_transaction (folder->parent_store->cdb_w, folder->full_name, vuid, NULL);
 	camel_folder_summary_remove_uid_fast(folder->summary, vuid);
 
 	if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && folder_unmatched != NULL) {
@@ -1457,7 +1399,7 @@
 }
 
 static void
-folder_changed_change_uid(CamelFolder *sub, const char *uid, const char hash[8], CamelVeeFolder *vf)
+folder_changed_change_uid(CamelFolder *sub, const char *uid, const char hash[8], CamelVeeFolder *vf, gboolean use_db)
 {
 	char *vuid;
 	CamelVeeMessageInfo *vinfo, *uinfo = NULL;
@@ -1476,22 +1418,19 @@
 		info = camel_folder_get_message_info(sub, uid);
 		if (info) {
 			if (vinfo) {
-				guint32 of = vinfo->old_flags;
 				camel_folder_change_info_change_uid(vf->changes, vuid);
-				update_summary (vinfo, camel_message_info_flags(info), of, FALSE /* Doesn't matter */, TRUE);
 				camel_message_info_free((CamelMessageInfo *)vinfo);
 			}
 
 			if (uinfo) {
 				camel_folder_change_info_change_uid(folder_unmatched->changes, vuid);
-				update_summary (uinfo, camel_message_info_flags(info), uinfo->old_flags, FALSE /* Doesn't matter */, TRUE);				
 				camel_message_info_free((CamelMessageInfo *)uinfo);
 			}
 
 			camel_folder_free_message_info(sub, info);
 		} else {
 			if (vinfo) {
-				folder_changed_remove_uid(sub, uid, hash, FALSE, vf);
+				folder_changed_remove_uid(sub, uid, hash, FALSE, vf, use_db);
 				camel_message_info_free((CamelMessageInfo *)vinfo);
 			}
 			if (uinfo)
@@ -1530,6 +1469,9 @@
 	GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
 	GPtrArray *present = NULL;
 
+	/* See vee_rebuild_folder. */
+	gboolean correlating = expression_is_correlating(vf->expression);
+
 	/* Check the folder hasn't beem removed while we weren't watching */
 	CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
 	if (g_list_find(_PRIVATE(vf)->folders, sub) == NULL) {
@@ -1599,7 +1541,7 @@
 	/* Always remove removed uid's, in any case */
 	for (i=0;i<changes->uid_removed->len;i++) {
 		dd(printf("  removing uid '%s'\n", (char *)changes->uid_removed->pdata[i]));
-		folder_changed_remove_uid(sub, changes->uid_removed->pdata[i], hash, FALSE, vf);
+		folder_changed_remove_uid(sub, changes->uid_removed->pdata[i], hash, FALSE, vf, !correlating);
 	}
 
 	/* Add any newly matched or to unmatched folder if they dont */
@@ -1613,7 +1555,7 @@
 			uid = changes->uid_added->pdata[i];
 			if (g_hash_table_lookup(matches_hash, uid)) {
 				dd(printf("  adding uid '%s' [newly matched]\n", (char *)uid));
-				folder_changed_add_uid(sub, uid, hash, vf);
+				folder_changed_add_uid(sub, uid, hash, vf, !correlating);
 			} else if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
 				if (strlen(uid)+9 > vuidlen) {
 					vuidlen = strlen(uid)+64;
@@ -1639,20 +1581,31 @@
 
 	/* Change any newly changed */
 	if (always_changed) {
-		GHashTable *ht_present = g_hash_table_new (g_str_hash, g_str_equal);
-
-		for (i=0;present && i<present->len;i++) {
-			folder_changed_change_uid(sub, present->pdata[i], hash, vf);
-			g_hash_table_insert (ht_present, present->pdata[i], present->pdata[i]);
-		}
-		
-		for (i=0; i<always_changed->len; i++) {
-			if (!present || !g_hash_table_lookup(ht_present, always_changed->pdata[i])) {
-				folder_changed_remove_uid(sub, always_changed->pdata[i], hash, FALSE, vf);
+		if (correlating) {
+			/* Messages may be pulled in by the correlation even if
+			 * they do not match the expression individually, so it
+			 * would be wrong to preemptively remove anything here.
+			 * vee_rebuild_folder will make any necessary removals
+			 * when it re-queries the entire source folder. */
+			for (i=0;i<always_changed->len;i++)
+				folder_changed_change_uid(sub, always_changed->pdata[i], hash, vf, !correlating);
+		} else {
+			GHashTable *ht_present = g_hash_table_new (g_str_hash, g_str_equal);
+	
+			for (i=0;present && i<present->len;i++) {
+				folder_changed_change_uid(sub, present->pdata[i], hash, vf, !correlating);
+				g_hash_table_insert (ht_present, present->pdata[i], present->pdata[i]);
 			}
+			
+			for (i=0; i<always_changed->len; i++) {
+				if (!present || !g_hash_table_lookup(ht_present, always_changed->pdata[i]))
+					/* XXX: IIUC, these messages haven't been deleted from the
+					 * source folder, so shouldn't "keep" be set to TRUE? */
+					folder_changed_remove_uid(sub, always_changed->pdata[i], hash, TRUE, vf, !correlating);
+			}
+	
+			g_hash_table_destroy (ht_present);
 		}
-
-		g_hash_table_destroy (ht_present);
 		g_ptr_array_free(always_changed, TRUE);
 	}
 
@@ -1680,21 +1633,21 @@
 				if (g_hash_table_lookup(matches_hash, uid)) {
 					/* A uid we dont have, but now it matches, add it */
 					dd(printf("  adding uid '%s' [newly matched]\n", uid));
-					folder_changed_add_uid(sub, uid, hash, vf);
+					folder_changed_add_uid(sub, uid, hash, vf, !correlating);
 				} else {
 					/* A uid we still don't have, just change it (for unmatched) */
-					folder_changed_change_uid(sub, uid, hash, vf);
+					folder_changed_change_uid(sub, uid, hash, vf, !correlating);
 				}
 			} else {
 				if ((vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO) == 0
 				    || g_hash_table_lookup(matches_hash, uid)) {
 					/* still match, or we're not auto-updating, change event, (if it changed) */
 					dd(printf("  changing uid '%s' [still matches]\n", uid));
-					folder_changed_change_uid(sub, uid, hash, vf);
+					folder_changed_change_uid(sub, uid, hash, vf, !correlating);
 				} else {
 					/* No longer matches, remove it, but keep it in unmatched (potentially) */
 					dd(printf("  removing uid '%s' [did match]\n", uid));
-					folder_changed_remove_uid(sub, uid, hash, TRUE, vf);
+					folder_changed_remove_uid(sub, uid, hash, TRUE, vf, !correlating);
 				}
 				camel_message_info_free((CamelMessageInfo *)vinfo);
 			}
@@ -1703,7 +1656,7 @@
 	} else {
 		/* stuff didn't match but it changed - check unmatched folder for changes */
 		for (i=0;i<changed->len;i++)
-			folder_changed_change_uid(sub, changed->pdata[i], hash, vf);
+			folder_changed_change_uid(sub, changed->pdata[i], hash, vf, !correlating);
 	}
 
 	if (folder_unmatched != NULL) {
@@ -1746,15 +1699,25 @@
 		camel_folder_change_info_free(unmatched_changes);
 	}
 	
-	if (vf_changes) {
-		/* If not auto-updating, keep track of changed folders for later re-sync */
-		if ((vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO) == 0) {
-			CAMEL_VEE_FOLDER_LOCK(vf, changed_lock);
-			if (g_list_find(vf->priv->folders_changed, sub) != NULL)
-				vf->priv->folders_changed = g_list_prepend(vf->priv->folders_changed, sub);
-			CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock);
-		}
+	/* Add to folders_changed if we need to call vee_rebuild_folder, which
+	 * could be the case for two reasons:
+	 * - We changed the vfolder and it is not auto-updating.  Need to re-sync.
+	 * - Vfolder is correlating.  Changes to non-matching source messages
+	 *   won't be processed here and won't show up in vf_changes but may
+	 *   still affect the vfolder contents (e.g., non-matching messages
+	 *   added to a matching thread), so we re-run the query on the whole
+	 *   source folder.  (For match-threads, it may be enough to do this if
+	 *   changes->uid_added->len > 0, but I'm not completely sure and I'd
+	 *   rather be safe than sorry.)
+	 */
+	if ((vf_changes && (vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO) == 0) || correlating) {
+		CAMEL_VEE_FOLDER_LOCK(vf, changed_lock);
+		if (g_list_find(vf->priv->folders_changed, sub) == NULL)
+			vf->priv->folders_changed = g_list_prepend(vf->priv->folders_changed, sub);
+		CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock);
+	}
 
+	if (vf_changes) {
 		camel_object_trigger_event((CamelObject *)vf, "folder_changed", vf_changes);
 		camel_folder_change_info_free(vf_changes);
 	}
@@ -1840,15 +1803,16 @@
 			count--;
 
 			vinfo = vee_folder_add_uid(vf, sub, uid+8, hash);
-			if (vinfo)
+			if (vinfo) {
 				camel_folder_change_info_add_uid(vf->changes, camel_message_info_uid(vinfo));
 
-			/* check unmatched uid's table for any matches */
-			if (vf == folder_unmatched
-			    && g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
-				g_hash_table_remove(unmatched_uids, oldkey);
-				g_hash_table_insert(unmatched_uids, g_strdup(camel_message_info_uid(vinfo)), oldval);
-				g_free(oldkey);
+				/* check unmatched uid's table for any matches */
+				if (vf == folder_unmatched
+				    && g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
+					g_hash_table_remove(unmatched_uids, oldkey);
+					g_hash_table_insert(unmatched_uids, g_strdup(camel_message_info_uid(vinfo)), oldval);
+					g_free(oldkey);
+				}
 			}
 		}
 
@@ -1938,96 +1902,6 @@
 	CAMEL_FOLDER_CLASS (camel_vee_folder_parent)->thaw(folder);
 }
 
-
-struct _folder_flags_msg {
-	CamelSessionThreadMsg msg;
-	CamelFolder *sub;
-	CamelVeeFolder *vf;
-};
-
-static void
-folder_load_flags(CamelSession *session, CamelSessionThreadMsg *msg)
-{
-	struct _folder_flags_msg *m = (struct _folder_flags_msg *)msg;
-	CamelFolder *sub = m->sub;
-	CamelFolder *folder = (CamelFolder *)m->vf;
-	GPtrArray *array;
-	char *shash, hash[8];
-	int i;
-
-	camel_vee_folder_hash_folder(sub, hash);	
-	shash = g_strdup_printf("%c%c%c%c%c%c%c%c", hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7]);
-	dd(printf("Loading summary of %s to vfolder %s\n", sub->full_name, folder->full_name));
-
-	/* Get the summary of vfolder */
-	array = camel_folder_summary_array (folder->summary);
-	for (i=0; i<array->len; i++) {
-		if (strncmp(array->pdata[i], shash, 8) == 0) {
-			/* We have got a vuid for this sub folder.*/
-			CamelVeeMessageInfo *vinfo;
-			CamelMessageInfo *info;
-			char *uid;
-			vinfo = (CamelVeeMessageInfo *) camel_folder_summary_uid (folder->summary, (char *)array->pdata[i]);
-			if (!vinfo) /* What else we can do ?*/
-				continue;
-			uid = ((char *)array->pdata[i])+8;
-			info = camel_folder_summary_uid (sub->summary, uid);
-			if (!info) {
-				camel_message_info_free((CamelMessageInfo *)vinfo);
-				continue;
-			}
-
-			vinfo->old_flags = camel_message_info_flags (info);
-			camel_message_info_free((CamelMessageInfo *)info);
-			camel_message_info_free((CamelMessageInfo *)vinfo);
-		}
-	}
-	camel_folder_free_summary (folder, array);
-	g_free(shash);	
-}
-
-static void
-folder_load_flags_free(CamelSession *session, CamelSessionThreadMsg *msg)
-{
-	struct _folder_flags_msg *m = (struct _folder_flags_msg *)msg;
-	
-	g_object_unref((CamelObject *)m->vf);
-	g_object_unref((CamelObject *)m->sub);	
-}
-
-static CamelSessionThreadOps folder_flags_ops = {
-	folder_load_flags,
-	folder_load_flags_free,
-};
-
-static void
-summary_reloaded(CamelObject *o, void *event_data, void *data)
-{
-	CamelFolderSummary *summary = event_data;
-	CamelVeeFolder *vf = (CamelVeeFolder *)data;
-	struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);	
-	struct _folder_flags_msg *m;
-	CamelSession *session = ((CamelService *)((CamelFolder *)vf)->parent_store)->session;
-
-	if (p->destroyed)
-		return; 
-
-	/* Kick off a thread to reload flags from the summary */
-	if (GPOINTER_TO_INT(g_hash_table_lookup (vf->loaded, summary->folder))) {	
-		g_hash_table_remove (vf->loaded, summary->folder);
-		camel_object_unhook_event((CamelObject *)o, "summary_reloaded", (CamelObjectEventHookFunc) summary_reloaded, data);
-	}
-	
-	/*
-	m = camel_session_thread_msg_new(session, &folder_flags_ops, sizeof(*m));
-	m->sub = summary->folder;
-	g_object_ref((CamelObject *)summary->folder);
-	m->vf = vf;
-	g_object_ref((CamelObject *)vf);
-	camel_session_thread_queue(session, &m->msg, 0);
-	*/
-}
-
 /* vfolder base implementaitons */
 static void
 vee_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
@@ -2105,10 +1979,12 @@
 vf_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
 {
 	CamelFolder *folder = (CamelFolder *)object;
+	CamelVeeFolder *vf = (CamelVeeFolder *)folder;
 	int i;
 	guint32 tag;
 	int unread = -1, deleted = 0, junked = 0, visible = 0, count = -1, junked_not_deleted = -1;
 
+
 	for (i=0;i<args->argc;i++) {
 		CamelArgGet *arg = &args->argv[i];
 
@@ -2122,7 +1998,10 @@
 		case CAMEL_FOLDER_ARG_JUNKED:
 		case CAMEL_FOLDER_ARG_JUNKED_NOT_DELETED:	
 		case CAMEL_FOLDER_ARG_VISIBLE:
-			
+
+			if (vf->expression && vf->priv->unread_vfolder == -1)
+				camel_vee_summary_load_check_unread_vfolder ((CamelVeeSummary *)folder->summary);
+		
 			/* This is so we can get the values atomically, and also so we can calculate them only once */
 			if (unread == -1) {
 				int j;
@@ -2156,7 +2035,10 @@
 
 			switch (tag & CAMEL_ARG_TAG) {
 			case CAMEL_FOLDER_ARG_UNREAD:
-				count = unread == -1 ? 0 : unread;
+				if (vf->priv->unread_vfolder == 1)
+					count = unread == -1 ? 0 : unread - junked_not_deleted;
+				else
+					count = unread == -1 ? 0 : unread;
 				break;
 			case CAMEL_FOLDER_ARG_DELETED:
 				count = deleted == -1 ? 0 : deleted;
@@ -2168,7 +2050,11 @@
 				count = junked_not_deleted == -1 ? 0 : junked_not_deleted;
 				break;				
 			case CAMEL_FOLDER_ARG_VISIBLE:
-				count = visible == -1 ? 0 : visible;
+				if (vf->priv->unread_vfolder == 1)
+					count = unread == -1 ? 0 : unread - junked_not_deleted;
+				else
+					count = visible == -1 ? 0 : visible;
+
 				break;
 			}
 			folder->summary->unread_count = unread == -1 ? 0 : unread;
@@ -2244,11 +2130,13 @@
 	obj->changes = camel_folder_change_info_new();
 	obj->search = camel_folder_search_new();
 	obj->hashes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-	obj->loaded = g_hash_table_new (g_direct_hash, g_direct_equal);
+	/* Loaded is no longer used.*/
+	obj->loaded = NULL; 
 	obj->deleted = FALSE;
 	p->summary_lock = g_mutex_new();
 	p->subfolder_lock = g_mutex_new();
 	p->changed_lock = g_mutex_new();
+	p->unread_vfolder = -1;
 }
 
 void
@@ -2287,10 +2175,6 @@
 	camel_object_unhook_event((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf);
 	camel_object_unhook_event((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf);
 	camel_object_unhook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc) folder_renamed, vf);
-	if (GPOINTER_TO_INT(g_hash_table_lookup (vf->loaded, sub))) {
-		g_hash_table_remove (vf->loaded, sub);
-		camel_object_unhook_event((CamelObject *)sub->summary, "summary_reloaded", (CamelObjectEventHookFunc) summary_reloaded, vf);
-	}
 	
 	p->folders = g_list_remove(p->folders, sub);
 	
@@ -2399,6 +2283,5 @@
 	g_mutex_free(p->subfolder_lock);
 	g_mutex_free(p->changed_lock);
 	g_hash_table_destroy (vf->hashes);
-	g_hash_table_destroy (vf->loaded);	
 	g_free(p);
 }

Modified: branches/camel-gobject/camel/camel-vee-store.c
==============================================================================
--- branches/camel-gobject/camel/camel-vee-store.c	(original)
+++ branches/camel-gobject/camel/camel-vee-store.c	Thu Apr 16 01:23:17 2009
@@ -28,6 +28,7 @@
 #include <glib/gi18n-lib.h>
 #include <glib/gstdio.h>
 
+#include "camel-db.h"
 #include "camel-exception.h"
 #include "camel-private.h"
 #include "camel-vee-folder.h"
@@ -102,17 +103,17 @@
 static void
 construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex)
 {
-	/*  CamelStore *store = (CamelStore *)service;
-	 CamelVeeStore *obj = (CamelVeeStore *)service; */
+	 CamelStore *store = (CamelStore *)service;
+	 CamelVeeStore *obj = (CamelVeeStore *)service; 
 	 
 	 ((CamelServiceClass *) camel_vee_store_parent)->construct(service, session, provider, url, ex);
 	 
 	/* Set up unmatched folder */
-#ifdef VEE_UNMATCHED_ENABLE
+#ifndef VEE_UNMATCHED_ENABLE
 	obj->unmatched_uids = g_hash_table_new (g_str_hash, g_str_equal);
 	obj->folder_unmatched = g_object_new (CAMEL_TYPE_VEE_FOLDER, NULL);
 	camel_vee_folder_construct (obj->folder_unmatched, store, CAMEL_UNMATCHED_NAME, _("Unmatched"), CAMEL_STORE_FOLDER_PRIVATE);
-	camel_db_create_vfolder (store->cdb, _("Unmatched"), NULL);
+	camel_db_create_vfolder (store->cdb_r, _("Unmatched"), NULL);
 #endif
 	 
 }
@@ -347,7 +348,7 @@
 
 	/* and always add UNMATCHED, if scanning from top/etc */
 	/* FIXME[disk-summary] comment it out well */
-	if (0 && (top == NULL || top[0] == 0 || strncmp(top, CAMEL_UNMATCHED_NAME, strlen(CAMEL_UNMATCHED_NAME)) == 0)) {
+	if ((top == NULL || top[0] == 0 || strncmp(top, CAMEL_UNMATCHED_NAME, strlen(CAMEL_UNMATCHED_NAME)) == 0)) {
 		info = camel_folder_info_new ();
 		url = camel_url_new("vfolder:", NULL);
 		camel_url_set_path(url, ((CamelService *)store)->url->path);

Modified: branches/camel-gobject/camel/camel-vee-summary.c
==============================================================================
--- branches/camel-gobject/camel/camel-vee-summary.c	(original)
+++ branches/camel-gobject/camel/camel-vee-summary.c	Thu Apr 16 01:23:17 2009
@@ -171,15 +171,14 @@
 	return res;
 }
 
-static gboolean
-vee_info_set_flags(CamelMessageInfo *mi, guint32 flags, guint32 set)
+void
+camel_vee_summary_load_check_unread_vfolder (CamelVeeSummary *vs)
 {
-	int res = FALSE;
-	CamelVeeFolder *vf = (CamelVeeFolder *)mi->summary->folder;
+	static int only_once = FALSE;
 	static char *exp = NULL;
-	static only_once = FALSE;
+	char *meta;
 	gboolean hacked_unread_folder = FALSE;
-	char *meta = NULL;
+	CamelVeeFolder *vf = (CamelVeeFolder *) ((CamelFolderSummary *)vs)->folder;
 
 	/* HACK: Ugliest of all hacks. Its virtually not possible now
 	 * to maintain counts and the non matching uids of unread vfolder here.
@@ -192,17 +191,42 @@
 	if (!exp || !*exp)
 		exp = g_strcompress(unread_str);
 
-	if (camel_debug("vfolderexp"))
-		printf("Expression for vfolder '%s' is '%s'\n", mi->summary->folder->full_name, g_strescape(vf->expression, ""));
-
-	if (strstr(exp, vf->expression) &&  (vf->flags & CAMEL_STORE_VEE_FOLDER_SPECIAL) == 0)
+	if (vf->expression && strstr(exp, vf->expression) &&  (vf->flags & CAMEL_STORE_VEE_FOLDER_SPECIAL) == 0)
 		hacked_unread_folder = TRUE;
 
-	meta = camel_object_meta_get (mi->summary->folder, "vfolder:unread");
+	meta = camel_object_meta_get (vf, "vfolder:unread");
 	if (!hacked_unread_folder && meta && strcmp (meta, "true") == 0)
 		hacked_unread_folder = TRUE;
 	g_free(meta);
 
+	if (hacked_unread_folder)
+		vf->priv->unread_vfolder = 1;
+	else
+		vf->priv->unread_vfolder = 0;
+}
+
+static gboolean
+vee_info_set_flags(CamelMessageInfo *mi, guint32 flags, guint32 set)
+{
+	int res = FALSE;
+	CamelVeeFolder *vf = (CamelVeeFolder *)mi->summary->folder;
+	gboolean hacked_unread_folder = FALSE;
+
+	if (camel_debug("vfolderexp"))
+		printf("Expression for vfolder '%s' is '%s'\n", mi->summary->folder->full_name, g_strescape(vf->expression, ""));
+
+	if (vf->priv->unread_vfolder == -1)
+		camel_vee_summary_load_check_unread_vfolder (mi->summary);
+
+	if (vf->priv->unread_vfolder == 1)
+		hacked_unread_folder = TRUE;
+	else {
+		char *meta = camel_object_meta_get (mi->summary->folder, "vfolder:unread");
+		if (meta && strcmp (meta, "true") == 0)
+			hacked_unread_folder = TRUE;
+		g_free(meta);
+	}
+
 	if (mi->uid) {
 		guint32 old_visible, old_unread, old_deleted, old_junked, old_junked_not_deleted;
 		guint32 visible, unread, deleted, junked, junked_not_deleted;
@@ -238,11 +262,11 @@
 			vsummary->fake_visible_count = mi->summary->visible_count;
 
 		/* Keep the summary in sync */
-		mi->summary->unread_count += unread - old_unread;
-		mi->summary->deleted_count += deleted - old_deleted;
-		mi->summary->junk_count += junked - old_junked;
-		mi->summary->junk_not_deleted_count += junked_not_deleted - old_junked_not_deleted;
-		mi->summary->visible_count += visible - old_visible;
+		//mi->summary->unread_count += unread - old_unread;
+		//mi->summary->deleted_count += deleted - old_deleted;
+		//mi->summary->junk_count += junked - old_junked;
+		//mi->summary->junk_not_deleted_count += junked_not_deleted - old_junked_not_deleted;
+		//mi->summary->visible_count += visible - old_visible;
 
 		if (vsummary->fake_visible_count || hacked_unread_folder)
 			vsummary->fake_visible_count += visible - old_visible;

Modified: branches/camel-gobject/camel/camel-vee-summary.h
==============================================================================
--- branches/camel-gobject/camel/camel-vee-summary.h	(original)
+++ branches/camel-gobject/camel/camel-vee-summary.h	Thu Apr 16 01:23:17 2009
@@ -62,6 +62,7 @@
 
 CamelVeeMessageInfo * camel_vee_summary_add(CamelVeeSummary *s, CamelFolderSummary *summary, const char *uid, const char hash[8]);
 GPtrArray * camel_vee_summary_get_ids (CamelVeeSummary *summary, char hash[8]);
+void camel_vee_summary_load_check_unread_vfolder  (CamelVeeSummary *vs);
 
 G_END_DECLS
 

Modified: branches/camel-gobject/camel/providers/groupwise/camel-groupwise-folder.c
==============================================================================
--- branches/camel-gobject/camel/providers/groupwise/camel-groupwise-folder.c	(original)
+++ branches/camel-gobject/camel/providers/groupwise/camel-groupwise-folder.c	Thu Apr 16 01:23:17 2009
@@ -26,6 +26,12 @@
  */
 
 
+/* This file is broken and suffers from multiple author syndrome. 
+This needs to be rewritten with a lot of functions cleaned up. 
+
+There are a lot of places where code is unneccesarily duplicated, 
+which needs to be better organized via functions */
+
 #ifdef HAVE_CONFIG_H
 #include <config.h> 
 #endif
@@ -89,6 +95,8 @@
 static void groupwise_msg_set_recipient_list (CamelMimeMessage *msg, EGwItem *item);
 static void gw_update_cache ( CamelFolder *folder, GList *item_list, CamelException *ex, gboolean uid_flag);
 static CamelMimeMessage *groupwise_folder_item_to_msg ( CamelFolder *folder, EGwItem *item, CamelException *ex );
+static char* groupwise_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
+static const char *get_from_from_org (EGwItemOrganizer *org);
 
 
 #define d(x)  
@@ -96,6 +104,16 @@
 const char * GET_ITEM_VIEW_WITH_CACHE = "peek default recipient threading attachments subject status priority startDate created delivered size recurrenceKey message notification";
 const char * GET_ITEM_VIEW_WITHOUT_CACHE = "peek default recipient threading hasAttachment subject status priority startDate created delivered size recurrenceKey";
 
+static char* 
+groupwise_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelGroupwiseFolder *gw_folder = CAMEL_GROUPWISE_FOLDER(folder);
+
+	return camel_data_cache_get_filename (gw_folder->cache, "cache", uid, ex);
+}
+
+
+/* Get a message from cache if available otherwise get it from server */
 static CamelMimeMessage *
 groupwise_folder_get_message( CamelFolder *folder, const char *uid, CamelException *ex )
 {
@@ -209,20 +227,31 @@
 	return msg;
 }
 
+/* create a mime message out of an gwitem */
 static void
 groupwise_populate_details_from_item (CamelMimeMessage *msg, EGwItem *item)
 {
+	EGwItemType type;
 	char *dtstring = NULL;
 	char *temp_str = NULL;
 
 	temp_str = (char *)e_gw_item_get_subject(item);
 	if(temp_str)
 		camel_mime_message_set_subject (msg, temp_str);
+	type = e_gw_item_get_item_type (item);
+
+	if (type == E_GW_ITEM_TYPE_APPOINTMENT  || type == E_GW_ITEM_TYPE_NOTE || type == E_GW_ITEM_TYPE_TASK) {
+		int offset = 0;
+		dtstring = e_gw_item_get_start_date (item);
+		time_t actual_time = e_gw_connection_get_date_from_string (dtstring);
+		camel_mime_message_set_date (msg, actual_time, offset);
+		return;
+	}
+
 	dtstring = e_gw_item_get_delivered_date (item);
 	if(dtstring) {
 		int offset = 0;
-		time_t time = e_gw_connection_get_date_from_string (dtstring);
-		time_t actual_time = camel_header_decode_date (ctime(&time), &offset);
+		time_t actual_time = e_gw_connection_get_date_from_string (dtstring);
 		camel_mime_message_set_date (msg, actual_time, offset);
 	} else {
 		time_t time;
@@ -230,14 +259,14 @@
 		int offset = 0;
 		dtstring = e_gw_item_get_creation_date (item);
 		if (dtstring) {
-				time = e_gw_connection_get_date_from_string (dtstring);
-				actual_time = camel_header_decode_date (ctime(&time), NULL);
+				actual_time = e_gw_connection_get_date_from_string (dtstring);
 		} else
 				actual_time = (time_t) 0;
 		camel_mime_message_set_date (msg, actual_time, offset);
 	}
 }
 
+/* convert an item to a msg body. set content type etc. */
 static void
 groupwise_populate_msg_body_from_item (EGwConnection *cnc, CamelMultipart *multipart, EGwItem *item, char *body)
 {
@@ -302,6 +331,7 @@
 	g_object_unref (part);
 }
 
+/* Set the recipients list in the message from the item */
 static void
 groupwise_msg_set_recipient_list (CamelMimeMessage *msg, EGwItem *item)
 {
@@ -361,7 +391,7 @@
 			}
 		}
 
-		/* README: This entire status-opt code should go away once the new status-tracking code is tested */
+		/* The status tracking code is working fine. someone need to remove this */
 		if (enabled) {
 			camel_medium_add_header ( CAMEL_MEDIUM (msg), "X-gw-status-opt", (const char *)status_opt);
 			g_free (status_opt);
@@ -391,20 +421,14 @@
 
 	if (org) {
 		if (org->display_name && org->display_name[0] && org->email != NULL && org->email[0] != '\0') {
-				int i;
-				for (i = 0; org->display_name[i] != '<' && 
-						org->display_name[i] != '\0';
-						i++);
-
-				org->display_name[i] = '\0';
-		}
-		if (org->display_name && org->email) 
+			org->display_name = g_strdelimit (org->display_name, "<>", ' ');
 			ha=camel_header_address_new_name(org->display_name, org->email);
+		} else if (org->email) 
+			ha=camel_header_address_new_name(org->email, org->email);
 		else if (org->display_name)
 			ha=camel_header_address_new_group(org->display_name);
 		else
 			ha = NULL;
-
 		if (ha) {
 			subs_email = camel_header_address_list_encode (ha);	
 			camel_medium_set_header (CAMEL_MEDIUM (msg), "From", subs_email);
@@ -414,6 +438,7 @@
 	}
 }
 
+/* code to rename a folder. all the "meta nonsense" code should simply go away */
 static void
 groupwise_folder_rename (CamelFolder *folder, const char *new)
 {
@@ -522,10 +547,13 @@
 	}
 }
 
+/* This is a point of contention. We behave like the GW client and update our junk list
+in the same way as the GroupWise client. Add senders to junk list */
 static void
 update_junk_list (CamelStore *store, CamelMessageInfo *info, int flag)
 {
 	gchar **email = NULL, *from = NULL;	
+	int index = 0;
 	CamelGroupwiseStore *gw_store= CAMEL_GROUPWISE_STORE(store);
 	CamelGroupwiseStorePrivate  *priv = gw_store->priv;
 	EGwConnection *cnc = cnc_lookup (priv);
@@ -535,18 +563,25 @@
 
 	email = g_strsplit_set (from, "<>", -1);
 
-	if (!email || !email[1])
+	if (from [0] == '<') {
+		/* g_strsplit_set will add a dummy empty string as the first string if the first character in the 
+		original string is one of the delimiters that you want to suppress. 
+		Refer to g_strsplit_set documentation */
+		index = 1;
+	}
+
+	if (!email || !email[index])
 		goto error;
 
 	if (flag == ADD_JUNK_ENTRY)
-		e_gw_connection_create_junk_entry (cnc, email[1], "email", "junk");
+		e_gw_connection_create_junk_entry (cnc, email[index], "email", "junk");
 	else if (flag == REMOVE_JUNK_ENTRY) {
 		GList *list = NULL;
 		EGwJunkEntry *entry;
 		if (e_gw_connection_get_junk_entries (cnc, &list)== E_GW_CONNECTION_STATUS_OK){
 			while (list) {
 				entry = list->data;
-				if (!g_ascii_strcasecmp (entry->match, email[1])) { 
+				if (!g_ascii_strcasecmp (entry->match, email[index])) { 
 					e_gw_connection_remove_junk_entry (cnc, entry->id);
 				}
 				list = list->next;
@@ -616,6 +651,7 @@
 	camel_store_summary_save ((CamelStoreSummary *)((CamelGroupwiseStore *)folder->parent_store)->summary);
 }
 
+/* This may need to be reorganized. */
 static void
 groupwise_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
 {
@@ -667,6 +703,11 @@
 			continue;
 		flags = camel_message_info_flags (info);	
 
+		if (!(flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
+				camel_message_info_free(info);
+				continue;
+		}
+
 		if ((flags & CAMEL_MESSAGE_JUNK) && strcmp(camel_folder_get_name(folder), JUNK_FOLDER)) { 
 			/*marked a message junk*/
 			move_to_junk (folder, info, ex);
@@ -764,6 +805,8 @@
 	
 	CAMEL_GROUPWISE_FOLDER_REC_UNLOCK (folder, cache_lock);
 
+	/* Do things in bulk. Reduces server calls, network latency etc.  */
+
 	if (deleted_items) {
 		CAMEL_SERVICE_REC_LOCK (gw_store, connect_lock);
 		if (!strcmp (folder->full_name, "Trash")) {
@@ -1065,6 +1108,7 @@
 	char *time_string = NULL, *t_str = NULL;
 	struct _folder_update_msg *msg;
 	gboolean check_all = FALSE;
+	int new_items = 0;
 
 	/* Sync-up the (un)read changes before getting updates,
 	so that the getFolderList will reflect the most recent changes too */
@@ -1159,7 +1203,7 @@
 		   for ( sl = slist ; sl != NULL; sl = sl->next) 
 		   list = g_list_append (list, sl->data);*/
 
-		if (slist && g_slist_length(slist) != 0)
+		if (slist && (new_items = g_slist_length(slist)) != 0)
 			check_all = TRUE;
 
 		g_slist_free (slist);
@@ -1194,25 +1238,36 @@
 		if (!check_all && slist && g_slist_length(slist) != 0)
 			check_all = TRUE;
 
+		if (gw_store->current_folder != folder)
+			groupwise_store_set_current_folder (gw_store, folder);
+
 		g_slist_free (slist);
 		slist = NULL;
 
-		if (gw_store->current_folder != folder) {
-			gw_store->current_folder = folder;
-		}
-		
 		if (check_all && !is_proxy) {
 				EGwContainer *container;
-				container = e_gw_connection_get_container (cnc, container_id);
+				int i=0;
 
-				d(printf ("Evolution's folder summary length is : %u\tserver has %u items",
-										camel_folder_summary_count (folder->summary), e_gw_container_get_total_count (container)));
+				do {
+						/* HACK: Refer to Novell bugzilla bug #464379 */ 
+						container = e_gw_connection_get_container (cnc, container_id);
+						++i;
+						if (!strcmp (folder->full_name, e_gw_container_get_name (container))) 
+								i = 10;
+				} while (i < 2);
+
+				if (i == 10) {
+						/* HACK: Refer to Novell bugzilla bug #464379 */ 
+						d(printf ("Evolution's folder summary length is : %u\tserver has %u items",
+												camel_folder_summary_count (folder->summary), e_gw_container_get_total_count (container)));
 
-				if (camel_folder_summary_count (folder->summary) == e_gw_container_get_total_count (container))
-						check_all = FALSE;
+						if ((camel_folder_summary_count (folder->summary) + new_items) == e_gw_container_get_total_count (container))
+								check_all = FALSE;
 
-				folder->summary->unread_count = e_gw_container_get_unread_count (container);
-				folder->summary->visible_count = e_gw_container_get_total_count (container);
+						folder->summary->unread_count = e_gw_container_get_unread_count (container);
+						folder->summary->visible_count = e_gw_container_get_total_count (container);
+				} else
+					check_all = FALSE;
 				g_object_unref (container);
 		}
 
@@ -1258,6 +1313,7 @@
 	return;
 }
 
+/* Update the GroupWise cache with the list of items passed. should happen in thread. */
 static void
 gw_update_cache (CamelFolder *folder, GList *list, CamelException *ex, gboolean uid_flag) 
 {
@@ -1393,32 +1449,7 @@
 		mi->server_flags = mi->info.flags;
 
 		org = e_gw_item_get_organizer (item); 
-
-		if (org) {
-				GString *str;
-				int i;
-				str = g_string_new ("");
-
-				if (org->display_name && org->display_name[0] && org->email != NULL && org->email[0] != '\0') {
-						for (i = 0; org->display_name[i] != '<' && 
-										org->display_name[i] != '\0'; 
-										i++);
-
-						org->display_name[i] = '\0';
-						str = g_string_append (str, org->display_name);
-						str = g_string_append (str, " ");
-				}
-
-				if (org->email && org->email[0]) { 
-						g_string_append (str, "<");
-						str = g_string_append (str, org->email);
-						g_string_append (str, ">");
-				}
-
-
-				mi->info.from = camel_pstring_strdup (str->str);
-				g_string_free (str, TRUE);
-		}
+		mi->info.from = get_from_from_org (org);
 
 		g_string_truncate (str, 0);
 		recp_list = e_gw_item_get_recipient_list (item);
@@ -1445,24 +1476,20 @@
 				|| type ==  E_GW_ITEM_TYPE_TASK ) {
 			temp_date = e_gw_item_get_start_date (item);
 			if (temp_date) {
-				time_t time = e_gw_connection_get_date_from_string (temp_date);
-				time_t actual_time = camel_header_decode_date (ctime(&time), NULL);
+				time_t actual_time = e_gw_connection_get_date_from_string (temp_date);
 				mi->info.date_sent = mi->info.date_received = actual_time;
 			}
 		} else {
 			temp_date = e_gw_item_get_delivered_date(item);
 			if (temp_date) {
-				time_t time = e_gw_connection_get_date_from_string (temp_date);
-				time_t actual_time = camel_header_decode_date (ctime(&time), NULL);
+				time_t actual_time = e_gw_connection_get_date_from_string (temp_date);
 				mi->info.date_sent = mi->info.date_received = actual_time;
 			} else {
-				time_t time;
 				time_t actual_time;
 				temp_date = e_gw_item_get_creation_date (item);
 				if (temp_date) {
 						/* Creation date can be returned as null for auto-generated meetings */
-						time = e_gw_connection_get_date_from_string (temp_date);
-						actual_time = camel_header_decode_date (ctime(&time), NULL);
+						actual_time = e_gw_connection_get_date_from_string (temp_date);
 				} else
 					actual_time = (time_t) 0;
 				mi->info.date_sent = mi->info.date_received = actual_time;
@@ -1522,6 +1549,38 @@
 	camel_folder_change_info_free (changes);
 }
 
+static const char *
+get_from_from_org (EGwItemOrganizer *org)
+{
+	const char *ret = NULL;
+
+	if (org) {
+		GString *str;
+		
+		str = g_string_new ("");
+		if (org->display_name && org->display_name[0]) {
+			org->display_name = g_strdelimit (org->display_name, "<>", ' ');
+			str = g_string_append (str, org->display_name);
+			str = g_string_append (str, " ");
+		} else if (org->email && org->email [0]) {
+			str = g_string_append (str, org->email);
+			str = g_string_append (str, " ");
+		}
+
+		if (org->email && org->email[0]) { 
+			g_string_append (str, "<");
+			str = g_string_append (str, org->email);
+			g_string_append (str, ">");
+		}
+		ret = camel_pstring_strdup (str->str);
+		g_string_free (str, TRUE);
+
+		return ret;
+	} else
+	       return camel_pstring_strdup ("");
+}
+
+/* Update summary, if there is none existing, create one */
 void
 gw_update_summary ( CamelFolder *folder, GList *list,CamelException *ex) 
 {
@@ -1621,28 +1680,8 @@
 		mi->server_flags = mi->info.flags;
 
 		org = e_gw_item_get_organizer (item); 
-		if (org) {
-			GString *str;
-			int i;
-			str = g_string_new ("");
-			if (org->display_name && org->display_name[0] && org->email != NULL && org->email[0] != '\0') {
-				for (i = 0; org->display_name[i] != '<' && 
-						org->display_name[i] != '\0'; 
-						i++);
-
-				org->display_name[i] = '\0';
-				str = g_string_append (str, org->display_name);
-				str = g_string_append (str, " ");
-			}
-
-			if (org->email && org->email[0]) { 
-				g_string_append (str, "<");
-				str = g_string_append (str, org->email);
-				g_string_append (str, ">");
-			}
-			mi->info.from = camel_pstring_strdup (str->str);
-			g_string_free (str, TRUE);
-		}
+		mi->info.from = get_from_from_org (org);
+
 		g_string_truncate (str, 0);
 		recp_list = e_gw_item_get_recipient_list (item);
 		if (recp_list) {
@@ -1666,23 +1705,19 @@
 		    type ==  E_GW_ITEM_TYPE_TASK ) {
 			temp_date = e_gw_item_get_start_date (item);
 			if (temp_date) {
-				time_t time = e_gw_connection_get_date_from_string (temp_date);
-				time_t actual_time = camel_header_decode_date (ctime(&time), NULL);
+				time_t actual_time = e_gw_connection_get_date_from_string (temp_date);
 				mi->info.date_sent = mi->info.date_received = actual_time;
 			} 
 		} else {
 			temp_date = e_gw_item_get_delivered_date(item);
 			if (temp_date) {
-				time_t time = e_gw_connection_get_date_from_string (temp_date);
-				time_t actual_time = camel_header_decode_date (ctime(&time), NULL);
+				time_t actual_time = e_gw_connection_get_date_from_string (temp_date);
 				mi->info.date_sent = mi->info.date_received = actual_time;
 			} else {
-				time_t time;
 				time_t actual_time;
 				temp_date = e_gw_item_get_creation_date (item);
 				if (temp_date) {
-						time = e_gw_connection_get_date_from_string (temp_date);
-						actual_time = camel_header_decode_date (ctime(&time), NULL);
+						actual_time = e_gw_connection_get_date_from_string (temp_date);
 				} else
 						actual_time = (time_t) 0;
 				mi->info.date_sent = mi->info.date_received = actual_time;
@@ -1894,6 +1929,8 @@
 			if (attach->contentid && (is_text_html_embed != TRUE))
 				is_text_html_embed = TRUE;
 
+			/* MIME.822 from server for the weak hearted client programmer */
+
 			if ( (!g_ascii_strcasecmp (attach->name, "TEXT.htm") ||
 			     !g_ascii_strcasecmp (attach->name, "Mime.822") ||
 			     !g_ascii_strcasecmp (attach->name, "Header") ||
@@ -2007,6 +2044,8 @@
 	}/* if attach_list */
 	/********************/
 
+	
+	/* this is broken for translations. someone should care to fix these hacks. nobody except groupwise users are affected though */
 	if (e_gw_item_get_priority (item))
 		camel_medium_add_header ( CAMEL_MEDIUM (msg), "Priority", e_gw_item_get_priority(item));
 
@@ -2113,6 +2152,7 @@
 	
 	item = camel_groupwise_util_item_from_message (cnc, message, CAMEL_ADDRESS (message->from));
 	/*Set the source*/
+	/* FIXME: use flags and avoid such name comparisons in future */
 	if (!strcmp (folder->name, RECEIVED))
 		e_gw_item_set_source (item, "received");
 	if (!strcmp (folder->name, SENT))
@@ -2154,6 +2194,8 @@
 	CAMEL_SERVICE_REC_UNLOCK (folder->parent_store, connect_lock);
 }
 
+/* A function to compare uids, inspired by strcmp .
+This code was used in some other provider also , imap4rev1 iirc */
 static int
 uid_compar (const void *va, const void *vb)
 {
@@ -2170,6 +2212,7 @@
 		return 1;
 }
 
+/* move messages */
 static void
 groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids, 
 		CamelFolder *destination, GPtrArray **transferred_uids, 
@@ -2310,6 +2353,7 @@
 			}
 		}
 
+
 		if (destination_is_trash) {
 				e_gw_connection_remove_item (cnc, source_container_id, (const char*) uids->pdata[index]);
 				camel_folder_summary_remove_uid (source->summary, uids->pdata[index]);
@@ -2336,6 +2380,10 @@
 								/*if ( !strcmp(source->full_name, SENT) ) {
 								  camel_folder_delete_message(source, uids->pdata[index]);
 								  } else {*/
+
+								if (!(gw_info->info.flags & CAMEL_MESSAGE_SEEN))
+										source->summary->unread_count --;
+
 								camel_folder_summary_remove_uid (source->summary, uids->pdata[index]);
 								camel_folder_change_info_remove_uid (changes, uids->pdata[index]);
 								//}
@@ -2358,7 +2406,7 @@
 	camel_folder_summary_touch (source->summary);
 	camel_folder_summary_touch (destination->summary);
 
-	gw_store->current_folder = source;
+	groupwise_store_set_current_folder (gw_store, source);
 
 	CAMEL_SERVICE_REC_UNLOCK (source->parent_store, connect_lock);
 }
@@ -2488,6 +2536,7 @@
 	camel_folder_class->sync = groupwise_sync;
 	camel_folder_class->expunge = groupwise_expunge;
 	camel_folder_class->transfer_messages_to = groupwise_transfer_messages_to;
+	camel_folder_class->get_filename = groupwise_get_filename;
 }
 
 static void

Modified: branches/camel-gobject/camel/providers/groupwise/camel-groupwise-journal.c
==============================================================================
--- branches/camel-gobject/camel/providers/groupwise/camel-groupwise-journal.c	(original)
+++ branches/camel-gobject/camel/providers/groupwise/camel-groupwise-journal.c	Thu Apr 16 01:23:17 2009
@@ -47,7 +47,7 @@
 #include "camel-groupwise-journal.h"
 #include "camel-groupwise-store.h"
 
-#define d(x) x
+#define d(x)
 
 
 static void camel_groupwise_journal_class_init (CamelGroupwiseJournalClass *klass);

Modified: branches/camel-gobject/camel/providers/groupwise/camel-groupwise-journal.h
==============================================================================
--- branches/camel-gobject/camel/providers/groupwise/camel-groupwise-journal.h	(original)
+++ branches/camel-gobject/camel/providers/groupwise/camel-groupwise-journal.h	Thu Apr 16 01:23:17 2009
@@ -54,7 +54,7 @@
 struct _CamelGroupwiseJournalEntry {
 	CamelDListNode node;
 	
-	int type;
+	guint32 type;
 
 	char *uid;
 	char *original_uid;

Modified: branches/camel-gobject/camel/providers/groupwise/camel-groupwise-provider.c
==============================================================================
--- branches/camel-gobject/camel/providers/groupwise/camel-groupwise-provider.c	(original)
+++ branches/camel-gobject/camel/providers/groupwise/camel-groupwise-provider.c	Thu Apr 16 01:23:17 2009
@@ -165,7 +165,6 @@
 	guint hash = 0;
 
 	add_hash (&hash, u->user);
-	add_hash (&hash, u->authmech);
 	add_hash (&hash, u->host);
 	hash ^= u->port;
 	
@@ -195,7 +194,6 @@
 	
 	return check_equal (u1->protocol, u2->protocol)
 		&& check_equal (u1->user, u2->user)
-		&& check_equal (u1->authmech, u2->authmech)
 		&& check_equal (u1->host, u2->host)
 		&& u1->port == u2->port;
 }

Modified: branches/camel-gobject/camel/providers/groupwise/camel-groupwise-store.c
==============================================================================
--- branches/camel-gobject/camel/providers/groupwise/camel-groupwise-store.c	(original)
+++ branches/camel-gobject/camel/providers/groupwise/camel-groupwise-store.c	Thu Apr 16 01:23:17 2009
@@ -258,6 +258,26 @@
 
 }
 
+/* resets the current folder. To just free current folder, pass NULL for folder */
+void
+groupwise_store_set_current_folder (CamelGroupwiseStore *groupwise_store, CamelFolder *folder)
+{
+		
+	CAMEL_SERVICE_REC_LOCK (groupwise_store, connect_lock);
+	
+	if (groupwise_store->current_folder) {
+		camel_object_unref (groupwise_store->current_folder);
+		groupwise_store->current_folder = NULL;
+	}
+
+	if (folder) {
+		camel_object_ref (folder);
+		groupwise_store->current_folder = folder;
+	}
+	
+	CAMEL_SERVICE_REC_UNLOCK (groupwise_store, connect_lock);
+}
+
 static gboolean
 groupwise_connect (CamelService *service, CamelException *ex)
 {
@@ -390,6 +410,9 @@
 			g_object_unref (groupwise_store->priv->cnc);
 			groupwise_store->priv->cnc = NULL;
 		}
+
+		groupwise_store_set_current_folder (groupwise_store, NULL);
+
 		CAMEL_SERVICE_REC_UNLOCK (groupwise_store, connect_lock);
 	}
 	
@@ -462,7 +485,11 @@
 		fi->flags |= CAMEL_FOLDER_TYPE_TRASH;
 	else if (!strcmp (folder_name, "Junk Mail"))
 		fi->flags |= CAMEL_FOLDER_TYPE_JUNK;
-		
+
+	if (groupwise_is_system_folder (folder_name))
+		fi->flags |= CAMEL_FOLDER_SYSTEM;
+	
+
 	fi->name = g_strdup(name);
 	return fi;
 }
@@ -543,7 +570,7 @@
 	
 	folder = groupwise_get_folder_from_disk (store, folder_name, flags, ex);
 	if (folder) {
-		g_object_ref (folder);
+		groupwise_store_set_current_folder (gw_store, folder);
 		return folder;
 	}
 
@@ -551,16 +578,13 @@
 
 	CAMEL_SERVICE_REC_LOCK (gw_store, connect_lock);
 
+	groupwise_store_set_current_folder (gw_store, NULL);
+
 	if (!camel_groupwise_store_connected (gw_store, ex)) {
 		CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
 		return NULL;
 	}
 	
-	if (gw_store->current_folder) {
-		g_object_unref (gw_store->current_folder);
-		gw_store->current_folder = NULL;
-	}
-
 	if (!E_IS_GW_CONNECTION( priv->cnc)) {
 		if (!groupwise_connect (CAMEL_SERVICE(store), ex)) {
 			CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
@@ -667,8 +691,7 @@
 
 	camel_folder_summary_save_to_db (folder->summary, ex);
 
-	gw_store->current_folder = folder;
-	g_object_ref (folder);
+	groupwise_store_set_current_folder (gw_store, folder);
 
 	g_free (container_id);
 	CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
@@ -787,7 +810,7 @@
 
 	camel_folder_summary_save_to_db (folder->summary, ex);
 
-	gw_store->current_folder = folder;
+	groupwise_store_set_current_folder (gw_store, NULL);
 	
 	g_free (container_id);
 	CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
@@ -1294,8 +1317,7 @@
 	status = e_gw_connection_remove_item (priv->cnc, container, container);
 
 	if (status == E_GW_CONNECTION_STATUS_OK) {
-		if (groupwise_store->current_folder)
-			g_object_unref (groupwise_store->current_folder);
+		groupwise_store_set_current_folder (groupwise_store, NULL);
 
 		groupwise_forget_folder(groupwise_store,folder_name,ex);
 
@@ -1332,6 +1354,8 @@
 		return;
 	}
 
+	groupwise_store_set_current_folder (groupwise_store, NULL);
+
 	container_id = camel_groupwise_store_container_id_lookup (groupwise_store, old_name);
 	temp_new = strrchr (new_name, '/');
 	if (temp_new)
@@ -1587,6 +1611,7 @@
 	priv->user = NULL;
 	priv->cnc = NULL;
 	groupwise_store->priv = priv;
+	groupwise_store->current_folder = NULL;
 	
 }
 

Modified: branches/camel-gobject/camel/providers/groupwise/camel-groupwise-store.h
==============================================================================
--- branches/camel-gobject/camel/providers/groupwise/camel-groupwise-store.h	(original)
+++ branches/camel-gobject/camel/providers/groupwise/camel-groupwise-store.h	Thu Apr 16 01:23:17 2009
@@ -79,6 +79,7 @@
 CamelFolderInfo * create_junk_folder (CamelStore *store);
 gboolean camel_groupwise_store_connected (CamelGroupwiseStore *store, CamelException *ex);
 void gw_store_reload_folder (CamelGroupwiseStore *store, CamelFolder *folder, guint32 flags, CamelException *ex);
+void groupwise_store_set_current_folder (CamelGroupwiseStore *groupwise_store, CamelFolder *folder);
 
 G_END_DECLS
 

Modified: branches/camel-gobject/camel/providers/groupwise/camel-groupwise-summary.c
==============================================================================
--- branches/camel-gobject/camel/providers/groupwise/camel-groupwise-summary.c	(original)
+++ branches/camel-gobject/camel/providers/groupwise/camel-groupwise-summary.c	Thu Apr 16 01:23:17 2009
@@ -47,6 +47,8 @@
 #define EXTRACT_FIRST_DIGIT(val) part ? val=strtoul (part, &part, 10) : 0;
 #define EXTRACT_DIGIT(val) part++; part ? val=strtoul (part, &part, 10) : 0;
 
+#define d(x) 
+
 /*Prototypes*/
 static int gw_summary_header_load (CamelFolderSummary *, FILE *);
 static int gw_summary_header_save (CamelFolderSummary *, FILE *);
@@ -317,8 +319,13 @@
 	guint32 type=0;
 	
 	if (part) {
-		EXTRACT_FIRST_DIGIT (type);
+		if (*part == ' ')
+			part++;
+		if (part) {
+			EXTRACT_FIRST_DIGIT (type);
+		}
 	}
+	mir->cinfo = part;
 	if (type)
 		return camel_groupwise_summary_parent->content_info_from_db (s, mir);
 	else
@@ -362,70 +369,66 @@
 static gboolean
 gw_info_set_flags (CamelMessageInfo *info, guint32 flags, guint32 set)
 {
-	guint32 old;
-	CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
+		guint32 old;
+		CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
+		int read = 0 , deleted = 0;
 
-	/* TODO: locking? */
+		int junk_flag = 0, junk_learn_flag = 0;
 
-	old = mi->flags;
-	/* we don't set flags which aren't appropriate for the folder*/
-	if ((set == (CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN|CAMEL_MESSAGE_SEEN)) && (old & CAMEL_GW_MESSAGE_JUNK))
-		return FALSE;
-	
-	mi->flags = (old & ~flags) | (set & flags);
-	if (old != mi->flags) {
-		mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
-
-		if (mi->summary) {
-
-				if ((set & CAMEL_MESSAGE_SEEN) && !(old & CAMEL_MESSAGE_SEEN)) {
-						mi->summary->unread_count -- ;
-				} else if ( (!(set & CAMEL_MESSAGE_SEEN)) && (old & CAMEL_MESSAGE_SEEN) ) {
-						mi->summary->unread_count ++ ;
-				}
+		/* TODO: locking? */
 
-				if ((flags & CAMEL_MESSAGE_DELETED) && !(old & CAMEL_MESSAGE_DELETED)) {
-						mi->summary->deleted_count ++ ;
+		if (flags & CAMEL_MESSAGE_SEEN && ((set & CAMEL_MESSAGE_SEEN) != (mi->flags & CAMEL_MESSAGE_SEEN)))
+		{ read = set & CAMEL_MESSAGE_SEEN ? 1 : -1; d(printf("Setting read as %d\n", set & CAMEL_MESSAGE_SEEN ? 1 : 0));}
 
-						/* FIXME[disk-summary] What to do when the user has set to show-deleted-messages */
-						mi->summary->visible_count -- ;
+		if (flags & CAMEL_MESSAGE_DELETED && ((set & CAMEL_MESSAGE_DELETED) != (mi->flags & CAMEL_MESSAGE_DELETED)))
+		{ deleted = set & CAMEL_MESSAGE_DELETED ? 1 : -1; d(printf("Setting deleted as %d\n", set & CAMEL_MESSAGE_DELETED ? 1 : 0));}
 
-						if (!(flags & CAMEL_MESSAGE_SEEN))
-							mi->summary->unread_count -- ;
-				}
+		old = mi->flags;
+		mi->flags = (old & ~flags) | (set & flags);
 
+		if (old != mi->flags) {
+				mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
 				mi->dirty = TRUE;
-				camel_folder_summary_touch(mi->summary);
+
+				if (((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags & ~CAMEL_MESSAGE_SYSTEM_MASK)) )
+						return FALSE;
+
+				if (mi->summary) {
+						mi->summary->deleted_count += deleted;
+						mi->summary->unread_count -= read;
+						camel_folder_summary_touch(mi->summary);
+				}
 		}
-	}
-	/* This is a hack, we are using CAMEL_MESSAGE_JUNK justo to hide the item
-	 * we make sure this doesn't have any side effects*/
-	
-	if ((set == CAMEL_MESSAGE_JUNK_LEARN) && (old & CAMEL_GW_MESSAGE_JUNK)) {
-		mi->flags |= CAMEL_GW_MESSAGE_NOJUNK | CAMEL_MESSAGE_JUNK;
 
-		/* This has ugly side-effects. Evo will never learn unjunk. 
+		junk_flag = ((flags & CAMEL_MESSAGE_JUNK) && (set & CAMEL_MESSAGE_JUNK));
+		junk_learn_flag = ((flags & CAMEL_MESSAGE_JUNK_LEARN) && (set & CAMEL_MESSAGE_JUNK_LEARN));
 
-		   We need to create one CAMEL_MESSAGE_HIDDEN flag which must be used for all hiding operations. We must also get rid of the seperate file that is maintained somewhere in evolution/mail/em-folder-browser.c for hidden messages
-		 */
+		/* This is a hack, we are using CAMEL_MESSAGE_JUNK justo to hide the item
+		 * we make sure this doesn't have any side effects*/
 
-		if (mi->summary) {
-			camel_folder_summary_touch(mi->summary);
+		if (junk_learn_flag && !junk_flag  && (old & CAMEL_GW_MESSAGE_JUNK)) {
+				/* 
+				   This has ugly side-effects. Evo will never learn unjunk. 
+				   We need to create one CAMEL_MESSAGE_HIDDEN flag which must be
+				   used for all hiding operations. We must also get rid of the seperate file 
+				   that is maintained somewhere in evolution/mail/em-folder-browser.c for hidden messages
+				 */
+				mi->flags |= CAMEL_GW_MESSAGE_NOJUNK | CAMEL_MESSAGE_JUNK | CAMEL_MESSAGE_JUNK_LEARN;
+		} else if (junk_learn_flag && junk_flag && !(old & CAMEL_GW_MESSAGE_JUNK)) {
+				mi->flags |= CAMEL_GW_MESSAGE_JUNK | CAMEL_MESSAGE_JUNK | CAMEL_MESSAGE_JUNK_LEARN;
 		}
 
-	} else	if ((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags & ~CAMEL_MESSAGE_SYSTEM_MASK)) 
-		return FALSE;
 
-	if (mi->summary && mi->summary->folder && mi->uid) {
-		CamelFolderChangeInfo *changes = camel_folder_change_info_new();
+		if (mi->summary && mi->summary->folder && mi->uid) {
+				CamelFolderChangeInfo *changes = camel_folder_change_info_new();
 
-		camel_folder_change_info_change_uid(changes, camel_message_info_uid(info));
-		camel_object_trigger_event(mi->summary->folder, "folder_changed", changes);
-		camel_folder_change_info_free(changes);
-	}
-
-	return TRUE;
+				camel_folder_change_info_change_uid(changes, camel_message_info_uid(info));
+				camel_object_trigger_event(mi->summary->folder, "folder_changed", changes);
+				camel_folder_change_info_free(changes);
+				camel_folder_summary_touch(mi->summary);
+		}
 
+		return TRUE;
 }
 
 

Modified: branches/camel-gobject/camel/providers/groupwise/camel-groupwise-summary.h
==============================================================================
--- branches/camel-gobject/camel/providers/groupwise/camel-groupwise-summary.h	(original)
+++ branches/camel-gobject/camel/providers/groupwise/camel-groupwise-summary.h	Thu Apr 16 01:23:17 2009
@@ -56,11 +56,11 @@
 
 
 struct _CamelGroupwiseSummary {
-	CamelFolderSummary parent ;
+	CamelFolderSummary parent;
 
 	char *time_string;
-	guint32 version ;
-	guint32 validity ;
+	gint32 version;
+	gint32 validity;
 } ;
 
 

Modified: branches/camel-gobject/camel/providers/hula/camel-hula-provider.c
==============================================================================
--- branches/camel-gobject/camel/providers/hula/camel-hula-provider.c	(original)
+++ branches/camel-gobject/camel/providers/hula/camel-hula-provider.c	Thu Apr 16 01:23:17 2009
@@ -148,7 +148,6 @@
 	guint hash = 0;
 
 	add_hash (&hash, u->user);
-	add_hash (&hash, u->authmech);
 	add_hash (&hash, u->host);
 	hash ^= u->port;
 	
@@ -178,7 +177,6 @@
 	
 	return check_equal (u1->protocol, u2->protocol)
 		&& check_equal (u1->user, u2->user)
-		&& check_equal (u1->authmech, u2->authmech)
 		&& check_equal (u1->host, u2->host)
 		&& u1->port == u2->port;
 }

Modified: branches/camel-gobject/camel/providers/imap/camel-imap-folder.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap/camel-imap-folder.c	(original)
+++ branches/camel-gobject/camel/providers/imap/camel-imap-folder.c	Thu Apr 16 01:23:17 2009
@@ -102,10 +102,14 @@
 static void imap_expunge (CamelFolder *folder, CamelException *ex);
 //static void imap_cache_message (CamelDiscoFolder *disco_folder, const char *uid, CamelException *ex);
 static void imap_rename (CamelFolder *folder, const char *new);
+static GPtrArray * imap_get_uncached_uids (CamelFolder *folder, GPtrArray * uids, CamelException *ex);
+static char* imap_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
 
 /* message manipulation */
 static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid,
 					   CamelException *ex);
+static void imap_sync_message (CamelFolder *folder, const gchar *uid,
+			       CamelException *ex);
 static void imap_append_online (CamelFolder *folder, CamelMimeMessage *message,
 				const CamelMessageInfo *info, char **appended_uid,
 				CamelException *ex);
@@ -135,6 +139,12 @@
 
 static GData *parse_fetch_response (CamelImapFolder *imap_folder, char *msg_att);
 
+/* internal helpers */
+static CamelImapMessageInfo * imap_folder_summary_uid_or_error(
+	CamelFolderSummary *summary,
+	const char * uid,
+	CamelException *ex);
+
 #ifdef G_OS_WIN32
 /* The strtok() in Microsoft's C library is MT-safe (but still uses
  * only one buffer pointer per thread, but for the use of strtok_r()
@@ -167,7 +177,10 @@
 	camel_folder_class->expunge = imap_expunge;
 	camel_folder_class->sync= imap_sync;
 	camel_folder_class->append_message = imap_append_online;
+	camel_folder_class->sync_message = imap_sync_message;
 	camel_folder_class->transfer_messages_to = imap_transfer_online;
+	camel_folder_class->get_uncached_uids = imap_get_uncached_uids;
+	camel_folder_class->get_filename = imap_get_filename;
 }
 
 static void
@@ -187,6 +200,7 @@
 	g_static_mutex_init(&imap_folder->priv->search_lock);
 	g_static_rec_mutex_init(&imap_folder->priv->cache_lock);
 #endif
+	imap_folder->priv->ignore_recent = NULL;
 
 	imap_folder->journal = NULL;
 	imap_folder->need_rescan = TRUE;
@@ -313,8 +327,9 @@
 		} else if (!g_ascii_strncasecmp (resp, "OK [PERMANENTFLAGS ", 19)) {
 			resp += 19;
 			
-			/* workaround for broken IMAP servers that send "* OK [PERMANENTFLAGS ()] Permanent flags"
-			 * even tho they do allow storing flags. *Sigh* So many fucking broken IMAP servers out there. */
+			/* workaround for broken IMAP servers that send
+			 * "* OK [PERMANENTFLAGS ()] Permanent flags"
+			 * even tho they do allow storing flags. */
 			imap_parse_flag_list (&resp, &perm_flags, NULL);
 			if (perm_flags != 0)
 				folder->permanent_flags = perm_flags;
@@ -437,6 +452,8 @@
 	g_static_mutex_free(&imap_folder->priv->search_lock);
 	g_static_rec_mutex_free(&imap_folder->priv->cache_lock);
 #endif
+	if (imap_folder->priv->ignore_recent)
+		g_hash_table_unref (imap_folder->priv->ignore_recent);
 
 	if (imap_folder->journal) {
 		camel_offline_journal_write (imap_folder->journal, NULL);
@@ -446,6 +463,14 @@
 	g_free(imap_folder->priv);
 }
 
+static char*
+imap_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelImapFolder *imap_folder = (CamelImapFolder*) folder;
+
+	return camel_imap_message_cache_get_filename (imap_folder->cache, uid, "", ex);
+}
+
 static int
 imap_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
 {
@@ -953,6 +978,13 @@
 			continue;
 
 		info = camel_folder_summary_uid (folder->summary, uid);
+		if (!info) {
+			if (g_getenv("CRASH_IMAP")) { /* Debug logs to tackle on hard to get imap crasher */
+				printf("CRASH: %s: %s", folder->full_name, uid);
+				g_assert(0);
+			} else
+				continue;
+		}
 
 		iinfo = (CamelImapMessageInfo *)info;
 
@@ -1833,6 +1865,27 @@
 		g_free (uid);
 }
 
+static void
+imap_folder_add_ignore_recent (CamelImapFolder *imap_folder, const char *uid)
+{
+	g_return_if_fail (imap_folder != NULL);
+	g_return_if_fail (uid != NULL);
+
+	if (!imap_folder->priv->ignore_recent)
+		imap_folder->priv->ignore_recent = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
+
+	g_hash_table_insert (imap_folder->priv->ignore_recent, g_strdup (uid), GINT_TO_POINTER (1));
+}
+
+static gboolean
+imap_folder_uid_in_ignore_recent (CamelImapFolder *imap_folder, const char *uid)
+{
+	g_return_val_if_fail (imap_folder != NULL, FALSE);
+	g_return_val_if_fail (uid != NULL, FALSE);
+
+	return imap_folder->priv->ignore_recent && g_hash_table_lookup (imap_folder->priv->ignore_recent, uid);
+}
+
 static CamelImapResponse *
 do_append (CamelFolder *folder, CamelMimeMessage *message,
 	   const CamelMessageInfo *info, char **uid,
@@ -1929,6 +1982,9 @@
 		}
 	} else
 		*uid = NULL;
+
+	if (*uid)
+		imap_folder_add_ignore_recent (CAMEL_IMAP_FOLDER (folder), *uid);
 	
 	return response2;
 }
@@ -2124,6 +2180,8 @@
 			camel_imap_message_cache_copy (scache, src->pdata[i],
 						       dcache, dest->pdata[i],
 						       NULL);
+
+			imap_folder_add_ignore_recent (CAMEL_IMAP_FOLDER (destination), dest->pdata[i]);
 		}
 		CAMEL_IMAP_FOLDER_REC_UNLOCK (source, cache_lock);
 		CAMEL_IMAP_FOLDER_REC_UNLOCK (destination, cache_lock);
@@ -2809,6 +2867,20 @@
 	return FALSE;
 }
 
+static CamelImapMessageInfo *
+imap_folder_summary_uid_or_error(CamelFolderSummary *summary, const char * uid, CamelException *ex)
+{
+  	CamelImapMessageInfo *mi;
+	mi = (CamelImapMessageInfo *)camel_folder_summary_uid (summary, uid);
+	if (mi == NULL) {
+		camel_exception_setv (
+                	ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
+			_("Cannot get message with message ID %s: %s"),
+			uid, _("No such message available."));
+	}
+	return mi;
+}
+
 static CamelMimeMessage *
 imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
 {
@@ -2819,14 +2891,9 @@
 	CamelStream *stream = NULL;
 	int retry;
 
-	mi = (CamelImapMessageInfo *)camel_folder_summary_uid (folder->summary, uid);
-	if (mi == NULL) {
-		camel_exception_setv (
-                	ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
-			_("Cannot get message with message ID %s: %s"),
-			uid, _("No such message available."));
-		return NULL;
-	}
+	mi = imap_folder_summary_uid_or_error(folder->summary, uid, ex);
+	if (!mi)
+	  return NULL;
 
 	/* If its cached in full, just get it as is, this is only a shortcut,
 	   since we get stuff from the cache anyway.  It affects a busted connection though. */
@@ -2947,6 +3014,44 @@
 	return msg;
 }
 
+/**
+ * imap_sync_message
+ *
+ * Ensure that a message is cached locally, but don't retrieve the content if
+ * it is already local.
+ */
+static void
+imap_sync_message (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+	CamelImapMessageInfo *mi;
+	CamelMimeMessage *msg = NULL;
+	CamelStream *stream = NULL;
+
+	mi = imap_folder_summary_uid_or_error(folder->summary, uid, ex);
+	if (!mi)
+	  /* No such UID - is this duplicate work? The sync process selects
+	   * UIDs to start with.
+	   */
+	  return;
+	camel_message_info_free(&mi->info);
+
+	/* If we can get a stream, assume its fully cached. This may be false
+	 * if partial streams are saved elsewhere in the code - but that seems
+	 * best solved by knowning more about whether a given message is fully
+	 * available locally or not,
+	 */
+	/* If its cached in full, just get it as is, this is only a shortcut,
+	   since we get stuff from the cache anyway.  It affects a busted connection though. */
+	if ((stream = camel_imap_folder_fetch_data(imap_folder, uid, "", TRUE, NULL))) {
+		camel_object_unref (stream);
+		return;
+	}
+	msg = imap_get_message(folder, uid, ex);
+	if (msg)
+		camel_object_unref(msg);
+}
+
 /* FIXME Remove it after confirming
 static void
 imap_cache_message (CamelDiscoFolder *disco_folder, const char *uid,
@@ -3411,8 +3516,6 @@
 			}
 			
 			if (pmi == NULL) {
-				/* Server response is *really* fucked up,
-				   I guess we just pretend it never happened? */
 				continue;
 			}
 			
@@ -3498,14 +3601,22 @@
 		update_summary (folder->summary, (CamelMessageInfoBase *)mi);
 		camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi));
 
-		/* report all new messages as recent, even without that flag, thus new
-		   messages will be filtered even after saw by other software earlier */
-		if ((mi->info.flags & CAMEL_IMAP_MESSAGE_RECENT) != 0 || getenv ("FILTER_RECENT") == NULL)
+		/* Report all new messages as recent, even without that flag, thus new
+		   messages will be filtered even after saw by other software earlier.
+		   Only skip those which we added ourself, like after drag&drop to this folder. */
+		if (!imap_folder_uid_in_ignore_recent (imap_folder, camel_message_info_uid (mi))
+		    && ((mi->info.flags & CAMEL_IMAP_MESSAGE_RECENT) != 0 || getenv ("FILTER_RECENT") == NULL))
 			camel_folder_change_info_recent_uid (changes, camel_message_info_uid (mi));
+
 	}
 
 	g_ptr_array_free (messages, TRUE);
-	
+
+	if (imap_folder->priv->ignore_recent) {
+		g_hash_table_unref (imap_folder->priv->ignore_recent);
+		imap_folder->priv->ignore_recent = NULL;
+	}
+
 	return;
 	
  lose:
@@ -3523,6 +3634,11 @@
 		}
 		g_ptr_array_free (messages, TRUE);
 	}
+
+	if (imap_folder->priv->ignore_recent) {
+		g_hash_table_unref (imap_folder->priv->ignore_recent);
+		imap_folder->priv->ignore_recent = NULL;
+	}
 }
 
 /* Called with the store's connect_lock locked */
@@ -3919,3 +4035,19 @@
 	CAMEL_SERVICE_REC_UNLOCK (imap_store, connect_lock);
 	return res;
 }
+
+/**
+ * Scan for messages that are local and return the rest.
+ */
+static GPtrArray *
+imap_get_uncached_uids (CamelFolder *folder, GPtrArray * uids, CamelException *ex)
+{
+	GPtrArray *result;
+	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+
+	CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
+	result = camel_imap_message_cache_filter_cached (imap_folder->cache, uids, ex);
+	CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
+	return result;
+}
+

Modified: branches/camel-gobject/camel/providers/imap/camel-imap-message-cache.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap/camel-imap-message-cache.c	(original)
+++ branches/camel-gobject/camel/providers/imap/camel-imap-message-cache.c	Thu Apr 16 01:23:17 2009
@@ -35,6 +35,7 @@
 #include "camel-data-wrapper.h"
 #include "camel-exception.h"
 #include "camel-stream-fs.h"
+#include "camel-string-utils.h"
 
 #include "camel-imap-message-cache.h"
 
@@ -42,9 +43,26 @@
 #define O_BINARY 0
 #endif
 
+/* Common define to start reducing duplication of base-part handling on win32.
+ */
+#ifdef G_OS_WIN32
+/* See comment in insert_setup() */
+#define BASE_PART_SUFFIX ".~"
+#else
+#define BASE_PART_SUFFIX "."
+#endif
+
 static void finalize (CamelImapMessageCache *cache);
 static void stream_finalize (CamelObject *stream, gpointer event_data, gpointer user_data);
 
+struct _part_find {
+	/* UID name on disk - e.g. "0." or "0.HEADERS". On windows "0." is
+	 * stored as "0.~"
+	 */
+	char *disk_part_name;
+	/* Was the part found? */
+	int found;
+};
 
 GType
 camel_imap_message_cache_get_type (void)
@@ -142,6 +160,8 @@
  * Return value: a new CamelImapMessageCache object using @path for
  * storage. If cache files already exist in @path, then any that do not
  * correspond to messages in @summary will be deleted.
+ * @path is scanned for its contents, which means creating a cache object can be
+ * expensive, but the parts hash is immediately usable.
  **/
 CamelImapMessageCache *
 camel_imap_message_cache_new (const char *path, CamelFolderSummary *summary,
@@ -438,6 +458,35 @@
 	}
 }
 
+/**
+ * camel_imap_message_cache_get_filename:
+ * @cache: the cache
+ * @uid: the UID of the data to get
+ * @part_spec: the part_spec of the data to get
+ * @ex: exception
+ *
+ * Return value: the filename of a cache item
+ **/
+char*
+camel_imap_message_cache_get_filename (CamelImapMessageCache *cache,
+				       const char *uid,
+				       const char *part_spec,
+				       CamelException *ex)
+{
+	char *path;
+	
+	if (uid[0] == 0)
+		return NULL;
+	
+#ifdef G_OS_WIN32
+	/* See comment in insert_setup() */
+	if (!*part_spec)
+		part_spec = "~";
+#endif
+	path = g_strdup_printf ("%s/%s.%s", cache->path, uid, part_spec);
+
+	return path;
+}
 
 /**
  * camel_imap_message_cache_get:
@@ -591,3 +640,67 @@
 		}
 	}
 }
+
+
+static void
+_match_part(gpointer part_name, gpointer user_data)
+{
+	struct _part_find *part_find = (struct _part_find *) user_data;
+	if (g_str_equal(part_name, part_find->disk_part_name))
+		part_find->found = 1;
+}
+
+/**
+ * Filter uids by the uids cached in cache.
+ * The intent is that only uids fully cached are returned, but that may not be
+ * what is achieved. An additional constraint is that this check should be
+ * cheap, so that going offline is not an expensive operation. Filtering all
+ * uids is inefficient in the first place; significant processing per uid 
+ * makes synchronisation very expensive. At the suggestion of Srinivasa Ragavan
+ * (see http://bugzilla.gnome.org/show_bug.cgi?id=564339) the cache->parts hash
+ * table is consulted. If there is a parts-list in the hash table containing
+ * the part "", then we assume the message has been completely downloaded. This
+ * is incorrect (see http://bugzilla.gnome.org/show_bug.cgi?id=561211 for the
+ * symptoms). The code this replaces, a loop over all uids asking for the ""
+ * part of the message has the same flaw: it is no /less/ accurate to assess
+ * 'cached' in the manner this method does (assuming no concurrent process is
+ * removing messages from the cache).
+ *
+ * In the future, fixing bug 561211 needs a check for *all* the parts of a
+ * given uid. If the complete list of parts is available in the folder summary
+ * information then it can be done cheaply, otherwise some redesign will be
+ * needed.
+ */
+GPtrArray *
+camel_imap_message_cache_filter_cached(CamelImapMessageCache *cache, GPtrArray *uids, CamelException *ex)
+{
+	GPtrArray *result, *parts_list;
+	int i;
+	struct _part_find part_find;
+	/* Look for a part "" for each uid. */
+	result = g_ptr_array_sized_new(uids->len);
+	for (i = 0; i < uids->len; i++) {
+		if ((parts_list = g_hash_table_lookup(cache->parts, uids->pdata[i]))) {
+			/* At least one part locally present; look for "" (the
+			 * HEADERS part can be present without anything else,
+			 * and that part is not useful for users wanting to
+			 * read the message).
+			 */
+			part_find.found = 0;
+			part_find.disk_part_name = g_strdup_printf("%s" BASE_PART_SUFFIX,
+								   (char *)uids->pdata[i]);
+			g_ptr_array_foreach(parts_list, _match_part, &part_find);
+			g_free(part_find.disk_part_name);
+			if (part_find.found)
+				/* The message is cached locally, do not
+				 * include it in the result.
+				 */
+				continue;
+		}
+		/* No message parts, or message part "" not found: include the
+		 * uid in the result.
+		 */
+		g_ptr_array_add(result, (char *)camel_pstring_strdup(uids->pdata[i]));
+	}
+	return result;
+}

Modified: branches/camel-gobject/camel/providers/imap/camel-imap-message-cache.h
==============================================================================
--- branches/camel-gobject/camel/providers/imap/camel-imap-message-cache.h	(original)
+++ branches/camel-gobject/camel/providers/imap/camel-imap-message-cache.h	Thu Apr 16 01:23:17 2009
@@ -41,6 +41,13 @@
 	CamelObject parent_object;
 
 	char *path;
+        /* parts contains two sorts of objects.
+         * If the key contains '.' then it is a stream (also reverse-indexed in
+         * cached).
+         * Otherwise it is a g_ptr_array containing the subparts the message
+         * has. (e.g. 0., or 0.MIME.1).
+         */
+        /* cached contains streams for recently accessed messages */
 	GHashTable *parts, *cached;
 	guint32 max_uid;
 };
@@ -86,6 +93,11 @@
 					      const char *part_spec,
 					      CamelException *ex);
 
+char*       camel_imap_message_cache_get_filename (CamelImapMessageCache *cache,
+					      const char *uid,
+					      const char *part_spec,
+					      CamelException *ex);
+
 void         camel_imap_message_cache_remove (CamelImapMessageCache *cache,
 					      const char *uid);
 
@@ -98,6 +110,9 @@
 					      CamelException *ex);
 gboolean     camel_imap_message_cache_delete (const char *path, 
 					      CamelException *ex);
+GPtrArray *  camel_imap_message_cache_filter_cached(CamelImapMessageCache *,
+                                              GPtrArray *uids,
+                                              CamelException *ex);
 
 /* Standard Camel function */
 GType camel_imap_message_cache_get_type (void);

Modified: branches/camel-gobject/camel/providers/imap/camel-imap-private.h
==============================================================================
--- branches/camel-gobject/camel/providers/imap/camel-imap-private.h	(original)
+++ branches/camel-gobject/camel/providers/imap/camel-imap-private.h	Thu Apr 16 01:23:17 2009
@@ -15,6 +15,7 @@
 	GStaticMutex search_lock;	/* for locking the search object */
 	GStaticRecMutex cache_lock;	/* for locking the cache object */
 #endif
+	GHashTable *ignore_recent;	/* hash table of UIDs to ignore as recent when updating folder */
 };
 
 #ifdef ENABLE_THREADS

Modified: branches/camel-gobject/camel/providers/imap/camel-imap-provider.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap/camel-imap-provider.c	(original)
+++ branches/camel-gobject/camel/providers/imap/camel-imap-provider.c	Thu Apr 16 01:23:17 2009
@@ -133,7 +133,6 @@
 	guint hash = 0;
 
 	add_hash (&hash, u->user);
-	add_hash (&hash, u->authmech);
 	add_hash (&hash, u->host);
 	hash ^= u->port;
 	
@@ -163,7 +162,6 @@
 	
 	return check_equal (u1->protocol, u2->protocol)
 		&& check_equal (u1->user, u2->user)
-		&& check_equal (u1->authmech, u2->authmech)
 		&& check_equal (u1->host, u2->host)
 		&& u1->port == u2->port;
 }

Modified: branches/camel-gobject/camel/providers/imap/camel-imap-store.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap/camel-imap-store.c	(original)
+++ branches/camel-gobject/camel/providers/imap/camel-imap-store.c	Thu Apr 16 01:23:17 2009
@@ -3000,8 +3000,6 @@
 }
 
 
-/* FIXME: please god, when will the hurting stop? Thus function is so
-   fucking broken it's not even funny. */
 ssize_t
 camel_imap_store_readline (CamelImapStore *store, char **dest, CamelException *ex)
 {

Modified: branches/camel-gobject/camel/providers/imap/camel-imap-summary.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap/camel-imap-summary.c	(original)
+++ branches/camel-gobject/camel/providers/imap/camel-imap-summary.c	Thu Apr 16 01:23:17 2009
@@ -213,7 +213,7 @@
 		if it cannot be loaded, for some random reason.
 		We need to pass the ex and find out why it is not loaded etc. ? */
 		camel_folder_summary_clear_db (summary);
-		g_warning ("Unable to load summary %s\n", camel_exception_get_description (&ex));
+		g_message ("Unable to load summary: %s\n", camel_exception_get_description (&ex));
 		camel_exception_clear (&ex);
 	}
 

Modified: branches/camel-gobject/camel/providers/imap4/camel-imap4-command.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap4/camel-imap4-command.c	(original)
+++ branches/camel-gobject/camel/providers/imap4/camel-imap4-command.c	Thu Apr 16 01:23:17 2009
@@ -678,7 +678,6 @@
 			
 		unexpected:
 			
-			/* no fucking clue what we got... */
 			if (camel_imap4_engine_line (engine, &linebuf, &len, &ic->ex) == -1)
 				goto exception;
 			

Modified: branches/camel-gobject/camel/providers/imap4/camel-imap4-engine.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap4/camel-imap4-engine.c	(original)
+++ branches/camel-gobject/camel/providers/imap4/camel-imap4-engine.c	Thu Apr 16 01:23:17 2009
@@ -40,7 +40,7 @@
 #include "camel-imap4-summary.h"
 #include "camel-imap4-utils.h"
 
-#define d(x) x
+#define d(x)
 
 
 static void camel_imap4_engine_class_init (CamelIMAP4EngineClass *klass);

Modified: branches/camel-gobject/camel/providers/imap4/camel-imap4-folder.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap4/camel-imap4-folder.c	(original)
+++ branches/camel-gobject/camel/providers/imap4/camel-imap4-folder.c	Thu Apr 16 01:23:17 2009
@@ -58,7 +58,7 @@
 #include "camel-imap4-summary.h"
 #include "camel-imap4-search.h"
 
-#define d(x) x
+#define d(x)
 
 static void camel_imap4_folder_class_init (CamelIMAP4FolderClass *klass);
 static void camel_imap4_folder_init (CamelIMAP4Folder *folder, CamelIMAP4FolderClass *klass);
@@ -78,7 +78,7 @@
 static GPtrArray *imap4_search_by_expression (CamelFolder *folder, const char *expr, CamelException *ex);
 static GPtrArray *imap4_search_by_uids (CamelFolder *folder, const char *expr, GPtrArray *uids, CamelException *ex);
 static void imap4_search_free (CamelFolder *folder, GPtrArray *uids);
-
+static char* imap4_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
 
 static CamelOfflineFolderClass *parent_class = NULL;
 
@@ -139,6 +139,7 @@
 	folder_class->search_by_expression = imap4_search_by_expression;
 	folder_class->search_by_uids = imap4_search_by_uids;
 	folder_class->search_free = imap4_search_free;
+	folder_class->get_filename = imap4_get_filename;
 }
 
 static void
@@ -170,6 +171,14 @@
 	g_free (folder->cachedir);
 }
 
+static char*
+imap4_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelIMAP4Folder *imap4_folder = (CamelIMAP4Folder *) folder;
+
+	return camel_data_cache_get_filename (imap4_folder->cache, "cache", uid, ex);
+}
+
 static int
 imap4_getv (CamelObject *object, CamelException *ex, CamelArgGetV *args)
 {

Modified: branches/camel-gobject/camel/providers/imap4/camel-imap4-journal.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap4/camel-imap4-journal.c	(original)
+++ branches/camel-gobject/camel/providers/imap4/camel-imap4-journal.c	Thu Apr 16 01:23:17 2009
@@ -43,7 +43,7 @@
 #include "camel-imap4-folder.h"
 #include "camel-imap4-journal.h"
 
-#define d(x) x
+#define d(x)
 
 
 static void camel_imap4_journal_class_init (CamelIMAP4JournalClass *klass);

Modified: branches/camel-gobject/camel/providers/imap4/camel-imap4-provider.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap4/camel-imap4-provider.c	(original)
+++ branches/camel-gobject/camel/providers/imap4/camel-imap4-provider.c	Thu Apr 16 01:23:17 2009
@@ -105,7 +105,6 @@
 	guint hash = 0;
 	
 	add_hash (&hash, u->user);
-	add_hash (&hash, u->authmech);
 	add_hash (&hash, u->host);
 	hash ^= u->port;
 	
@@ -135,7 +134,6 @@
 	
 	return check_equal (u1->protocol, u2->protocol)
 		&& check_equal (u1->user, u2->user)
-		&& check_equal (u1->authmech, u2->authmech)
 		&& check_equal (u1->host, u2->host)
 		&& u1->port == u2->port;
 }

Modified: branches/camel-gobject/camel/providers/imap4/camel-imap4-store.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap4/camel-imap4-store.c	(original)
+++ branches/camel-gobject/camel/providers/imap4/camel-imap4-store.c	Thu Apr 16 01:23:17 2009
@@ -50,7 +50,7 @@
 #include "camel-imap4-summary.h"
 #include "camel-imap4-utils.h"
 
-#define d(x) x
+#define d(x)
 
 static void camel_imap4_store_class_init (CamelIMAP4StoreClass *klass);
 static void camel_imap4_store_init (CamelIMAP4Store *store, CamelIMAP4StoreClass *klass);

Modified: branches/camel-gobject/camel/providers/imap4/camel-imap4-summary.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap4/camel-imap4-summary.c	(original)
+++ branches/camel-gobject/camel/providers/imap4/camel-imap4-summary.c	Thu Apr 16 01:23:17 2009
@@ -53,7 +53,7 @@
 #include "camel-imap4-summary.h"
 #include "camel-imap4-utils.h"
 
-#define d(x) x
+#define d(x)
 
 #define CAMEL_IMAP4_SUMMARY_VERSION  3
 
@@ -753,7 +753,7 @@
 }
 
 static void
-courier_imap_is_a_piece_of_shit (CamelFolderSummary *summary, guint32 msg)
+courier_imap_show_error (CamelFolderSummary *summary, guint32 msg)
 {
 	CamelSession *session = ((CamelService *) summary->folder->parent_store)->session;
 	char *warning;
@@ -791,7 +791,7 @@
 	for (i = 0; i < fetch->added->len; i++) {
 		if (!(envelope = fetch->added->pdata[i])) {
 			if (complete)
-				courier_imap_is_a_piece_of_shit (fetch->summary, i + fetch->first);
+				courier_imap_show_error (fetch->summary, i + fetch->first);
 			break;
 		}
 		
@@ -883,7 +883,7 @@
 	
 	for (i = 0; i < fetch->added->len; i++) {
 		if (!(envelope = fetch->added->pdata[i])) {
-			courier_imap_is_a_piece_of_shit (fetch->summary, i + fetch->first);
+			courier_imap_show_error (fetch->summary, i + fetch->first);
 			continue;
 		}
 		

Modified: branches/camel-gobject/camel/providers/imapp/camel-imapp-driver.c
==============================================================================
--- branches/camel-gobject/camel/providers/imapp/camel-imapp-driver.c	(original)
+++ branches/camel-gobject/camel/providers/imapp/camel-imapp-driver.c	Thu Apr 16 01:23:17 2009
@@ -24,7 +24,7 @@
 #include "camel-imapp-summary.h"
 #include "camel-imapp-utils.h"
 
-#define d(x) x
+#define d(x)
 
 static int driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata);
 static int driver_resp_expunge(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata);

Modified: branches/camel-gobject/camel/providers/local/Makefile.am
==============================================================================
--- branches/camel-gobject/camel/providers/local/Makefile.am	(original)
+++ branches/camel-gobject/camel/providers/local/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -29,6 +29,7 @@
 	camel-local-folder.c			\
 	camel-local-store.c			\
 	camel-local-summary.c			\
+	camel-local-private.c			\
 	camel-local-provider.c			\
 	camel-mbox-folder.c			\
 	camel-mbox-store.c			\

Modified: branches/camel-gobject/camel/providers/local/camel-local-folder.c
==============================================================================
--- branches/camel-gobject/camel/providers/local/camel-local-folder.c	(original)
+++ branches/camel-gobject/camel/providers/local/camel-local-folder.c	Thu Apr 16 01:23:17 2009
@@ -489,14 +489,16 @@
 
 	CAMEL_FOLDER_REC_LOCK(folder, lock);
 
-	if (camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex) == -1)
+	if (camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex) == -1) {
+		CAMEL_FOLDER_REC_UNLOCK(folder, lock);
 		return;
+	}
 
+	CAMEL_FOLDER_REC_UNLOCK(folder, lock);
 	if (camel_folder_change_info_changed(lf->changes)) {
 		camel_object_trigger_event((CamelObject *)folder, "folder_changed", lf->changes);
 		camel_folder_change_info_clear(lf->changes);
 	}
-	CAMEL_FOLDER_REC_UNLOCK(folder, lock);
 	
 }
 

Modified: branches/camel-gobject/camel/providers/local/camel-local-private.h
==============================================================================
--- branches/camel-gobject/camel/providers/local/camel-local-private.h	(original)
+++ branches/camel-gobject/camel/providers/local/camel-local-private.h	Thu Apr 16 01:23:17 2009
@@ -31,6 +31,7 @@
 #include <config.h>
 #endif
 
+#include <glib.h>
 #include <pthread.h>
 
 G_BEGIN_DECLS
@@ -42,6 +43,8 @@
 #define CAMEL_LOCAL_FOLDER_LOCK(f, l) (g_mutex_lock(((CamelLocalFolder *)f)->priv->l))
 #define CAMEL_LOCAL_FOLDER_UNLOCK(f, l) (g_mutex_unlock(((CamelLocalFolder *)f)->priv->l))
 
+int camel_local_frompos_sort (void *enc, int len1, void * data1, int len2, void *data2);
+
 G_END_DECLS
 
 #endif /* CAMEL_LOCAL_PRIVATE_H */

Modified: branches/camel-gobject/camel/providers/local/camel-local-summary.c
==============================================================================
--- branches/camel-gobject/camel/providers/local/camel-local-summary.c	(original)
+++ branches/camel-gobject/camel/providers/local/camel-local-summary.c	Thu Apr 16 01:23:17 2009
@@ -65,6 +65,7 @@
 static int local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex);
 static int local_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
 static CamelMessageInfo *local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex);
+static int local_summary_need_index();
 
 static void camel_local_summary_class_init (CamelLocalSummaryClass *klass);
 static void camel_local_summary_init       (CamelLocalSummary *obj);
@@ -111,6 +112,7 @@
 
 	klass->encode_x_evolution = local_summary_encode_x_evolution;
 	klass->decode_x_evolution = local_summary_decode_x_evolution;
+	klass->need_index = local_summary_need_index;
 }
 
 static void
@@ -160,7 +162,7 @@
 {
 	d(printf("Loading summary ...\n"));
 
-	if (forceindex
+	if ((forceindex && ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->need_index())
 	    || ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->load(cls, forceindex, ex) == -1) {
 		w(g_warning("Could not load summary: flags may be reset"));
 		camel_folder_summary_clear((CamelFolderSummary *)cls);
@@ -422,6 +424,11 @@
 	return ret;
 }
 
+static int
+local_summary_need_index() {
+	return 1;
+}
+
 static void
 update_summary (CamelFolderSummary *summary, CamelMessageInfoBase *info, CamelMessageInfoBase *old)
 {
@@ -484,6 +491,7 @@
 			
 			update_summary (s, (CamelMessageInfoBase *) mi, (CamelMessageInfoBase *) info);
 			mi->info.flags |= (camel_message_info_flags(info) & 0xffff);
+			camel_folder_summary_update_flag_cache (s, mi->info.uid, mi->info.flags);
 			mi->info.size = camel_message_info_size(info);
 		}
 

Modified: branches/camel-gobject/camel/providers/local/camel-local-summary.h
==============================================================================
--- branches/camel-gobject/camel/providers/local/camel-local-summary.h	(original)
+++ branches/camel-gobject/camel/providers/local/camel-local-summary.h	Thu Apr 16 01:23:17 2009
@@ -70,6 +70,7 @@
 
 	char *(*encode_x_evolution)(CamelLocalSummary *cls, const CamelLocalMessageInfo *info);
 	int (*decode_x_evolution)(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *info);
+	int (*need_index)();
 };
 
 GType	camel_local_summary_get_type	(void);

Modified: branches/camel-gobject/camel/providers/local/camel-maildir-folder.c
==============================================================================
--- branches/camel-gobject/camel/providers/local/camel-maildir-folder.c	(original)
+++ branches/camel-gobject/camel/providers/local/camel-maildir-folder.c	Thu Apr 16 01:23:17 2009
@@ -56,6 +56,7 @@
 
 static void maildir_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, char **appended_uid, CamelException * ex);
 static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex);
+static char* maildir_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
 
 static void maildir_finalize(CamelObject * object);
 
@@ -102,6 +103,7 @@
 
 	camel_folder_class->append_message = maildir_append_message;
 	camel_folder_class->get_message = maildir_get_message;
+	camel_folder_class->get_filename = maildir_get_filename;
 
 	lclass->create_summary = maildir_create_summary;
 }
@@ -232,6 +234,28 @@
 	g_free (dest);
 }
 
+static char* 
+maildir_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
+	CamelMaildirMessageInfo *mdi;
+	CamelMessageInfo *info;
+
+	/* get the message summary info */
+	if ((info = camel_folder_summary_uid(folder->summary, uid)) == NULL) {
+		camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
+				     _("Cannot get message: %s from folder %s\n  %s"),
+				     uid, lf->folder_path, _("No such message"));
+		return NULL;
+	}
+
+	mdi = (CamelMaildirMessageInfo *)info;
+
+	/* what do we do if the message flags (and :info data) changes?  filename mismatch - need to recheck I guess */
+	return g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename(mdi));
+}
+
+
 static CamelMimeMessage *
 maildir_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex)
 {

Modified: branches/camel-gobject/camel/providers/local/camel-maildir-summary.h
==============================================================================
--- branches/camel-gobject/camel/providers/local/camel-maildir-summary.h	(original)
+++ branches/camel-gobject/camel/providers/local/camel-maildir-summary.h	Thu Apr 16 01:23:17 2009
@@ -47,7 +47,7 @@
 typedef struct _CamelMaildirMessageInfo {
 	CamelLocalMessageInfo info;
 
-	char *filename;		/* maildir has this annoying status shit on the end of the filename, use this to get the real message id */
+	char *filename;		/* maildir has this annoying status on the end of the filename, use this to get the real message id */
 } CamelMaildirMessageInfo;
 
 struct _CamelMaildirSummary {

Modified: branches/camel-gobject/camel/providers/local/camel-mbox-folder.c
==============================================================================
--- branches/camel-gobject/camel/providers/local/camel-mbox-folder.c	(original)
+++ branches/camel-gobject/camel/providers/local/camel-mbox-folder.c	Thu Apr 16 01:23:17 2009
@@ -5,8 +5,8 @@
  *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  *
- * This program is free software; you can redistribute it and/or 
- * modify it under the terms of version 2 of the GNU Lesser General Public 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
  * License as published by the Free Software Foundation.
  *
  * This program is distributed in the hope that it will be useful,
@@ -31,6 +31,7 @@
 #include <unistd.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <inttypes.h>
 
 #include <glib.h>
 #include <glib/gi18n-lib.h>
@@ -67,6 +68,7 @@
 static void mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info,	char **appended_uid, CamelException *ex);
 static CamelMimeMessage *mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex);
 static CamelLocalSummary *mbox_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index);
+static char* mbox_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
 
 static void mbox_finalize(CamelObject * object);
 
@@ -83,6 +85,7 @@
 	/* virtual method overload */
 	camel_folder_class->append_message = mbox_append_message;
 	camel_folder_class->get_message = mbox_get_message;
+	camel_folder_class->get_filename = mbox_get_filename;
 
 	lclass->create_summary = mbox_create_summary;
 	lclass->lock = mbox_lock;
@@ -241,24 +244,24 @@
 	filter_from = (CamelMimeFilter *) camel_mime_filter_from_new();
 	camel_stream_filter_add((CamelStreamFilter *) filter_stream, filter_from);
 	g_object_unref (filter_from);
-	
+
 	if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) message, filter_stream) == -1 ||
 	    camel_stream_write (filter_stream, "\n", 1) == -1 ||
 	    camel_stream_flush (filter_stream) == -1)
 		goto fail_write;
-	
+
 	/* filter stream ref's the output stream itself, so we need to unref it too */
 	g_object_unref (filter_stream);
 	g_object_unref (output_stream);
 	g_free(fromline);
-	
+
 	/* now we 'fudge' the summary  to tell it its uptodate, because its idea of uptodate has just changed */
 	/* the stat really shouldn't fail, we just wrote to it */
 	if (g_stat (lf->folder_path, &st) == 0) {
 		((CamelFolderSummary *) mbs)->time = st.st_mtime;
 		mbs->folder_size = st.st_size;
 	}
-	
+
 	/* unlock as soon as we can */
 	camel_local_folder_unlock(lf);
 
@@ -280,30 +283,30 @@
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 				      _("Cannot append message to mbox file: %s: %s"),
 				      lf->folder_path, g_strerror (errno));
-	
+
 	if (output_stream) {
 		/* reset the file to original size */
 		do {
 			retval = ftruncate (((CamelStreamFs *) output_stream)->fd, mbs->folder_size);
 		} while (retval == -1 && errno == EINTR);
-		
+
 		g_object_unref (output_stream);
 	}
-	
+
 	if (filter_stream)
 		g_object_unref (filter_stream);
-	
+
 	g_free(fromline);
-	
+
 	/* remove the summary info so we are not out-of-sync with the mbox */
 	camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (mbs), camel_message_info_uid (mi));
-	
+
 	/* and tell the summary it's up-to-date */
 	if (g_stat (lf->folder_path, &st) == 0) {
 		((CamelFolderSummary *) mbs)->time = st.st_mtime;
 		mbs->folder_size = st.st_size;
 	}
-	
+
 fail:
 	/* make sure we unlock the folder - before we start triggering events into appland */
 	camel_local_folder_unlock(lf);
@@ -315,6 +318,54 @@
 	}
 }
 
+static char*
+mbox_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
+	CamelMboxMessageInfo *info;
+	off_t frompos;
+	char *filename = NULL;
+
+	d(printf("Getting message %s\n", uid));
+
+	/* lock the folder first, burn if we can't, need write lock for summary check */
+	if (camel_local_folder_lock(lf, CAMEL_LOCK_WRITE, ex) == -1)
+		return NULL;
+
+	/* check for new messages always */
+	if (camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex) == -1) {
+		camel_local_folder_unlock(lf);
+		return NULL;
+	}
+
+	/* get the message summary info */
+	info = (CamelMboxMessageInfo *) camel_folder_summary_uid(folder->summary, uid);
+
+	if (info == NULL) {
+		camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
+				     _("Cannot get message: %s from folder %s\n  %s"),
+				     uid, lf->folder_path, _("No such message"));
+		goto fail;
+	}
+
+	if (info->frompos == -1) {
+		camel_message_info_free((CamelMessageInfo *)info);
+		goto fail;
+	}
+
+	frompos = info->frompos;
+	camel_message_info_free((CamelMessageInfo *)info);
+
+
+	filename = g_strdup_printf ("%s%s!%" PRId64, lf->folder_path, G_DIR_SEPARATOR_S, (gint64) frompos);
+
+fail:
+	/* and unlock now we're finished with it */
+	camel_local_folder_unlock(lf);
+
+	return filename;
+}
+
 static CamelMimeMessage *
 mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex)
 {
@@ -337,7 +388,7 @@
 		camel_local_folder_unlock(lf);
 		return NULL;
 	}
-	
+
 retry:
 	/* get the message summary info */
 	info = (CamelMboxMessageInfo *) camel_folder_summary_uid(folder->summary, uid);
@@ -356,7 +407,7 @@
 
 	frompos = info->frompos;
 	camel_message_info_free((CamelMessageInfo *)info);
-	
+
 	/* we use an fd instead of a normal stream here - the reason is subtle, camel_mime_part will cache
 	   the whole message in memory if the stream is non-seekable (which it is when built from a parser
 	   with no stream).  This means we dont have to lock the mbox for the life of the message, but only
@@ -400,7 +451,7 @@
 				     _("The folder appears to be irrecoverably corrupted."));
 		goto fail;
 	}
-	
+
 	message = camel_mime_message_new();
 	if (camel_mime_part_construct_from_parser((CamelMimePart *)message, parser) == -1) {
 		camel_exception_setv(ex, errno==EINTR?CAMEL_EXCEPTION_USER_CANCEL:CAMEL_EXCEPTION_SYSTEM,
@@ -418,12 +469,12 @@
 
 	if (parser)
 		g_object_unref((CamelObject *)parser);
-	
+
 	/* use the opportunity to notify of changes (particularly if we had a rebuild) */
 	if (camel_folder_change_info_changed(lf->changes)) {
 		camel_object_trigger_event((CamelObject *)folder, "folder_changed", lf->changes);
 		camel_folder_change_info_clear(lf->changes);
 	}
-	
+
 	return message;
 }

Modified: branches/camel-gobject/camel/providers/local/camel-mbox-summary.c
==============================================================================
--- branches/camel-gobject/camel/providers/local/camel-mbox-summary.c	(original)
+++ branches/camel-gobject/camel/providers/local/camel-mbox-summary.c	Thu Apr 16 01:23:17 2009
@@ -46,6 +46,7 @@
 #include "camel-string-utils.h"
 #include "camel-store.h"
 #include "camel-folder.h"
+#include "camel-local-private.h"
 
 #define io(x)
 #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
@@ -211,29 +212,6 @@
 {
 	/*CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY(obj);*/
 }
-static int 
-frompos_sort (void *enc, int len1, void * data1, int len2, void *data2)
-{
-	static char *sa1=NULL, *sa2=NULL;
-	static int l1=0, l2=0;
-	int a1, a2;
-
-	if (l1 < len1+1) {
-		sa1 = g_realloc (sa1, len1+1);
-		l1 = len1+1;
-	}
-	if (l2 < len2+1) {
-		sa2 = g_realloc (sa2, len2+1);
-		l2 = len2+1;
-	}
-	strncpy (sa1, data1, len1);sa1[len1] = 0;
-	strncpy (sa2, data2, len2);sa2[len2] = 0;
-
-	a1 = strtoul (sa1, NULL, 10);
-	a2 = strtoul (sa2, NULL, 10);
-
-	return (a1 < a1) ? -1 : (a1 > a2) ? 1 : 0;
-}
 
 /**
  * camel_mbox_summary_new:
@@ -253,7 +231,7 @@
 		CamelFolderSummary *summary = (CamelFolderSummary *)new;
 
 		/* Set the functions for db sorting */
-		camel_db_set_collate (folder->parent_store->cdb_r, "bdata", "mbox_frompos_sort", (CamelDBCollate)frompos_sort);
+		camel_db_set_collate (folder->parent_store->cdb_r, "bdata", "mbox_frompos_sort", (CamelDBCollate)camel_local_frompos_sort);
 		summary->sort_by = "bdata";
 		summary->collate = "mbox_frompos_sort";
 

Modified: branches/camel-gobject/camel/providers/local/camel-mh-folder.c
==============================================================================
--- branches/camel-gobject/camel/providers/local/camel-mh-folder.c	(original)
+++ branches/camel-gobject/camel/providers/local/camel-mh-folder.c	Thu Apr 16 01:23:17 2009
@@ -55,6 +55,7 @@
 
 static void mh_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, char **appended_uid, CamelException * ex);
 static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex);
+static char* mh_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
 
 static void mh_finalize(CamelObject * object);
 
@@ -70,6 +71,7 @@
 	/* virtual method overload */
 	camel_folder_class->append_message = mh_append_message;
 	camel_folder_class->get_message = mh_get_message;
+	camel_folder_class->get_filename = mh_get_filename;
 
 	lclass->create_summary = mh_create_summary;
 }
@@ -187,6 +189,14 @@
 	g_free (name);
 }
 
+static char* mh_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
+
+	return g_strdup_printf("%s/%s", lf->folder_path, uid);
+}
+
+
 static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex)
 {
 	CamelLocalFolder *lf = (CamelLocalFolder *)folder;

Modified: branches/camel-gobject/camel/providers/local/camel-spool-summary.c
==============================================================================
--- branches/camel-gobject/camel/providers/local/camel-spool-summary.c	(original)
+++ branches/camel-gobject/camel/providers/local/camel-spool-summary.c	Thu Apr 16 01:23:17 2009
@@ -41,6 +41,7 @@
 #include "camel-store.h"
 
 #include "camel-spool-summary.h"
+#include "camel-local-private.h"
 
 #define io(x)
 #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
@@ -51,6 +52,7 @@
 static int spool_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex);
 
 static int spool_summary_sync_full(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
+static int spool_summary_need_index();
 
 static void camel_spool_summary_class_init (CamelSpoolSummaryClass *klass);
 static void camel_spool_summary_init       (CamelSpoolSummary *obj);
@@ -86,6 +88,7 @@
 
 	lklass->load = spool_summary_load;
 	lklass->check = spool_summary_check;
+	lklass->need_index = spool_summary_need_index;
 
 	mklass->sync_full = spool_summary_sync_full;
 }
@@ -107,30 +110,6 @@
 	/*CamelSpoolSummary *mbs = CAMEL_SPOOL_SUMMARY(obj);*/
 }
 
-static int 
-frompos_sort (void *enc, int len1, void * data1, int len2, void *data2)
-{
-	static char *sa1=NULL, *sa2=NULL;
-	static int l1=0, l2=0;
-	int a1, a2;
-
-	if (l1 < len1+1) {
-		sa1 = g_realloc (sa1, len1+1);
-		l1 = len1+1;
-	}
-	if (l2 < len2+1) {
-		sa2 = g_realloc (sa2, len2+1);
-		l2 = len2+1;
-	}
-	strncpy (sa1, data1, len1);sa1[len1] = 0;
-	strncpy (sa2, data2, len2);sa2[len2] = 0;
-
-	a1 = strtoul (sa1, NULL, 10);
-	a2 = strtoul (sa2, NULL, 10);
-
-	return (a1 < a1) ? -1 : (a1 > a2) ? 1 : 0;
-}
-
 CamelSpoolSummary *
 camel_spool_summary_new(struct _CamelFolder *folder, const char *mbox_name)
 {
@@ -139,7 +118,7 @@
 	new = g_object_new (CAMEL_TYPE_SPOOL_SUMMARY, NULL);
 	((CamelFolderSummary *)new)->folder = folder;
 	if (folder) {
-		camel_db_set_collate (folder->parent_store->cdb_r, "bdata", "spool_frompos_sort", (CamelDBCollate)frompos_sort);
+		camel_db_set_collate (folder->parent_store->cdb_r, "bdata", "spool_frompos_sort", (CamelDBCollate)camel_local_frompos_sort);
 		((CamelFolderSummary *)new)->sort_by = "bdata";
 		((CamelFolderSummary *)new)->collate = "spool_frompos_sort";
 	}
@@ -366,3 +345,8 @@
 
 	return 0;
 }
+
+static int
+spool_summary_need_index() {
+	return 0;
+}

Modified: branches/camel-gobject/camel/providers/nntp/camel-nntp-folder.c
==============================================================================
--- branches/camel-gobject/camel/providers/nntp/camel-nntp-folder.c	(original)
+++ branches/camel-gobject/camel/providers/nntp/camel-nntp-folder.c	Thu Apr 16 01:23:17 2009
@@ -123,6 +123,25 @@
         return ((CamelFolderClass *) folder_class)->set_message_flags (folder, uid, flags, set);
 }
 
+static char*
+nntp_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelNNTPStore *nntp_store = (CamelNNTPStore *) folder->parent_store;
+	char *article, *msgid;
+
+	article = alloca(strlen(uid)+1);
+	strcpy(article, uid);
+	msgid = strchr (article, ',');
+	if (msgid == NULL) {
+		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+				      _("Internal error: UID in invalid format: %s"), uid);
+		return NULL;
+	}
+	*msgid++ = 0;
+
+	return camel_data_cache_get_filename (nntp_store->cache, "cache", msgid, ex);
+}
+
 static CamelStream *
 nntp_folder_download_message (CamelNNTPFolder *nntp_folder, const char *id, const char *msgid, CamelException *ex)
 {
@@ -483,6 +502,7 @@
 	camel_folder_class->count_by_expression = nntp_folder_count_by_expression;
 	camel_folder_class->search_by_uids = nntp_folder_search_by_uids;
 	camel_folder_class->search_free = nntp_folder_search_free;
+	camel_folder_class->get_filename = nntp_get_filename;
 }
 
 GType

Modified: branches/camel-gobject/camel/providers/nntp/camel-nntp-store.c
==============================================================================
--- branches/camel-gobject/camel/providers/nntp/camel-nntp-store.c	(original)
+++ branches/camel-gobject/camel/providers/nntp/camel-nntp-store.c	Thu Apr 16 01:23:17 2009
@@ -248,11 +248,13 @@
 
 	if (xover_setup(store, ex) == -1)
 		goto fail;
-	
-	path = g_build_filename (store->storage_path, ".ev-journal", NULL);
-	disco_store->diary = camel_disco_diary_new (disco_store, path, ex);
-	g_free (path);	
-	
+
+	if (!disco_store->diary) {
+		path = g_build_filename (store->storage_path, ".ev-journal", NULL);
+		disco_store->diary = camel_disco_diary_new (disco_store, path, ex);
+		g_free (path);
+	}
+
 	retval = TRUE;
 
 	g_free(store->current_folder);
@@ -342,7 +344,10 @@
 		camel_data_cache_set_expire_age (nntp_store->cache, 60*60*24*14);
 		camel_data_cache_set_expire_access (nntp_store->cache, 60*60*24*5);
 	}	
-	
+
+	if (disco_store->diary)
+		return TRUE;
+
 	path = g_build_filename (nntp_store->storage_path, ".ev-journal", NULL);
 	disco_store->diary = camel_disco_diary_new (disco_store, path, ex);
 	g_free (path);
@@ -561,7 +566,7 @@
 		}
 	}
 
-	printf("store info update '%s' first '%u' last '%u'\n", line, first, last);
+	dd(printf("store info update '%s' first '%u' last '%u'\n", line, first, last));
 
 	if (si->last) {
 		if (last > si->last)
@@ -650,7 +655,7 @@
 	    root_or_flag = (orig_top == NULL || orig_top[0] == '\0') ? 1 : 0,
 	    recursive_flag = flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE;
 	CamelStoreInfo *si;
-	CamelFolderInfo *first = NULL, *last = NULL, *fi = NULL;
+	CamelFolderInfo *first = NULL, *last = NULL, *fi = NULL, *l;
 	char *tmpname;
 	char *top = g_strconcat(orig_top?orig_top:"", ".", NULL);
 	int toplen = strlen(top);
@@ -677,6 +682,9 @@
 					tmpname = g_strdup(si->path);
 					*(strchr(tmpname + toplen, '.')) = '\0';
 					fi = nntp_folder_info_from_name(store, FALSE, tmpname);
+					if (!fi)
+						continue;
+
 					fi->flags |= CAMEL_FOLDER_NOSELECT;
 					if (store->folder_hierarchy_relative) {
 						g_free(fi->name);
@@ -687,6 +695,20 @@
 					continue;
 				}
 			}
+
+			for (l = first; l; l = l->next) {
+				if (l->full_name && fi->full_name && g_str_equal (l->full_name, fi->full_name)) {
+					/* it's there already, do not add it twice */
+					camel_folder_info_free (fi);
+					break;
+				}
+			}
+
+			if (l) {
+				/* a duplicate has been found above */
+				continue;
+			}
+
 			if (last)
 				last->next = fi;
 			else
@@ -971,6 +993,7 @@
 {
 	/* call base finalize */
 	CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (object);
+	CamelDiscoStore *disco_store = (CamelDiscoStore *) nntp_store;
 	struct _CamelNNTPStorePrivate *p = nntp_store->priv;
 	struct _xover_header *xover, *xn;
 	
@@ -1000,7 +1023,12 @@
 
 	if (nntp_store->cache)
 		g_object_unref(nntp_store->cache);
-	
+
+	if (disco_store->diary) {
+		camel_object_unref (disco_store->diary);
+		disco_store->diary = NULL;
+	}
+
 	g_free(p);
 }
 

Modified: branches/camel-gobject/camel/providers/pop3/camel-pop3-folder.c
==============================================================================
--- branches/camel-gobject/camel/providers/pop3/camel-pop3-folder.c	(original)
+++ branches/camel-gobject/camel/providers/pop3/camel-pop3-folder.c	Thu Apr 16 01:23:17 2009
@@ -54,6 +54,7 @@
 static GPtrArray *pop3_get_uids (CamelFolder *folder);
 static CamelMimeMessage *pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex);
 static gboolean pop3_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set);
+static char* pop3_get_filename (CamelFolder *folder, const char *uid, CamelException *ex);
 
 static void
 camel_pop3_folder_class_init (CamelPOP3FolderClass *camel_pop3_folder_class)
@@ -69,7 +70,8 @@
 	camel_folder_class->get_message_count = pop3_get_message_count;
 	camel_folder_class->get_uids = pop3_get_uids;
 	camel_folder_class->free_uids = camel_folder_free_shallow;
-	
+	camel_folder_class->get_filename = pop3_get_filename;
+
 	camel_folder_class->get_message = pop3_get_message;
 	camel_folder_class->set_message_flags = pop3_set_message_flags;
 }
@@ -515,6 +517,23 @@
 	fi->stream = NULL;
 }
 
+static char*
+pop3_get_filename (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+	CamelPOP3Folder *pop3_folder = (CamelPOP3Folder *)folder;
+	CamelPOP3Store *pop3_store = (CamelPOP3Store *)((CamelFolder *)pop3_folder)->parent_store;
+	CamelPOP3FolderInfo *fi;
+
+	fi = g_hash_table_lookup(pop3_folder->uids_uid, uid);
+	if (fi == NULL) {
+		camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
+				      _("No message with UID %s"), uid);
+		return NULL;
+	}
+
+	return camel_data_cache_get_filename (pop3_store->cache, "cache", fi->uid, NULL);
+}
+
 static CamelMimeMessage *
 pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
 {

Modified: branches/camel-gobject/camel/tests/mime-filter/test-charset.c
==============================================================================
--- branches/camel-gobject/camel/tests/mime-filter/test-charset.c	(original)
+++ branches/camel-gobject/camel/tests/mime-filter/test-charset.c	Thu Apr 16 01:23:17 2009
@@ -16,7 +16,7 @@
 #include <camel/camel-stream-filter.h>
 #include <camel/camel-mime-filter-charset.h>
 
-#define d(x) x
+#define d(x)
 
 #define CHUNK_SIZE 4096
 

Modified: branches/camel-gobject/camel/tests/mime-filter/test-crlf.c
==============================================================================
--- branches/camel-gobject/camel/tests/mime-filter/test-crlf.c	(original)
+++ branches/camel-gobject/camel/tests/mime-filter/test-crlf.c	Thu Apr 16 01:23:17 2009
@@ -14,7 +14,7 @@
 #include <camel/camel-stream-filter.h>
 #include <camel/camel-mime-filter-crlf.h>
 
-#define d(x) x
+#define d(x)
 
 #define NUM_CASES 1
 #define CHUNK_SIZE 4096

Modified: branches/camel-gobject/camel/tests/mime-filter/test-tohtml.c
==============================================================================
--- branches/camel-gobject/camel/tests/mime-filter/test-tohtml.c	(original)
+++ branches/camel-gobject/camel/tests/mime-filter/test-tohtml.c	Thu Apr 16 01:23:17 2009
@@ -19,7 +19,7 @@
 #include <camel/camel-stream-filter.h>
 #include <camel/camel-mime-filter-tohtml.h>
 
-#define d(x) x
+#define d(x)
 
 #define CHUNK_SIZE 4096
 

Modified: branches/camel-gobject/camel/tests/mime-filter/test1.c
==============================================================================
--- branches/camel-gobject/camel/tests/mime-filter/test1.c	(original)
+++ branches/camel-gobject/camel/tests/mime-filter/test1.c	Thu Apr 16 01:23:17 2009
@@ -14,7 +14,7 @@
 #include <camel/camel-stream-filter.h>
 #include <camel/camel-mime-filter-canon.h>
 
-#define d(x) x
+#define d(x)
 
 #define NUM_CASES 1
 #define CHUNK_SIZE 4096

Modified: branches/camel-gobject/configure.in
==============================================================================
--- branches/camel-gobject/configure.in	(original)
+++ branches/camel-gobject/configure.in	Thu Apr 16 01:23:17 2009
@@ -3,8 +3,8 @@
 
 # Evolution-Data-Server version */
 m4_define([eds_major_version], [2])
-m4_define([eds_minor_version], [25])
-m4_define([eds_micro_version], [4])
+m4_define([eds_minor_version], [26])
+m4_define([eds_micro_version], [1])
 
 m4_define([eds_version],
           [eds_major_version.eds_minor_version.eds_micro_version])
@@ -22,7 +22,7 @@
 
 # Required Package Versions
 m4_define([glib_minimum_version], [2.16.1])
-m4_define([gtk_minimum_version], [2.10.0])
+m4_define([gtk_minimum_version], [2.14.0])
 m4_define([ORBit_minimum_version], [2.9.8])
 m4_define([libbonobo_minimum_version], [2.20.3])
 m4_define([gconf_minimum_version], [2.0.0])             # XXX Just a Guess
@@ -33,6 +33,7 @@
 m4_define([gnome_keyring_minimum_version], [2.20.1])
 m4_define([sqlite_minimum_version], [3.5])
 m4_define([gweather_minimum_version], [2.25.4])
+m4_define([libical_minimum_version], [0.43])
 
 dnl *************************************************************************************************
 dnl Base Version
@@ -73,15 +74,15 @@
 LIBEDATABOOK_REVISION=1
 LIBEDATABOOK_AGE=4
 
-LIBEBOOK_CURRENT=11
+LIBEBOOK_CURRENT=12
 LIBEBOOK_REVISION=0
-LIBEBOOK_AGE=2
+LIBEBOOK_AGE=3
 
 LIBEGROUPWISE_CURRENT=13
 LIBEGROUPWISE_REVISION=1
 LIBEGROUPWISE_AGE=0
 
-LIBCAMEL_CURRENT=13
+LIBCAMEL_CURRENT=14
 LIBCAMEL_REVISION=0
 LIBCAMEL_AGE=0
 
@@ -242,6 +243,9 @@
          libxml-2.0 >= libxml_minimum_version
          libsoup-2.4 >= libsoup_minimum_version])
 
+LIBICAL_REQUIRED=libical_minimum_version
+AC_SUBST(LIBICAL_REQUIRED)
+
 dnl **************************************************
 dnl * regex checking
 dnl **************************************************
@@ -299,20 +303,18 @@
 AC_ARG_WITH(libiconv, 
   AC_HELP_STRING( [--with-libiconv],
 		  [Prefix where libiconv is installed]))
-case $withval in
-/*)
+if test -d $withval; then
     ICONV_CFLAGS="-I$withval/include"
     ICONV_LIBS="-L$withval/lib"
-    ;;
-esac
+fi
 
 save_CFLAGS="$CFLAGS"
 save_LIBS="$LIBS"
 CFLAGS="$CFLAGS $ICONV_CFLAGS"
 LIBS="$LIBS $ICONV_LIBS -liconv"
-AC_CACHE_CHECK(for iconv in -liconv, ac_cv_libiconv, AC_TRY_RUN([
+AC_CACHE_CHECK(for iconv in -liconv, ac_cv_libiconv, AC_TRY_LINK([
 #include <iconv.h>
-#include <stdlib.h>
+#include <stdlib.h>],[
 
 int main (int argc, char **argv)
 {
@@ -320,7 +322,7 @@
 	cd = iconv_open ("UTF-8", "ISO-8859-1");
 	exit (0);
 }
-], ac_cv_libiconv=yes, ac_cv_libiconv=no, ac_cv_libiconv=no))
+], ac_cv_libiconv=yes, ac_cv_libiconv=no))
 if test $ac_cv_libiconv = yes; then
 	ICONV_LIBS="$ICONV_LIBS -liconv"
 	if test $os_win32 = yes; then
@@ -371,7 +373,7 @@
 		exit (1);
 
 	exit (0);
-}], ac_cv_libiconv_utf8=yes, [ac_cv_libiconv_utf8=no; have_iconv=no], [ac_cv_libiconv_utf8=no; have_iconv=no]))
+}], ac_cv_libiconv_utf8=yes, [ac_cv_libiconv_utf8=no; have_iconv=no], ac_cv_libiconv_utf8=HOPEFULLY))
 fi
 
 if test "$have_iconv" = no; then
@@ -396,7 +398,24 @@
 	*** iconv library. It is suggested that you install a
 	*** working iconv library such as the one found at
 	*** ftp://ftp.gnu.org/pub/gnu/libiconv
-	])
+])
+],[
+  if test x$os_win32 = xyes; then
+    AC_MSG_RESULT(using cached win32 result)
+    echo "/* This is an auto-generated header, DO NOT EDIT! */" > iconv-detect.h
+    echo "" >>iconv-detect.h
+    echo "#define ICONV_ISO_D_FORMAT \"iso-%d-%d\"" >>iconv-detect.h
+    echo "#define ICONV_ISO_S_FORMAT \"iso-%d-%s\"" >>iconv-detect.h
+    echo "#define ICONV_10646 \"UCS-4BE\"" >>iconv-detect.h
+  else
+	AC_MSG_RESULT(unknown)
+	AC_WARN([
+	*** The iconv-detect program was unable to determine the
+	*** preferred charset formats recognized by your system
+	*** iconv library. You are crosscompiling and supposed
+	*** to know what you are doing. (:-)
+    ])
+  fi
 ])
 
 CFLAGS="$save_CFLAGS"
@@ -715,6 +734,8 @@
 AC_SUBST(MANUAL_NSS_CFLAGS)
 AC_SUBST(MANUAL_NSS_LIBS)
 
+if test $os_win32 != yes; then
+
 dnl check for socklen_t (in Unix98)
 AC_MSG_CHECKING(for socklen_t)
 AC_TRY_COMPILE([#include <sys/types.h>
@@ -730,6 +751,8 @@
 AC_MSG_RESULT(int)
 AC_DEFINE(socklen_t,int)])])
 
+fi
+
 dnl
 dnl system mail stuff
 dnl
@@ -994,7 +1017,6 @@
 
 if test "x${enable_calendar}" != "xno"; then
         AC_DEFINE(ENABLE_CALENDAR, 1, [Define if Calendar should be built])
-	AC_DEFINE(HANDLE_LIBICAL_MEMORY, 1, [Define it once memory returned by libical is free'ed properly])
 fi
 AM_CONDITIONAL(ENABLE_CALENDAR, test x$enable_calendar = xyes)
 AC_MSG_RESULT($enable_calendar)
@@ -1005,7 +1027,7 @@
 dnl **************************************************
 AC_MSG_CHECKING(if we should build the weather calendar backend)
 AC_ARG_WITH([weather], 
-  [AS_HELP_STRING([--with-weather], [Build the weather calendar backend (default=yes)])],
+  [AC_HELP_STRING([--with-weather], [Build the weather calendar backend (default=yes)])],
   [use_gweather=$withval], 
   [use_gweather=yes])
 if test $enable_calendar = no; then
@@ -1085,7 +1107,7 @@
         msg_hula=no
 fi
 AM_CONDITIONAL(ENABLE_HULA, test x$enable_hula = xyes)
- 
+
 dnl **************************************************
 dnl * File locking
 dnl **************************************************
@@ -1455,7 +1477,7 @@
 esac
 
 PKG_CHECK_MODULES(ORBIT, ORBit-2.0 >= ORBit_minimum_version)
-ORBIT_IDL=`$PKG_CONFIG --variable=orbit_idl ORBit-2.0`
+test x$ORBIT_IDL = x && ORBIT_IDL=`$PKG_CONFIG --variable=orbit_idl ORBit-2.0`
 AC_SUBST(ORBIT_CFLAGS)
 AC_SUBST(ORBIT_LIBS)
 AC_SUBST(ORBIT_IDL)
@@ -1474,8 +1496,8 @@
 dnl  EVO_SET_COMPILE_FLAGS(VAR-PREFIX, DEPS, EXTRA-CFLAGS, EXTRA-LIBS)
 AC_DEFUN([EVO_SET_COMPILE_FLAGS], [
 	PKG_CHECK_MODULES([$1], [$2])
-	$1_CFLAGS="[$]$1_CFLAGS \$(WERROR) $3"
-	$1_LIBS="[$]$1_LIBS $4"
+	$1_CFLAGS="[$]$1_CFLAGS $3 "
+	$1_LIBS="[$]$1_LIBS $4 "
 ])
 
 dnl ****************************************
@@ -1512,9 +1534,21 @@
 
 dnl --- evolution-calendar flags
 if test "x${enable_calendar}" = "xyes"; then
-	EVOLUTION_CALENDAR_DEPS="libxml-2.0 libbonobo-2.0 gio-2.0 gobject-2.0 gthread-2.0 gconf-2.0"
+	EVOLUTION_CALENDAR_DEPS="libical >= libical_minimum_version libxml-2.0 libbonobo-2.0 gio-2.0 gobject-2.0 gthread-2.0 gconf-2.0"
 
-	EVO_SET_COMPILE_FLAGS(EVOLUTION_CALENDAR, $EVOLUTION_CALENDAR_DEPS)
+dnl *****
+dnl libical.pc from libical-0.43 has a bug in it's CFlags. 
+dnl It wants apps to include <libical/ical*.h> but it's CFlags make it difficult
+dnl to differentiate between <libical/ical.h> and <ical.h>
+dnl We have fixed all our instances to use <libical/ical.h>. Until the .pc from 
+dnl libical is fixed, we have to work-around the buggy CFlags.
+dnl *****
+LIBICAL_EXTRA_CFLAGS=" -I`$PKG_CONFIG --variable=includedir libical` "
+LIBICAL_EXTRA_LIBS=""
+AC_SUBST(LIBICAL_EXTRA_CFLAGS)
+AC_SUBST(LIBICAL_EXTRA_LIBS)
+
+	EVO_SET_COMPILE_FLAGS(EVOLUTION_CALENDAR, $EVOLUTION_CALENDAR_DEPS, $LIBICAL_EXTRA_CFLAGS, $LIBICAL_EXTRA_LIBS)
 	AC_SUBST(EVOLUTION_CALENDAR_CFLAGS)
 	AC_SUBST(EVOLUTION_CALENDAR_LIBS)
 fi
@@ -1522,11 +1556,19 @@
 dnl --- factory flags
 
 E_FACTORY_DEPS="libgnome-2.0 $mozilla_nspr"
-
-EVO_SET_COMPILE_FLAGS(E_FACTORY, $E_FACTORY_DEPS, $THREADS_CFLAGS $MANUAL_NSPR_CFLAGS, $THREADS_LIBS $MANUAL_NSPR_LIBS)
+if test "x${enable_calendar}" = "xyes"; then
+   E_FACTORY_DEPS="$E_FACTORY_DEPS libical"
+fi
+EVO_SET_COMPILE_FLAGS(E_FACTORY, $E_FACTORY_DEPS, $THREADS_CFLAGS $MANUAL_NSPR_CFLAGS $LIBICAL_EXTRA_CFLAGS, $THREADS_LIBS $MANUAL_NSPR_LIBS $LIBICAL_EXTRA_LIBS)
 AC_SUBST(E_FACTORY_CFLAGS)
 AC_SUBST(E_FACTORY_LIBS)
 
+dnl --- Google flags
+GDATA_DEPS="libsoup-2.4 libxml-2.0"
+EVO_SET_COMPILE_FLAGS(GDATA, $GDATA_DEPS)
+AC_SUBST(GDATA_CFLAGS)
+AC_SUBST(GDATA_LIBS)
+
 dnl --- Groupwise flags
 LIBSOUP_REQUIRED=libsoup_minimum_version
 AC_SUBST(LIBSOUP_REQUIRED)
@@ -1688,9 +1730,6 @@
 export privincludedir
 export privdatadir
 
-if test $enable_calendar = yes; then
-        AC_CONFIG_SUBDIRS(calendar/libical)
-fi
 if test $dynamic_libdb = no; then
         AC_CONFIG_SUBDIRS(libdb/dist)
 fi

Modified: branches/camel-gobject/docs/reference/addressbook/libebook/libebook-sections.txt
==============================================================================
--- branches/camel-gobject/docs/reference/addressbook/libebook/libebook-sections.txt	(original)
+++ branches/camel-gobject/docs/reference/addressbook/libebook/libebook-sections.txt	Thu Apr 16 01:23:17 2009
@@ -169,6 +169,7 @@
 e_contact_field_name
 e_contact_pretty_name
 e_contact_field_id
+e_contact_field_id_from_vcard
 e_contact_cert_free
 e_contact_get_attributes
 e_contact_set_attributes
@@ -293,7 +294,7 @@
 EVC_X_LIST
 EVC_X_MANAGER
 EVC_X_MSN
-EVC_X_SPOUSE
+EVC_X_SKYPE
 EVC_X_WANTS_HTML
 EVC_X_YAHOO
 EVC_X_BOOK_URI
@@ -307,6 +308,8 @@
 EVC_X_DEST_SOURCE_UID
 EVC_X_GROUPWISE
 EVC_X_RADIO
+EVC_X_SIP
+EVC_X_SPOUSE
 EVC_X_TELEX
 EVC_X_TTYTDD
 EVC_X_VIDEO_URL

Modified: branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-book-types.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-book-types.sgml	(original)
+++ branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-book-types.sgml	Thu Apr 16 01:23:17 2009
@@ -62,6 +62,7 @@
 @E_BOOK_ERROR_OTHER_ERROR: 
 @E_BOOK_ERROR_INVALID_SERVER_VERSION: 
 @E_BOOK_ERROR_UNSUPPORTED_AUTHENTICATION_METHOD: 
+ E_BOOK_ERROR_NO_SPACE: 
 
 <!-- ##### ENUM EBookViewStatus ##### -->
 <para>

Modified: branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-contact.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-contact.sgml	(original)
+++ branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-contact.sgml	Thu Apr 16 01:23:17 2009
@@ -613,6 +613,11 @@
 
 </para>
 
+<!-- ##### ARG EContact:sip ##### -->
+<para>
+
+</para>
+
 <!-- ##### ARG EContact:spouse ##### -->
 <para>
 
@@ -778,6 +783,7 @@
 @E_CONTACT_IM_SKYPE_WORK_2: 
 @E_CONTACT_IM_SKYPE_WORK_3: 
 @E_CONTACT_IM_SKYPE: 
+ E_CONTACT_SIP: 
 @E_CONTACT_FIELD_LAST: 
 @E_CONTACT_FIELD_FIRST: 
 @E_CONTACT_LAST_SIMPLE_STRING: 
@@ -1042,6 +1048,15 @@
 @Returns: 
 
 
+<!-- ##### FUNCTION e_contact_field_id_from_vcard ##### -->
+<para>
+
+</para>
+
+ vcard_field: 
+ Returns: 
+
+
 <!-- ##### FUNCTION e_contact_cert_free ##### -->
 <para>
 

Modified: branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-vcard.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-vcard.sgml	(original)
+++ branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-vcard.sgml	Thu Apr 16 01:23:17 2009
@@ -754,9 +754,9 @@
 
 
 
-<!-- ##### MACRO EVC_X_SPOUSE ##### -->
+<!-- ##### MACRO EVC_X_SKYPE ##### -->
 <para>
-Spouse
+
 </para>
 
 
@@ -852,6 +852,20 @@
 
 
 
+<!-- ##### MACRO EVC_X_SIP ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO EVC_X_SPOUSE ##### -->
+<para>
+Spouse
+</para>
+
+
+
 <!-- ##### MACRO EVC_X_TELEX ##### -->
 <para>
 

Modified: branches/camel-gobject/docs/reference/calendar/libecal/Makefile.am
==============================================================================
--- branches/camel-gobject/docs/reference/calendar/libecal/Makefile.am	(original)
+++ branches/camel-gobject/docs/reference/calendar/libecal/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -22,13 +22,10 @@
 GTKDOC_CFLAGS = \
 	-I$(top_srcdir) 					\
 	-I$(top_srcdir)/calendar				\
-	-I$(top_srcdir)/calendar/libical/src			\
-	-I$(top_srcdir)/calendar/libical/src/libical		\
 	-I$(top_builddir)					\
 	-I$(top_builddir)/calendar				\
 	-I$(top_builddir)/calendar/libecal			\
-	-I$(top_builddir)/calendar/libical/src			\
-	-I$(top_builddir)/calendar/libical/src/libical		\
+	$(LIBICAL_CFLAGS)					\
 	$(EVOLUTION_CALENDAR_CFLAGS)
 
 GTKDOC_LIBS = \

Modified: branches/camel-gobject/docs/reference/calendar/libedata-cal/Makefile.am
==============================================================================
--- branches/camel-gobject/docs/reference/calendar/libedata-cal/Makefile.am	(original)
+++ branches/camel-gobject/docs/reference/calendar/libedata-cal/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -21,12 +21,9 @@
 GTKDOC_CFLAGS = \
 	-I$(top_srcdir) 				\
 	-I$(top_srcdir)/calendar			\
-	-I$(top_srcdir)/calendar/libical/src		\
-	-I$(top_srcdir)/calendar/libical/src/libical	\
 	-I$(top_builddir)				\
 	-I$(top_builddir)/calendar			\
-	-I$(top_builddir)/calendar/libical/src		\
-	-I$(top_builddir)/calendar/libical/src/libical	\
+	$(LIBICAL_CFLAGS)				\
 	$(EVOLUTION_CALENDAR_CFLAGS)
 
 GTKDOC_LIBS = \

Modified: branches/camel-gobject/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt
==============================================================================
--- branches/camel-gobject/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt	(original)
+++ branches/camel-gobject/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt	Thu Apr 16 01:23:17 2009
@@ -180,6 +180,7 @@
 E_TYPE_CAL_BACKEND
 E_CAL_BACKEND_CLASS
 E_IS_CAL_BACKEND_CLASS
+E_CAL_BACKEND_GET_CLASS
 <SUBSECTION Private>
 ECalBackendPrivate
 e_cal_backend_get_type
@@ -274,6 +275,7 @@
 e_cal_backend_mail_account_get_default
 e_cal_backend_mail_account_is_valid
 e_cal_backend_status_to_string
+e_cal_backend_user_declined
 </SECTION>
 
 <SECTION>

Modified: branches/camel-gobject/docs/reference/calendar/libedata-cal/tmpl/e-cal-backend-util.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/calendar/libedata-cal/tmpl/e-cal-backend-util.sgml	(original)
+++ branches/camel-gobject/docs/reference/calendar/libedata-cal/tmpl/e-cal-backend-util.sgml	Thu Apr 16 01:23:17 2009
@@ -46,3 +46,12 @@
 @Returns: 
 
 
+<!-- ##### FUNCTION e_cal_backend_user_declined ##### -->
+<para>
+
+</para>
+
+ icalcomp: 
+ Returns: 
+
+

Modified: branches/camel-gobject/docs/reference/camel/camel-sections.txt
==============================================================================
--- branches/camel-gobject/docs/reference/camel/camel-sections.txt	(original)
+++ branches/camel-gobject/docs/reference/camel/camel-sections.txt	Thu Apr 16 01:23:17 2009
@@ -157,6 +157,7 @@
 camel_data_cache_get
 camel_data_cache_remove
 camel_data_cache_clear
+camel_data_cache_get_filename
 <SUBSECTION Standard>
 CAMEL_DATA_CACHE
 CAMEL_IS_DATA_CACHE
@@ -194,6 +195,9 @@
 <FILE>camel-db</FILE>
 <TITLE>CamelDB</TITLE>
 CAMEL_DB_FILE
+CAMEL_DB_IN_MEMORY_TABLE
+CAMEL_DB_IN_MEMORY_DB
+CAMEL_DB_IN_MEMORY_TABLE_LIMIT
 CAMEL_DB_FREE_CACHE_SIZE
 CAMEL_DB_SLEEP_INTERVAL
 CAMEL_DB_RELEASE_SQLITE_MEMORY
@@ -224,6 +228,7 @@
 camel_db_read_folder_info_record
 camel_db_prepare_message_info_table
 camel_db_write_message_info_record
+camel_db_write_fresh_message_info_record
 camel_db_read_message_info_records
 camel_db_read_message_info_record_with_uid
 camel_db_count_junk_message_info
@@ -243,6 +248,7 @@
 camel_db_add_to_vfolder
 camel_db_add_to_vfolder_transaction
 camel_db_get_folder_uids
+camel_db_get_folder_uids_flags
 camel_db_get_folder_junk_uids
 camel_db_get_folder_deleted_uids
 camel_db_sqlize_string
@@ -250,6 +256,8 @@
 camel_db_get_column_name
 camel_db_set_collate
 camel_db_migrate_vfolders_to_14
+camel_db_start_in_memory_transactions
+camel_db_flush_in_memory_transactions
 <SUBSECTION Private>
 CamelDBPrivate
 </SECTION>
@@ -402,9 +410,11 @@
 camel_folder_get_summary
 camel_folder_free_summary
 camel_folder_get_message
+camel_folder_sync_message
 camel_folder_delete_message
 camel_folder_get_uids
 camel_folder_free_uids
+camel_folder_get_uncached_uids
 camel_folder_sort_uids
 camel_folder_has_search_capability
 camel_folder_search_by_expression
@@ -427,6 +437,7 @@
 camel_folder_free_nop
 camel_folder_free_shallow
 camel_folder_free_deep
+camel_folder_get_filename
 camel_folder_change_info_new
 camel_folder_change_info_clear
 camel_folder_change_info_free
@@ -534,6 +545,8 @@
 camel_folder_summary_array
 camel_folder_summary_get_hashtable
 camel_folder_summary_free_hashtable
+camel_folder_summary_get_flag_cache
+camel_folder_summary_update_flag_cache
 camel_folder_summary_encode_token
 camel_folder_summary_decode_token
 camel_flag_get
@@ -1687,6 +1700,7 @@
 camel_session_get_junk_headers
 camel_session_set_junk_headers
 camel_session_lookup_addressbook
+camel_session_forward_to
 <SUBSECTION Standard>
 CAMEL_SESSION
 CAMEL_IS_SESSION
@@ -1792,6 +1806,7 @@
 CAMEL_STORE_FILTER_INBOX
 CAMEL_STORE_VJUNK
 CAMEL_STORE_PROXY
+CAMEL_STORE_IS_MIGRATING
 CAMEL_STORE_FOLDER_CREATE
 CAMEL_STORE_FOLDER_EXCL
 CAMEL_STORE_FOLDER_BODY_INDEX
@@ -2147,6 +2162,7 @@
 camel_vee_summary_new
 camel_vee_summary_add
 camel_vee_summary_get_ids
+camel_vee_summary_load_check_unread_vfolder
 <SUBSECTION Standard>
 CAMEL_VEE_SUMMARY
 CAMEL_IS_VEE_SUMMARY
@@ -2320,10 +2336,12 @@
 camel_imap_message_cache_insert_stream
 camel_imap_message_cache_insert_wrapper
 camel_imap_message_cache_get
+camel_imap_message_cache_get_filename
 camel_imap_message_cache_remove
 camel_imap_message_cache_clear
 camel_imap_message_cache_copy
 camel_imap_message_cache_delete
+camel_imap_message_cache_filter_cached
 <SUBSECTION Standard>
 CAMEL_IMAP_MESSAGE_CACHE
 CAMEL_IS_IMAP_MESSAGE_CACHE
@@ -3878,6 +3896,7 @@
 camel_utf8_utf7
 camel_utf8_ucs2
 camel_ucs2_utf8
+camel_utf8_make_valid
 </SECTION>
 
 <SECTION>

Modified: branches/camel-gobject/docs/reference/camel/tmpl/camel-data-cache.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/camel/tmpl/camel-data-cache.sgml	(original)
+++ branches/camel-gobject/docs/reference/camel/tmpl/camel-data-cache.sgml	Thu Apr 16 01:23:17 2009
@@ -117,3 +117,15 @@
 @Returns: 
 
 
+<!-- ##### FUNCTION camel_data_cache_get_filename ##### -->
+<para>
+
+</para>
+
+ cdc: 
+ path: 
+ key: 
+ ex: 
+ Returns: 
+
+

Modified: branches/camel-gobject/docs/reference/camel/tmpl/camel-folder-summary.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/camel/tmpl/camel-folder-summary.sgml	(original)
+++ branches/camel-gobject/docs/reference/camel/tmpl/camel-folder-summary.sgml	Thu Apr 16 01:23:17 2009
@@ -573,6 +573,25 @@
 @Returns: 
 
 
+<!-- ##### FUNCTION camel_folder_summary_get_flag_cache ##### -->
+<para>
+
+</para>
+
+ summary: 
+ Returns: 
+
+
+<!-- ##### FUNCTION camel_folder_summary_update_flag_cache ##### -->
+<para>
+
+</para>
+
+ s: 
+ uid: 
+ flag: 
+
+
 <!-- ##### FUNCTION camel_folder_summary_encode_token ##### -->
 <para>
 

Modified: branches/camel-gobject/docs/reference/camel/tmpl/camel-folder.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/camel/tmpl/camel-folder.sgml	(original)
+++ branches/camel-gobject/docs/reference/camel/tmpl/camel-folder.sgml	Thu Apr 16 01:23:17 2009
@@ -321,6 +321,16 @@
 @Returns: 
 
 
+<!-- ##### FUNCTION camel_folder_sync_message ##### -->
+<para>
+
+</para>
+
+ folder: 
+ uid: 
+ ex: 
+
+
 <!-- ##### MACRO camel_folder_delete_message ##### -->
 <para>
 
@@ -348,6 +358,17 @@
 @array: 
 
 
+<!-- ##### FUNCTION camel_folder_get_uncached_uids ##### -->
+<para>
+
+</para>
+
+ Param1: 
+ uids: 
+ Param3: 
+ Returns: 
+
+
 <!-- ##### FUNCTION camel_folder_sort_uids ##### -->
 <para>
 
@@ -545,6 +566,17 @@
 @array: 
 
 
+<!-- ##### FUNCTION camel_folder_get_filename ##### -->
+<para>
+
+</para>
+
+ folder: 
+ uid: 
+ ex: 
+ Returns: 
+
+
 <!-- ##### FUNCTION camel_folder_change_info_new ##### -->
 <para>
 

Modified: branches/camel-gobject/docs/reference/camel/tmpl/camel-imap-message-cache.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/camel/tmpl/camel-imap-message-cache.sgml	(original)
+++ branches/camel-gobject/docs/reference/camel/tmpl/camel-imap-message-cache.sgml	Thu Apr 16 01:23:17 2009
@@ -107,6 +107,18 @@
 @Returns: 
 
 
+<!-- ##### FUNCTION camel_imap_message_cache_get_filename ##### -->
+<para>
+
+</para>
+
+ cache: 
+ uid: 
+ part_spec: 
+ ex: 
+ Returns: 
+
+
 <!-- ##### FUNCTION camel_imap_message_cache_remove ##### -->
 <para>
 
@@ -146,3 +158,14 @@
 @Returns: 
 
 
+<!-- ##### FUNCTION camel_imap_message_cache_filter_cached ##### -->
+<para>
+
+</para>
+
+ Param1: 
+ uids: 
+ ex: 
+ Returns: 
+
+

Modified: branches/camel-gobject/docs/reference/camel/tmpl/camel-session.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/camel/tmpl/camel-session.sgml	(original)
+++ branches/camel-gobject/docs/reference/camel/tmpl/camel-session.sgml	Thu Apr 16 01:23:17 2009
@@ -318,3 +318,15 @@
 @Returns: 
 
 
+<!-- ##### FUNCTION camel_session_forward_to ##### -->
+<para>
+
+</para>
+
+ session: 
+ folder: 
+ message: 
+ address: 
+ ex: 
+
+

Modified: branches/camel-gobject/docs/reference/camel/tmpl/camel-store.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/camel/tmpl/camel-store.sgml	(original)
+++ branches/camel-gobject/docs/reference/camel/tmpl/camel-store.sgml	Thu Apr 16 01:23:17 2009
@@ -229,6 +229,13 @@
 
 
 
+<!-- ##### MACRO CAMEL_STORE_IS_MIGRATING ##### -->
+<para>
+
+</para>
+
+
+
 <!-- ##### MACRO CAMEL_STORE_FOLDER_CREATE ##### -->
 <para>
 

Modified: branches/camel-gobject/docs/reference/camel/tmpl/camel-utf8.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/camel/tmpl/camel-utf8.sgml	(original)
+++ branches/camel-gobject/docs/reference/camel/tmpl/camel-utf8.sgml	Thu Apr 16 01:23:17 2009
@@ -90,3 +90,12 @@
 @Returns: 
 
 
+<!-- ##### FUNCTION camel_utf8_make_valid ##### -->
+<para>
+
+</para>
+
+ text: 
+ Returns: 
+
+

Modified: branches/camel-gobject/docs/reference/camel/tmpl/camel-vee-summary.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/camel/tmpl/camel-vee-summary.sgml	(original)
+++ branches/camel-gobject/docs/reference/camel/tmpl/camel-vee-summary.sgml	Thu Apr 16 01:23:17 2009
@@ -66,3 +66,11 @@
 @Returns: 
 
 
+<!-- ##### FUNCTION camel_vee_summary_load_check_unread_vfolder ##### -->
+<para>
+
+</para>
+
+ vs: 
+
+

Modified: branches/camel-gobject/docs/reference/libedataserver/libedataserver-sections.txt
==============================================================================
--- branches/camel-gobject/docs/reference/libedataserver/libedataserver-sections.txt	(original)
+++ branches/camel-gobject/docs/reference/libedataserver/libedataserver-sections.txt	Thu Apr 16 01:23:17 2009
@@ -168,9 +168,9 @@
 <TITLE>EProxy</TITLE>
 EProxy
 e_proxy_new
-e_proxy_peek_uri
-e_proxy_require_proxy_for_uri
+e_proxy_peek_uri_for
 e_proxy_setup_proxy
+e_proxy_require_proxy_for_uri
 <SUBSECTION Standard>
 E_TYPE_PROXY
 E_PROXY

Modified: branches/camel-gobject/docs/reference/libedataserver/tmpl/e-proxy.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/libedataserver/tmpl/e-proxy.sgml	(original)
+++ branches/camel-gobject/docs/reference/libedataserver/tmpl/e-proxy.sgml	Thu Apr 16 01:23:17 2009
@@ -33,30 +33,31 @@
 @Returns: 
 
 
-<!-- ##### FUNCTION e_proxy_peek_uri ##### -->
+<!-- ##### FUNCTION e_proxy_peek_uri_for ##### -->
 <para>
 
 </para>
 
 @proxy: 
+ uri: 
 @Returns: 
 
 
-<!-- ##### FUNCTION e_proxy_require_proxy_for_uri ##### -->
+<!-- ##### FUNCTION e_proxy_setup_proxy ##### -->
 <para>
 
 </para>
 
 @proxy: 
- uri: 
- Returns: 
 
 
-<!-- ##### FUNCTION e_proxy_setup_proxy ##### -->
+<!-- ##### FUNCTION e_proxy_require_proxy_for_uri ##### -->
 <para>
 
 </para>
 
 @proxy: 
+ uri: 
+ Returns: 
 
 

Modified: branches/camel-gobject/docs/reference/libedataserverui/libedataserverui-docs.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/libedataserverui/libedataserverui-docs.sgml	(original)
+++ branches/camel-gobject/docs/reference/libedataserverui/libedataserverui-docs.sgml	Thu Apr 16 01:23:17 2009
@@ -10,6 +10,7 @@
     <title>Evolution-Data-Server Manual: Graphical Utilities (libedataserverui)</title>
     <xi:include href="xml/e-book-auth-util.xml"/>
     <xi:include href="xml/e-categories-dialog.xml"/>
+    <xi:include href="xml/e-category-completion.xml"/>
     <xi:include href="xml/e-cell-renderer-color.xml"/>
     <xi:include href="xml/e-contact-store.xml"/>
     <xi:include href="xml/e-data-server-ui-marshal.xml"/>

Modified: branches/camel-gobject/docs/reference/libedataserverui/libedataserverui-sections.txt
==============================================================================
--- branches/camel-gobject/docs/reference/libedataserverui/libedataserverui-sections.txt	(original)
+++ branches/camel-gobject/docs/reference/libedataserverui/libedataserverui-sections.txt	Thu Apr 16 01:23:17 2009
@@ -1,4 +1,22 @@
 <SECTION>
+<FILE>e-category-completion</FILE>
+<TITLE>ECategoryCompletion</TITLE>
+ECategoryCompletion
+e_category_completion_new
+<SUBSECTION Standard>
+E_TYPE_CATEGORY_COMPLETION
+E_CATEGORY_COMPLETION
+E_CATEGORY_COMPLETION_CLASS
+E_IS_CATEGORY_COMPLETION
+E_IS_CATEGORY_COMPLETION_CLASS
+E_CATEGORY_COMPLETION_GET_CLASS
+ECategoryCompletionClass
+<SUBSECTION Private>
+ECategoryCompletionPrivate
+e_category_completion_get_type
+</SECTION>
+
+<SECTION>
 <FILE>e-cell-renderer-color</FILE>
 <TITLE>ECellRendererColor</TITLE>
 ECellRendererColor

Modified: branches/camel-gobject/libebackend/e-file-cache.c
==============================================================================
--- branches/camel-gobject/libebackend/e-file-cache.c	(original)
+++ branches/camel-gobject/libebackend/e-file-cache.c	Thu Apr 16 01:23:17 2009
@@ -263,10 +263,15 @@
 {
 	EFileCachePrivate *priv;
 	GSList *keys = NULL;
+	gboolean iFroze;
 
 	g_return_val_if_fail (E_IS_FILE_CACHE (cache), FALSE);
 
 	priv = cache->priv;
+	iFroze = !priv->frozen;
+
+	if (iFroze)
+		e_file_cache_freeze_changes (cache);
 
 	e_xmlhash_foreach_key (priv->xml_hash, (EXmlHashFunc) add_key_to_slist, &keys);
 	while (keys != NULL) {
@@ -274,6 +279,9 @@
 		keys = g_slist_remove (keys, keys->data);
 	}
 
+	if (iFroze)
+		e_file_cache_thaw_changes (cache);
+
 	return TRUE;
 }
 

Modified: branches/camel-gobject/libedataserver/e-account.c
==============================================================================
--- branches/camel-gobject/libedataserver/e-account.c	(original)
+++ branches/camel-gobject/libedataserver/e-account.c	Thu Apr 16 01:23:17 2009
@@ -361,7 +361,7 @@
 			changed |= xml_set_prop (node, "uid", &id->sig_uid);
 			if (!id->sig_uid) {
 
-				/* WTF is this shit doing here?  Migrate is supposed to "handle this" */
+				/* XXX Migrate is supposed to "handle this" */
 
 				/* set a fake sig uid so the migrate code can handle this */
 				gboolean autogen = FALSE;

Modified: branches/camel-gobject/libedataserver/e-iconv.c
==============================================================================
--- branches/camel-gobject/libedataserver/e-iconv.c	(original)
+++ branches/camel-gobject/libedataserver/e-iconv.c	Thu Apr 16 01:23:17 2009
@@ -190,7 +190,6 @@
 }
 
 
-/* fucking glib... */
 static const char *
 e_strdown (char *str)
 {

Modified: branches/camel-gobject/libedataserver/e-proxy.c
==============================================================================
--- branches/camel-gobject/libedataserver/e-proxy.c	(original)
+++ branches/camel-gobject/libedataserver/e-proxy.c	Thu Apr 16 01:23:17 2009
@@ -48,27 +48,55 @@
 /* Debug */
 #define d(x)
 
+enum ProxyType {
+	PROXY_TYPE_SYSTEM = 0,
+	PROXY_TYPE_NO_PROXY,
+	PROXY_TYPE_MANUAL,
+	PROXY_TYPE_AUTO_URL /* no auto-proxy at the moment */
+};
+
 /* GConf paths and keys */
-#define PATH_GCONF_NETWORK_CONFIG "/apps/evolution/shell/network_config"
-#define KEY_GCONF_HTTP_PROXY_PORT (PATH_GCONF_NETWORK_CONFIG "/" "http_port")
-#define KEY_GCONF_HTTP_PROXY_HOST (PATH_GCONF_NETWORK_CONFIG "/" "http_host")
-#define KEY_GCONF_HTTPS_PROXY_PORT (PATH_GCONF_NETWORK_CONFIG "/" "secure_port")
-#define KEY_GCONF_HTTPS_PROXY_HOST (PATH_GCONF_NETWORK_CONFIG "/" "secure_host")
-#define KEY_GCONF_SOCKS_PROXY_PORT (PATH_GCONF_NETWORK_CONFIG "/" "socks_port")
-#define KEY_GCONF_SOCKS_PROXY_HOST (PATH_GCONF_NETWORK_CONFIG "/" "socks_host")
-#define KEY_GCONF_USE_HTTP_PROXY (PATH_GCONF_NETWORK_CONFIG "/" "use_http_proxy")
-#define KEY_GCONF_HTTP_AUTH_USER (PATH_GCONF_NETWORK_CONFIG "/" "authentication_user")
-#define KEY_GCONF_HTTP_AUTH_PW   (PATH_GCONF_NETWORK_CONFIG "/" "authentication_password")
-#define KEY_GCONF_HTTP_USE_AUTH (PATH_GCONF_NETWORK_CONFIG "/" "use_authentication")
+#define PATH_GCONF_EVO_NETWORK_CONFIG "/apps/evolution/shell/network_config"
+#define KEY_GCONF_EVO_PROXY_TYPE       PATH_GCONF_EVO_NETWORK_CONFIG "/proxy_type"
+
+#define KEY_GCONF_EVO_USE_HTTP_PROXY    PATH_GCONF_EVO_NETWORK_CONFIG "/use_http_proxy"
+#define KEY_GCONF_EVO_HTTP_HOST         PATH_GCONF_EVO_NETWORK_CONFIG "/http_host"
+#define KEY_GCONF_EVO_HTTP_PORT         PATH_GCONF_EVO_NETWORK_CONFIG "/http_port"
+#define KEY_GCONF_EVO_HTTP_USE_AUTH     PATH_GCONF_EVO_NETWORK_CONFIG "/use_authentication"
+#define KEY_GCONF_EVO_HTTP_AUTH_USER    PATH_GCONF_EVO_NETWORK_CONFIG "/authentication_user"
+#define KEY_GCONF_EVO_HTTP_AUTH_PWD     PATH_GCONF_EVO_NETWORK_CONFIG "/authentication_password"
+#define KEY_GCONF_EVO_HTTP_IGNORE_HOSTS PATH_GCONF_EVO_NETWORK_CONFIG "/ignore_hosts"
+#define KEY_GCONF_EVO_HTTPS_HOST        PATH_GCONF_EVO_NETWORK_CONFIG "/secure_host"
+#define KEY_GCONF_EVO_HTTPS_PORT        PATH_GCONF_EVO_NETWORK_CONFIG "/secure_port"
+#define KEY_GCONF_EVO_SOCKS_HOST        PATH_GCONF_EVO_NETWORK_CONFIG "/socks_host"
+#define KEY_GCONF_EVO_SOCKS_PORT        PATH_GCONF_EVO_NETWORK_CONFIG "/socks_port"
+#define KEY_GCONF_EVO_AUTOCONFIG_URL    PATH_GCONF_EVO_NETWORK_CONFIG "/autoconfig_url"
+
+#define PATH_GCONF_SYS_PROXY "/system/proxy"
+#define PATH_GCONF_SYS_HTTP_PROXY "/system/http_proxy"
+
+#define KEY_GCONF_SYS_USE_HTTP_PROXY    PATH_GCONF_SYS_HTTP_PROXY "/use_http_proxy"
+#define KEY_GCONF_SYS_HTTP_HOST         PATH_GCONF_SYS_HTTP_PROXY "/host"
+#define KEY_GCONF_SYS_HTTP_PORT         PATH_GCONF_SYS_HTTP_PROXY "/port"
+#define KEY_GCONF_SYS_HTTP_USE_AUTH     PATH_GCONF_SYS_HTTP_PROXY "/use_authentication"
+#define KEY_GCONF_SYS_HTTP_AUTH_USER    PATH_GCONF_SYS_HTTP_PROXY "/authentication_user"
+#define KEY_GCONF_SYS_HTTP_AUTH_PWD     PATH_GCONF_SYS_HTTP_PROXY "/authentication_password"
+#define KEY_GCONF_SYS_HTTP_IGNORE_HOSTS PATH_GCONF_SYS_HTTP_PROXY "/ignore_hosts"
+#define KEY_GCONF_SYS_HTTPS_HOST        PATH_GCONF_SYS_PROXY "/secure_host"
+#define KEY_GCONF_SYS_HTTPS_PORT        PATH_GCONF_SYS_PROXY "/secure_port"
+#define KEY_GCONF_SYS_SOCKS_HOST        PATH_GCONF_SYS_PROXY "/socks_host"
+#define KEY_GCONF_SYS_SOCKS_PORT        PATH_GCONF_SYS_PROXY "/socks_port"
+#define KEY_GCONF_SYS_AUTOCONFIG_URL    PATH_GCONF_SYS_PROXY "/autoconfig_url"
 
-#define KEY_GCONF_HTTP_PROXY_IGNORE_HOSTS (PATH_GCONF_NETWORK_CONFIG "/" "ignore_hosts")
+#define RIGHT_KEY(sufix) (priv->type == PROXY_TYPE_SYSTEM ? KEY_GCONF_SYS_ ## sufix : KEY_GCONF_EVO_ ## sufix)
 
 struct _EProxyPrivate {
-	SoupURI* uri;
-	guint notify_id; 	/* conxn id of gconf_client_notify_add  */
+	SoupURI *uri_http, *uri_https;
+	guint notify_id_evo, notify_id_sys, notify_id_sys_http; /* conxn id of gconf_client_notify_add  */
 	GSList* ign_hosts;	/* List of hostnames. (Strings)		*/
 	GSList* ign_addrs;	/* List of hostaddrs. (ProxyHostAddrs)	*/
-	gboolean use_proxy;	/* Is system-proxy enabled? */
+	gboolean use_proxy;	/* Is our-proxy enabled? */
+	enum ProxyType type;
 };
 
 /* Enum definition is copied from gnome-vfs/modules/http-proxy.c */
@@ -158,9 +186,13 @@
 	pxy->priv = priv;
 	priv->ign_hosts = NULL;
 	priv->ign_addrs = NULL;
-	priv->uri = NULL;
-	priv->notify_id = 0;
+	priv->uri_http = NULL;
+	priv->uri_https = NULL;
+	priv->notify_id_evo = 0;
+	priv->notify_id_sys = 0;
+	priv->notify_id_sys_http = 0;
 	priv->use_proxy = FALSE;
+	priv->type = PROXY_TYPE_SYSTEM;
 }
 
 static void
@@ -178,25 +210,33 @@
 		GConfClient* client = NULL;
 
 		if ((client = gconf_client_get_default ())) {
-			if (priv->notify_id > 0)
-				gconf_client_notify_remove (client, priv->notify_id);
+			if (priv->notify_id_evo > 0)
+				gconf_client_notify_remove (client, priv->notify_id_evo);
+			if (priv->notify_id_sys > 0)
+				gconf_client_notify_remove (client, priv->notify_id_sys);
+			if (priv->notify_id_sys_http > 0)
+				gconf_client_notify_remove (client, priv->notify_id_sys_http);
 			g_object_unref (client);
 		}
 
-		if (priv->uri)
-			soup_uri_free (priv->uri);
+		if (priv->uri_http)
+			soup_uri_free (priv->uri_http);
+		if (priv->uri_https)
+			soup_uri_free (priv->uri_https);
 
 		if (priv->ign_hosts) {
-			g_slist_foreach (priv->ign_hosts, (GFunc) ep_free_proxy_host_addr, NULL);
+			g_slist_foreach (priv->ign_hosts, (GFunc) g_free, NULL);
 			g_slist_free (priv->ign_hosts);
 		}
 
 		if (priv->ign_addrs) {
-			g_slist_foreach (priv->ign_addrs, (GFunc) g_free, NULL);
+			g_slist_foreach (priv->ign_addrs, (GFunc) ep_free_proxy_host_addr, NULL);
 			g_slist_free (priv->ign_addrs);
 		}
 		
-		priv->notify_id = 0;
+		priv->notify_id_evo = 0;
+		priv->notify_id_sys = 0;
+		priv->notify_id_sys_http = 0;
 		
 		g_free (priv);
 		priv = NULL;
@@ -226,7 +266,39 @@
 }
 
 static gboolean
-ep_need_proxy (EProxy* proxy, const char* host)
+ep_is_in_ignored (EProxy *proxy, const char *host)
+{
+	EProxyPrivate *priv;
+	GSList* l;
+	gchar *hn;
+
+	g_return_val_if_fail (proxy != NULL, FALSE);
+	g_return_val_if_fail (host != NULL, FALSE);
+
+	priv = proxy->priv;
+	if (!priv->ign_hosts)
+		return FALSE;
+
+	hn = g_ascii_strdown (host, -1);
+		
+	for (l = priv->ign_hosts; l; l = l->next) {
+		if (*((gchar *)l->data) == '*') {
+			if (g_str_has_suffix (hn, ((gchar *)l->data)+1)) {
+				g_free (hn);
+				return TRUE;
+			}
+		} else if (strcmp (hn, l->data) == 0) {
+				g_free (hn);
+				return TRUE;
+		}
+	}
+	g_free (hn);
+
+	return FALSE;
+}
+
+static gboolean
+ep_need_proxy_http (EProxy* proxy, const char* host)
 {
 	SoupAddress *addr = NULL;
 	EProxyPrivate *priv = proxy->priv;
@@ -234,6 +306,10 @@
 	GSList *l;
 	guint status;
 
+	/* check for ignored first */
+	if (ep_is_in_ignored (proxy, host))
+		return FALSE;
+
 	addr = soup_address_new (host, 0);
 	status = soup_address_resolve_sync (addr, NULL);
 	if (status == SOUP_STATUS_OK) {
@@ -296,29 +372,20 @@
 				}
 			}
 		}
-	} else {
-		GSList* l;
-		gchar* hn = g_ascii_strdown (host, -1);
-		
-		for (l = priv->ign_hosts; l; l = l->next) {
-			if (*((gchar *)l->data) == '*') {
-				if (g_str_has_suffix (hn, ((gchar *)l->data)+1)) {
-					g_free (hn);
-					return FALSE;
-				}
-			} else if (strcmp (hn, l->data) == 0) {
-					g_free (hn);
-					return FALSE;
-			}
-		}
-		g_free (hn);
 	}
-
+	
 	d(g_print ("%s needs a proxy to connect to internet\n", host));
 	return TRUE;
 }
 
 static gboolean
+ep_need_proxy_https (EProxy* proxy, const char* host)
+{
+	/* Can we share ignore list from HTTP at all? */
+	return !ep_is_in_ignored (proxy, host);
+}
+
+static gboolean
 ep_manipulate_ipv4 (ProxyHostAddr *host_addr, 
 		    struct in_addr *addr_in, 
 		    gchar* netmask)
@@ -475,112 +542,169 @@
 	g_object_unref (addr);
 }
 
+static gboolean
+ep_change_uri (SoupURI **soup_uri, const char *uri)
+{
+	gboolean changed = FALSE;
+
+	g_return_val_if_fail (soup_uri != NULL, FALSE);
+
+	if (!uri || !*uri) {
+		if (*soup_uri) {
+			soup_uri_free (*soup_uri);
+			*soup_uri = NULL;
+			changed = TRUE;
+		}			
+	} else if (*soup_uri) {
+		char *old = soup_uri_to_string (*soup_uri, FALSE);
+
+		changed = old && uri && g_ascii_strcasecmp (old, uri) != 0;
+		if (changed) {
+			soup_uri_free (*soup_uri);
+			*soup_uri = soup_uri_new (uri);
+		}
+
+		g_free (old);
+	} else {
+		*soup_uri = soup_uri_new (uri);
+		changed = TRUE;
+	}
+
+	return changed;
+}
+
 static void
 ep_set_proxy (GConfClient *client, 
 	      gpointer user_data, 
-	      gboolean regen_ign_host_list,
-	      gboolean set_auth)
+	      gboolean regen_ign_host_list)
 {
-	char *proxy_server = NULL, *proxy_user = NULL, *proxy_pw = NULL, *uri = NULL;
-	gboolean use_auth;
-	int proxy_port;
+	char *proxy_server, *uri_http = NULL, *uri_https = NULL;
+	int proxy_port, old_type;
 	EProxy* proxy = (EProxy *)user_data;
 	EProxyPrivate* priv = proxy->priv;
 	GSList *ignore;
+	gboolean changed = FALSE;
 
-	priv->use_proxy = gconf_client_get_bool (client, KEY_GCONF_USE_HTTP_PROXY, NULL);
-	if (priv->use_proxy == FALSE) {
-		if (priv->uri) {
-			soup_uri_free (priv->uri);
-			priv->uri = NULL;
-		}
+	old_type = priv->type;
+	priv->type = gconf_client_get_int (client, KEY_GCONF_EVO_PROXY_TYPE, NULL);
+	if (priv->type < PROXY_TYPE_SYSTEM || priv->type > PROXY_TYPE_AUTO_URL)
+		priv->type = PROXY_TYPE_SYSTEM;
+	changed = priv->type != old_type;
+
+	priv->use_proxy = gconf_client_get_bool (client, RIGHT_KEY (USE_HTTP_PROXY), NULL);
+	if (!priv->use_proxy || priv->type == PROXY_TYPE_NO_PROXY) {
+		changed = ep_change_uri (&priv->uri_http, NULL) || changed;
+		changed = ep_change_uri (&priv->uri_https, NULL) || changed;
 		goto emit_signal;
 	}
-	
-	proxy_server = gconf_client_get_string (client, KEY_GCONF_HTTP_PROXY_HOST, NULL);
-	proxy_port = gconf_client_get_int (client, KEY_GCONF_HTTP_PROXY_PORT, NULL);
-	uri = g_strdup_printf ("http://%s:%d";, proxy_server, proxy_port);
-	d(g_print ("ep_set_proxy: uri: %s\n", uri));
 
-	if (regen_ign_host_list) {		
+	proxy_server = gconf_client_get_string (client, RIGHT_KEY (HTTP_HOST), NULL);
+	proxy_port = gconf_client_get_int (client, RIGHT_KEY (HTTP_PORT), NULL);
+	uri_http = g_strdup_printf ("http://%s:%d";, proxy_server, proxy_port);
+	g_free (proxy_server);
+	d(g_print ("ep_set_proxy: uri_http: %s\n", uri_http));
+
+	proxy_server = gconf_client_get_string (client, RIGHT_KEY (HTTPS_HOST), NULL);
+	proxy_port = gconf_client_get_int (client, RIGHT_KEY (HTTPS_PORT), NULL);
+	uri_https = g_strdup_printf ("https://%s:%d";, proxy_server, proxy_port);
+	g_free (proxy_server);
+	d(g_print ("ep_set_proxy: uri_http: %s\n", uri_http));
+
+	if (regen_ign_host_list) {
 		if (priv->ign_hosts) {
 			g_slist_foreach (priv->ign_hosts, (GFunc) g_free, NULL);
 			g_slist_free (priv->ign_hosts);
 			priv->ign_hosts = NULL;
 		}
-		
+
 		if (priv->ign_addrs) {
-			g_slist_foreach (priv->ign_addrs, (GFunc) g_free, NULL);
+			g_slist_foreach (priv->ign_addrs, (GFunc) ep_free_proxy_host_addr, NULL);
 			g_slist_free (priv->ign_addrs);
 			priv->ign_addrs = NULL;
 		}
 
-		ignore = gconf_client_get_list (client, KEY_GCONF_HTTP_PROXY_IGNORE_HOSTS, 
-						GCONF_VALUE_STRING, NULL);
+		ignore = gconf_client_get_list (client, RIGHT_KEY (HTTP_IGNORE_HOSTS), GCONF_VALUE_STRING, NULL);
 		if (ignore) {
 			g_slist_foreach (ignore, (GFunc) ep_parse_ignore_host, proxy);
-			g_slist_foreach (ignore, (GFunc) g_free, NULL);	
+			g_slist_foreach (ignore, (GFunc) g_free, NULL);
 			g_slist_free (ignore);
 		}
-	} else if (set_auth) {
-	
-		use_auth = gconf_client_get_bool (client, KEY_GCONF_HTTP_USE_AUTH, NULL);
-		if (use_auth == TRUE) {
-			proxy_user = gconf_client_get_string (client, KEY_GCONF_HTTP_AUTH_USER, NULL);
-			proxy_pw = gconf_client_get_string (client, KEY_GCONF_HTTP_AUTH_PW, NULL);
-		
-			if (uri)
-				g_free (uri);
-
-			uri = g_strdup_printf ("http://%s:%s %s:%d", proxy_user, proxy_pw, proxy_server, proxy_port);
-		} 
 	}
 
-	if (priv->uri) {
-		soup_uri_free (priv->uri);
-		priv->uri = NULL;
+	if (gconf_client_get_bool (client, RIGHT_KEY (HTTP_USE_AUTH), NULL)) {
+		char *proxy_user, *proxy_pw, *tmp;
+
+		proxy_user = gconf_client_get_string (client, RIGHT_KEY (HTTP_AUTH_USER), NULL);
+		proxy_pw = gconf_client_get_string (client, RIGHT_KEY (HTTP_AUTH_PWD), NULL);
+
+		tmp = uri_http;
+
+		uri_http = g_strdup_printf ("http://%s:%s %s", proxy_user, proxy_pw, tmp + strlen ("http://";));
+
+		g_free (proxy_user);
+		g_free (proxy_pw);
+		g_free (tmp);
 	}
-	
-	if (uri)
-		priv->uri = soup_uri_new (uri);
-	d(g_print ("system-proxy: uri: %s\n", uri));
 
- emit_signal:	
-	g_signal_emit (proxy, signals[CHANGED], 0);
+	changed = ep_change_uri (&priv->uri_http, uri_http) || changed;
+	changed = ep_change_uri (&priv->uri_https, uri_https) || changed;
+	d(g_print ("system-proxy: uri_http: %s; uri_https: %s\n", uri_http ? uri_http : "[null]", uri_https ? uri_https : "[null]"));
 
-	g_free (uri);
+ emit_signal:
+	if (changed)
+		g_signal_emit (proxy, signals[CHANGED], 0);
+
+	g_free (uri_http);
+	g_free (uri_https);
 
 	return;
 }
 
 static void
-ep_setting_changed (GConfClient *client, guint32 cnxn_id,
-		       GConfEntry *entry, gpointer user_data)
+ep_setting_changed (GConfClient *client, guint32 cnxn_id, GConfEntry *entry, gpointer user_data)
 {
-    const char *key;
-    EProxy* proxy = (EProxy *)user_data;
+	const char *key;
+	EProxy* proxy = (EProxy *)user_data;
+	EProxyPrivate *priv;
 
-    if (!proxy || !proxy->priv)
-	    return;
+	if (!proxy || !proxy->priv)
+		return;
 
-    key = gconf_entry_get_key(entry);
-
-    if (strcmp(key, KEY_GCONF_USE_HTTP_PROXY) == 0
-        || strcmp(key, KEY_GCONF_HTTP_PROXY_IGNORE_HOSTS) == 0
-        || strcmp(key, KEY_GCONF_HTTP_PROXY_HOST) == 0
-        || strcmp(key, KEY_GCONF_HTTP_PROXY_PORT) == 0) {
-	    gboolean regen_ign_host_list = FALSE;
-
-	    if (strcmp(key, KEY_GCONF_HTTP_PROXY_IGNORE_HOSTS) == 0)
-		    regen_ign_host_list = TRUE;
-	    ep_set_proxy (client, user_data, regen_ign_host_list, FALSE);
-	    d(g_print ("e-proxy.c:ep_settings_changed: proxy settings changed\n"));
-    } else if (strcmp(key, KEY_GCONF_HTTP_AUTH_USER) == 0
-               || strcmp(key, KEY_GCONF_HTTP_AUTH_PW) == 0
-               || strcmp(key, KEY_GCONF_HTTP_USE_AUTH) == 0) {
-	    ep_set_proxy (client, user_data, FALSE, TRUE);
-	    d(g_print ("e-proxy.c:ep_settings_changed: auth settings changed\n"));	    
-    }
+	priv = proxy->priv;
+	key = gconf_entry_get_key (entry);
+
+	if (g_str_equal (key, KEY_GCONF_EVO_PROXY_TYPE)) {
+		ep_set_proxy (client, user_data, FALSE);
+		d(g_print ("e-proxy.c:ep_settings_changed: proxy type changed\n"));
+	} else if (g_str_equal (key, RIGHT_KEY (USE_HTTP_PROXY)) ||
+		   g_str_equal (key, RIGHT_KEY (HTTP_IGNORE_HOSTS)) ||
+		   g_str_equal (key, RIGHT_KEY (HTTP_HOST)) ||
+		   g_str_equal (key, RIGHT_KEY (HTTP_PORT))) {
+		gboolean regen_ign_host_list = FALSE;
+
+		if (g_str_equal (key, RIGHT_KEY (HTTP_IGNORE_HOSTS)))
+			regen_ign_host_list = TRUE;
+
+		ep_set_proxy (client, user_data, regen_ign_host_list);
+		d(g_print ("e-proxy.c:ep_settings_changed: proxy settings changed\n"));
+	} else if (g_str_equal (key, RIGHT_KEY (HTTP_AUTH_USER)) ||
+		   g_str_equal (key, RIGHT_KEY (HTTP_AUTH_PWD)) ||
+		   g_str_equal (key, RIGHT_KEY (HTTP_USE_AUTH))) {
+
+		ep_set_proxy (client, user_data, FALSE);
+		d(g_print ("e-proxy.c:ep_settings_changed: auth settings changed\n"));
+	} else if (g_str_equal (key, RIGHT_KEY (HTTPS_HOST)) ||
+		   g_str_equal (key, RIGHT_KEY (HTTPS_PORT))) {
+
+		ep_set_proxy (client, user_data, FALSE);
+		d(g_print ("e-proxy.c:ep_settings_changed: https\n"));
+	} else if (g_str_equal (key, RIGHT_KEY (SOCKS_HOST)) ||
+		   g_str_equal (key, RIGHT_KEY (SOCKS_PORT)) ||
+		   g_str_equal (key, RIGHT_KEY (AUTOCONFIG_URL))) {
+
+		/* ep_set_proxy (client, user_data, FALSE); */
+		d(g_print ("e-proxy.c:ep_settings_changed: socks/autoconf-url changed\n"));
+	}
 }
 
 EProxy* 
@@ -608,27 +732,45 @@
 	if (!proxy || !proxy->priv)
 		return;
 
-	/* Listen to the changes in the evolution-shell path */
-	gconf_client_add_dir (client, PATH_GCONF_NETWORK_CONFIG,
-			      GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
-
-	if (proxy->priv->notify_id == 0)
-		proxy->priv->notify_id = gconf_client_notify_add (client, PATH_GCONF_NETWORK_CONFIG,
-								  ep_setting_changed, (gpointer)proxy, 
-								  NULL, NULL);
-	
-	ep_set_proxy (client, proxy, TRUE, TRUE);
+	if (proxy->priv->notify_id_evo == 0) {
+		/* Listen to the changes in the evolution-shell path */
+		gconf_client_add_dir (client, PATH_GCONF_EVO_NETWORK_CONFIG, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+		/* and system proxy setup changes */
+		gconf_client_add_dir (client, PATH_GCONF_SYS_PROXY, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+		gconf_client_add_dir (client, PATH_GCONF_SYS_HTTP_PROXY, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+
+		proxy->priv->notify_id_evo = gconf_client_notify_add (client, PATH_GCONF_EVO_NETWORK_CONFIG,
+								      ep_setting_changed, (gpointer)proxy, 
+								      NULL, NULL);
+		proxy->priv->notify_id_sys = gconf_client_notify_add (client, PATH_GCONF_SYS_PROXY,
+								      ep_setting_changed, (gpointer)proxy, 
+								      NULL, NULL);
+		proxy->priv->notify_id_sys_http = gconf_client_notify_add (client, PATH_GCONF_SYS_HTTP_PROXY,
+								      ep_setting_changed, (gpointer)proxy, 
+								      NULL, NULL);
+	}
+
+	ep_set_proxy (client, proxy, TRUE);
 
 	g_object_unref (client);
 }
 
 SoupURI*
-e_proxy_peek_uri (EProxy* proxy)
+e_proxy_peek_uri_for (EProxy* proxy, const char *uri)
 {
-	if (!proxy || !proxy->priv)
+	SoupURI *suri;
+
+	if (!proxy || !proxy->priv || !uri || !*uri)
 		return NULL;
-	
-	return proxy->priv->uri;
+
+	suri = soup_uri_new (uri);
+	g_return_val_if_fail (suri != NULL, NULL);
+
+	if (suri->scheme == SOUP_URI_SCHEME_HTTPS) {
+		return proxy->priv->uri_https;
+	}
+
+	return proxy->priv->uri_http;
 }
 
 gboolean
@@ -640,16 +782,22 @@
 	if (!uri || !proxy || !proxy->priv)
 		return ret;
 
-	if (!proxy->priv->use_proxy) {
+	if (!proxy->priv->use_proxy || proxy->priv->type == PROXY_TYPE_NO_PROXY) {
 		d(g_print ("[%s] don't need a proxy to connect to internet\n", uri));
 		return ret;
 	}
 
 	srv_uri = soup_uri_new (uri);
-	
-	ret = ep_need_proxy (proxy, srv_uri->host);
 
-	soup_uri_free (srv_uri);
+	if (srv_uri) {
+		if (srv_uri->scheme == SOUP_URI_SCHEME_HTTPS) {
+			ret = ep_need_proxy_https (proxy, srv_uri->host);
+		} else {
+			ret = ep_need_proxy_http (proxy, srv_uri->host);
+		}
+
+		soup_uri_free (srv_uri);
+	}
 
 	return ret;
 }

Modified: branches/camel-gobject/libedataserver/e-proxy.h
==============================================================================
--- branches/camel-gobject/libedataserver/e-proxy.h	(original)
+++ branches/camel-gobject/libedataserver/e-proxy.h	Thu Apr 16 01:23:17 2009
@@ -51,7 +51,7 @@
 };
 
 EProxy* e_proxy_new (void);
-SoupURI* e_proxy_peek_uri (EProxy* proxy);
+SoupURI* e_proxy_peek_uri_for (EProxy* proxy, const char *uri);
 void e_proxy_setup_proxy (EProxy* proxy);
 GType e_proxy_get_type (void);
 gboolean e_proxy_require_proxy_for_uri (EProxy *proxy, 

Modified: branches/camel-gobject/libedataserver/e-sexp.c
==============================================================================
--- branches/camel-gobject/libedataserver/e-sexp.c	(original)
+++ branches/camel-gobject/libedataserver/e-sexp.c	Thu Apr 16 01:23:17 2009
@@ -214,27 +214,26 @@
 
 /* implementations for the builtin functions */
 
-/* can you tell, i dont like glib? */
 /* we can only itereate a hashtable from a called function */
-struct _glib_sux_donkeys {
+struct IterData {
 	int count;
 	GPtrArray *uids;
 };
 
 /* ok, store any values that are in all sets */
 static void
-g_lib_sux_htand(char *key, int value, struct _glib_sux_donkeys *fuckup)
+htand(char *key, int value, struct IterData *iter_data)
 {
-	if (value == fuckup->count) {
-		g_ptr_array_add(fuckup->uids, key);
+	if (value == iter_data->count) {
+		g_ptr_array_add(iter_data->uids, key);
 	}
 }
 
 /* or, store all unique values */
 static void
-g_lib_sux_htor(char *key, int value, struct _glib_sux_donkeys *fuckup)
+htor(char *key, int value, struct IterData *iter_data)
 {
-	g_ptr_array_add(fuckup->uids, key);
+	g_ptr_array_add(iter_data->uids, key);
 }
 
 static ESExpResult *
@@ -242,7 +241,7 @@
 {
 	struct _ESExpResult *r, *r1;
 	GHashTable *ht = g_hash_table_new(g_str_hash, g_str_equal);
-	struct _glib_sux_donkeys lambdafoo;
+	struct IterData lambdafoo;
 	int type=-1;
 	int bool = TRUE;
 	int i;
@@ -286,7 +285,7 @@
 	if (type == ESEXP_RES_ARRAY_PTR) {
 		lambdafoo.count = argc;
 		lambdafoo.uids = g_ptr_array_new();
-		g_hash_table_foreach(ht, (GHFunc)g_lib_sux_htand, &lambdafoo);
+		g_hash_table_foreach(ht, (GHFunc)htand, &lambdafoo);
 		r->type = ESEXP_RES_ARRAY_PTR;
 		r->value.ptrarray = lambdafoo.uids;
 	} else if (type == ESEXP_RES_BOOL) {
@@ -305,7 +304,7 @@
 {
 	struct _ESExpResult *r, *r1;
 	GHashTable *ht = g_hash_table_new(g_str_hash, g_str_equal);
-	struct _glib_sux_donkeys lambdafoo;
+	struct IterData lambdafoo;
 	int type = -1;
 	int bool = FALSE;
 	int i;
@@ -345,7 +344,7 @@
 	if (type == ESEXP_RES_ARRAY_PTR) {
 		lambdafoo.count = argc;
 		lambdafoo.uids = g_ptr_array_new();
-		g_hash_table_foreach(ht, (GHFunc)g_lib_sux_htor, &lambdafoo);
+		g_hash_table_foreach(ht, (GHFunc)htor, &lambdafoo);
 		r->type = ESEXP_RES_ARRAY_PTR;
 		r->value.ptrarray = lambdafoo.uids;
 	} else if (type == ESEXP_RES_BOOL) {

Modified: branches/camel-gobject/libedataserver/e-source.c
==============================================================================
--- branches/camel-gobject/libedataserver/e-source.c	(original)
+++ branches/camel-gobject/libedataserver/e-source.c	Thu Apr 16 01:23:17 2009
@@ -810,6 +810,8 @@
 	g_return_val_if_fail (E_IS_SOURCE (a), FALSE); 
 	g_return_val_if_fail (E_IS_SOURCE (b), FALSE); 
 
+	#define ONLY_ONE_NULL(aa, bb) (((aa) == NULL && (bb) != NULL) || ((aa) != NULL && (bb) == NULL))
+
 	/* Compare source stuff */
 	if (a->priv->uid 
 	 && b->priv->uid 
@@ -831,9 +833,10 @@
 	 && g_ascii_strcasecmp (a->priv->absolute_uri, b->priv->absolute_uri))
 		return FALSE; 
 
-	if (a->priv->color_spec 
+	if ((a->priv->color_spec 
 	 && b->priv->color_spec 
-	 && g_ascii_strcasecmp (a->priv->color_spec, b->priv->color_spec))
+	 && g_ascii_strcasecmp (a->priv->color_spec, b->priv->color_spec)) ||
+	 (ONLY_ONE_NULL (a->priv->color_spec, b->priv->color_spec)))
 		return FALSE; 
 
 	if (a->priv->readonly != b->priv->readonly)
@@ -842,6 +845,8 @@
 	if (!compare_str_hashes (a->priv->properties, b->priv->properties))
 		return FALSE; 
 
+	#undef ONLY_ONE_NULL
+
 	return TRUE; 
 }
 

Modified: branches/camel-gobject/libedataserverui/e-categories-dialog.c
==============================================================================
--- branches/camel-gobject/libedataserverui/e-categories-dialog.c	(original)
+++ branches/camel-gobject/libedataserverui/e-categories-dialog.c	Thu Apr 16 01:23:17 2009
@@ -472,6 +472,7 @@
 	GtkEntryCompletion *completion;
 	GtkTreeViewColumn *column;
 	GtkWidget *main_widget;
+	GtkWidget *content_area;
 	char *gladefile;
 
 	priv = g_new0 (ECategoriesDialogPrivate, 1);
@@ -490,8 +491,10 @@
 		return;
 	}
 
+	content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
 	main_widget = glade_xml_get_widget (priv->gui, "table-categories");
-	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), main_widget, TRUE, TRUE, 0);
+	gtk_box_pack_start (GTK_BOX (content_area), main_widget, TRUE, TRUE, 0);
 
 	priv->categories_entry = glade_xml_get_widget (priv->gui, "entry-categories");
 	priv->categories_list = glade_xml_get_widget (priv->gui, "categories-list");

Modified: branches/camel-gobject/libedataserverui/e-cell-renderer-color.c
==============================================================================
--- branches/camel-gobject/libedataserverui/e-cell-renderer-color.c	(original)
+++ branches/camel-gobject/libedataserverui/e-cell-renderer-color.c	Thu Apr 16 01:23:17 2009
@@ -57,20 +57,28 @@
 	gint color_height = 16;
 	gint calc_width;
 	gint calc_height;
+	gfloat xalign;
+	gfloat yalign;
+	guint xpad;
+	guint ypad;
+
+	g_object_get (
+		cell, "xalign", &xalign, "yalign", &yalign,
+		"xpad", &xpad, "ypad", &ypad, NULL);
 
-	calc_width  = (gint) cell->xpad * 2 + color_width;
-	calc_height = (gint) cell->ypad * 2 + color_height;
+	calc_width  = (gint) xpad * 2 + color_width;
+	calc_height = (gint) ypad * 2 + color_height;
 
 	if (cell_area && color_width > 0 && color_height > 0) {
 		if (x_offset) {
 			*x_offset = (((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ?
-					(1.0 - cell->xalign) : cell->xalign) *
+					(1.0 - xalign) : xalign) *
 					(cell_area->width - calc_width));
 			*x_offset = MAX (*x_offset, 0);
 		}
 
 		if (y_offset) {
-			*y_offset = (cell->yalign *
+			*y_offset =(yalign *
 				(cell_area->height - calc_height));
 			*y_offset = MAX (*y_offset, 0);
 		}
@@ -99,6 +107,8 @@
 	GdkRectangle pix_rect;
 	GdkRectangle draw_rect;
 	GdkGC *gc;
+	guint xpad;
+	guint ypad;
 
 	priv = E_CELL_RENDERER_COLOR_GET_PRIVATE (cell);
 
@@ -110,10 +120,12 @@
 		&pix_rect.x, &pix_rect.y,
 		&pix_rect.width, &pix_rect.height);
 
-	pix_rect.x += cell_area->x + cell->xpad;
-	pix_rect.y += cell_area->y + cell->ypad;
-	pix_rect.width  -= cell->xpad * 2;
-	pix_rect.height -= cell->ypad * 2;
+	g_object_get (cell, "xpad", &xpad, "ypad", &ypad, NULL);
+
+	pix_rect.x += cell_area->x + xpad;
+	pix_rect.y += cell_area->y + ypad;
+	pix_rect.width  -= xpad * 2;
+	pix_rect.height -= ypad * 2;
 
 	if (!gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect) ||
 	    !gdk_rectangle_intersect (expose_area, &draw_rect, &draw_rect))
@@ -218,7 +230,7 @@
 {
 	cellcolor->priv = E_CELL_RENDERER_COLOR_GET_PRIVATE (cellcolor);
 
-	GTK_CELL_RENDERER (cellcolor)->xpad = 4;
+	g_object_set (cellcolor, "xpad", 4, NULL);
 }
 
 GtkCellRenderer *

Modified: branches/camel-gobject/libedataserverui/e-contact-store.h
==============================================================================
--- branches/camel-gobject/libedataserverui/e-contact-store.h	(original)
+++ branches/camel-gobject/libedataserverui/e-contact-store.h	Thu Apr 16 01:23:17 2009
@@ -29,14 +29,26 @@
 #include <libebook/e-book-query.h>
 #include <libebook/e-book-types.h>
 
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_CONTACT_STORE \
+	(e_contact_store_get_type ())
+#define E_CONTACT_STORE(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_CONTACT_STORE, EContactStore))
+#define E_CONTACT_STORE_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_CONTACT_STORE, EContactStoreClass))
+#define E_IS_CONTACT_STORE(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_CONTACT_STORE))
+#define E_IS_CONTACT_STORE_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_CONTACT_STORE))
+#define E_CONTACT_STORE_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_CONTACT_STORE, EContactStoreClass))
 
-#define E_TYPE_CONTACT_STORE            (e_contact_store_get_type ())
-#define E_CONTACT_STORE(obj)	        (GTK_CHECK_CAST ((obj), E_TYPE_CONTACT_STORE, EContactStore))
-#define E_CONTACT_STORE_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_CONTACT_STORE, EContactStoreClass))
-#define E_IS_CONTACT_STORE(obj)         (GTK_CHECK_TYPE ((obj), E_TYPE_CONTACT_STORE))
-#define E_IS_CONTACT_STORE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_CONTACT_STORE))
-#define E_CONTACT_STORE_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), E_TYPE_CONTACT_STORE, EContactStoreClass))
+G_BEGIN_DECLS
 
 typedef struct _EContactStore       EContactStore;
 typedef struct _EContactStoreClass  EContactStoreClass;
@@ -55,7 +67,7 @@
 	GArray     *contact_sources;
 };
 
-GtkType        e_contact_store_get_type     (void);
+GType          e_contact_store_get_type     (void);
 EContactStore *e_contact_store_new          (void);
 
 EBook         *e_contact_store_get_book     (EContactStore *contact_store, GtkTreeIter *iter);

Modified: branches/camel-gobject/libedataserverui/e-destination-store.h
==============================================================================
--- branches/camel-gobject/libedataserverui/e-destination-store.h	(original)
+++ branches/camel-gobject/libedataserverui/e-destination-store.h	Thu Apr 16 01:23:17 2009
@@ -26,14 +26,26 @@
 #include <gtk/gtk.h>
 #include <libebook/e-destination.h>
 
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_DESTINATION_STORE \
+	(e_destination_store_get_type ())
+#define E_DESTINATION_STORE(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_DESTINATION_STORE, EDestinationStore))
+#define E_DESTINATION_STORE_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_DESTINATION_STORE, EDestinationStoreClass))
+#define E_IS_DESTINATION_STORE(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_DESTINATION_STORE))
+#define E_IS_DESTINATION_STORE_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_DESTINATION_STORE))
+#define E_DESTINATION_STORE_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_DESTINATION_STORE, EDestinationStoreClass))
 
-#define E_TYPE_DESTINATION_STORE            (e_destination_store_get_type ())
-#define E_DESTINATION_STORE(obj)	    (GTK_CHECK_CAST ((obj), E_TYPE_DESTINATION_STORE, EDestinationStore))
-#define E_DESTINATION_STORE_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_DESTINATION_STORE, EDestinationStoreClass))
-#define E_IS_DESTINATION_STORE(obj)         (GTK_CHECK_TYPE ((obj), E_TYPE_DESTINATION_STORE))
-#define E_IS_DESTINATION_STORE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_DESTINATION_STORE))
-#define E_DESTINATION_STORE_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), E_TYPE_DESTINATION_STORE, EDestinationStoreClass))
+G_BEGIN_DECLS
 
 typedef struct _EDestinationStore       EDestinationStore;
 typedef struct _EDestinationStoreClass  EDestinationStoreClass;
@@ -61,7 +73,7 @@
 }
 EDestinationStoreColumnType;
 
-GtkType            e_destination_store_get_type           (void);
+GType              e_destination_store_get_type           (void);
 EDestinationStore *e_destination_store_new                (void);
 
 EDestination      *e_destination_store_get_destination    (EDestinationStore *destination_store,

Modified: branches/camel-gobject/libedataserverui/e-name-selector-dialog.c
==============================================================================
--- branches/camel-gobject/libedataserverui/e-name-selector-dialog.c	(original)
+++ branches/camel-gobject/libedataserverui/e-name-selector-dialog.c	Thu Apr 16 01:23:17 2009
@@ -132,7 +132,9 @@
 	GtkCellRenderer   *cell_renderer;
 	GtkWidget         *widget;
 	GtkWidget         *container;
+	GtkWidget         *content_area;
 	GtkWidget	  *label;
+	GtkWidget         *parent;
 	GtkTreeSelection  *selection;
 	ESourceList       *source_list;
 	char              *gladefile;
@@ -168,9 +170,13 @@
 
 	/* Reparent it to inside ourselves */
 
+	content_area = gtk_dialog_get_content_area (
+		GTK_DIALOG (name_selector_dialog));
+
 	g_object_ref (widget);
-	gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
-	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (name_selector_dialog)->vbox), widget, TRUE, TRUE, 0);
+	parent = gtk_widget_get_parent (widget);
+	gtk_container_remove (GTK_CONTAINER (parent), widget);
+	gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0);
 	g_object_unref (widget);
 
 	/* Store pointers to relevant widgets */

Modified: branches/camel-gobject/libedataserverui/e-name-selector-dialog.h
==============================================================================
--- branches/camel-gobject/libedataserverui/e-name-selector-dialog.h	(original)
+++ branches/camel-gobject/libedataserverui/e-name-selector-dialog.h	Thu Apr 16 01:23:17 2009
@@ -30,14 +30,26 @@
 #include <libedataserverui/e-contact-store.h>
 #include <libedataserverui/e-name-selector-model.h>
 
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_NAME_SELECTOR_DIALOG \
+	(e_name_selector_dialog_get_type ())
+#define E_NAME_SELECTOR_DIALOG(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_NAME_SELECTOR_DIALOG, ENameSelectorDialog))
+#define E_NAME_SELECTOR_DIALOG_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_NAME_SELECTOR_DIALOG, ENameSelectorDialogClass))
+#define E_IS_NAME_SELECTOR_DIALOG(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	(obj, E_TYPE_NAME_SELECTOR_DIALOG))
+#define E_IS_NAME_SELECTOR_DIALOG_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_NAME_SELECTOR_DIALOG))
+#define E_NAME_SELECTOR_DIALOG_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_NAME_SELECTOR_DIALOG, ENameSelectorDialogClass))
 
-#define E_TYPE_NAME_SELECTOR_DIALOG            (e_name_selector_dialog_get_type ())
-#define E_NAME_SELECTOR_DIALOG(obj)            (GTK_CHECK_CAST ((obj), e_name_selector_dialog_get_type (), ENameSelectorDialog))
-#define E_NAME_SELECTOR_DIALOG_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), e_name_selector_dialog_get_type (), ENameSelectorDialogClass))
-#define E_IS_NAME_SELECTOR_DIALOG(obj)         (GTK_CHECK_TYPE (obj, e_name_selector_dialog_get_type ()))
-#define E_IS_NAME_SELECTOR_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), e_name_selector_dialog_get_type ()))
-#define E_NAME_SELECTOR_DIALOG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), E_NAME_SELECTOR_DIALOG_TYPE, ENameSelectorDialogClass))
+G_BEGIN_DECLS
 
 typedef struct _ENameSelectorDialog      ENameSelectorDialog;
 typedef struct _ENameSelectorDialogClass ENameSelectorDialogClass;

Modified: branches/camel-gobject/libedataserverui/e-name-selector-entry.h
==============================================================================
--- branches/camel-gobject/libedataserverui/e-name-selector-entry.h	(original)
+++ branches/camel-gobject/libedataserverui/e-name-selector-entry.h	Thu Apr 16 01:23:17 2009
@@ -30,19 +30,31 @@
 #include <libedataserverui/e-destination-store.h>
 #include <libedataserverui/e-tree-model-generator.h>
 
-G_BEGIN_DECLS
-
-#define E_TYPE_NAME_SELECTOR_ENTRY            (e_name_selector_entry_get_type ())
-#define E_NAME_SELECTOR_ENTRY(obj)            (GTK_CHECK_CAST ((obj), e_name_selector_entry_get_type (), ENameSelectorEntry))
-#define E_NAME_SELECTOR_ENTRY_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), e_name_selector_entry_get_type (), ENameSelectorEntryClass))
-#define E_IS_NAME_SELECTOR_ENTRY(obj)         (GTK_CHECK_TYPE (obj, e_name_selector_entry_get_type ()))
-#define E_IS_NAME_SELECTOR_ENTRY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), e_name_selector_entry_get_type ()))
-#define E_NAME_SELECTOR_ENTRY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), E_NAME_SELECTOR_ENTRY_TYPE, ENameSelectorEntryClass))
+/* Standard GObject macros */
+#define E_TYPE_NAME_SELECTOR_ENTRY \
+	(e_name_selector_entry_get_type ())
+#define E_NAME_SELECTOR_ENTRY(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_NAME_SELECTOR_ENTRY, ENameSelectorEntry))
+#define E_NAME_SELECTOR_ENTRY_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_NAME_SELECTOR_ENTRY, ENameSelectorEntryClass))
+#define E_IS_NAME_SELECTOR_ENTRY(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_NAME_SELECTOR_ENTRY))
+#define E_IS_NAME_SELECTOR_ENTRY_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_NAME_SELECTOR_ENTRY))
+#define E_NAME_SELECTOR_ENTRY_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_NAME_SELECTOR_ENTRY, ENameSelectorEntryClass))
 
 #define MINIMUM_QUERY_LENGTH "/apps/evolution/addressbook/completion/minimum_query_length"
 #define FORCE_SHOW_ADDRESS   "/apps/evolution/addressbook/completion/show_address"
 #define USER_QUERY_FIELDS "/apps/evolution/addressbook/completion/user_query_fields"
 
+G_BEGIN_DECLS
+
 typedef struct _ENameSelectorEntry      ENameSelectorEntry;
 typedef struct _ENameSelectorEntryClass ENameSelectorEntryClass;
 

Modified: branches/camel-gobject/libedataserverui/e-name-selector-list.c
==============================================================================
--- branches/camel-gobject/libedataserverui/e-name-selector-list.c	(original)
+++ branches/camel-gobject/libedataserverui/e-name-selector-list.c	Thu Apr 16 01:23:17 2009
@@ -71,10 +71,12 @@
 static void
 enl_popup_position (ENameSelectorList *list)
 {
+	GdkWindow *window;
 	int x,y;
 
 	enl_popup_size (list);
-	gdk_window_get_origin (((GtkWidget *)list)->window, &x, &y);
+	window = gtk_widget_get_window (GTK_WIDGET (list));
+	gdk_window_get_origin (window, &x, &y);
 	y = y +((GtkWidget *)list)->allocation.height;
 
 	gtk_window_move (list->popup, x, y);
@@ -83,17 +85,20 @@
 static void
 enl_popup_grab (ENameSelectorList *list)
 {
+	GdkWindow *window;
 	int len;
 
+	window = gtk_widget_get_window (GTK_WIDGET (list->popup));
+
 	gtk_grab_add (GTK_WIDGET (list->popup));
 
-	gdk_pointer_grab (((GtkWidget *)list->popup)->window, TRUE,
+	gdk_pointer_grab (window, TRUE,
                     	  GDK_BUTTON_PRESS_MASK |
                     	  GDK_BUTTON_RELEASE_MASK |
                     	  GDK_POINTER_MOTION_MASK,
                 	  NULL, NULL, GDK_CURRENT_TIME);
 
-    	gdk_keyboard_grab (((GtkWidget *)list->popup)->window, TRUE, GDK_CURRENT_TIME);
+    	gdk_keyboard_grab (window, TRUE, GDK_CURRENT_TIME);
 	gtk_widget_grab_focus ((GtkWidget *)list);
 
 	/* Build the listview from the model */
@@ -610,7 +615,9 @@
 					GTK_POLICY_AUTOMATIC);
 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
                                        	     GTK_SHADOW_NONE);
-	gtk_widget_set_size_request (GTK_SCROLLED_WINDOW (scroll)->vscrollbar, -1, 0);
+	gtk_widget_set_size_request (
+		gtk_scrolled_window_get_vscrollbar (
+		GTK_SCROLLED_WINDOW (scroll)), -1, 0);
 
 	list->popup =  GTK_WINDOW (gtk_window_new (GTK_WINDOW_POPUP));
  	gtk_window_set_resizable (GTK_WINDOW (list->popup), FALSE);

Modified: branches/camel-gobject/libedataserverui/e-name-selector-list.h
==============================================================================
--- branches/camel-gobject/libedataserverui/e-name-selector-list.h	(original)
+++ branches/camel-gobject/libedataserverui/e-name-selector-list.h	Thu Apr 16 01:23:17 2009
@@ -34,12 +34,24 @@
 
 G_BEGIN_DECLS
 
-#define E_TYPE_NAME_SELECTOR_LIST            (e_name_selector_list_get_type ())
-#define E_NAME_SELECTOR_LIST(obj)            (GTK_CHECK_CAST ((obj), e_name_selector_list_get_type (), ENameSelectorEntry))
-#define E_NAME_SELECTOR_LIST_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), e_name_selector_list_get_type (), ENameSelectorEntryClass))
-#define E_IS_NAME_SELECTOR_LIST(obj)         (GTK_CHECK_TYPE (obj, e_name_selector_list_get_type ()))
-#define E_IS_NAME_SELECTOR_LIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), e_name_selector_list_get_type ()))
-#define E_NAME_SELECTOR_LIST_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), E_NAME_SELECTOR_LIST_TYPE, ENameSelectorEntryClass))
+/* Standard GObject macros */
+#define E_TYPE_NAME_SELECTOR_LIST \
+	(e_name_selector_list_get_type ())
+#define E_NAME_SELECTOR_LIST(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), e_name_selector_list_get_type (), ENameSelectorEntry))
+#define E_NAME_SELECTOR_LIST_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), e_name_selector_list_get_type (), ENameSelectorEntryClass))
+#define E_IS_NAME_SELECTOR_LIST(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), e_name_selector_list_get_type ()))
+#define E_IS_NAME_SELECTOR_LIST_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), e_name_selector_list_get_type ()))
+#define E_NAME_SELECTOR_LIST_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_NAME_SELECTOR_LIST_TYPE, ENameSelectorEntryClass))
 
 typedef struct _ENameSelectorList      ENameSelectorList;
 typedef struct _ENameSelectorListClass ENameSelectorListClass;

Modified: branches/camel-gobject/libedataserverui/e-passwords.c
==============================================================================
--- branches/camel-gobject/libedataserverui/e-passwords.c	(original)
+++ branches/camel-gobject/libedataserverui/e-passwords.c	Thu Apr 16 01:23:17 2009
@@ -1103,6 +1103,8 @@
 {
 	GtkWidget *widget;
 	GtkWidget *container;
+	GtkWidget *action_area;
+	GtkWidget *content_area;
 	gint type = msg->flags & E_PASSWORDS_REMEMBER_MASK;
 	guint noreply = msg->noreply;
 	gboolean visible;
@@ -1124,13 +1126,14 @@
 	gtk_container_set_border_width (GTK_CONTAINER (widget), 12);
 	password_dialog = GTK_DIALOG (widget);
 
+	action_area = gtk_dialog_get_action_area (password_dialog);
+	content_area = gtk_dialog_get_content_area (password_dialog);
+
 	/* Override GtkDialog defaults */
-	widget = password_dialog->vbox;
-	gtk_box_set_spacing (GTK_BOX (widget), 12);
-	gtk_container_set_border_width (GTK_CONTAINER (widget), 0);
-	widget = password_dialog->action_area;
-	gtk_box_set_spacing (GTK_BOX (widget), 12);
-	gtk_container_set_border_width (GTK_CONTAINER (widget), 0);
+	gtk_box_set_spacing (GTK_BOX (action_area), 12);
+	gtk_container_set_border_width (GTK_CONTAINER (action_area), 0);
+	gtk_box_set_spacing (GTK_BOX (content_area), 12);
+	gtk_container_set_border_width (GTK_CONTAINER (content_area), 0);
 
 	/* Table */
 	container = gtk_table_new (2, 3, FALSE);
@@ -1141,8 +1144,7 @@
 	gtk_widget_show (container);
 
 	gtk_box_pack_start (
-		GTK_BOX (password_dialog->vbox),
-		container, FALSE, TRUE, 0);
+		GTK_BOX (content_area), container, FALSE, TRUE, 0);
 
 	/* Password Image */
 	widget = gtk_image_new_from_icon_name (

Modified: branches/camel-gobject/libedataserverui/e-source-combo-box.c
==============================================================================
--- branches/camel-gobject/libedataserverui/e-source-combo-box.c	(original)
+++ branches/camel-gobject/libedataserverui/e-source-combo-box.c	Thu Apr 16 01:23:17 2009
@@ -108,14 +108,13 @@
 	gboolean iter_valid;
 
 	priv = source_combo_box->priv;
-	g_hash_table_remove_all (priv->uid_index);
 
 	combo_box = GTK_COMBO_BOX (source_combo_box);
-	gtk_combo_box_set_active (combo_box, -1);
 
 	model = gtk_combo_box_get_model (combo_box);
 	store = GTK_LIST_STORE (model);
-	gtk_list_store_clear (store);
+
+	gtk_tree_model_get_iter_first (model, &iter);
 
 	for (groups = e_source_list_peek_groups (source_list);
 		groups != NULL; groups = groups->next) {
@@ -125,7 +124,8 @@
 			continue;
 
 		name = e_source_group_peek_name (groups->data);
-		gtk_list_store_append (store, &iter);
+		if (!gtk_list_store_iter_is_valid (store, &iter))
+			gtk_list_store_append (store, &iter);
 		gtk_list_store_set (
 			store, &iter,
 			COLUMN_COLOR, NULL,
@@ -133,6 +133,7 @@
 			COLUMN_SENSITIVE, FALSE,
 			COLUMN_SOURCE, groups->data,
 			-1);
+		gtk_tree_model_iter_next (model, &iter);
 
 		sources = get_sorted_sources (e_source_group_peek_sources (groups->data));
 		for (s = sources; s != NULL; s = s->next) {
@@ -148,7 +149,8 @@
 				visible = TRUE;
 			}
 
-			gtk_list_store_append (store, &iter);
+			if (!gtk_list_store_iter_is_valid (store, &iter))
+				gtk_list_store_append (store, &iter);
 			gtk_list_store_set (
 				store, &iter,
 				COLUMN_COLOR, color_spec ? &color : NULL,
@@ -159,16 +161,21 @@
 
 			uid = e_source_peek_uid (s->data);
 			path = gtk_tree_model_get_path (model, &iter);
-			g_hash_table_insert (
+			g_hash_table_replace (
 				priv->uid_index, g_strdup (uid),
 				gtk_tree_row_reference_new (model, path));
 			gtk_tree_path_free (path);
+			gtk_tree_model_iter_next (model, &iter);
 
 			g_free (indented_name);
 		}
 		g_slist_free (sources);
 	}
 
+	/* Remove any extra references that might be leftover from the original model */
+	while (gtk_list_store_iter_is_valid (store, &iter))
+		gtk_list_store_remove (store, &iter);
+
 	/* Set the visible column based on whether we've seen a color. */
 	iter_valid = gtk_tree_model_get_iter_first (model, &iter);
 	while (iter_valid) {

Modified: branches/camel-gobject/libedataserverui/e-source-option-menu.c
==============================================================================
--- branches/camel-gobject/libedataserverui/e-source-option-menu.c	(original)
+++ branches/camel-gobject/libedataserverui/e-source-option-menu.c	Thu Apr 16 01:23:17 2009
@@ -126,7 +126,7 @@
 
 		gtk_widget_set_sensitive (item1, FALSE);
 		gtk_widget_show (item1);
-		gtk_menu_append (GTK_MENU (menu), item1);
+		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item1);
 
 		i ++;
 

Modified: branches/camel-gobject/libedataserverui/e-source-selector-dialog.c
==============================================================================
--- branches/camel-gobject/libedataserverui/e-source-selector-dialog.c	(original)
+++ branches/camel-gobject/libedataserverui/e-source-selector-dialog.c	Thu Apr 16 01:23:17 2009
@@ -86,18 +86,23 @@
 e_source_selector_dialog_init (ESourceSelectorDialog *dialog)
 {
 	ESourceSelectorDialogPrivate *priv;
+	GtkWidget *action_area;
+	GtkWidget *content_area;
 
 	priv = g_new0 (ESourceSelectorDialogPrivate, 1);
 	priv->selected_source = NULL;
 	dialog->priv = priv;
 
+	action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
+	content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
 	/* prepare the dialog */
 	gtk_window_set_title (GTK_WINDOW (dialog), _("Select destination"));
 	gtk_window_set_default_size (GTK_WINDOW (dialog), 320, 240);
 	gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
 	gtk_widget_ensure_style (GTK_WIDGET (dialog));
-	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 0);
-	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 12);
+	gtk_container_set_border_width (GTK_CONTAINER (content_area), 0);
+	gtk_container_set_border_width (GTK_CONTAINER (action_area), 12);
 	gtk_dialog_add_buttons (GTK_DIALOG (dialog),
 				GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 				GTK_STOCK_OK, GTK_RESPONSE_OK,
@@ -135,14 +140,17 @@
 setup_dialog (GtkWindow *parent, ESourceSelectorDialog *dialog, ESourceList *source_list)
 {
 	GtkWidget *vbox, *label, *scroll, *hbox, *spacer;
+	GtkWidget *content_area;
 	char *label_text;
 	ESourceSelectorDialogPrivate *priv = dialog->priv;
 
 	priv->source_list = g_object_ref (source_list);
 
+	content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
 	vbox = gtk_vbox_new (FALSE, 12);
 	gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
-	gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
+	gtk_container_add (GTK_CONTAINER (content_area), vbox);
 	gtk_widget_show (vbox);
 
 	label_text = g_strdup_printf ("<b>%s</b>", _("_Destination"));

Modified: branches/camel-gobject/libedataserverui/e-source-selector.c
==============================================================================
--- branches/camel-gobject/libedataserverui/e-source-selector.c	(original)
+++ branches/camel-gobject/libedataserverui/e-source-selector.c	Thu Apr 16 01:23:17 2009
@@ -75,6 +75,63 @@
 
 G_DEFINE_TYPE (ESourceSelector, e_source_selector, GTK_TYPE_TREE_VIEW)
 
+/* safe-toggle-renderer definition - it'll not call 'toggled' signal on 'activate', when mouse is not over the toggle */
+
+typedef struct _ECellRendererSafeToggle {
+	GtkCellRendererToggle parent;
+} ECellRendererSafeToggle;
+
+typedef struct _ECellRendererSafeToggleClass {
+	GtkCellRendererToggleClass parent_class;
+} ECellRendererSafeToggleClass;
+
+GType e_cell_renderer_safe_toggle_get_type (void);
+
+G_DEFINE_TYPE (ECellRendererSafeToggle, e_cell_renderer_safe_toggle, GTK_TYPE_CELL_RENDERER_TOGGLE)
+
+static gboolean
+safe_toggle_activate (GtkCellRenderer      *cell,
+		      GdkEvent             *event,
+		      GtkWidget            *widget,
+		      const gchar          *path,
+		      GdkRectangle         *background_area,
+		      GdkRectangle         *cell_area,
+		      GtkCellRendererState  flags)
+{
+	if (event->type == GDK_BUTTON_PRESS && cell_area) {
+		GdkRegion *reg = gdk_region_rectangle (cell_area);
+
+		if (!gdk_region_point_in (reg, event->button.x, event->button.y)) {
+			gdk_region_destroy (reg);
+			return FALSE;
+		}
+
+		gdk_region_destroy (reg);
+	}
+
+	return GTK_CELL_RENDERER_CLASS (e_cell_renderer_safe_toggle_parent_class)->activate (cell, event, widget, path, background_area, cell_area, flags);
+}
+
+static void
+e_cell_renderer_safe_toggle_class_init (ECellRendererSafeToggleClass *klass)
+{
+	GtkCellRendererClass *rndr_class;
+	
+	rndr_class = GTK_CELL_RENDERER_CLASS (klass);
+	rndr_class->activate = safe_toggle_activate;
+}
+
+static void
+e_cell_renderer_safe_toggle_init (ECellRendererSafeToggle *obj)
+{
+}
+
+static GtkCellRenderer *
+e_cell_renderer_safe_toggle_new (void)
+{
+	return g_object_new (e_cell_renderer_safe_toggle_get_type (), NULL);
+}
+
 /* Selection management.  */
 
 static GHashTable *
@@ -1120,7 +1177,7 @@
 	g_object_set (G_OBJECT (cell_renderer), "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
 	gtk_tree_view_column_pack_start (column, cell_renderer, FALSE);
 	gtk_tree_view_column_set_cell_data_func (column, cell_renderer, (GtkTreeCellDataFunc) pixbuf_cell_data_func, selector, NULL);
-	cell_renderer = gtk_cell_renderer_toggle_new ();
+	cell_renderer = e_cell_renderer_safe_toggle_new ();
 	gtk_tree_view_column_pack_start (column, cell_renderer, FALSE);
 	gtk_tree_view_column_set_cell_data_func (column, cell_renderer, (GtkTreeCellDataFunc) toggle_cell_data_func, selector, NULL);
 	g_signal_connect (cell_renderer, "toggled", G_CALLBACK (cell_toggled_callback), selector);

Modified: branches/camel-gobject/libedataserverui/e-tree-model-generator.c
==============================================================================
--- branches/camel-gobject/libedataserverui/e-tree-model-generator.c	(original)
+++ branches/camel-gobject/libedataserverui/e-tree-model-generator.c	Thu Apr 16 01:23:17 2009
@@ -770,7 +770,7 @@
 void
 e_tree_model_generator_set_generate_func (ETreeModelGenerator *tree_model_generator,
 					  ETreeModelGeneratorGenerateFunc func,
-					  gpointer data, GtkDestroyNotify destroy)
+					  gpointer data, GDestroyNotify destroy)
 {
 	g_return_if_fail (E_IS_TREE_MODEL_GENERATOR (tree_model_generator));
 
@@ -793,7 +793,7 @@
 void
 e_tree_model_generator_set_modify_func (ETreeModelGenerator *tree_model_generator,
 					ETreeModelGeneratorModifyFunc func,
-					gpointer data, GtkDestroyNotify destroy)
+					gpointer data, GDestroyNotify destroy)
 {
 	g_return_if_fail (E_IS_TREE_MODEL_GENERATOR (tree_model_generator));
 

Modified: branches/camel-gobject/libedataserverui/e-tree-model-generator.h
==============================================================================
--- branches/camel-gobject/libedataserverui/e-tree-model-generator.h	(original)
+++ branches/camel-gobject/libedataserverui/e-tree-model-generator.h	Thu Apr 16 01:23:17 2009
@@ -25,14 +25,26 @@
 
 #include <gtk/gtk.h>
 
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_TREE_MODEL_GENERATOR \
+	(e_tree_model_generator_get_type ())
+#define E_TREE_MODEL_GENERATOR(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_TREE_MODEL_GENERATOR, ETreeModelGenerator))
+#define E_TREE_MODEL_GENERATOR_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_TREE_MODEL_GENERATOR, ETreeModelGeneratorClass))
+#define E_IS_TREE_MODEL_GENERATOR(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_TREE_MODEL_GENERATOR))
+#define E_IS_TREE_MODEL_GENERATOR_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_TREE_MODEL_GENERATOR))
+#define E_TREE_MODEL_GENERATOR_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_TREE_MODEL_GENERATOR, ETreeModelGeneratorClass))
 
-#define E_TYPE_TREE_MODEL_GENERATOR            (e_tree_model_generator_get_type ())
-#define E_TREE_MODEL_GENERATOR(obj)	       (GTK_CHECK_CAST ((obj), E_TYPE_TREE_MODEL_GENERATOR, ETreeModelGenerator))
-#define E_TREE_MODEL_GENERATOR_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_TREE_MODEL_GENERATOR, ETreeModelGeneratorClass))
-#define E_IS_TREE_MODEL_GENERATOR(obj)         (GTK_CHECK_TYPE ((obj), E_TYPE_TREE_MODEL_GENERATOR))
-#define E_IS_TREE_MODEL_GENERATOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_TREE_MODEL_GENERATOR))
-#define E_TREE_MODEL_GENERATOR_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), E_TYPE_TREE_MODEL_GENERATOR, ETreeModelGeneratorClass))
+G_BEGIN_DECLS
 
 typedef gint (*ETreeModelGeneratorGenerateFunc) (GtkTreeModel *model, GtkTreeIter *child_iter,
 						 gpointer data);
@@ -63,17 +75,17 @@
 	gpointer                         modify_func_data;
 };
 
-GtkType              e_tree_model_generator_get_type                   (void);
+GType                e_tree_model_generator_get_type                   (void);
 
 ETreeModelGenerator *e_tree_model_generator_new                        (GtkTreeModel *child_model);
 GtkTreeModel        *e_tree_model_generator_get_model                  (ETreeModelGenerator *tree_model_generator);
 
 void                 e_tree_model_generator_set_generate_func          (ETreeModelGenerator *tree_model_generator,
 									ETreeModelGeneratorGenerateFunc func,
-									gpointer data, GtkDestroyNotify destroy);
+									gpointer data, GDestroyNotify destroy);
 void                 e_tree_model_generator_set_modify_func            (ETreeModelGenerator *tree_model_generator,
 									ETreeModelGeneratorModifyFunc func,
-									gpointer data, GtkDestroyNotify destroy);
+									gpointer data, GDestroyNotify destroy);
 
 GtkTreePath         *e_tree_model_generator_convert_child_path_to_path (ETreeModelGenerator *tree_model_generator,
 									GtkTreePath *child_path);

Modified: branches/camel-gobject/po/LINGUAS
==============================================================================
--- branches/camel-gobject/po/LINGUAS	(original)
+++ branches/camel-gobject/po/LINGUAS	Thu Apr 16 01:23:17 2009
@@ -42,6 +42,7 @@
 ku
 lt
 lv
+mai
 mk
 ml
 mn

Modified: branches/camel-gobject/po/POTFILES.in
==============================================================================
--- branches/camel-gobject/po/POTFILES.in	(original)
+++ branches/camel-gobject/po/POTFILES.in	Thu Apr 16 01:23:17 2009
@@ -205,6 +205,8 @@
 libedataserverui/e-book-auth-util.c
 libedataserverui/e-categories-dialog.c
 libedataserverui/e-categories-dialog.glade
+libedataserverui/e-category-completion.c
+libedataserverui/e-cell-renderer-color.c
 libedataserverui/e-name-selector-dialog.c
 libedataserverui/e-name-selector-dialog.glade
 libedataserverui/e-name-selector-entry.c
@@ -220,4 +222,3 @@
 servers/groupwise/e-gw-connection.c
 src/GNOME_Evolution_DataServer.server.in.in
 src/server.c
-libedataserverui/e-cell-renderer-color.c

Modified: branches/camel-gobject/po/POTFILES.skip
==============================================================================
--- branches/camel-gobject/po/POTFILES.skip	(original)
+++ branches/camel-gobject/po/POTFILES.skip	Thu Apr 16 01:23:17 2009
@@ -5,6 +5,4 @@
 camel/providers/nntp/camel-nntp-newsrc.c
 camel/providers/nntp/camel-nntp-utils.c
 camel/providers/nntp/test-newsrc.c
-calendar/libical/src/libicalss/icalssyacc.c
-calendar/libical/src/libicalvcal/vcc.c
 servers/exchange/lib/e2k-user-dialog.c

Modified: branches/camel-gobject/servers/exchange/lib/Makefile.am
==============================================================================
--- branches/camel-gobject/servers/exchange/lib/Makefile.am	(original)
+++ branches/camel-gobject/servers/exchange/lib/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -2,13 +2,13 @@
 
 INCLUDES =                                                      \
 	-DCONNECTOR_PREFIX=\""$(prefix)"\"			\
+	-I$(top_srcdir)						\
+	-I$(top_srcdir)/servers/exchange/xntlm			\
 	$(LDAP_CFLAGS)						\
 	$(KRB5_CFLAGS)						\
 	$(SOUP_CFLAGS)						\
 	$(E_DATA_SERVER_CFLAGS)					\
-	$(E_DATA_SERVER_UI_CFLAGS)				\
-	-I$(top_srcdir)						\
-	-I$(top_srcdir)/servers/exchange/xntlm
+	$(E_DATA_SERVER_UI_CFLAGS)
 
 noinst_LTLIBRARIES =						\
 	libexchange.la

Modified: branches/camel-gobject/servers/exchange/lib/e2k-context.c
==============================================================================
--- branches/camel-gobject/servers/exchange/lib/e2k-context.c	(original)
+++ branches/camel-gobject/servers/exchange/lib/e2k-context.c	Thu Apr 16 01:23:17 2009
@@ -145,7 +145,7 @@
 	if (!e_proxy_require_proxy_for_uri (proxy, ctx->priv->owa_uri))
 		proxy_uri = NULL;
 	else
-		proxy_uri = e_proxy_peek_uri (proxy);
+		proxy_uri = e_proxy_peek_uri_for (proxy, ctx->priv->owa_uri);
 
 	if (ctx->priv->session)
 		g_object_set (ctx->priv->session, SOUP_SESSION_PROXY_URI,
@@ -436,7 +436,7 @@
 
 	/* Check do we need a proxy to contact the server? */
         if (e_proxy_require_proxy_for_uri (ctx->priv->proxy, ctx->priv->owa_uri))
-                uri = e_proxy_peek_uri (ctx->priv->proxy);
+                uri = e_proxy_peek_uri_for (ctx->priv->proxy, ctx->priv->owa_uri);
 
 	ctx->priv->session = soup_session_sync_new_with_options (
 		SOUP_SESSION_USE_NTLM, !authmech || !strcmp (authmech, "NTLM"),
@@ -466,8 +466,10 @@
 		soup_logger_set_request_filter (logger, e2k_debug_request_filter, NULL, NULL);
 		soup_logger_set_response_filter (logger, e2k_debug_response_filter, NULL, NULL);
 	}
-	soup_logger_attach (logger, ctx->priv->session);
-	soup_logger_attach (logger, ctx->priv->async_session);
+	soup_session_add_feature (
+		ctx->priv->session, SOUP_SESSION_FEATURE (logger));
+	soup_session_add_feature (
+		ctx->priv->async_session, SOUP_SESSION_FEATURE (logger));
 #endif
 }
 
@@ -613,8 +615,31 @@
 		g_free (suri->path);
 		suri->path = g_strdup (value);
 		action = soup_uri_to_string (suri, FALSE);
-		soup_uri_decode (action);
 		soup_uri_free (suri);
+	} else if (strncmp(value, "http", 4) != 0) {
+		SoupURI *suri;
+		char *path_end;
+		const char *location;
+
+		location = soup_message_headers_get (failed_msg->response_headers,
+		                                     "Location");
+		if (location != NULL) {/*Make sure we can get absolute path*/
+			suri = soup_uri_new (location);
+			if (suri != NULL) {/*Valid URI*/
+				if (!suri->path || strchr (suri->path, '/') == NULL)
+					goto failed;
+
+				path_end = strrchr (suri->path, '/') + 1;
+				*path_end = '\0';
+				suri->path = g_realloc (suri->path,
+		                                path_end - suri->path + strlen (value) + 1);
+				strcat (suri->path, value);
+				g_free (suri->query);
+				suri->query = NULL;
+				action = soup_uri_to_string (suri, FALSE);
+				soup_uri_free (suri);
+			}
+		}
 	} else
 		action = g_strdup (value);
 	xmlFree (value);
@@ -650,7 +675,7 @@
 	xmlFreeDoc (doc);
 	doc = NULL;
 
-	form_body = soup_form_encode_urlencoded (form_data);
+	form_body = soup_form_encode_hash (form_data);
 	g_hash_table_destroy (form_data);
 
 	post_msg = e2k_soup_message_new_full (ctx, action, "POST",

Modified: branches/camel-gobject/servers/exchange/storage/Makefile.am
==============================================================================
--- branches/camel-gobject/servers/exchange/storage/Makefile.am	(original)
+++ branches/camel-gobject/servers/exchange/storage/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -13,15 +13,15 @@
 	-DLIBDIR=\""$(datadir)"\"	 			\
 	-DCONNECTOR_LOCALEDIR=\""$(localedir)\""		\
 	-DCONNECTOR_GLADEDIR=\""$(gladedir)"\"			\
+	-I$(top_builddir)/servers/exchange/lib			\
+	-I$(top_srcdir)						\
+	-I$(top_srcdir)/servers/exchange/lib			\
+	-I$(top_srcdir)/servers/exchange/xntlm			\
 	$(KRB5_CFLAGS)						\
 	$(LDAP_CFLAGS)						\
 	$(SOUP_CFLAGS)						\
 	$(E_DATA_SERVER_CFLAGS)					\
-	$(E_DATA_SERVER_UI_CFLAGS)				\
-	-I$(top_builddir)/servers/exchange/lib			\
-	-I$(top_srcdir)						\
-	-I$(top_srcdir)/servers/exchange/lib			\
-	-I$(top_srcdir)/servers/exchange/xntlm
+	$(E_DATA_SERVER_UI_CFLAGS)
 
 lib_LTLIBRARIES =						\
 	libexchange-storage-1.2.la

Modified: branches/camel-gobject/servers/exchange/storage/exchange-esource.c
==============================================================================
--- branches/camel-gobject/servers/exchange/storage/exchange-esource.c	(original)
+++ branches/camel-gobject/servers/exchange/storage/exchange-esource.c	Thu Apr 16 01:23:17 2009
@@ -126,7 +126,7 @@
 		}
 
 		if (foriegn_folder && (folder_type != EXCHANGE_CONTACTS_FOLDER)) {
-			e_source_set_property (source, "alarm", "never");
+			e_source_set_property (source, "alarm", "false");
 			e_source_set_property (source, "foreign", "1");
 			e_source_set_property (source, "subscriber", useremail);
 		}
@@ -174,7 +174,7 @@
 				e_source_set_property (source, "auth", "1");
 
 			if (foriegn_folder && (folder_type != EXCHANGE_CONTACTS_FOLDER)) {
-				e_source_set_property (source, "alarm", "never");
+				e_source_set_property (source, "alarm", "false");
 				e_source_set_property (source, "foreign", "1");
 				e_source_set_property (source, "subscriber", useremail);
 			}

Modified: branches/camel-gobject/servers/exchange/storage/exchange-hierarchy-foreign.c
==============================================================================
--- branches/camel-gobject/servers/exchange/storage/exchange-hierarchy-foreign.c	(original)
+++ branches/camel-gobject/servers/exchange/storage/exchange-hierarchy-foreign.c	Thu Apr 16 01:23:17 2009
@@ -268,7 +268,6 @@
 	{ N_("Sent Items"),	E2K_PR_STD_FOLDER_SENT_ITEMS },
 	{ N_("Tasks"),		E2K_PR_STD_FOLDER_TASKS }
 };
-const static int n_std_folders = sizeof (std_folders) / sizeof (std_folders[0]);
 static ExchangeAccountFolderResult
 create_internal (ExchangeHierarchy *hier, EFolder *parent,
 		 const char *name, const char *type, EFolder **folder_out)
@@ -293,7 +292,7 @@
 		return EXCHANGE_ACCOUNT_FOLDER_ALREADY_EXISTS;
 	}
 
-	for (i = 0; i < n_std_folders; i++) {
+	for (i = 0; i < G_N_ELEMENTS (std_folders); i++) {
 		if (g_ascii_strcasecmp (std_folders[i].name, name) != 0 &&
 		    g_utf8_collate (_(std_folders[i].name), name) != 0)
 			continue;

Modified: branches/camel-gobject/servers/google/libgdata-google/Makefile.am
==============================================================================
--- branches/camel-gobject/servers/google/libgdata-google/Makefile.am	(original)
+++ branches/camel-gobject/servers/google/libgdata-google/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -3,8 +3,7 @@
 	-I$(top_srcdir)						\
 	-I$(top_builddir)					\
 	-I$(top_srcdir)/servers/google/libgdata			\
-	$(SOUP_CFLAGS)						\
-	$(E_DATA_SERVER_CFLAGS)
+	$(GDATA_CFLAGS)
 
 lib_LTLIBRARIES = libgdata-google-1.2.la
 
@@ -14,8 +13,7 @@
 
 libgdata_google_1_2_la_LIBADD =					\
 	$(top_builddir)/servers/google/libgdata/libgdata-1.2.la	\
-	$(E_DATA_SERVER_LIBS)					\
-	$(SOUP_LIBS)
+	$(GDATA_LIBS)
 
 libgdata_google_1_2_la_LDFLAGS =	                       \
         -version-info $(LIBGDATA_GOOGLE_CURRENT):$(LIBGDATA_GOOGLE_REVISION):$(LIBGDATA_GOOGLE_AGE) $(NO_UNDEFINED)

Modified: branches/camel-gobject/servers/google/libgdata-google/gdata-google-service.c
==============================================================================
--- branches/camel-gobject/servers/google/libgdata-google/gdata-google-service.c	(original)
+++ branches/camel-gobject/servers/google/libgdata-google/gdata-google-service.c	Thu Apr 16 01:23:17 2009
@@ -190,7 +190,8 @@
 	soup_session_send_message (soup_session, msg);
 	if (msg->status_code != 200) {
 		g_set_error (error, SOUP_HTTP_ERROR,
-					 msg->status_code, msg->reason_phrase);
+					 msg->status_code, "%s", msg->reason_phrase);
+
 		g_object_unref (msg);
 		return NULL;
 	}
@@ -262,7 +263,7 @@
 
 	if (msg->status_code != 201) {
 		g_set_error (error, SOUP_HTTP_ERROR,
-					 msg->status_code, msg->reason_phrase);
+					 msg->status_code, "%s", msg->reason_phrase);
 		g_object_unref (msg);
 		return NULL;
 	}
@@ -324,7 +325,7 @@
 
     	if (msg->status_code != 200) {
 		g_set_error (error, SOUP_HTTP_ERROR,
-					 msg->status_code, msg->reason_phrase);
+					 msg->status_code, "%s", msg->reason_phrase);
 	} else {
 		retval = TRUE;
 	}
@@ -408,7 +409,7 @@
 
     	if (msg->status_code != 200) {
 		g_set_error (error, SOUP_HTTP_ERROR,
-					 msg->status_code, msg->reason_phrase);
+					 msg->status_code, "%s", msg->reason_phrase);
 		g_object_unref (msg);
 		return updated_entry;
 	}
@@ -689,7 +690,7 @@
 	g_hash_table_insert (request_form, "service", priv->name);
 	g_hash_table_insert (request_form, "source", priv->agent);
 	g_hash_table_insert (request_form, "accountType", "HOSTED_OR_GOOGLE");
-	request_body = soup_form_encode_urlencoded (request_form);
+	request_body = soup_form_encode_hash (request_form);
 	g_hash_table_destroy (request_form);
 
 	msg = soup_message_new(SOUP_METHOD_POST, GOOGLE_CLIENT_LOGIN);
@@ -702,7 +703,7 @@
 
     	if (msg->status_code != 200) {
 		g_set_error (error, SOUP_HTTP_ERROR,
-					 msg->status_code, msg->reason_phrase);
+					 msg->status_code, "%s", msg->reason_phrase);
 		g_object_unref(msg);
 		return (NULL != token);
 	}

Modified: branches/camel-gobject/servers/google/libgdata-google/libgdata-google.pc.in
==============================================================================
--- branches/camel-gobject/servers/google/libgdata-google/libgdata-google.pc.in	(original)
+++ branches/camel-gobject/servers/google/libgdata-google/libgdata-google.pc.in	Thu Apr 16 01:23:17 2009
@@ -5,14 +5,12 @@
 datarootdir= datarootdir@
 datadir= datadir@
 
-idldir= idldir@
-IDL_INCLUDES=-I${idldir} @IDL_INCLUDES@
-
 privincludedir= privincludedir@
 
 Name: libgdata-google
 Description: Client library for accessing google POA through SOAP interface
 Version: @VERSION@
 Requires: libsoup-2.4 >= @LIBSOUP_REQUIRED@ 
+Requires.private: libgdata-1.2
 Libs: -L${libdir} -lgdata-google-1.2
-Cflags: -I${privincludedir}/google/libgdata -I${privincludedir}/google/libgdata-google
+Cflags: -I${privincludedir}/google/libgdata-google

Modified: branches/camel-gobject/servers/google/libgdata/Makefile.am
==============================================================================
--- branches/camel-gobject/servers/google/libgdata/Makefile.am	(original)
+++ branches/camel-gobject/servers/google/libgdata/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -2,8 +2,7 @@
 	-DG_LOG_DOMAIN=\"libgdata\"			\
 	-I$(top_srcdir)					\
 	-I$(top_builddir)				\
-	$(SOUP_CFLAGS)					\
-	$(E_DATA_SERVER_CFLAGS)
+	$(GDATA_CFLAGS)
 
 lib_LTLIBRARIES = libgdata-1.2.la
 
@@ -16,8 +15,7 @@
 	gdata-service-iface.h			
 
 libgdata_1_2_la_LIBADD =			\
-	$(E_DATA_SERVER_LIBS)			\
-	$(SOUP_LIBS)
+	$(GDATA_LIBS)
 
 libgdata_1_2_la_LDFLAGS =                       \
         -version-info $(LIBGDATA_CURRENT):$(LIBGDATA_REVISION):$(LIBGDATA_AGE) $(NO_UNDEFINED)

Modified: branches/camel-gobject/servers/google/libgdata/libgdata.pc.in
==============================================================================
--- branches/camel-gobject/servers/google/libgdata/libgdata.pc.in	(original)
+++ branches/camel-gobject/servers/google/libgdata/libgdata.pc.in	Thu Apr 16 01:23:17 2009
@@ -5,9 +5,6 @@
 datarootdir= datarootdir@
 datadir= datadir@
 
-idldir= idldir@
-IDL_INCLUDES=-I${idldir} @IDL_INCLUDES@
-
 privincludedir= privincludedir@
 
 Name: libgdata

Modified: branches/camel-gobject/servers/groupwise/e-gw-connection.c
==============================================================================
--- branches/camel-gobject/servers/groupwise/e-gw-connection.c	(original)
+++ branches/camel-gobject/servers/groupwise/e-gw-connection.c	Thu Apr 16 01:23:17 2009
@@ -75,7 +75,7 @@
 		return;
 	
 	if (e_proxy_require_proxy_for_uri (proxy, uri))
-		proxy_uri = e_proxy_peek_uri (proxy);
+		proxy_uri = e_proxy_peek_uri_for (proxy, uri);
 
 	g_object_set (session, SOUP_SESSION_PROXY_URI,
 		      proxy_uri, NULL);	
@@ -839,8 +839,9 @@
 				return NULL;
 		}
 
-		e_gw_message_write_string_parameter (msg, "uid", NULL, uid);
-		e_gw_message_write_string_parameter (msg, "view", NULL, "count unreadCount");
+		e_gw_message_write_string_parameter (msg, "id", NULL, uid);
+		/* The server does not feel good if the name, id view elements are not passed */
+		e_gw_message_write_string_parameter (msg, "view", NULL, "name id uid count unreadCount");
 		e_gw_message_write_footer (msg);
 
 		/* send message to server */
@@ -1810,46 +1811,6 @@
 	return (const char *) cnc->priv->server_time ;
 }
 
-static time_t
-timet_from_string (const char *str)
-{
-		struct tm date;
-		int len, i;
-
-		g_return_val_if_fail (str != NULL, -1);
-
-		/* yyyymmdd[Thhmmss[Z]] */
-		len = strlen (str);
-
-		if (!(len == 8 || len == 15 || len == 16))
-				return -1;
-
-		for (i = 0; i < len; i++)
-				if (!((i != 8 && i != 15 && isdigit (str[i]))
-										|| (i == 8 && str[i] == 'T')
-										|| (i == 15 && str[i] == 'Z')))
-						return -1;
-
-#define digit_at(x,y) (x[y] - '0')
-
-		date.tm_year = digit_at (str, 0) * 1000
-				+ digit_at (str, 1) * 100
-				+ digit_at (str, 2) * 10
-				+ digit_at (str, 3) -1900;
-		date.tm_mon = digit_at (str, 4) * 10 + digit_at (str, 5) -1;
-		date.tm_mday = digit_at (str, 6) * 10 + digit_at (str, 7);
-		if (len > 8) {
-				date.tm_hour = digit_at (str, 9) * 10 + digit_at (str, 10);
-				date.tm_min  = digit_at (str, 11) * 10 + digit_at (str, 12);
-				date.tm_sec  = digit_at (str, 13) * 10 + digit_at (str, 14);
-		} else
-				date.tm_hour = date.tm_min = date.tm_sec = 0;
-
-		date.tm_wday = date.tm_yday = date.tm_isdst = 0;
-
-		return mktime (&date);
-}
-
 char *
 e_gw_connection_format_date_string (const char *dtstring)
 {
@@ -1874,24 +1835,35 @@
 time_t
 e_gw_connection_get_date_from_string (const char *dtstring)
 {
-        char *str2;
-	int i, j, len;
-	time_t t;
+	time_t t = 0;
+	GTimeVal t_val;
 
 	g_return_val_if_fail (dtstring != NULL, 0);
 
-	len = strlen (dtstring);
-        str2 = g_malloc0 (len+1);
-        for (i = 0,j = 0; i < len; i++) {
-                if ((dtstring[i] != '-') && (dtstring[i] != ':')) {
-			str2[j] = dtstring[i];
-			j++;
-                }
-        }
+	if (g_time_val_from_iso8601 (dtstring, &t_val)) {
+		t = (time_t) t_val.tv_sec;
+	} else if (strlen (dtstring) == 8) {
+		/* It might be a date value */
+		GDate date;
+		struct tm tt;
 
-	str2[j] = '\0';
-	t = timet_from_string (str2);
-	g_free (str2);
+		g_date_clear (&date, 1);
+#define digit_at(x,y) (x[y] - '0')
+		guint16 year = digit_at (dtstring, 0) * 1000
+				+ digit_at (dtstring, 1) * 100
+				+ digit_at (dtstring, 2) * 10
+				+ digit_at (dtstring, 3);
+		guint month = digit_at (dtstring, 4) * 10 + digit_at (dtstring, 5);
+		guint8 day = digit_at (dtstring, 6) * 10 + digit_at (dtstring, 7);
+		g_date_set_year (&date, year);
+		g_date_set_month (&date, month);
+		g_date_set_day (&date, day);
+
+		g_date_to_struct_tm (&date, &tt);
+		t = mktime (&tt);
+
+	} else 
+		g_warning ("Could not parse the string \n");
 
         return t;
 }

Modified: branches/camel-gobject/servers/groupwise/e-gw-container.c
==============================================================================
--- branches/camel-gobject/servers/groupwise/e-gw-container.c	(original)
+++ branches/camel-gobject/servers/groupwise/e-gw-container.c	Thu Apr 16 01:23:17 2009
@@ -205,25 +205,26 @@
 	/* retrieve the name */
 	subparam = soup_soap_parameter_get_first_child_by_name (param, "name");
 	if (!subparam) {
-		g_warning (G_STRLOC ": found container with no name");
-		return FALSE;
+			/* GroupWise 7.X servers does not return the name field. 
+			This is not an issue with Bonsai 8.X . So, keep this code for 
+			working well with the broken GW 7.X series */
+			e_gw_container_set_name (container, "");
+	} else {
+			value = soup_soap_parameter_get_string_value (subparam);
+			e_gw_container_set_name (container, (const char *) value);
+			g_free (value);
 	}
 
-	value = soup_soap_parameter_get_string_value (subparam);
-	e_gw_container_set_name (container, (const char *) value);
-	g_free (value);
-
 	/* retrieve the ID */
 	subparam = soup_soap_parameter_get_first_child_by_name (param, "id");
 	if (!subparam) {
-		g_warning (G_STRLOC ": found container with no ID");
-		return FALSE;
+			e_gw_container_set_id (container, "");
+	} else {
+			value = soup_soap_parameter_get_string_value (subparam);
+			e_gw_container_set_id (container, (const char *) value);
+			g_free (value);
 	}
 
-	value = soup_soap_parameter_get_string_value (subparam);
-	e_gw_container_set_id (container, (const char *) value);
-	g_free (value);
-
 	/* retrieve the parent container id */
 	subparam = soup_soap_parameter_get_first_child_by_name (param, "parent");
 	if (!subparam) {

Modified: branches/camel-gobject/servers/groupwise/e-gw-item.c
==============================================================================
--- branches/camel-gobject/servers/groupwise/e-gw-item.c	(original)
+++ branches/camel-gobject/servers/groupwise/e-gw-item.c	Thu Apr 16 01:23:17 2009
@@ -3119,12 +3119,20 @@
 			max_elements = sizeof (rrule->by_day) / sizeof (rrule->by_day[0]);
 			/* expand into  a sequence of 'day' here  */
 			for (i = 0; i < max_elements && rrule->by_day [i] != E_GW_ITEM_RECUR_END_MARKER; i++) {
-				/*TODO occurence attribute */
-				e_gw_message_write_string_parameter (msg, "day", NULL,
-						e_gw_recur_get_day_of_week (rrule->by_day [i]));
+				const char *dow = e_gw_recur_get_day_of_week (rrule->by_day [i]);
+
+				if (rrule->by_setpos [i] == E_GW_ITEM_RECUR_END_MARKER)
+					e_gw_message_write_string_parameter (msg, "day", NULL, dow);
+				else {
+					char occur [3];
+
+					g_sprintf (occur, "%d", rrule->by_setpos [i]);
+					e_gw_message_write_string_parameter_with_attribute (msg, "day", NULL, dow, "occurrence", occur);
+				}
 			}
 			soup_soap_message_end_element (msg);
 		}
+
 		/* byMonthDay*/
 		if (rrule->by_month_day) {
 			int i, max_elements;

Modified: branches/camel-gobject/servers/groupwise/e-gw-recur-utils.h
==============================================================================
--- branches/camel-gobject/servers/groupwise/e-gw-recur-utils.h	(original)
+++ branches/camel-gobject/servers/groupwise/e-gw-recur-utils.h	Thu Apr 16 01:23:17 2009
@@ -50,6 +50,7 @@
 #define E_GW_ITEM_BY_MONTHDAY_SIZE 32
 #define E_GW_ITEM_BY_YEARDAY_SIZE 367
 #define E_GW_ITEM_BY_MONTH_SIZE 13
+#define E_GW_ITEM_BY_SETPOS_SIZE 367
 
 typedef struct {
 	char *frequency;
@@ -60,6 +61,7 @@
 	short by_month_day[E_GW_ITEM_BY_MONTHDAY_SIZE];
 	short by_year_day[E_GW_ITEM_BY_YEARDAY_SIZE];
 	short by_month[E_GW_ITEM_BY_MONTH_SIZE];
+	short by_setpos [E_GW_ITEM_BY_SETPOS_SIZE];
 } EGwItemRecurrenceRule;
 
 

Modified: branches/camel-gobject/src/Makefile.am
==============================================================================
--- branches/camel-gobject/src/Makefile.am	(original)
+++ branches/camel-gobject/src/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -10,10 +10,6 @@
 	-I$(top_srcdir)/calendar			\
 	-I$(top_srcdir)/calendar			\
 	-I$(top_builddir)/calendar			\
-	-I$(top_srcdir)/calendar/libical/src		\
-	-I$(top_builddir)/calendar/libical/src		\
-	-I$(top_srcdir)/calendar/libical/src/libical	\
-	-I$(top_builddir)/calendar/libical/src/libical	\
 	-DEVOLUTION_LOCALEDIR=\""$(localedir)"\"	\
 	$(SOUP_CFLAGS)					\
 	$(E_FACTORY_CFLAGS)				\
@@ -63,9 +59,13 @@
         $(E_FACTORY_LIBS)						\
 	$(E_DATA_SERVER_LIBS)
 
+if OS_WIN32
+evolution_data_server_LDFLAGS = -mwindows
+endif
+
 install-evolution-data-servers:
 	$(mkinstalldirs) $(DESTDIR)$(libexecdir)
-	$(LIBTOOL) --mode=install $(INSTALL_PROGRAM) evolution-data-server $(DESTDIR)$(libexecdir)/evolution-data-server-$(BASE_VERSION)
+	$(LIBTOOL) --mode=install $(INSTALL_PROGRAM) evolution-data-server EXEEXT@ $(DESTDIR)$(libexecdir)/evolution-data-server-$(BASE_VERSION)@EXEEXT@
 
 SERVER_IN_FILE=GNOME_Evolution_DataServer.server.in.in
 
@@ -87,7 +87,7 @@
 install-exec-local: install-evolution-data-servers
 
 uninstall-local:
-	rm -f $(DESTDIR)$(libexecdir)/evolution-data-server-$(BASE_VERSION)
+	rm -f $(DESTDIR)$(libexecdir)/evolution-data-server-$(BASE_VERSION)@EXEEXT@
 
 dist-hook:
 	cd $(distdir); rm -f $(BUILT_SOURCES)
@@ -97,7 +97,7 @@
 
 all-local: evolution-data-server.pure
 
-evolution-data-server.pure: evolution-data-server
+evolution-data-server.pure: evolution-data-server EXEEXT@
 	@rm -f evolution-data-server.pure
 	$(PLINK) $(evolution_data_server_LDFLAGS) $(evolution_data_server_OBJECTS) $(evolution_data_server_LDADD) $(LIBS)
 

Modified: branches/camel-gobject/src/server-interface-check.h
==============================================================================
--- branches/camel-gobject/src/server-interface-check.h	(original)
+++ branches/camel-gobject/src/server-interface-check.h	Thu Apr 16 01:23:17 2009
@@ -32,11 +32,21 @@
 
 G_BEGIN_DECLS
 
-#define SERVER_TYPE_INTERFACE_CHECK		(server_interface_check_get_type ())
-#define SERVER_INTERFACE_CHECK(obj)		(GTK_CHECK_CAST ((obj), SERVER_TYPE_INTERFACE_CHECK, ServerInterfaceCheck))
-#define SERVER_INTERFACE_CHECK_CLASS(klass)	(GTK_CHECK_CLASS_CAST ((klass), SERVER_TYPE_INTERFACE_CHECK, ServerInterfaceCheckClass))
-#define SERVER_IS_INTERFACE_CHECK(obj)		(GTK_CHECK_TYPE ((obj), SERVER_TYPE_INTERFACE_CHECK))
-#define SERVER_IS_INTERFACE_CHECK_CLASS(klass)	(GTK_CHECK_CLASS_TYPE ((obj), SERVER_TYPE_INTERFACE_CHECK))
+/* Standard GObject macros */
+#define SERVER_TYPE_INTERFACE_CHECK \
+	(server_interface_check_get_type ())
+#define SERVER_INTERFACE_CHECK(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), SERVER_TYPE_INTERFACE_CHECK, ServerInterfaceCheck))
+#define SERVER_INTERFACE_CHECK_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), SERVER_TYPE_INTERFACE_CHECK, ServerInterfaceCheckClass))
+#define SERVER_IS_INTERFACE_CHECK(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), SERVER_TYPE_INTERFACE_CHECK))
+#define SERVER_IS_INTERFACE_CHECK_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), SERVER_TYPE_INTERFACE_CHECK))
 
 
 typedef struct _ServerInterfaceCheck        ServerInterfaceCheck;

Modified: branches/camel-gobject/win32/Makefile.am
==============================================================================
--- branches/camel-gobject/win32/Makefile.am	(original)
+++ branches/camel-gobject/win32/Makefile.am	Thu Apr 16 01:23:17 2009
@@ -14,6 +14,6 @@
 libedataserverui-1.2.la: dummy.la libedataserverui.def
 	sed -e s!%DLL%!libedataserverui-1.2-$(libedataserverui_current_minus_age)! -e s!%LIB%!libedataserverui-1.2! -e s!%PFX%!$(prefix)! <dummy.la >$@
 	mkdir -p .libs
-	dlltool --output-lib=.libs/libedataserverui-1.2.dll.a --dllname=libedataserverui-1.2-$(libedataserverui_current_minus_age).dll --input-def=libedataserverui.def
+	$(DLLTOOL) --output-lib=.libs/libedataserverui-1.2.dll.a --dllname=libedataserverui-1.2-$(libedataserverui_current_minus_age).dll --input-def=libedataserverui.def
 
 CLEANFILES = $(BOOTSTRAP_LIBS)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]